BUUCTF:[CSAWQual 2019]byte_me
阿新 • • 發佈:2021-01-12
首先在buuctf裡是可以拿到原始碼的,這裡也可以直接猜測一下,不停的輸入a,你會發現到一定數量後發回來的密文的前32位不會再發生變化,這裡便是ECB加密模式的特點,首先來看一下ECB加密的原理(網圖)
加密:randomstr+yourinput+flag,如果你輸入的a與randomstr相加剛好等於分組數(16bytes),那麼密文的前32位(16進位制)都是randomstr+(16-randomstr)*'a'的加密結果,自然你後面再增加a的數量密文也不會再改變,所以我們可以先來把前面這段補齊
from pwn import * r=remote('node3.buuoj.cn',25676) re=r.recvline().decode() re=bytes.fromhex(re) set1=[] print('attack start.......') for i in range(1,17): sen_mes='a'*i try: r.sendline(sen_mes) except: print('something ro') r.recvline() re1=r.recvline().strip().decode() if re1[0:16] in set1: head=i-1 break set1.append(re1[:16]) print(head)
通過密文的長度我們可以估計flag的長度大概 32<flag<48,這裡直接爆破顯然是不太可能的,我們需要將\((128-32)^{len(flag)}簡化為k(128-32)\)
我們只需構造上圖中的資料,爆破i的值就可以了通過對比密文的第二組資料來得到flag[0]也就是'f',按照這種思路我們就可以在\(k(128-32)\)的情況下爆破出flag的值,完整的指令碼如下
from pwn import * r=remote('node3.buuoj.cn',25676) re=r.recvline().decode() re=bytes.fromhex(re) set1=[] print('attack start.......') for i in range(1,17): sen_mes='a'*i try: r.sendline(sen_mes) except: print('something ro') r.recvline() re1=r.recvline().strip().decode() if re1[0:16] in set1: head=i-1 break set1.append(re1[:16]) print(head) #a reference #attack [0:16] mes='a'*head realflag='' for i in range(1,17): ju=mes+'b'*(16-i) r.sendline(ju) r.recvline() ju_recv=r.recvline().strip().decode() for j in range(32,128): mes_add=mes+'b'*(16-i)+realflag+chr(j) r.sendline(mes_add) r.recvline() try_recv=r.recvline().strip().decode() if ju_recv[32:64]==try_recv[32:64]: realflag=realflag+chr(j) print('realflag:{}'.format(realflag)) break #attack[16:32] for i in range(1,17): ju=mes+'b'*(16-i) r.sendline(ju) r.recvline() ju_recv=r.recvline().strip().decode() for j in range(32,128): mes_add=mes+realflag[i:15+i]+chr(j) r.sendline(mes_add) r.recvline() try_recv=r.recvline().strip().decode() if ju_recv[64:96]==try_recv[32:64]: realflag=realflag+chr(j) print('realflag:{}'.format(realflag)) break #attack all for i in range(1,17): ju=mes+'b'*(16-i) r.sendline(ju) r.recvline() ju_recv=r.recvline().strip().decode() for j in range(32,128): mes_add=mes+realflag[i+16:31+i]+chr(j) r.sendline(mes_add) r.recvline() try_recv=r.recvline().strip().decode() if ju_recv[96:128]==try_recv[32:64]: realflag=realflag+chr(j) print('realflag:{}'.format(realflag)) if chr(j) == '}': exit(0) break