f = open('114514','rb') content = f.read() n = open('res.png','wb') new = b'' for i in content: new += chr(i^0x58).encode().replace(b'\xc2',b'').replace(b'\xc3',b'') n.write(new)
key = 253 cipher = '9b919c9a8685cd8fa294c8a28c88cc89cea2ce9c878480' flag = "" for i in range(0,len(cipher),2): flag += chr(int(cipher[i:i+2],16) ^ key) print(flag)
Crypto4.RSA_begin
下载附件,得到脚本
from Crypto.Util.number import * from secret import flag assert len(flag) % 5 == 0 cnt = len(flag) // 5 flags = [flag[cnt*i:cnt*(i+1)] for i in range(5)] # Try to implement your RSA with primes p and q def level1(message): m = bytes_to_long(message) p = getPrime(512) q = getPrime(512) n = p * q e = 0x10001 assert m < n c = pow(m, e, n) print(f'c = {c}') print(f'p = {p}') print(f'q = {q}') # But how can we attack the RSA when we didn't know the primes? def level2(message): m = bytes_to_long(message) p = getPrime(64) q = getPrime(64) n = p * q e = 0x10001 assert m < n c = pow(m, e, n) print(f'c = {c}') print(f'n = {n}') # Different e may cause danger? def level3(message): m = bytes_to_long(message) p = getPrime(512) q = getPrime(512) e = 3 n = p * q assert m < n c = pow(m, e, n) print(f'c = {c}') print(f'n = {n}') # So is there anything wrong with RSA as shown below? def level4(message): m = bytes_to_long(message) p = getPrime(512) q = getPrime(512) d = getPrime(64) e = inverse(d, (p-1) * (q-1)) n = p * q assert m < n c = pow(m, e, n) print(f'c = {c}') print(f'e = {e}') print(f'n = {n}') # What about different n? Just have a try with the hint! def level5(message): m = bytes_to_long(message) p = getPrime(512) q = getPrime(512) n = p * p * q e = 0x10001 d = inverse(e, p * (p-1) * (q-1)) assert m < n c = pow(m, e, n) hint = pow(d, e, n) print(f'c = {c}') print(f'hint = {hint}') print(f'n = {n}') print('Level 1:') level1(flags[0]) print('Level 2:') level2(flags[1]) print('Level 3:') level3(flags[2]) print('Level 4:') level4(flags[3]) print('Level 5:') level5(flags[4])
Level 1: c = 22160015525054597533062795679117215923801827397299805735087138192137742945881204146337349060934854888054628153923021387981306839951210090523829296521835965212118849043671673133979884712755090374758002677916820953359774554825569218497687506468472278309097929775388010403607769802840990547048001743970754496905 p = 6962443023774446497102092246794613339314677593117417573764609329949026862782472380488956732038459060928443992561763464365758383525259954798321350043810351 q = 9631855759661411029901156175243744760977799976661519182223576693685069000499866459636568713055906075171480855575061732016121299027658733834671035383233163 Level 2: c = 17250922799297131008803303235771955129 n = 134097988095851988085603926250918812377 Level 3: c = 2776571135646565181849912433877522437622755332262910824866791711 n = 85793694792655420934945863688968944466300304898903354212780512650924132933351787673979641944071634528676901506049360194331553838080226562532784448832916022442020751986591703547743056267118831445759258041047213294368605599719242059474324548598203039032847591828382166845797857139844445858881218318006747115157 Level 4: c = 68588738085497640698861260094482876262596289469248772328560280530093163764972313090939471997156632421517452790632223565521726590730640805290182026911025142051864898712501214753986865172996090706657535814234291235489829621372021092488300236623525366939477695283380634188510950335639019458758643273802572617191 e = 51999725233581619348238930320668315462087635295211755849675812266270026439521805156908952855288255992098479180003264827305694330542325533165867427898010879823017054891520626992724274019277478717788189662456052796449734904215067032681345261878977193341769514961038309763898052908572726913209883965288047452751 n = 68816697240190744603903822351423855593899797203703723038363240057913366227564780805815565183450516726498872118491739132110437976570592602837245705802946829337567674506561850972973663435358068441037127926802688722648016352967768929007662772115485020718202683004813042834036078650571763978066558718285783045969 Level 5: c = 1135954814335407362237156338232840769700916726653557860319741136149066730262056907097728029957898420630256832277578506404721904131425822963948589774909272408535427656986176833063600681390871582834223748797942203560505159946141171210061405977060061656807175913366911284450695116982731157917343650021723054666494528470413522258995220648163505549701953152705111304471498547618002847587649651689203632845303117282630095814054989963116013144483037051076441508388998829 hint = 611144874477135520868450203622074557606421849009025270666985817360484127602945558050689975570970227439583312738313767886380304814871432558985582586031211416586296452510050692235459883608453661597776103386009579351911278185434163016083552988251266501525188362673472772346212970459561496301631587043106524741903627979311997541301471894670374945556313285203740782346029579923650160327646876967315182335114575921178144825057359851607166387868294019144940296084605930 n = 1232865496850144050320992645475166723525103370117149219196294373695624167653495180701004894188767069545579706264513808335877905149818445940067870026924895990672091745229251935876434509430457142930654307044403355838663341948471348893414890261787326255632362887647279204029327042915224570484394917295606592360109952538313570951448278525753313335289675455996833500751672463525151201002407861423542656805624090223118747404488579783372944593022796321473618301206064979
内容是flag被分成5份,分别交给5个rsa进行运算,最终需要我们搞对5个rsa即可获得flag
全程rsa工具一把梭,太香了
level1:
# Try to implement your RSA with primes p and q def level1(message): m = bytes_to_long(message) p = getPrime(512) q = getPrime(512) n = p * q e = 0x10001 assert m < n c = pow(m, e, n) print(f'c = {c}') print(f'p = {p}') print(f'q = {q}')
Level 1: c = 22160015525054597533062795679117215923801827397299805735087138192137742945881204146337349060934854888054628153923021387981306839951210090523829296521835965212118849043671673133979884712755090374758002677916820953359774554825569218497687506468472278309097929775388010403607769802840990547048001743970754496905 p = 6962443023774446497102092246794613339314677593117417573764609329949026862782472380488956732038459060928443992561763464365758383525259954798321350043810351 q = 9631855759661411029901156175243744760977799976661519182223576693685069000499866459636568713055906075171480855575061732016121299027658733834671035383233163
给了p和q还有e,最基础的直接解出。
level2:
# But how can we attack the RSA when we didn't know the primes? def level2(message): m = bytes_to_long(message) p = getPrime(64) q = getPrime(64) n = p * q e = 0x10001 assert m < n c = pow(m, e, n) print(f'c = {c}') print(f'n = {n}')
Level 2: c = 17250922799297131008803303235771955129 n = 134097988095851988085603926250918812377
这题给了n,没有p q可以考虑分解一下
p=10094271714305059493 q=13284562957208247589
分解出来p q,就照常做了
level3:
# Different e may cause danger? def level3(message): m = bytes_to_long(message) p = getPrime(512) q = getPrime(512) e = 3 n = p * q assert m < n c = pow(m, e, n) print(f'c = {c}') print(f'n = {n}')
Level 3: c = 2776571135646565181849912433877522437622755332262910824866791711 n = 85793694792655420934945863688968944466300304898903354212780512650924132933351787673979641944071634528676901506049360194331553838080226562532784448832916022442020751986591703547743056267118831445759258041047213294368605599719242059474324548598203039032847591828382166845797857139844445858881218318006747115157
e很小,考虑小e攻击
level4:
# So is there anything wrong with RSA as shown below? def level4(message): m = bytes_to_long(message) p = getPrime(512) q = getPrime(512) d = getPrime(64) e = inverse(d, (p-1) * (q-1)) n = p * q assert m < n c = pow(m, e, n) print(f'c = {c}') print(f'e = {e}') print(f'n = {n}')
Level 4: c = 68588738085497640698861260094482876262596289469248772328560280530093163764972313090939471997156632421517452790632223565521726590730640805290182026911025142051864898712501214753986865172996090706657535814234291235489829621372021092488300236623525366939477695283380634188510950335639019458758643273802572617191 e = 51999725233581619348238930320668315462087635295211755849675812266270026439521805156908952855288255992098479180003264827305694330542325533165867427898010879823017054891520626992724274019277478717788189662456052796449734904215067032681345261878977193341769514961038309763898052908572726913209883965288047452751 n = 68816697240190744603903822351423855593899797203703723038363240057913366227564780805815565183450516726498872118491739132110437976570592602837245705802946829337567674506561850972973663435358068441037127926802688722648016352967768929007662772115485020718202683004813042834036078650571763978066558718285783045969
看到这个e = inverse(d, (p-1) * (q-1)),可以考虑维纳攻击
level5:
# What about different n? Just have a try with the hint! def level5(message): m = bytes_to_long(message) p = getPrime(512) q = getPrime(512) n = p * p * q e = 0x10001 d = inverse(e, p * (p-1) * (q-1)) assert m < n c = pow(m, e, n) hint = pow(d, e, n) print(f'c = {c}') print(f'hint = {hint}') print(f'n = {n}')
Level 5: c = 1135954814335407362237156338232840769700916726653557860319741136149066730262056907097728029957898420630256832277578506404721904131425822963948589774909272408535427656986176833063600681390871582834223748797942203560505159946141171210061405977060061656807175913366911284450695116982731157917343650021723054666494528470413522258995220648163505549701953152705111304471498547618002847587649651689203632845303117282630095814054989963116013144483037051076441508388998829 hint = 611144874477135520868450203622074557606421849009025270666985817360484127602945558050689975570970227439583312738313767886380304814871432558985582586031211416586296452510050692235459883608453661597776103386009579351911278185434163016083552988251266501525188362673472772346212970459561496301631587043106524741903627979311997541301471894670374945556313285203740782346029579923650160327646876967315182335114575921178144825057359851607166387868294019144940296084605930 n = 1232865496850144050320992645475166723525103370117149219196294373695624167653495180701004894188767069545579706264513808335877905149818445940067870026924895990672091745229251935876434509430457142930654307044403355838663341948471348893414890261787326255632362887647279204029327042915224570484394917295606592360109952538313570951448278525753313335289675455996833500751672463525151201002407861423542656805624090223118747404488579783372944593022796321473618301206064979
def LC(key, x, times, flags): (k1, k2) = key xn = [] xn.append(x) if flags: xn.append(1 - 2 * xn[0]**2) else: xn.append(k2 * xn[0]**3 + (1 - k2)*xn[0]) for i in range(times): assert xn[i]>=-1 and xn[i]<=1 and xn[i+1]>=-1 and xn[i+1]<=1 if flags: xn.append((1 - 2 * xn[i]**2)*(k1 * xn[i+1]**3 + (1 - k1)*xn[i+1])) else: xn.append((k2 * xn[i]**3 + (1 - k2)*xn[i])*(1 - 2 * xn[i+1]**2)) return xn[times + 1] m, c = [], [23, 84, 105, 111, 230, 105, 97, 50, 58, 61, 25, 97, 57, 21, 175, 77, 102, 138, 120, 17, 66, 172, 52, 178, 101, 221, 109, 126, 71, 149, 63, 32, 56, 6, 134, 255, 110, 57, 15, 20, 116] miu, omiga = [], [] ta = timea1 tb = timeb1 res = [] for flag in c: miu.append(LC(key, a_1, ta, 1)) omiga.append(LC(key, b_1, tb, 0)) res.append(((int(miu[-1] * 1000) + int(omiga[-1] * 1000))%256)^flag) delta = flag/256 for i in range(3): y = (yc_1 + delta) % 1 y = k1 * y**3 + (1 - k1) * y x = xc_1 x = k2 * x**3 + (1 - k2) * x ta = 3 + int(1000 * x) % 30 tb = 3 + int(1000 * y) % 30 print(res)
只需把原脚本tmp修改成我们遍历c取得值即可。
打印结果:
看到这个102对应的就是f,只要都ascii解码下就是最终flag了。
最终脚本:
sum, r, k = 0, 1, [107, 99, 55, 198, 210, 56, 137, 44, 127, 25, 150, 113, 75, 215, 187, 132] k1,k2 = 3.967139695598587, 3.7926025078694305 for i in k: sum += i r ^= i a_1 = (sum/256) % 1 timea1 = 3 + int(1000 * a_1) % 30 b_1 = (r/256) timeb1 = 3 + int(1000 * b_1) % 30 xc_1 = a_1 * b_1 yc_1 = (a_1 + b_1) % 1 data = (a_1, timea1, b_1, timeb1, xc_1, yc_1) key = (k1,k2) print(key,data) def LC(key, x, times, flags): (k1, k2) = key xn = [] xn.append(x) if flags: xn.append(1 - 2 * xn[0]**2) else: xn.append(k2 * xn[0]**3 + (1 - k2)*xn[0]) for i in range(times): assert xn[i]>=-1 and xn[i]<=1 and xn[i+1]>=-1 and xn[i+1]<=1 if flags: xn.append((1 - 2 * xn[i]**2)*(k1 * xn[i+1]**3 + (1 - k1)*xn[i+1])) else: xn.append((k2 * xn[i]**3 + (1 - k2)*xn[i])*(1 - 2 * xn[i+1]**2)) return xn[times + 1] m, c = [], [23, 84, 105, 111, 230, 105, 97, 50, 58, 61, 25, 97, 57, 21, 175, 77, 102, 138, 120, 17, 66, 172, 52, 178, 101, 221, 109, 126, 71, 149, 63, 32, 56, 6, 134, 255, 110, 57, 15, 20, 116] miu, omiga = [], [] ta = timea1 tb = timeb1 res = [] for flag in c: miu.append(LC(key, a_1, ta, 1)) omiga.append(LC(key, b_1, tb, 0)) res.append(((int(miu[-1] * 1000) + int(omiga[-1] * 1000))%256)^flag) delta = flag/256 for i in range(3): y = (yc_1 + delta) % 1 y = k1 * y**3 + (1 - k1) * y x = xc_1 x = k2 * x**3 + (1 - k2) * x ta = 3 + int(1000 * x) % 30 tb = 3 + int(1000 * y) % 30 print(res) f = "" for i in res: f += chr(i) print(f)
Reverse
Re1.Hello_Reverse
下载附件 64位,无壳
主函数发现一半的flag,还有一半在.rdata段中
flag就是两个拼接在一起
Re2.Baby_Re
64位程序分析,
看到底下,输入的字符串异或i过后经过compare函数后return 1时就说明flag正确
跟进compare函数
可以看到flag为32位长,然后遍历输入的字符串,要求和final一样。跟进final,
写脚本,for循环final长度并将我们final字符串一一异或for循环的次数。
final = [0x66,0x6d,0x63,0x64,0x7f,0x56,0x69,0x6a,0x6d,0x7d,0x62,0x62,0x62,0x6a,0x51,0x7d,0x65,0x7f,0x4d,0x71,0x71,0x73,0x79,0x65,0x7d,0x46,0x77,0x7a,0x75,0x73,0x21,0x62] flag = "" for i in range(len(final)): flag += chr(final[i] ^i) print(flag)
运行后得到flag,但这个flag是错误的。
经过flag内容和题目提示,说明还有些细节遗漏,
再次分析ida 发现有四个bytes
跟进functionname,发现
发现有4个字节要修改。对应改下重新运行,
final = [0x66,0x6d,0x63,0x64,0x7f,0x56,0x36,0x6a,0x6d,0x7d,0x3a,0x62,0x62,0x6a,0x51,0x7d,0x65,0x7f,0x4d,0x71,0x71,0x73,0x26,0x65,0x7d,0x46,0x77,0x7a,0x75,0x73,0x3f,0x62] flag = "" for i in range(len(final)): flag += chr(final[i] ^i) print(flag)
import base64 import string final = [8,8,14,13,40,64,17,17,60,46,43,30,61,15,'',3,59,61,60,21,40,5,80,70,63,42,57,9,49,86,36,28] for i in '?$P<,%#K': final.append(ord(i)) print(final) Str= "Reverse" flag = [] for i in range(len(final)): try: flag.append(chr(final[i]^ord(Str[i%len(Str)]))) except: flag.append(final[i]) for i in string.ascii_letters+string.digits: flag[14] = i content ="".join(flag) b64 = base64.b64decode(content) print(b64)
from pwn import * p = remote('node4.buuoj.cn',29946) for i in range(100): p.recvuntil('answer?') n = p.recvline().decode() print(n) question = n.strip().split('=')[0] if 'x' in question: question = question.replace('x','*') answer = str(eval(question)) p.sendline(answer) p.interactive()