首页
社区
课程
招聘
[原创]从内核在WOW64进程中执行用户态shellcode
发表于: 2014-7-29 11:35 15459

[原创]从内核在WOW64进程中执行用户态shellcode

2014-7-29 11:35
15459

首先说说 KeUserModeCallback

之前做某个项目时,用到了KeUserModeCallback的方式执行用户态的shellcode.
当时遗留了一个问题,关于wow64下,KeUserModeCallback的分发没有搞清楚.
导致只能执行原生的shellcode.
普通的32位和64位模式下原生的KeUserModeCallback执行ring3代码大家都不陌生了.
详情可见俄国人的ring0MsgBox.

但是如果内核所在的进程空间是一个wow64的进程,就有点麻烦了.
在内核 nt! KeUserModeCallback
                        -> nt! KiCallUserMode
进入Ring3之后,首先到达的分发函数是 ntdll64!KiUserCallbackDispatcher
虽然是WOW64进程,但是当前的CPU模式是 x64!是没法直接执行我们的x86 shellcode的.

.text:0000000078E9FDD6                         ; NTSTATUS __stdcall KiUserCallbackDispatcher(ULONG Index, PVOID Argument, ULONG ArgumentLength)
.text:0000000078E9FDD6                                         public KiUserCallbackDispatcher
.text:0000000078E9FDD6                         KiUserCallbackDispatcher proc near      ; DATA XREF: .rdata:off_78F58128o
.text:0000000078E9FDD6
.text:0000000078E9FDD6                         arg_18          = qword ptr  20h
.text:0000000078E9FDD6                         arg_20          = dword ptr  28h
.text:0000000078E9FDD6                         arg_24          = dword ptr  2Ch
.text:0000000078E9FDD6
.text:0000000078E9FDD6 48 8B 4C 24 20                          mov     rcx, [rsp+arg_18]
.text:0000000078E9FDDB 8B 54 24 28                             mov     edx, [rsp+arg_20]
.text:0000000078E9FDDF 44 8B 44 24 2C                          mov     r8d, [rsp+arg_24]
.text:0000000078E9FDE4 65 48 8B 04 25 60 00 00+                mov     rax, gs:60h     ; rax = PEB
.text:0000000078E9FDED 4C 8B 48 58                             mov     r9, [rax+58h]   ; r9 = KernelCallbackTable
.text:0000000078E9FDF1 43 FF 14 C1                             call    qword ptr [r9+r8*8]
.text:0000000078E9FDF1                         KiUserCallbackDispatcher endp ; sp-analysis failed

但是系统的自带的功能是可以正常切换到wow64模式的,比如 user32!_ClientLoadLibrary.
简单IDA之后,发现系统是存在一个模式切换的过程.

以 ClientLoadLibrary为例.
首先,到达 ntdll64!KiUserCallbackDispatcher 之后, call    qword ptr [r9+r8*8] 这里的地址是
wow64win !whcbClientLoadLibrary 这里都是x64的代码.

.text:0000000078BA92C3 41 B9 28 00 00 00                       mov     r9d, 28h                                        ;参数的大小
.text:0000000078BA92C9 45 8B C2                                mov     r8d, r10d                                        ;参数的地址
.text:0000000078BA92CC 41 8D 51 19                             lea     edx, [r9+19h]                                ; Wow64模式的ApiIndex
.text:0000000078BA92D0 48 8D 4C 24 30                          lea     rcx, [rsp+9F8h+pContext]        ;线程的上下文
.text:0000000078BA92D5 E8 2C 69 00 00                          call    Wow64KiUserCallbackDispatcher

wow64win !whcbClientLoadLibrary  内部继续分发了wow64!Wow64KiUserCallbackDispatcher

        void Wow64KiUserCallbackDispatcher(
OUT PCONTEXT Context,        //线程上下文,需要外部分配内存
IN LONG ApiIndex,                //wow64的KernelCallbackTable的ApiIndex
IN PVOID pParam,
IN ULONG ParamSize
);

wow64!Wow64KiUserCallbackDispatcher 中会复制参数到之前的context对应的栈上,
这个context已经是将来要使用的wow64模式 的context

