首页
社区
课程
招聘
[原创]R3层最后的倔强--权限切换
发表于: 2022-7-10 17:00 10569

[原创]R3层最后的倔强--权限切换

2022-7-10 17:00
10569

针对r3层的最强防御,应该就是自己实现调用r0的内核函数。不使用系统提供的API接口。这样能防御别人在导入函数的下断点,或者IAT HOOK。当然如果有些函数是不用进入内核,在r3层就 实现了所有功能的,不在这个讨论范围之内。

通过具体的两个API,来看r3是如何进入r0,看如何实现权限切换的。分析的环境为win10x64,版本为1903,样本程序也是64位程序。

图片描述

调用OpenProcess

OpenProcess本质调用的是NtOpenProcess

NtOpenProcess的关键代码就是调用syscall

● 本质上所有进入内核的API都是通过syscall(32系统通过sysenter来进入内核,xp通过int 0x2e中断进入内核)进入r0,通过sysret从r0返回r3.
● 通过寄存器eax来区分不同的API.实际这个编号就是SSDT的序号。
图片描述
● 参数通过栈传递,拷贝
● 关于0x7FFE308是_KUSER_SHARED_DATA结构体。内核有读写权限,r3只有读取权限。通过 _KUSER_SHARED_DATA.SystemCall的高位来判断系统是走中断进入内核还是通过门进入内核。
_KUSER_SHARED_DATA结构体解析如下:

● mov r10,rcx为什么要添加这句汇编指令,没有分析出来求大佬补充。
● 注意这里用windbg单步步入syscall是会跑飞的,只能在nt!NtOpenProcess下个断点,才能调试内核。

图片描述

VirtualAllocEx函数调用

VirtualAllocEx内部调用kernelbase.VirtualAllocExNuma

kernelbase.VirtualAllocExNuma 调用 ZwAllocateVirtualMemory

ntdll!ZwAllocateVirtualMemory 进入内核

● 内核对应函数名nt!NtAllocateVirtualMemory
图片描述

通过分析后得到,r3层最底层调用的是ntdll!NtOpenProcess。下面开始实现ntdll!NtOpenProcess。
● 由于vs对64位程序,不支持内联汇编。所以这里使用汇编和c/c++的联合编译。
● 由于根据IDA下载的微软pdb,能够解析NtOpenProcess调用的时候传入的参数的类型。但是没有具体的结构体的定义
● 通过wrk查询到OBJECT_ATTRIBUTES和CLIENT_ID结构体的定义。
门调用的关键代码

r3VirtualAllocExNuma测试效果如下:
图片描述
在ZwAllocateVirtualMemory下断点是不会被命中的:
图片描述

● 本意是想在写壳的时候,初始化IAT的时候,将IAT填入自己实现的API调用,避免在关键API下断。
● 奈何windows版本太多,ssdt的序号每个版本可能变化。提供两个思路:
○ 从不同版本的ntdll文件中解析ssdt序号
○ 从不同版本的pdb来解析ssdt序号
● 思路来自张老师讲Android的api的调用。Android的API序号不变,没有版本兼容问题。
● 如果有什么不对的欢迎大佬指点

