setcontext构造rop链

文章发布时间:

最后更新时间:

文章总字数:
928

预计阅读时间:
4 分钟

用途比较大的一个办法 通常适用的是开启了沙盒的堆 然后用来构造orw链
不过libc2.29是一个比较大的分水岭 前后的版本关于setcontext的利用不一样

libc2.27

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
.text:0000000000052070                 public setcontext ; weak
.text:0000000000052070 setcontext proc near ; CODE XREF: sub_586B0+C↓p
.text:0000000000052070 ; DATA XREF: LOAD:0000000000009018↑o
.text:0000000000052070 ; __unwind {
.text:0000000000052070 push rdi
.text:0000000000052071 lea rsi, [rdi+128h] ; nset
.text:0000000000052078 xor edx, edx ; oset
.text:000000000005207A mov edi, 2 ; how
.text:000000000005207F mov r10d, 8 ; sigsetsize
.text:0000000000052085 mov eax, 0Eh
.text:000000000005208A syscall ; LINUX - sys_rt_sigprocmask
.text:000000000005208C pop rdi
.text:000000000005208D cmp rax, 0FFFFFFFFFFFFF001h
.text:0000000000052093 jnb short loc_520F0
.text:0000000000052095 mov rcx, [rdi+0E0h]
.text:000000000005209C fldenv byte ptr [rcx]
.text:000000000005209E ldmxcsr dword ptr [rdi+1C0h]
.text:00000000000520A5 mov rsp, [rdi+0A0h]
.text:00000000000520AC mov rbx, [rdi+80h]
.text:00000000000520B3 mov rbp, [rdi+78h]
.text:00000000000520B7 mov r12, [rdi+48h]
.text:00000000000520BB mov r13, [rdi+50h]
.text:00000000000520BF mov r14, [rdi+58h]
.text:00000000000520C3 mov r15, [rdi+60h]
.text:00000000000520C7 mov rcx, [rdi+0A8h]
.text:00000000000520CE push rcx
.text:00000000000520CF mov rsi, [rdi+70h]
.text:00000000000520D3 mov rdx, [rdi+88h]
.text:00000000000520DA mov rcx, [rdi+98h]
.text:00000000000520E1 mov r8, [rdi+28h]
.text:00000000000520E5 mov r9, [rdi+30h]
.text:00000000000520E9 mov rdi, [rdi+68h]
.text:00000000000520E9 ; } // starts at 52070
.text:00000000000520ED ; __unwind {
.text:00000000000520ED xor eax, eax
.text:00000000000520EF retn

你可以在libc文件中搜索函数setcontext找到这一串汇编
前面的指令没啥用 重点是 .text:00000000000520A5 mov rsp, [rdi+0A0h] 这一句
rsp寄存器的值由rdi寄存器决定的 rdi可太好控制了 我们执行free函数 rdi的值就是被释放的chunk的用户区地址
但是光控制rsp寄存器也没用 他不执行啊 还得再把rop链弹到rip寄存器里面
那就要用到ret指令了是吧 往下看一看 找到了 .text:00000000000520CE push rcx
把rcx的值入栈 rcx能不能控制啊 能啊 .text:00000000000520C7 mov rcx, [rdi+0A8h]
那就意味着 我们可以利用这三行 实现一个栈迁移 劫持程序执行流
并且所需要的只是覆盖free_hook
演示的话 可以看一看wp分类里的Ciscn复现里的一题

libc2.29

2.29对于setcontext进行了优化 不好利用了

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
.text:0000000000055E00                 public setcontext ; weak
.text:0000000000055E00 setcontext proc near ; CODE XREF: sub_5C160+C↓p
.text:0000000000055E00 ; DATA XREF: LOAD:000000000000C6D8↑o
.text:0000000000055E00 ; __unwind {
.text:0000000000055E00 push rdi
.text:0000000000055E01 lea rsi, [rdi+128h] ; nset
.text:0000000000055E08 xor edx, edx ; oset
.text:0000000000055E0A mov edi, 2 ; how
.text:0000000000055E0F mov r10d, 8 ; sigsetsize
.text:0000000000055E15 mov eax, 0Eh
.text:0000000000055E1A syscall ; LINUX - sys_rt_sigprocmask
.text:0000000000055E1C pop rdx
.text:0000000000055E1D cmp rax, 0FFFFFFFFFFFFF001h
.text:0000000000055E23 jnb short loc_55E80
.text:0000000000055E25 mov rcx, [rdx+0E0h]
.text:0000000000055E2C fldenv byte ptr [rcx]
.text:0000000000055E2E ldmxcsr dword ptr [rdx+1C0h]
.text:0000000000055E35 mov rsp, [rdx+0A0h]
.text:0000000000055E3C mov rbx, [rdx+80h]
.text:0000000000055E43 mov rbp, [rdx+78h]
.text:0000000000055E47 mov r12, [rdx+48h]
.text:0000000000055E4B mov r13, [rdx+50h]
.text:0000000000055E4F mov r14, [rdx+58h]
.text:0000000000055E53 mov r15, [rdx+60h]
.text:0000000000055E57 mov rcx, [rdx+0A8h]
.text:0000000000055E5E push rcx
.text:0000000000055E5F mov rsi, [rdx+70h]
.text:0000000000055E63 mov rdi, [rdx+68h]
.text:0000000000055E67 mov rcx, [rdx+98h]
.text:0000000000055E6E mov r8, [rdx+28h]
.text:0000000000055E72 mov r9, [rdx+30h]
.text:0000000000055E76 mov rdx, [rdx+88h]
.text:0000000000055E76 ; } // starts at 55E00
.text:0000000000055E7D ; __unwind {
.text:0000000000055E7D xor eax, eax
.text:0000000000055E7F retn

你可以看到 变成rdx寻址了 不过也不碍事 还是有办法解决
介绍一个新的工具 ropper 其可以查询libc文件中的一些gadget

1
ropper -f libc文件路径 --search '指令'

就比如此时我们想要 可以修改rdx值的gadget
image.png
找到了很多串 远不止图片上这些
rdi寄存器还是很好控制的 所以我们想的是利用rdi控制rdx 利用rdx控制rsp 这样利用rdx做一个中间商
那就找呗 找啊找啊 找到下面这串
image.png
前面的mov 就不提了 可以修改rdx的值 最后的call才是关键呐
rdx此时已经被我们操控了 那么[rdx+0x20]也是可被控制的 这里填入setcontext的地址不就好了 此时rdx的值已经被控制了 所以rsp也可以 那么就跟上面一样了
实战利用在wp分类中的hgame2023