loading...
DASCTF八月挑战赛-Crypto
Published in:2021-09-04 |

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


参考:

https://blog.csdn.net/song_lee/article/details/107498149

Prev:
BUUCTF-Crypto系列[97-112]WP
Next:
CTFSHOW-吃瓜杯-Crypto系列
catalog
catalog