.text:0000000078BD8A29 65 48 8B 04 25 30 00 00+                mov     rax, gs:30h
.text:0000000078BD8A32 48 05 00 20 00 00                       add     rax, 2000h
.text:0000000078BD8A38 48 89 44 24 30                          mov     [rsp+348h+var_318], rax
.text:0000000078BD8A3D 48 8B 44 24 30                          mov     rax, [rsp+348h+var_318]
.text:0000000078BD8A42 8B 00                                   mov     eax, [rax]
.text:0000000078BD8A44 89 84 24 18 03 00 00                    mov     [rsp+348h+var_30], eax
.text:0000000078BD8A4B E8 D8 46 00 00                          call    RunCpuSimulation

这里的 wow64!RunCpuSimulation 只是一个stub,会跳转到 wow64cpu!CpuSimulate

.text:0000000078B625B0                                         public CpuSimulate
.text:0000000078B625B0                         CpuSimulate     proc near               ; DATA XREF: .text:off_78B63168o
.text:0000000078B625B0                                                                 ; .pdata:0000000078B650B4o
.text:0000000078B625B0
.text:0000000078B625B0                         var_B8          = qword ptr -0B8h
.text:0000000078B625B0                         var_B0          = word ptr -0B0h
.text:0000000078B625B0                         var_A8          = dword ptr -0A8h
.text:0000000078B625B0                         var_A0          = qword ptr -0A0h
.text:0000000078B625B0                         var_98          = word ptr -98h
.text:0000000078B625B0                         var_48          = byte ptr -48h
.text:0000000078B625B0                         var_40          = qword ptr -40h
.text:0000000078B625B0                         var_38          = qword ptr -38h
.text:0000000078B625B0                         var_30          = qword ptr -30h
.text:0000000078B625B0                         var_28          = qword ptr -28h
.text:0000000078B625B0                         var_20          = qword ptr -20h
.text:0000000078B625B0                         var_18          = qword ptr -18h
.text:0000000078B625B0                         var_10          = qword ptr -10h
.text:0000000078B625B0                         var_8           = qword ptr -8
.text:0000000078B625B0
.text:0000000078B625B0 48 81 EC B8 00 00 00                    sub     rsp, 0B8h
.text:0000000078B625B7 48 89 6C 24 78                          mov     [rsp+0B8h+var_40], rbp
.text:0000000078B625BC 48 89 BC 24 80 00 00 00                 mov     [rsp+0B8h+var_38], rdi
.text:0000000078B625C4 48 89 B4 24 88 00 00 00                 mov     [rsp+0B8h+var_30], rsi
.text:0000000078B625CC 48 89 9C 24 90 00 00 00                 mov     [rsp+0B8h+var_28], rbx
.text:0000000078B625D4 4C 89 A4 24 98 00 00 00                 mov     [rsp+0B8h+var_20], r12
.text:0000000078B625DC 4C 89 AC 24 A0 00 00 00                 mov     [rsp+0B8h+var_18], r13
.text:0000000078B625E4 4C 89 B4 24 A8 00 00 00                 mov     [rsp+0B8h+var_10], r14
.text:0000000078B625EC 4C 89 BC 24 B0 00 00 00                 mov     [rsp+0B8h+var_8], r15
.text:0000000078B625F4 4C 8D 74 24 70                          lea     r14, [rsp+0B8h+var_48]
.text:0000000078B625F9 65 4C 8B 24 25 30 00 00+                mov     r12, gs:30h
.text:0000000078B62602 4C 8D 3D 47 FE FF FF                    lea     r15, off_78B62450
.text:0000000078B62609 4D 8B AC 24 88 14 00 00                 mov     r13, [r12+1488h]
.text:0000000078B62611
.text:0000000078B62611                         loc_78B62611:                           ; CODE XREF:         ;TurboDispatchJumpAddressEnd+34j
.text:0000000078B62611 41 83 A5 D0 02 00 00 01                 and     dword ptr [r13+2D0h], 1
.text:0000000078B62619 0F 84 AF 00 00 00                       jz      loc_78B626CE       
.text:0000000078B6261F 41 0F 28 85 70 01 00 00                 movaps  xmm0, xmmword ptr [r13+170h]                ;x64模式!
.text:0000000078B62627 41 0F 28 8D 80 01 00 00                 movaps  xmm1, xmmword ptr [r13+180h]
.text:0000000078B6262F 41 0F 28 95 90 01 00 00                 movaps  xmm2, xmmword ptr [r13+190h]
.text:0000000078B62637 41 0F 28 9D A0 01 00 00                 movaps  xmm3, xmmword ptr [r13+1A0h]
.text:0000000078B6263F 41 0F 28 A5 B0 01 00 00                 movaps  xmm4, xmmword ptr [r13+1B0h]
.text:0000000078B62647 41 0F 28 AD C0 01 00 00                 movaps  xmm5, xmmword ptr [r13+1C0h]
.text:0000000078B6264F 41 8B 8D B0 00 00 00                    mov     ecx, [r13+0B0h]
.text:0000000078B62656 41 8B 95 AC 00 00 00                    mov     edx, [r13+0ACh]
.text:0000000078B6265D 41 83 A5 D0 02 00 00 FE                 and     dword ptr [r13+2D0h], 0FFFFFFFEh
.text:0000000078B62665 41 8B BD A0 00 00 00                    mov     edi, [r13+0A0h]
.text:0000000078B6266C 41 8B B5 A4 00 00 00                    mov     esi, [r13+0A4h]
.text:0000000078B62673 41 8B 9D A8 00 00 00                    mov     ebx, [r13+0A8h]
.text:0000000078B6267A 41 8B AD B8 00 00 00                    mov     ebp, [r13+0B8h]
.text:0000000078B62681 41 8B 85 B4 00 00 00                    mov     eax, [r13+0B4h]
.text:0000000078B62688 49 89 A4 24 80 14 00 00                 mov     [r12+1480h], rsp
.text:0000000078B62690 66 C7 44 24 08 23 00                    mov     [rsp+0B8h+var_B0], 23h
.text:0000000078B62697 66 C7 44 24 20 2B 00                    mov     [rsp+0B8h+var_98], 2Bh
.text:0000000078B6269E 45 8B 85 C4 00 00 00                    mov     r8d, [r13+0C4h]
.text:0000000078B626A5 41 81 A5 C4 00 00 00 FF+                and     dword ptr [r13+0C4h], 0FFFFFEFFh
.text:0000000078B626B0 44 89 44 24 10                          mov     [rsp+0B8h+var_A8], r8d
.text:0000000078B626B5 45 8B 85 C8 00 00 00                    mov     r8d, [r13+0C8h]
.text:0000000078B626BC 4C 89 44 24 18                          mov     [rsp+0B8h+var_A0], r8
.text:0000000078B626C1 45 8B 85 BC 00 00 00                    mov     r8d, [r13+0BCh]
.text:0000000078B626C8 4C 89 04 24                             mov     [rsp+0B8h+var_B8], r8
.text:0000000078B626CC 48 CF                                   iretq                        ;返回到x64
.text:0000000078B626CE                         ; ---------------------------------------------------------------------------
.text:0000000078B626CE
.text:0000000078B626CE                         loc_78B626CE:                           ;x86模式
.text:0000000078B626CE 41 8B BD A0 00 00 00                    mov     edi, [r13+0A0h]
.text:0000000078B626D5 41 8B B5 A4 00 00 00                    mov     esi, [r13+0A4h]
.text:0000000078B626DC 41 8B 9D A8 00 00 00                    mov     ebx, [r13+0A8h]
.text:0000000078B626E3 41 8B AD B8 00 00 00                    mov     ebp, [r13+0B8h]
.text:0000000078B626EA 41 8B 85 B4 00 00 00                    mov     eax, [r13+0B4h]
.text:0000000078B626F1 49 89 A4 24 80 14 00 00                 mov     [r12+1480h], rsp
.text:0000000078B626F9 41 C7 46 04 23 00 00 00                 mov     dword ptr [r14+4], 23h
.text:0000000078B62701 41 B8 2B 00 00 00                       mov     r8d, 2Bh
.text:0000000078B62707 41 8E D0                                mov     ss, r8w
.text:0000000078B6270A                                         assume ss:nothing
.text:0000000078B6270A 41 8B A5 C8 00 00 00                    mov     esp, [r13+0C8h]
.text:0000000078B62711 45 8B 8D BC 00 00 00                    mov     r9d, [r13+0BCh]
.text:0000000078B62718 45 89 0E                                mov     [r14], r9d
.text:0000000078B6271B 41 FF 2E                                jmp     fword ptr [r14]        ;这个大跳会切换到x86模式!

