RSA乘法同态

0x01 题目来源

https://ctf.sha2017.org/challenges?chal=13#challenge-information

0x02 解题思路

1、首先查看源码,知道题目的需求

RSA乘法同态_第1张图片

RSA乘法同态_第2张图片

从这两张图中可以看到,在输入的时候,需要输入两个字符串,在验证的时候,必须看到有“ticket:admin|root|“开头的字符串。但是,在输入后明显前面已有固定的”user“,那怎么办呢?

再来看签名的部分:
RSA乘法同态_第3张图片
在开头有固定的”\xff“需要被填充,这样防止用户去签名一个ticket。在签名阶段与加密类似,都是使用了pow函数。

2、数学背景

理解同态的含义,简单来说:
若: A * B = C mod n
则 :A^d ∗ B^d=C^d mod n
由此想到:先得到A的ticket与B的ticket,再相乘得到C的ticket

在这里:
C:是ticket:admin|root|开头的字符串
A:我用的是ticket:user|n|n
B:等待构造

对于确定的两个字符串,求得其16进制为:
‘ticket:user|n|n’
0x7469636b65743a757365727c6e7c6e

‘ticket:admin|root|’
0x7469636b65743a61646d696e7c726f6f747c

3、除运算代码(不是一次性得出的,根据输出调整)

import math
def str2num(s):
    return int(s.encode('hex'),16)
def num2str(n):
    d = ('%x' % n)
    if len(d) % 2 == 1:
        d = '0' + d
    return d.decode('hex')
n = 25504352309535290475248970674346405639150033303276037621954645287836414954584485104061261800020387562499019659311665606506084209652278825297538342995446093360707480284955051977871508969158833725741319229528482243960926606982225623875037437446029764584076579733157399563314682454896733000474399703682370015847387660034753890964070709371374885394037462378877025773834640334396506494513394772275132449199231593014288079343099475952658539203870198753180108893634430428519877349292223234156296946657199158953622932685066947832834071847602426570899103186305452954512045960946081356967938725965154991111592790767330692701669
s0 = int('0x7469636b65743a757365727c6e7c6e',16)  #n
s1 = int('0x7469636b65743a61646d696e7c726f6f747c4646546546456545465445454651321321345641',16)   #admin...
s2 = 0xffffffffffffffd3e3bae71d4e9ed4c26187cf5cfc0b72L

print "s1/s0:"+ num2str(s1/s0)
print 's0:'+ num2str(s0)
print 's1:'+num2str(s1)
#print 's1:'+num2str(s2)
print 's0*s2:'+ num2str(s2*s0)
#print s1
print hex(s1/s0)

sig1= int('0xc93e98ac7f97813d1f0ace708b35b581cb63a1a26db15f83e31e4926fe2c46c08152af5b9f219de1fdb021090cf18b2830ec689ac0df5f702e87fca92a3eb5cb98fec4bb4b5c5a342a0e16e6e228e0229072b3c6f6a8ba89386f38562d0f15baf5851cb3bd43b21b3c05373f51b419bc6e5f4217402cf9f9abcbc47bcfffbdf040761365e841b1f3d132ffbd1230133084b33dc93aa2e4ef66b1168ab6077d34e0f8cfcf3bd14fc8114384a255e376efed2c1035fb1b1e707073ed6e79aeb1a161bb17263366e284b2c7c4244cf85126cb3f1f74431905a3386bc587959c15e64a5d5e00575f551758ed3a1fd57a6d9a134d01e66dc5404f4b28b673fc46c3f6',16)
sig2= int('0x34b067f78759edb80611b8948010a072130b817977e8105b6b08ec5c81f74e4dbf6a8fd4d7408efc0a60d4c1a5b3f7f3d068ee90b1267f9a0a1fc39827578fc4284115d976003689627962f1927540107693a47f32a03a9f3c0e7ac7fb97cbfb8b2ccc88c2715fbc174bdc59dc8b15947ef2080e9f5619e1cbb8b04b3d26cabf68bf57bb36bc31302ea7ef6d1193afa6c22af06dde3b86302288e67a360ea67c006d92cd5b5cfa56ca65fc29643fc7db590e3ef2bfcae5e9c7018689a893ea47659ac3c96ed1268289ee617cee60a80a2ebdd6044442b935b739bf96d54e5b23595a65f30e4fff328000d10f831cc97158a6e10c984891bdab6f2d2c52ed97a6',16)

print hex((sig1*sig2)%n)

RSA乘法同态_第4张图片
从输出中确定代码中想要的s2。

4、构造加密签名

将上述的得到的有关内容分别进行源代码的1和3选项(需要注意输入时比得到的减少两个ff),得到如下的内容。
RSA乘法同态_第5张图片
上图相当于A^d。
RSA乘法同态_第6张图片
上图相当于B^d。

将上面两个图的内容相乘就是C^d,用python就可以实现,已包含在上述代码中。

5、获得FLAG

将得到的C^d作为输入,得到flag。
RSA乘法同态_第7张图片

你可能感兴趣的:(CTF中的密码学)