CTF练习

一.滴啤

该题属于dp泄露的问题

 运行脚本如下:

import libnum
import gmpy2

n = 93172788492926438327710592564562854206438712390394636149385608321800134934361353794206624031396988124455847768883785503795521389178814791213054124361007887496351504099772757164211666778414800698976335767027868761735533195880182982358937211282541379697714874313863354097646233575265223978310932841461535936931
dp = 307467153394842898333761625034462907680907310539113349710634557900919735848784017007186630645110812431448648273172817619775466967145608769260573615221635
c = 52777705692327501332528487168340175436832109866218597778822262268417075157567880409483079452903528883040715097136293765188858187142103081639134055997552543213589467751037524482578093572244313928030341356359989531451789166815462417484822009937089058352982739611755717666799278271494933382716633553199739292089
e = 65537
for i in range(1, 65535):
    p = (dp * e - 1) // i + 1
    if n % p == 0:
        q = n // p
        break
phi_n = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi_n)
m = pow(c, d, n)
flag = libnum.n2s(int(m)).decode()#十进制转字符串
print(flag)

 

二.不止一个pi

正常通过欧拉函数求phi,根据题目可知,该题考察的是RSA的欧拉函数变形,因为 n = p ** 3 * q ** 2,所以相应的phi_n=(p-1) * (q-1) * p ** 2 * q,稍微改下代码即可获得flag

import libnum
import gmpy2
q = 115478867870347527660680329271012852043845868401928361076102779938370270670897498759391844282137149013845956612257534640259997979275610235395706473965973203544920469416283181677660262509481282536465796731401967694683575843183509430017972506752901270887444490905891490955975762524187534052478173966117471143713
p = 171790960371317244087615913047696670778115765201883835525456016207966048658582417842936925149582378305610304505530997833147251832289276125084339614808085356814202236463900384335878760177630501950384919794386619363394169016560485152083893183420911295712446925318391793822371390439655160077212739260871923935217
c = 4459183928324369762397671605317600157512712503694330767938490496225669985050002776253470841193156951087663107866714426230222002399666306287642591077990897883174134404896800482234781531592939043551832049756571987010173667074168282355520711905659013076509353523088583347373358980842707686611157050425584598825151399870268083867269912139634929397957514376826145870752116583185351576051776627208882377413433140577461314504762388617595282085102271510792305560608934353515552201553674287954987323321512852114353266359364282603487098916608302944694600227628787791876600901537888110093703612414836676571562487005330299996908873589228072982641114844761980143047920770114535924959765518365614709272297666231481655857243004072049094078525569460293381479558148506346966064906164209362147313371962567040047084516510135054571080612077333228195608109065475260832580192321853906138811139036658485688320161530131239854003996457871663456850196483520239675981391047452381998620386899101820782421605287708727667663038905378115235163773867508258208867367314108701855709002634592329976912239956212490788262396106230191754680813790425433763427315230330459349320412354189010684525105318610102936715203529222491642807382215023468936755584632849348996666528981269240867612068382243822300418856599418223875522408986596925018975565057696218423036459144392625166761522424721268971676010427096379610266649911939139451989246194525553533699831110568146220347603627745407449761792135898110139743498767543521297525802809254842518002190381508964357001211353997061417710783337
n = p**3*q**2
phi_n=(p-1) * (q-1) * p ** 2 * q
d=gmpy2.invert(65537,phi_n)
m=pow(c,d,n)
flag=libnum.n2s(int(m)).decode()
print(flag)

flag{bu_zhi_yige_p1dsaf}

三.halfcandecode

根据其给出的文件

113021375625152132650190712599981988437204747209058903684387817901743950240396649608148052382567758817980625681440722581705541952712770770893410244646286485083142929097056891857721084849003860977390188797648441292666187101736281034814846427200984062294497391471725496839508139522313741138689378936638290593969
43054766235531111372528859352567995977948625157340673795619075138183683929001986100833866227688081563803862977936680822407924897357491201356413493645515962458854570731176193055259779564051991277092941379392700065150286936607784073707448630150405898083000157174927733260198355690620639487049523345380364948649
4a8a08f09d37b73795649038408b5f33 
03c7c0ace395d80182db07ae2c30f034 
e1671797c52e15f763380b45e841ec32 
b14a7b8059d9c055954c92674ce60032 
e358efa489f58062f10dd7316b65649e 
cfcd208495d565ef66e7dff9f98764da 
b14a7b8059d9c055954c92674ce60032 
8fa14cdd754f91cc6554c9e71929cce7 
0cc175b9c0f1b6a831c399e269772661 
4a8a08f09d37b73795649038408b5f33 
e358efa489f58062f10dd7316b65649e 
cfcd208495d565ef66e7dff9f98764da 
4b43b0aee35624cd95b910189b3dc231 
cbb184dd8e05c9709e5dcaedaa0495cf 

根据

p = getPrime(number // 2)
    q = gmpy2.next_prime(p)

明文分成两半,前一半根据生成p,q函数看出是相邻素数算出p,q,后面正常rsa算出前半明文,后半明文进行了一个一个字符进行MD5加密,只需要对MD5进行解密,即可拿到m

MD5免费在线解密破解_MD5在线加密-SOMD5MD5在线免费破解,支持md5,sha1,mysql,sha256,sha512,md4,织梦,vBulletin,Discuz,md5(Joomla),mssql(2012),ntlm,md5(base64),sha1(base64),md5(wordpress),md5(Phpbb3),md5(Unix),des(Unix)等数十种加密方式icon-default.png?t=N7T8https://www.somd5.com/转换结果如下

4a8a08f09d37b73795649038408b5f33 c
03c7c0ace395d80182db07ae2c30f034 s
e1671797c52e15f763380b45e841ec32 e
b14a7b8059d9c055954c92674ce60032 _
e358efa489f58062f10dd7316b65649e t
cfcd208495d565ef66e7dff9f98764da 0
b14a7b8059d9c055954c92674ce60032 _
8fa14cdd754f91cc6554c9e71929cce7 f
0cc175b9c0f1b6a831c399e269772661 a
4a8a08f09d37b73795649038408b5f33 c
e358efa489f58062f10dd7316b65649e t
cfcd208495d565ef66e7dff9f98764da 0
4b43b0aee35624cd95b910189b3dc231 r
cbb184dd8e05c9709e5dcaedaa0495cf }

 

