• NewStarCTF 2023 公开赛道 WEEK2|Crypto


    目录

    T1.滴啤

    T2.不止一个pi

    T3.halfcandecode

    T4.Rotate Xor

    T5.broadcast

    T6.partial decrypt


    T1.滴啤

        下载题目附件,我们获得到以下代码。

    1. from Crypto.Util.number import *
    2. import gmpy2
    3. from flag import flag
    4. def gen_prime(number):
    5. p = getPrime(number//2)
    6. q = getPrime(number//2)
    7. return p,q
    8. m = bytes_to_long(flag.encode())
    9. p,q = gen_prime(1024)
    10. print(p*q)
    11. e = 65537
    12. d = gmpy2.invert(e,(p-1)*(q-1))
    13. print(d%(p-1))
    14. print(pow(m,e,p*q))
    15. # n = 93172788492926438327710592564562854206438712390394636149385608321800134934361353794206624031396988124455847768883785503795521389178814791213054124361007887496351504099772757164211666778414800698976335767027868761735533195880182982358937211282541379697714874313863354097646233575265223978310932841461535936931
    16. # d1 = 307467153394842898333761625034462907680907310539113349710634557900919735848784017007186630645110812431448648273172817619775466967145608769260573615221635
    17. # c = 52777705692327501332528487168340175436832109866218597778822262268417075157567880409483079452903528883040715097136293765188858187142103081639134055997552543213589467751037524482578093572244313928030341356359989531451789166815462417484822009937089058352982739611755717666799278271494933382716633553199739292089

         观察代码得到,这是一道DP泄露题。面对DP泄露题的破解关注点就在于对于各个数学关系的利用。大体证明流程如下。

          d_{1}=d+k_{1}(p-1),de=1+k_{2}\Phi (n)那么,我们可以获得

          d_{1}*e=de+k_{1}(p-1)=1+k_{2}((p-1)*(q-1))+k_{1}(p-1),我们提取出(p-1)。那么上述式子可以简化为:d_{1}e=1+x(p-1)。于是我们可以通过爆破x来获取得到(p-1),继而得到p。值得一提的是,因为x=(k_{2}(q-1)+k_{1})=\frac{d_{1}e-1}{p-1}。可知x应当满足x

    1. d1 = 307467153394842898333761625034462907680907310539113349710634557900919735848784017007186630645110812431448648273172817619775466967145608769260573615221635
    2. n = 93172788492926438327710592564562854206438712390394636149385608321800134934361353794206624031396988124455847768883785503795521389178814791213054124361007887496351504099772757164211666778414800698976335767027868761735533195880182982358937211282541379697714874313863354097646233575265223978310932841461535936931
    3. e = 65537
    4. d1e = d1*e
    5. for x in range(e):
    6. p = (d1e-1)//x + 1
    7. if (isPrime(p) and isPrime(n // p)):
    8. print("p = %d" % p)
    9. print("q = %d" % (n//p))
    10. break
    11. # 运行上述代码获取(p,q)得到
    12. p = 11468682317608320448548512020423218884851236431873575184966338657457357272806919819351161191000926189140495197426822395189086385102915060848622773489345643
    13. q = 8124105796345459853548244027030096714175206734963482980448160704449968633993583782011947055608004745382787277674755027832520361002441996364399502642927017
    14. phi = (p-1)*(q-1)
    15. d = primefac.modinv(e, phi)
    16. c = 52777705692327501332528487168340175436832109866218597778822262268417075157567880409483079452903528883040715097136293765188858187142103081639134055997552543213589467751037524482578093572244313928030341356359989531451789166815462417484822009937089058352982739611755717666799278271494933382716633553199739292089
    17. m = pow(c, d, n)
    18. print(long_to_bytes(m))
    19. #最终获取flag:flag{cd5ff82d-989c-4fbf-9543-3f98ab567546}

     T2.不止一个pi

        加密附件如下:

    1. from flag import flag
    2. from Crypto.Util.number import *
    3. import gmpy2
    4. p = getPrime(1024)
    5. q = getPrime(1024)
    6. n = p**3*q**2
    7. print("q = ",q)
    8. print("p = ",p)
    9. m = bytes_to_long(flag.encode())
    10. c = pow(m,65537,n)
    11. print("c = ",c)
    12. # q = 115478867870347527660680329271012852043845868401928361076102779938370270670897498759391844282137149013845956612257534640259997979275610235395706473965973203544920469416283181677660262509481282536465796731401967694683575843183509430017972506752901270887444490905891490955975762524187534052478173966117471143713
    13. # p = 171790960371317244087615913047696670778115765201883835525456016207966048658582417842936925149582378305610304505530997833147251832289276125084339614808085356814202236463900384335878760177630501950384919794386619363394169016560485152083893183420911295712446925318391793822371390439655160077212739260871923935217
    14. # c = 4459183928324369762397671605317600157512712503694330767938490496225669985050002776253470841193156951087663107866714426230222002399666306287642591077990897883174134404896800482234781531592939043551832049756571987010173667074168282355520711905659013076509353523088583347373358980842707686611157050425584598825151399870268083867269912139634929397957514376826145870752116583185351576051776627208882377413433140577461314504762388617595282085102271510792305560608934353515552201553674287954987323321512852114353266359364282603487098916608302944694600227628787791876600901537888110093703612414836676571562487005330299996908873589228072982641114844761980143047920770114535924959765518365614709272297666231481655857243004072049094078525569460293381479558148506346966064906164209362147313371962567040047084516510135054571080612077333228195608109065475260832580192321853906138811139036658485688320161530131239854003996457871663456850196483520239675981391047452381998620386899101820782421605287708727667663038905378115235163773867508258208867367314108701855709002634592329976912239956212490788262396106230191754680813790425433763427315230330459349320412354189010684525105318610102936715203529222491642807382215023468936755584632849348996666528981269240867612068382243822300418856599418223875522408986596925018975565057696218423036459144392625166761522424721268971676010427096379610266649911939139451989246194525553533699831110568146220347603627745407449761792135898110139743498767543521297525802809254842518002190381508964357001211353997061417710783337

        很容易知道这道题考察的是欧拉函数。所以解密脚本如下:

    1. q = 115478867870347527660680329271012852043845868401928361076102779938370270670897498759391844282137149013845956612257534640259997979275610235395706473965973203544920469416283181677660262509481282536465796731401967694683575843183509430017972506752901270887444490905891490955975762524187534052478173966117471143713
    2. p = 171790960371317244087615913047696670778115765201883835525456016207966048658582417842936925149582378305610304505530997833147251832289276125084339614808085356814202236463900384335878760177630501950384919794386619363394169016560485152083893183420911295712446925318391793822371390439655160077212739260871923935217
    3. c = 4459183928324369762397671605317600157512712503694330767938490496225669985050002776253470841193156951087663107866714426230222002399666306287642591077990897883174134404896800482234781531592939043551832049756571987010173667074168282355520711905659013076509353523088583347373358980842707686611157050425584598825151399870268083867269912139634929397957514376826145870752116583185351576051776627208882377413433140577461314504762388617595282085102271510792305560608934353515552201553674287954987323321512852114353266359364282603487098916608302944694600227628787791876600901537888110093703612414836676571562487005330299996908873589228072982641114844761980143047920770114535924959765518365614709272297666231481655857243004072049094078525569460293381479558148506346966064906164209362147313371962567040047084516510135054571080612077333228195608109065475260832580192321853906138811139036658485688320161530131239854003996457871663456850196483520239675981391047452381998620386899101820782421605287708727667663038905378115235163773867508258208867367314108701855709002634592329976912239956212490788262396106230191754680813790425433763427315230330459349320412354189010684525105318610102936715203529222491642807382215023468936755584632849348996666528981269240867612068382243822300418856599418223875522408986596925018975565057696218423036459144392625166761522424721268971676010427096379610266649911939139451989246194525553533699831110568146220347603627745407449761792135898110139743498767543521297525802809254842518002190381508964357001211353997061417710783337
    4. e = 65537
    5. phi = (p**3 - p**2)*(q**2 - q)
    6. d = primefac.modinv(e, phi)
    7. n = p**3*q**2
    8. m = pow(c,d,n)
    9. print(long_to_bytes(m))
    10. #最终获取flag:flag{bu_zhi_yige_p1dsaf}

    T3.halfcandecode

    1. from Crypto.Util.number import *
    2. import gmpy2
    3. from flag import flag
    4. import os
    5. from hashlib import md5
    6. def gen_prime(number):
    7. p = getPrime(number // 2)
    8. q = gmpy2.next_prime(p)
    9. return p * q
    10. def md5_hash(m):
    11. return md5(m.encode()).hexdigest()
    12. e = 65537
    13. n = gen_prime(1024)
    14. m1 = bytes_to_long(flag[:len(flag) // 2].encode() + os.urandom(8))
    15. c1 = pow(m1, e, n)
    16. m2 = flag[len(flag) // 2:]
    17. with open("out.txt","w") as f:
    18. f.write(str(n) + '\n')
    19. f.write(str(c1) + '\n')
    20. for t in m2:
    21. f.write(str(md5_hash(t))+'\n')

          根据加密过程,我们知道这里应该采取费马费解法,所以我们可以把n丢到yafu中去,可以获取得到两个因子

    1. P155 = 10631151190024160908870967192522097752991652918777416177941351782447314225123009693276679810786266997133099934443701772661928189884235742113123409596993841
    2. P155 = 10631151190024160908870967192522097752991652918777416177941351782447314225123009693276679810786266997133099934443701772661928189884235742113123409596993409

         知道(p,q)后,我们就可以破解RSA了。接下来我们只需要用MD5在线工具破解下半段密文即可。

    T4.Rotate Xor

    1. from secret import flag
    2. from os import urandom
    3. from pwn import xor
    4. from Cryptodome.Util.number import *
    5. k1 = getPrime(64)
    6. k2 = getPrime(64)
    7. ROUND = 12
    8. ciphertext = xor(flag, long_to_bytes(k1))
    9. def round_rotate_left(num, step):
    10. return ((num) << step | num >> (64-step)) & 0xffffffffffffffff
    11. def encrypt_key(key):
    12. for _ in range(ROUND):
    13. key = round_rotate_left(key, 3) ^ k2
    14. return key
    15. print('ciphertext =', ciphertext)
    16. print('enc_k1 =', encrypt_key(k1))
    17. print('k2 =', k2)
    18. # ciphertext = b'\x8dSyy\xd2\xce\xe2\xd2\x98\x0fth\x9a\xc6\x8e\xbc\xde`zl\xc0\x85\xe0\xe4\xdfQlc'
    19. # enc_k1 = 7318833940520128665
    20. # k2 = 9982833494309156947

         这段就较为简单了,只需要根据代码写出逆过程即可。但是这里有一个小技巧,可以借用原来的代码设计,也就是右移3位等价于左移64-3位

    T5.broadcast

        这道题给出了一个靶机信息。在靶机中获取(n,c,e)。获取一组发现难以解密,所以考虑靶机特性,因为是对同一个明文加密,所以我们可以截获到多组信息。因此可以使用广播攻击(见题,如果关注到题目含义就能很快反应,笔者是崩溃的过程中提出为什么给我这么恶心的靶机才意识到的)。 

        因为懒得重新获取17组信息,所以我们只给出破解脚本

    1. def broadcast_attack(data, e):
    2. def gcdext(a, b):
    3. x, lastx = 0, 1
    4. y, lasty = 1, 0
    5. while b:
    6. a, (q, b) = b, divmod(a, b)
    7. x, lastx = lastx - x*q, x
    8. y, lasty = lasty - y*q, y
    9. return (a, lastx, lasty)
    10. def chinese_remainder_theorem(items):
    11. N = 1
    12. for _n, _c in items:
    13. N *= _n
    14. result = 0
    15. for _n, _c in items:
    16. m = N // _n
    17. r, s, d = gcdext(_n, m)
    18. if r != 1:
    19. N = N // n
    20. continue
    21. result += _c*d*m
    22. return (result % N, N)
    23. x, n = chinese_remainder_theorem(data)
    24. m = gmpy2.iroot(x, e)[0]
    25. print(m)
    26. return m

    T6.partial decrypt

    1. from secret import flag
    2. from Crypto.Util.number import *
    3. m = bytes_to_long(flag)
    4. e = 65537
    5. p = getPrime(512)
    6. q = getPrime(512)
    7. n = p*q
    8. c = pow(m,e,n)
    9. dp = inverse(e, (p-1))
    10. dq = inverse(e, (q-1))
    11. m1 = pow(c,dp, p)
    12. m2 = pow(c,dq, q)
    13. q_inv = inverse(q, p)
    14. h = (q_inv*(m1-m2)) % p
    15. print('m2 =', m2)
    16. print('h =', h)
    17. print('q =', q)
    18. # m2 = 4816725107096625408335954912986735584642230604517017890897348901815741632668751378729851753037917164989698483856004115922538576470127778342121497852554884
    19. # h = 4180720137090447835816240697100630525624574275
    20. # q = 7325294399829061614283539157853382831627804571792179477843187097003503398904074108324900986946175657737035770512213530293277111992799331251231223710406931

            这道题是一道魔改题,但是不是很难。好好分析还是挺简单的,因为只需要搞清楚h是什么就可以了。

            dp=1+k_{1}(p-1),dq=1+k_{2}(q-1),m1=m (mod p),m2=m (mod q)因为h=(q_inv*(m1-m2))。所以h=(q_inv*(k_{3}p-k_{4}q))(mod p)=-k_{4}(modp),但是k4大小我们未知,其的正负都有可能。但是看到题目只解一半,也就说m > q,即k4 < 0, 所以h就是我们要求取的系数。

    1. m = m2 + h*q
    2. print(long_to_bytes(m))

  • 相关阅读:
    安装Anaconda之后cmd打不开
    js 深入理解原型(prototype)及如何创建对象
    纯CSS实现tab栏切换,简易轮播图
    西门子 S7 协议解析
    外包干了2个月,技术退步明显...
    八、【VUE-CLI】待办事项案例(第一版)
    手把手带你给你的Linux驱动程序加入platform结构体
    Netty 高性能原因之一 采用了高性能的NIO 模式
    vue-router源码分析(上)
    金九银十!阿里P8手写的内部Java核心开发成长手册,涵盖p5-p8技术栈,秋招必看!
  • 原文地址:https://blog.csdn.net/qq_73643549/article/details/133775673