easymath
题目如下:
assert(len(open('flag.txt', 'rb').read()) < 50)
assert(str(int.from_bytes(open('flag.txt', 'rb').read(), byteorder='big') << 10000).endswith( '1862790884563160582365888530869690397667546628710795031544304378154769559410473276482265448754388655981091313419549689169381115573539422545933044902527020209259938095466283008'))
很容易理解,这是flag的低位泄露。分析如下:
flag的长度保证是小于50位的,然后值对其二进制位右移10000位,我们要根据后面的175位还原出原来的flag。
(flag 2 10000) % 10 175 = r % 10 * 175
很显然我们要求出2 10000关于10 175的乘法逆元,乘上逆元后左边就只剩下flag。
而2和10并不互素,所以这里我们要做一下转化10 = 2*5。这样子式子就变为:
((flag 2 10000) // 2 175) % 5 175 = (r // 2 175) % 5 * 175
记d = inverse(2 9875, 5 175),然后两边同乘d,式子变为:
flag = ((r // 2 175) * d) % 5 175。
脚本如下:
from Crypto.Util.number import *
r = 1862790884563160582365888530869690397667546628710795031544304378154769559410473276482265448754388655981091313419549689169381115573539422545933044902527020209259938095466283008
n = 5 ** 175
d = inverse(2 ** 9825, 5 ** 175)
assert 400 < len(bin(n))
flag = pow((r // (2 ** 175)) * d, 1, n)
print(long_to_bytes(flag))
运行脚本可得flag。
let’s play with rsa~
题目如下:
from sympy import isprime,nextprime
from Crypto.Util.number import getPrime as getprime ,long_to_bytes,bytes_to_long,inverse
flag='flag{***************}'
def play():
p=getprime(1024)
q=getprime(1024)
n=p*q
e=65537
print "Hello,let's play rsa~\n"
print 'Now,I make some numbers,wait a second\n'
n1=getprime(200)
n2=getprime(200)
number=n1*n2
print "Ok,i will send two numbers to you,one of them was encoded.\n"
print "Encode n1:%d,\n"%(pow(n1,e,n))
print "And n2:%d.\n"%n2
print "Information that can now be made public:the public key (n,e):(%d,%d)\n"%(n,e)
while True:
try:
c=int(raw_input("ok,now,tell me the value of the number (encode it for safe):"))
except:
print "Sorry,the input is illeagal, and the integer is accept~"
else:
break
d=inverse(e,(p-1)*(q-1))
m=pow(c,d,n)
if m==number:
print "It's easy and interesting,didn't it?\n"
print "This is the gift for you :"+flag
else:
print "Emmmmm,there is something wrong, bye~\n"
if __name__ == '__main__':
play()
代码中有一句非常的关键:m == number,理解起来就是通过生成的两个素数n1和n2,两个素数相乘后进行加密,再对其解密如果和明文相等就输出明文。启动靶机给出了加密后的n1、n、e、n2,只要提交密文就可以得到flag。密文的生成公式:
c = ((n1 n2) * e) % n。脚本如下:
e = 65537
n1 = 10653312769174158756266820984704503841751105519317318350549035067339863586828055624678419254680328410443130950328230973494600699078839610444782370063517931142385460144600794358827951162398025638643229903962194652684704638971608362830047801588344785410041823633217357467648032877202599184548305478669641158042951166723532538287741198075349658853420705615892242194115481594880932418336783477681216752531667886211480432398349831500215321001499114985422806607057934983865341677047172491741744692043226580613228089538206616300934400392295525377836032274328887264882684524904812074676228048334891589888582694671278613926469
n = 13909650504182810272126822694736660550034083024721359809884310836427178113806096852659208089966187163814754484590507030898909515167721615917708494037364571153216812320770417799419150452981733639142977852562557110894824929199058811865687712812075599710791186903372182520097983070692696938564316852118527835657298561123335009283304121643441845761678973988505930441465839957174888568550017365451398683514816376682932806171259464425899695270506034473820184656094133147074820038461235252812508990359250133909635229820662510025490215384197234903570098462910622260780095116608354065770630377973964579268692836432495371468933
n2 = 1517173260851875221291764110812663162076281374663483024293973
c = (n1 * pow(n2, e, n)) % n
print(c)
ezRSA
参考: