BUUCTF:[CSAWQual 2019]byte_me

首先在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
posted @ 2021-01-12 15:02  Mr_small  阅读(257)  评论(0编辑  收藏  举报