这个函数主要就是从之前获取到的context里初始化各个通用寄存器.然后根据想要模拟的CPU环境进行跳转.

OK.到这里,整个大概的分发流程已经清楚了, 实现我们的需求就很简单了,模拟一次即可以了.

要执行wow64模式的shellcode,
也需要构造这些stub.

一共是2个stub

1.        PsGetProcessPeb 返回的原生的PEB.
添加KeCallbackTable的entry指向我们的wow64 stub.

2.        PsGetProcessWow64Process获取到wow64模式的PEB,
然后定位到相应的WOW64 KeCallbackTable ,添加entry指向需要执行的x86 shellcode.

wow64模式的APC
相对来说就好多了.只有一个简单的变换

text:0000000078E9FCD0                                         public KiUserApcDispatcher
.text:0000000078E9FCD0                         KiUserApcDispatcher:                    ; CODE XREF: .text:0000000078E9FD07j
.text:0000000078E9FCD0                                                                 ; DATA XREF: .rdata:off_78F58128o
.text:0000000078E9FCD0 48 8B 4C 24 18                          mov     rcx, [rsp+18h]
.text:0000000078E9FCD5 48 8B C1                                mov     rax, rcx
.text:0000000078E9FCD8 4C 8B CC                                mov     r9, rsp
.text:0000000078E9FCDB 48 C1 F9 02                             sar     rcx, 2
.text:0000000078E9FCDF 48 8B 54 24 08                          mov     rdx, [rsp+8]
.text:0000000078E9FCE4 48 F7 D9                                neg     rcx
.text:0000000078E9FCE7 4C 8B 44 24 10                          mov     r8, [rsp+10h]
.text:0000000078E9FCEC 48 0F A4 C9 20                          shld    rcx, rcx, 20h
.text:0000000078E9FCF1 85 C9                                   test    ecx, ecx
.text:0000000078E9FCF3 74 22                                   jz      short loc_78E9FD17
.text:0000000078E9FCF5 48 8B 0C 24                             mov     rcx, [rsp]
.text:0000000078E9FCF9 FF D0                                   call    rax