00007FF790489EEF | 44:8B85 20010000         | mov r8d,dword ptr ss:[rbp+120]          | TestDomeDlg.cpp:632    //pid
00007FF790489EF6 | 33D2                     | xor edx,edx                             |                        //false
00007FF790489EF8 | B9 FFFF1F00              | mov ecx,1FFFFF                          |                        //PROCESS_ALL_ACCESS
00007FF790489EFD | FF15 4D21AB00            | call qword ptr ds:[<&OpenProcess>]      |
00007FF790489EEF | 44:8B85 20010000         | mov r8d,dword ptr ss:[rbp+120]          | TestDomeDlg.cpp:632    //pid
00007FF790489EF6 | 33D2                     | xor edx,edx                             |                        //false
00007FF790489EF8 | B9 FFFF1F00              | mov ecx,1FFFFF                          |                        //PROCESS_ALL_ACCESS
00007FF790489EFD | FF15 4D21AB00            | call qword ptr ds:[<&OpenProcess>]      |
00007FFC7207C0F0 | 4C:8BDC                  | mov r11,rsp                             |
00007FFC7207C0F3 | 48:83EC 68               | sub rsp,68                              |
00007FFC7207C0F7 | 49:8363 C0 00            | and qword ptr ds:[r11-40],0             |
00007FFC7207C0FC | 4D:8D4B B8               | lea r9,qword ptr ds:[r11-48]            |
00007FFC7207C100 | 49:63C0                  | movsxd rax,r8d                          |
00007FFC7207C103 | 0F57C0                   | xorps xmm0,xmm0                         |
00007FFC7207C106 | C74424 30 30000000       | mov dword ptr ss:[rsp+30],30            | 30:'0'
00007FFC7207C10E | 4D:8D43 C8               | lea r8,qword ptr ds:[r11-38]            |
00007FFC7207C112 | 49:8363 D0 00            | and qword ptr ds:[r11-30],0             |
00007FFC7207C117 | F7DA                     | neg edx                                 |
00007FFC7207C119 | 49:8943 B8               | mov qword ptr ds:[r11-48],rax           |
00007FFC7207C11D | 8BD1                     | mov edx,ecx                             |
00007FFC7207C11F | 49:8D4B 20               | lea rcx,qword ptr ds:[r11+20]           | [r11+20]:L"兽郴翷"
00007FFC7207C123 | 1BC0                     | sbb eax,eax                             |
00007FFC7207C125 | 83E0 02                  | and eax,2                               |
00007FFC7207C128 | 894424 48                | mov dword ptr ss:[rsp+48],eax           |
00007FFC7207C12C | 49:8363 D8 00            | and qword ptr ds:[r11-28],0             | [r11-28]:AfxWndProc+E1
00007FFC7207C131 | F3:0F7F4424 50           | movdqu xmmword ptr ss:[rsp+50],xmm0     |
00007FFC7207C137 | 48:FF15 BA781900         | call qword ptr ds:[<&NtOpenProcess>]    |
00007FFC7207C13E | 0F1F4400 00              | nop dword ptr ds:[rax+rax],eax          |
00007FFC7207C143 | 85C0                     | test eax,eax                            |
00007FFC7207C145 | 78 0E                    | js kernelbase.7FFC7207C155              |
00007FFC7207C147 | 48:8B8424 88000000       | mov rax,qword ptr ss:[rsp+88]           |
00007FFC7207C14F | 48:83C4 68               | add rsp,68                              |
00007FFC7207C153 | C3                       | ret                                     |
00007FFC7207C0F0 | 4C:8BDC                  | mov r11,rsp                             |
00007FFC7207C0F3 | 48:83EC 68               | sub rsp,68                              |
00007FFC7207C0F7 | 49:8363 C0 00            | and qword ptr ds:[r11-40],0             |
00007FFC7207C0FC | 4D:8D4B B8               | lea r9,qword ptr ds:[r11-48]            |
00007FFC7207C100 | 49:63C0                  | movsxd rax,r8d                          |
00007FFC7207C103 | 0F57C0                   | xorps xmm0,xmm0                         |
00007FFC7207C106 | C74424 30 30000000       | mov dword ptr ss:[rsp+30],30            | 30:'0'
00007FFC7207C10E | 4D:8D43 C8               | lea r8,qword ptr ds:[r11-38]            |
00007FFC7207C112 | 49:8363 D0 00            | and qword ptr ds:[r11-30],0             |
00007FFC7207C117 | F7DA                     | neg edx                                 |
00007FFC7207C119 | 49:8943 B8               | mov qword ptr ds:[r11-48],rax           |
00007FFC7207C11D | 8BD1                     | mov edx,ecx                             |
00007FFC7207C11F | 49:8D4B 20               | lea rcx,qword ptr ds:[r11+20]           | [r11+20]:L"兽郴翷"
00007FFC7207C123 | 1BC0                     | sbb eax,eax                             |
00007FFC7207C125 | 83E0 02                  | and eax,2                               |
00007FFC7207C128 | 894424 48                | mov dword ptr ss:[rsp+48],eax           |
00007FFC7207C12C | 49:8363 D8 00            | and qword ptr ds:[r11-28],0             | [r11-28]:AfxWndProc+E1
00007FFC7207C131 | F3:0F7F4424 50           | movdqu xmmword ptr ss:[rsp+50],xmm0     |
00007FFC7207C137 | 48:FF15 BA781900         | call qword ptr ds:[<&NtOpenProcess>]    |
00007FFC7207C13E | 0F1F4400 00              | nop dword ptr ds:[rax+rax],eax          |
00007FFC7207C143 | 85C0                     | test eax,eax                            |
00007FFC7207C145 | 78 0E                    | js kernelbase.7FFC7207C155              |
00007FFC7207C147 | 48:8B8424 88000000       | mov rax,qword ptr ss:[rsp+88]           |
00007FFC7207C14F | 48:83C4 68               | add rsp,68                              |
00007FFC7207C153 | C3                       | ret                                     |
00007FFC7454D1F0 | 4C:8BD1                  | mov r10,rcx                             |
00007FFC7454D1F3 | B8 26000000              | mov eax,26   //每个不同的API都有不同的编号来区分                          | 26:'&'
00007FFC7454D1F8 | F60425 0803FE7F 01       | test byte ptr ds:[7FFE0308],1           |
00007FFC7454D200 | 75 03                    | jne ntdll.7FFC7454D205                  |
00007FFC7454D202 | 0F05                     | syscall     //通过门进入内核
00007FFC7454D204 | C3                       | ret                                     |
00007FFC7454D205 | CD 2E                    | int 2E      //通过中断进入内核                             |
00007FFC7454D207 | C3                       | ret                                     |
00007FFC7454D1F0 | 4C:8BD1                  | mov r10,rcx                             |
00007FFC7454D1F3 | B8 26000000              | mov eax,26   //每个不同的API都有不同的编号来区分                          | 26:'&'
00007FFC7454D1F8 | F60425 0803FE7F 01       | test byte ptr ds:[7FFE0308],1           |
00007FFC7454D200 | 75 03                    | jne ntdll.7FFC7454D205                  |
00007FFC7454D202 | 0F05                     | syscall     //通过门进入内核
00007FFC7454D204 | C3                       | ret                                     |
00007FFC7454D205 | CD 2E                    | int 2E      //通过中断进入内核                             |
00007FFC7454D207 | C3                       | ret                                     |
1: kd> dt nt!_KUSER_SHARED_DATA
*** Unable to resolve unqualified symbol in Bp expression 'l'.
   +0x000 TickCountLowDeprecated : Uint4B
   +0x004 TickCountMultiplier : Uint4B
   +0x008 InterruptTime    : _KSYSTEM_TIME
   +0x014 SystemTime       : _KSYSTEM_TIME
   +0x020 TimeZoneBias     : _KSYSTEM_TIME
   +0x02c ImageNumberLow   : Uint2B
   +0x02e ImageNumberHigh  : Uint2B
   +0x030 NtSystemRoot     : [260] Wchar
   +0x238 MaxStackTraceDepth : Uint4B
   +0x23c CryptoExponent   : Uint4B
   +0x240 TimeZoneId       : Uint4B
   +0x244 LargePageMinimum : Uint4B
   +0x248 AitSamplingValue : Uint4B
   +0x24c AppCompatFlag    : Uint4B
   +0x250 RNGSeedVersion   : Uint8B
   +0x258 GlobalValidationRunlevel : Uint4B
   +0x25c TimeZoneBiasStamp : Int4B
   +0x260 NtBuildNumber    : Uint4B
   +0x264 NtProductType    : _NT_PRODUCT_TYPE
   +0x268 ProductTypeIsValid : UChar
   +0x269 Reserved0        : [1] UChar
   +0x26a NativeProcessorArchitecture : Uint2B
   +0x26c NtMajorVersion   : Uint4B
   +0x270 NtMinorVersion   : Uint4B
   +0x274 ProcessorFeatures : [64] UChar
   +0x2b4 Reserved1        : Uint4B
   +0x2b8 Reserved3        : Uint4B
   +0x2bc TimeSlip         : Uint4B
   +0x2c0 AlternativeArchitecture : _ALTERNATIVE_ARCHITECTURE_TYPE
   +0x2c4 BootId           : Uint4B
   +0x2c8 SystemExpirationDate : _LARGE_INTEGER
   +0x2d0 SuiteMask        : Uint4B
   +0x2d4 KdDebuggerEnabled : UChar
   +0x2d5 MitigationPolicies : UChar
   +0x2d5 NXSupportPolicy  : Pos 0, 2 Bits
   +0x2d5 SEHValidationPolicy : Pos 2, 2 Bits
   +0x2d5 CurDirDevicesSkippedForDlls : Pos 4, 2 Bits
   +0x2d5 Reserved         : Pos 6, 2 Bits
   +0x2d6 CyclesPerYield   : Uint2B
   +0x2d8 ActiveConsoleId  : Uint4B
   +0x2dc DismountCount    : Uint4B
   +0x2e0 ComPlusPackage   : Uint4B
   +0x2e4 LastSystemRITEventTickCount : Uint4B
   +0x2e8 NumberOfPhysicalPages : Uint4B
   +0x2ec SafeBootMode     : UChar
   +0x2ed VirtualizationFlags : UChar
   +0x2ee Reserved12       : [2] UChar
   +0x2f0 SharedDataFlags  : Uint4B
   +0x2f0 DbgErrorPortPresent : Pos 0, 1 Bit
   +0x2f0 DbgElevationEnabled : Pos 1, 1 Bit
   +0x2f0 DbgVirtEnabled   : Pos 2, 1 Bit
   +0x2f0 DbgInstallerDetectEnabled : Pos 3, 1 Bit
   +0x2f0 DbgLkgEnabled    : Pos 4, 1 Bit
   +0x2f0 DbgDynProcessorEnabled : Pos 5, 1 Bit
   +0x2f0 DbgConsoleBrokerEnabled : Pos 6, 1 Bit
   +0x2f0 DbgSecureBootEnabled : Pos 7, 1 Bit
   +0x2f0 DbgMultiSessionSku : Pos 8, 1 Bit
   +0x2f0 DbgMultiUsersInSessionSku : Pos 9, 1 Bit
   +0x2f0 DbgStateSeparationEnabled : Pos 10, 1 Bit
   +0x2f0 SpareBits        : Pos 11, 21 Bits
   +0x2f4 DataFlagsPad     : [1] Uint4B
   +0x2f8 TestRetInstruction : Uint8B
   +0x300 QpcFrequency     : Int8B
   +0x308 SystemCall       : Uint4B  //4位,根据汇编代码却检测的1
   +0x30c SystemCallPad0   : Uint4B
   +0x310 SystemCallPad    : [2] Uint8B
   +0x320 TickCount        : _KSYSTEM_TIME
   +0x320 TickCountQuad    : Uint8B
   +0x320 ReservedTickCountOverlay : [3] Uint4B
   +0x32c TickCountPad     : [1] Uint4B
   +0x330 Cookie           : Uint4B
   +0x334 CookiePad        : [1] Uint4B
   +0x338 ConsoleSessionForegroundProcessId : Int8B
   +0x340 TimeUpdateLock   : Uint8B
   +0x348 BaselineSystemTimeQpc : Uint8B
   +0x350 BaselineInterruptTimeQpc : Uint8B
   +0x358 QpcSystemTimeIncrement : Uint8B
   +0x360 QpcInterruptTimeIncrement : Uint8B
   +0x368 QpcSystemTimeIncrementShift : UChar
   +0x369 QpcInterruptTimeIncrementShift : UChar
   +0x36a UnparkedProcessorCount : Uint2B
   +0x36c EnclaveFeatureMask : [4] Uint4B
   +0x37c TelemetryCoverageRound : Uint4B
   +0x380 UserModeGlobalLogger : [16] Uint2B
   +0x3a0 ImageFileExecutionOptions : Uint4B
   +0x3a4 LangGenerationCount : Uint4B
   +0x3a8 Reserved4        : Uint8B
   +0x3b0 InterruptTimeBias : Uint8B
   +0x3b8 QpcBias          : Uint8B
   +0x3c0 ActiveProcessorCount : Uint4B
   +0x3c4 ActiveGroupCount : UChar
   +0x3c5 Reserved9        : UChar
   +0x3c6 QpcData          : Uint2B
   +0x3c6 QpcBypassEnabled : UChar
   +0x3c7 QpcShift         : UChar
   +0x3c8 TimeZoneBiasEffectiveStart : _LARGE_INTEGER
   +0x3d0 TimeZoneBiasEffectiveEnd : _LARGE_INTEGER
   +0x3d8 XState           : _XSTATE_CONFIGURATION