代码运行得到结果:flag{two_cloab\xdbxD-K\x01J\xe5

加上后半段

最终flag{two_cloabcse_t0_fact0r}

四.Rotate Xor

 先看该题题目

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

这个代码中自定义了两个函数

密文c=flag^k1,解密flag=c^k1,先从k1入手,定义了一个名为 round_rotate_left 的函数,用于对密钥进行循环左移操作,

在 encrypt_key 函数中,使用循环和异或操作对密钥进行了 ROUND 轮的处理,每轮都进行了循环左移和异或操作。

解密的话,就是逆向,先定义一个循环右移函数,再写一个函数,加密中是先左移再异或k2,解密就是先异或k2再进行循环右移还原k1,最后就是flag=xor^k1

from pwn import xor
from Crypto.Util.number import *
ROUND = 12
def round_rotate_right(num, step):
    return ((num >> step) | (num << (64 - step))) & 0xffffffffffffffff
def decrypt_key(enc_key):
    for _ in range(ROUND):
        enc_key = round_rotate_right(enc_key ^ k2, 3)
    return enc_key
ciphertext = b'\x8dSyy\xd2\xce\xe2\xd2\x98\x0fth\x9a\xc6\x8e\xbc\xde`zl\xc0\x85\xe0\xe4\xdfQlc'
enc_k1 = 7318833940520128665
k2 = 9982833494309156947
dec_k1 = decrypt_key(enc_k1)
plaintext = xor(ciphertext, long_to_bytes(dec_k1))
print(plaintext)

 

五.broadcast

题目

from secret import flag
from Crypto.Util.number import *
 
m = bytes_to_long(flag)
e = 65537
p = getPrime(512)
q = getPrime(512)
 
n = p*q 
 
c = pow(m,e,n)
 
dp = inverse(e, (p-1))
dq = inverse(e, (q-1))
m1 = pow(c,dp, p)
m2 = pow(c,dq, q)
q_inv = inverse(q, p)
h = (q_inv*(m1-m2)) % p
print('m2 =', m2)
print('h =', h)
print('q =', q)
 
# m2 = 4816725107096625408335954912986735584642230604517017890897348901815741632668751378729851753037917164989698483856004115922538576470127778342121497852554884
# h  = 4180720137090447835816240697100630525624574275
# q  = 7325294399829061614283539157853382831627804571792179477843187097003503398904074108324900986946175657737035770512213530293277111992799331251231223710406931

这个题要进行分析(这里是参考的别人的博客理解的)

 h = (q_inv * (m1 - m2)) % p
 
将m1和m2的表达式代入:   m1 = c^dp mod p
                       dp=d mod (p-1)
由于dp = d mod (p-1),这意味着存在一个整数 k,使得 dp = d + k(p-1)。
 
将 dp 代入 m1 = c^dp mod p 中,得到 m1 = c^(d + k(p-1)) mod p。
 
根据模运算的性质,我们有 c^(d + k(p-1)) mod p = (c^d * c^(k(p-1))) mod p。
 
由于 c^(k(p-1)) mod p = 1,根据模运算的性质,我们可以得到 m1 = c^d mod p。
                       m= c^d mod n
                       m1= m mod p
                       m1 = k1 * p + m
                       m2 = k2 * q + m
 
将m1和m2代入h的表达式: h = (q_inv * ((k1 * p + m) - (k2 * q + m))) % p
 
化简表达式: h = (q_inv * (k1 * p - k2 * q + m - m)) % p 
             h = (q_inv * (k1 * p - k2 * q)) % p
 
进一步化简: h = (q_inv * k1 * p - q_inv * k2 * q) % p
 
根据模运算的性质,我们有:q_inv=inverse(q,p)
                       (q_inv * q) % p = 1
 
将其代入上式: h = (q_inv * k1 * p - 1 * k2) % p
               h = (q_inv * k1 * p - k2) % p
 
因此,我们可以推出 h = (q_inv * k1 * p - k2) % p = -k2 % p。因为q_inv * k1 * p 是 p倍数 在mod p 下为0
根据所得 : h=-k2 % p 再由 m2= m mod q 得到 m2 =m+k2*q 我们所求m,根据提示解密只解密一半 m>q 所以k2<0
再由m=m2-k2*q 已知m2,q,再由h=-k2 % p ,-k2=h ,所以 m=m2+h*q

from Crypto.Util.number import *
m2 = 4816725107096625408335954912986735584642230604517017890897348901815741632668751378729851753037917164989698483856004115922538576470127778342121497852554884
h = 4180720137090447835816240697100630525624574275
q = 7325294399829061614283539157853382831627804571792179477843187097003503398904074108324900986946175657737035770512213530293277111992799331251231223710406931
m=m2+h*q
print(long_to_bytes(m))

flag{rsa_with_crt#b12a3a020c9cc5f1a6df4618256f7c88c83fdd95aab1a2b2656d760475bd0bf1}

  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值