红色标记的地方.,ntdll64! KiUserApcDispatcher 对应我们传递的Apc例程地址做了一个小变化,我们做逆变换即可.
#ifdef _WIN64
                if (bWow64)
                {
                        //Neg rax
                        //shl rax,2
                        pFixStubAddr = (void*) NEG( (LONG)pFixStubAddr);
                        pFixStubAddr = (void*) SHL( (LONG)pFixStubAddr,2);
                }
#endif

//附相关代码片段.

xSpy@BinVul.com
xSpy@Vxjump.net
20170724

排版全乱了.,传一份word版的吧
ExecShellCodeInWow64ModeFromRing0.doc


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 3
支持
分享
最新回复 (14)
雪    币: 2105
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
沙发 123456
2014-7-29 11:38
0
雪    币: 2161
活跃值: (750)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
mark
2014-7-29 11:44
0
雪    币: 13258
活跃值: (4306)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
必须顶。。。
2014-7-29 12:14
0
雪    币: 68
活跃值: (104)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
前排MACK
2014-7-29 12:31
0
雪    币: 1140
活跃值: (3166)
能力值: ( LV12,RANK:385 )
在线值:
发帖
回帖
粉丝
6
20170724

穿越未来了?

不过这两个网站还是不错的。
xSpy@BinVul.com
xSpy@Vxjump.net
2014-7-30 12:29
0
雪    币: 144
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
mark
2014-7-30 18:36
0
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
mark
2014-7-30 20:08
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
学习一下
2014-8-3 07:35
0
雪    币: 85
活跃值: (51)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
10
mark
2014-8-12 15:06
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
学习一下
2014-8-13 09:25
0
雪    币: 441
活跃值: (1055)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
12
学习学习!!
2018-1-18 13:13
0
雪    币: 231
活跃值: (2631)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
13
666
2018-1-23 10:11
0
雪    币: 965
活跃值: (89)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
学习一下
2018-1-23 11:26
0
雪    币: 515
活跃值: (3272)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wem
15
888
2018-6-8 21:05
0
游客
登录 | 注册 方可回帖
返回
//