1: kd> dt nt!_KUSER_SHARED_DATA
*** Unable to resolve unqualified symbol in Bp expression 'l'.
   +0x000 TickCountLowDeprecated : Uint4B
   +0x004 TickCountMultiplier : Uint4B
   +0x008 InterruptTime    : _KSYSTEM_TIME
   +0x014 SystemTime       : _KSYSTEM_TIME
   +0x020 TimeZoneBias     : _KSYSTEM_TIME
   +0x02c ImageNumberLow   : Uint2B
   +0x02e ImageNumberHigh  : Uint2B
   +0x030 NtSystemRoot     : [260] Wchar
   +0x238 MaxStackTraceDepth : Uint4B
   +0x23c CryptoExponent   : Uint4B
   +0x240 TimeZoneId       : Uint4B
   +0x244 LargePageMinimum : Uint4B
   +0x248 AitSamplingValue : Uint4B
   +0x24c AppCompatFlag    : Uint4B
   +0x250 RNGSeedVersion   : Uint8B
   +0x258 GlobalValidationRunlevel : Uint4B
   +0x25c TimeZoneBiasStamp : Int4B
   +0x260 NtBuildNumber    : Uint4B
   +0x264 NtProductType    : _NT_PRODUCT_TYPE
   +0x268 ProductTypeIsValid : UChar
   +0x269 Reserved0        : [1] UChar
   +0x26a NativeProcessorArchitecture : Uint2B
   +0x26c NtMajorVersion   : Uint4B
   +0x270 NtMinorVersion   : Uint4B
   +0x274 ProcessorFeatures : [64] UChar
   +0x2b4 Reserved1        : Uint4B
   +0x2b8 Reserved3        : Uint4B
   +0x2bc TimeSlip         : Uint4B
   +0x2c0 AlternativeArchitecture : _ALTERNATIVE_ARCHITECTURE_TYPE
   +0x2c4 BootId           : Uint4B
   +0x2c8 SystemExpirationDate : _LARGE_INTEGER
   +0x2d0 SuiteMask        : Uint4B
   +0x2d4 KdDebuggerEnabled : UChar
   +0x2d5 MitigationPolicies : UChar
   +0x2d5 NXSupportPolicy  : Pos 0, 2 Bits
   +0x2d5 SEHValidationPolicy : Pos 2, 2 Bits
   +0x2d5 CurDirDevicesSkippedForDlls : Pos 4, 2 Bits
   +0x2d5 Reserved         : Pos 6, 2 Bits
   +0x2d6 CyclesPerYield   : Uint2B
   +0x2d8 ActiveConsoleId  : Uint4B
   +0x2dc DismountCount    : Uint4B
   +0x2e0 ComPlusPackage   : Uint4B
   +0x2e4 LastSystemRITEventTickCount : Uint4B
   +0x2e8 NumberOfPhysicalPages : Uint4B
   +0x2ec SafeBootMode     : UChar
   +0x2ed VirtualizationFlags : UChar
   +0x2ee Reserved12       : [2] UChar
   +0x2f0 SharedDataFlags  : Uint4B
   +0x2f0 DbgErrorPortPresent : Pos 0, 1 Bit
   +0x2f0 DbgElevationEnabled : Pos 1, 1 Bit
   +0x2f0 DbgVirtEnabled   : Pos 2, 1 Bit
   +0x2f0 DbgInstallerDetectEnabled : Pos 3, 1 Bit
   +0x2f0 DbgLkgEnabled    : Pos 4, 1 Bit
   +0x2f0 DbgDynProcessorEnabled : Pos 5, 1 Bit
   +0x2f0 DbgConsoleBrokerEnabled : Pos 6, 1 Bit
   +0x2f0 DbgSecureBootEnabled : Pos 7, 1 Bit
   +0x2f0 DbgMultiSessionSku : Pos 8, 1 Bit
   +0x2f0 DbgMultiUsersInSessionSku : Pos 9, 1 Bit
   +0x2f0 DbgStateSeparationEnabled : Pos 10, 1 Bit
   +0x2f0 SpareBits        : Pos 11, 21 Bits
   +0x2f4 DataFlagsPad     : [1] Uint4B
   +0x2f8 TestRetInstruction : Uint8B
   +0x300 QpcFrequency     : Int8B
   +0x308 SystemCall       : Uint4B  //4位,根据汇编代码却检测的1
   +0x30c SystemCallPad0   : Uint4B
   +0x310 SystemCallPad    : [2] Uint8B
   +0x320 TickCount        : _KSYSTEM_TIME
   +0x320 TickCountQuad    : Uint8B
   +0x320 ReservedTickCountOverlay : [3] Uint4B
   +0x32c TickCountPad     : [1] Uint4B
   +0x330 Cookie           : Uint4B
   +0x334 CookiePad        : [1] Uint4B
   +0x338 ConsoleSessionForegroundProcessId : Int8B
   +0x340 TimeUpdateLock   : Uint8B
   +0x348 BaselineSystemTimeQpc : Uint8B
   +0x350 BaselineInterruptTimeQpc : Uint8B
   +0x358 QpcSystemTimeIncrement : Uint8B
   +0x360 QpcInterruptTimeIncrement : Uint8B
   +0x368 QpcSystemTimeIncrementShift : UChar
   +0x369 QpcInterruptTimeIncrementShift : UChar
   +0x36a UnparkedProcessorCount : Uint2B
   +0x36c EnclaveFeatureMask : [4] Uint4B
   +0x37c TelemetryCoverageRound : Uint4B
   +0x380 UserModeGlobalLogger : [16] Uint2B
   +0x3a0 ImageFileExecutionOptions : Uint4B
   +0x3a4 LangGenerationCount : Uint4B
   +0x3a8 Reserved4        : Uint8B
   +0x3b0 InterruptTimeBias : Uint8B
   +0x3b8 QpcBias          : Uint8B
   +0x3c0 ActiveProcessorCount : Uint4B
   +0x3c4 ActiveGroupCount : UChar
   +0x3c5 Reserved9        : UChar
   +0x3c6 QpcData          : Uint2B
   +0x3c6 QpcBypassEnabled : UChar

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2022-7-10 17:18 被kardpan编辑 ,原因:
收藏
免费 8
支持
分享
最新回复 (4)
雪    币: 12
活跃值: (423)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
SysWhispers 请! DirectCall 请!
2022-7-10 20:55
1
雪    币: 407
活跃值: (501)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
MaMy SysWhispers 请! DirectCall 请!
原来已经有大佬写了框架,赶紧去学习一波。
2022-7-10 22:23
0
雪    币: 1103
活跃值: (1662)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
4

kardpan大佬YYDS!!!

syscall地狱之门作为绕过EDR检测和病毒木马利用的常见手段,我一直也在研究。

关于mov r10,rcx的原因简要说是:rcx会在Syscall的过程中被修改。所以制定的ABI标准是将rcx移到r10中进行保存。

但是后面的理论还是比较复杂的,下面的讨论和文档的148页有更为详细的描述:

【1】https://stackoverflow.com/questions/63891991/whats-the-best-way-to-remember-the-x86-64-system-v-arg-register-order

【2】https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf

最后于 2023-1-20 20:50 被瑞皇编辑 ,原因:
2023-1-20 20:34
0
雪    币: 6124
活跃值: (4666)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
5
闭门造车是搞不好的
2023-1-20 23:38
0
游客
登录 | 注册 方可回帖
返回
//