吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3192|回复: 7
上一主题 下一主题
收起左侧

[调试逆向] Windows x64中断门提权 R3调用R0函数

[复制链接]
跳转到指定楼层
楼主
deadpoolwilson1 发表于 2023-4-26 16:55 回帖奖励


声明:
(1)本篇文章实验针对 未开启内核隔离(KPTI) 的Window10系统
(2)本次实验的实现 并不代表R3调用R0可以完全只由Ring3完成

   win10并不使用调用门、陷阱门、任务门,  一律只用中断门,本次实验采用中断门提权实现R3调用R0函数。
   没开启KPTI, Cr3始终为内核Cr3。

环境工具

(1) 调式工具:Windbg
(2) 虚拟机:windows10 19044.2846
(3) IDE: VS2019


一、原理分析

1.IDT表、中断描述符

-

中断:只使用一张IDT表,内核可以根据栈上的CS判断先前模式。
IDT表地址位于KPCR偏移0x38处

nt!_KPCR
+0x038 IdtBase : Ptr64 _KIDTENTRY64

-

64位中断门描述符:

图来自Intel 第3卷 Figure 6-7. 64-Bit IDT Gate Descriptors
参照此图方便后续构造中断门

-

2.Fs、Gs寄存器

X86:0环时FS指向KPCR,3环时FS指向TEB
X64:0环时GS指向KPCR,3环时GS指向TEB
FS和GS的基址在3个MSR寄存器中:

IA32_FS_BASE (下标0xC0000100)
IA32_GS_BASE (下标0xC0000101)
IA32_KERNEL_GS_BASE (下标0xC0000102)

-

3.简单分析3环进0环过程

(1) 分析int 3中断

windbg输入指令: !idt

可看到3号中断函数是KiBreakpointTrap,这是因为笔者的测试机是未开启KPTI的.
而在开启KPTI时:3号中断函数调用的是KiBreakpointTrapShadow

-

用IDA对内核文件ntoskrnl.exe的KiBreakpointTrapShadow分析

由IDA分析可知,KiBreakpointTrapShadow 只是做了一些调用0环函数前的准备行为,如切换内核Cr3,切换内核rsp,切换内核gs等, 最后跳到了KiBreakpointTrap真正执行中断函数。

而未开启KPTI时,中断函数并不是KiBreakpointTrapShadow而是KiBreakpointTrap,而KiBreakpointTrap中并没有这些进内核的准备行为,笔者猜测进KiBreakpointTrap前肯定还执行过类似的代码, 目前还未查到

后面本人通过构建中断门进行测试发现,进去中断函数时rsp已经切换为0环的rsp, _KTrap_Frame的那5个寄存器也在栈中, cr3本身就是内核cr3 ,不需要改, 但是gs还没修改, 所以我们的构建中断门函数代码里边只用修改gs就可以调用内核函数了

-


二、代码实现

1.配置项目

1.创建vs空项目, 笔者项目名为IntGate
2.创建main.cpp文件和x64asm.asm文件(asm文件随便创建一个文件后, 将后缀为.asm就行)  

-

3.右键项目->生成依赖性->生成自定义, 第四个打上勾


-

4.右键x64asm.asm,按如下图选择

5、打开项目属性设置固定基址, 并关闭增量链接


2.代码实现

代码如下(部分硬编码的地方需要更改):

main.cpp

#include <Windows.h>
#include <stdio.h>

extern "C" void InterruptEntry();
extern "C" void CaseInterrupt();

int main()
{
        printf("InterruptEntry Addr:%p\n", (ULONG64)InterruptEntry);
        // 笔者InterruptEntry为0x0000000140001200
        if ((ULONG64)InterruptEntry != 0x0000000140001200)
        {
                printf("InterruptEntry地址与中断门构建的地址不一样\n");
                system("pause");
                return 0;
        }
        system("pause");

        CaseInterrupt();

        system("pause");
        return 0;
}

x64asm.asm

option casemap:none

.data
pStr db 'I am the DbgPrint func', 0DH, 0AH

.code

InterruptEntry proc
        ;切换gs
        swapgs

        ;调用DbgPrint函数. 为方便直接用windbg查了之后将函数地址写成硬编码了
        mov rax,0fffff8047e7647b0h
        sub rsp,20h
        lea rcx,[pStr]
        call rax
        add rsp,20h

        ; 恢复gs
        swapgs
        iretq
InterruptEntry endp

CaseInterrupt proc
        int 0fh ;f号中断系统未使用
        ret
CaseInterrupt endp

end

windbg配置

1.构建中断门
笔者InterruptEntry地址为0x0000000140001200,中断门属性就填3号中断的属性,地址填0x0000000140001200

    windbg:
             eq idtr+f0 4000ee00`00101200
             eq idtr+f8 00000000`00000001
             !idt f

-

2.设置Cr4寄存器中SMEP和SMAP, 把3去掉就行

运行截图

参考资料

-

如有错误, 还请大佬指正

免费评分

参与人数 3吾爱币 +8 热心值 +3 收起 理由
way2888 + 1 + 1 热心回复!
抱歉、 + 1 用心讨论,共获提升!
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
CXC303 发表于 2023-4-28 00:47
望尘莫及,高手
3#
warmxxx 发表于 2023-5-6 09:42
4#
HYL6668 发表于 2023-8-16 00:34
5#
lmluo 发表于 2023-8-16 15:35
看的有点难受啊,看不懂
6#
YunYing 发表于 2023-9-10 16:01
本帖最后由 YunYing 于 2023-9-10 16:03 编辑

为什么要加eq idtr+f8 00000000`00000001?

高64位,最后一个段是Reserved吧?这个需要填麻
7#
c259179 发表于 2023-9-12 09:55
看的有点难受啊,看不懂
8#
mnss 发表于 2024-3-19 01:11
我在相同Windows版本下进行实验时发现,int 0xf 这行每次都会报0xC0000005的页错误;KPTI已经关闭,cr4的位修改过了,中断门设置的位置跟lz一样,为了以防万一我还改了cr0的wp再试,这几种方法都是报同样的错误,不知道lz是否也有过这个问题呢?想请教一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-3-28 15:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表