首次购买高性能云服务器,享低至2折优惠

搜搜吧

查看: 5|回复: 0

[资讯] 【硬件虚拟化】远离kernel的理想乡[含3P]

[复制链接]
  • TA的每日心情
    擦汗
    昨天 15:56
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    超级VIP贵宾会员

    83

    主题

    86

    帖子

    273

    积分

    Rank: 1

    UID
    21335
    威望
    -3
    贡献
    108
    在线时间
    1 小时
    注册时间
    2018-12-6
    发表于 6 天前 | 显示全部楼层 |阅读模式
    推广者专属福利,新客户无门槛领取总价值高达2775元代金券,每种代金券限量500张,先到先得。

    简介

    这个故事描述了如何使用硬件虚拟化(HVM)使得自己的一些hook代码远离内核不容易被其他内核hook所影响并且较难被检测。本文的思路来源于某学校的动态linux内核更新的玩意,代码大量抄自bluepill。

    e6dfe86cb81701d94e7a3e00342ab97e.jpg-wh_651x-s_3685843172.jpg

    第一章 (Avalon) 阿瓦隆的黎明

    由于驱动牛人越来越多系统控制权的争夺愈演愈烈,内核之中几乎无一块净土。inline hook、ssdt hook等等各种hook充斥着我们幼小的内核。他们有些结构复杂,有些相互关联,有些检测监视,想要重新获得那些控制点的控制权必须花些力气研究那些hook,使得原来很简单的hook变得牵一发而动全身。

    现在有硬件虚拟化技术,我们可以换个思路来解决那些问题了…

    一、(Avalon)阿瓦隆的构成

    (Avalon) 阿瓦隆的本体为以下几个部分:

    1、Avlboot.sys(用于保存刚初始化后还没被hook污染的系统内核方便之后使用)

    2、Avalon.sys(用于读取伪内核信息,开启硬件虚拟化加载伪内核)

    3、XXX.sys(用户利用Avlboot.sys中所提供的信息进行具体hook操作的程序)

    0cb35eeda9540eea8c2ca230125cb7a5.jpg

    二、(Avalon)阿瓦隆的真相

    本文所介绍的(Avalon) 阿瓦隆是一个基于虚拟化的内核加载框架。其利用硬件虚拟化(HVM)和一块没有被hook污染的内核内存,使得PC中同时运行着两个内核。并且Avalon通过控制sysenter_eip和idt中指向伪内核的相应地址来获得控制权。

    简而言之,(Avalon)阿瓦隆就是利用硬件虚拟化(HVM)加载自己的内核架空原内核,使得自己能在不被检测的环境下获得内核的控制权。

    实现原理如下图所示:


    69dc70ecd0f7903f6b52acd9ff8eaf03.jpg

    自己的hook程序在获得伪内核的基地址后,可以通过hookport来处理ssdt,shadow ssdt(strongod需要备份其所hook的ssdt稍微麻烦点,agp什么的只要把地址偏移一下就能用了)。

    三、(Avalon)阿瓦隆的应用

    其实我们可以把(Avalon)阿瓦隆看成是一种变相的sysenter hook+idt hook。

    由于(Avalon)阿瓦隆基于硬件虚拟化(HVM)使得我们可以架空整个内核,使得内核可以在运行时可以实时的替换。

    因为伪内核的所在内存范围不受内存监控,别的程序也无法直接访问,使得我们的伪内核就成了不用考虑其他干扰问题,可以随意hook的安全的理想乡。

    这种方式的hook和传统的一些hook相比有着以下优点:

    1、不在传统的内存监控的范围,较难检测。

    2、不干扰系统中原有的hook代码,兼容性较高。

    但是同样有一些缺点:

    1、无法直接干涉object hook,irp hook等不依赖于内核内存的hook代码

    2、整个系统依赖于硬件虚拟化(HVM),对硬件设备有一定要求。

    第二章 空想具现化

    一、纯洁的初始化

    首先我们来实现(Avalon)阿瓦隆的初始化,初始化由4个部分组成:内核信息获取、伪内核构造、IDT信息保存、原始SYSENTER_EIP获取。

    实现代码如下:

    • NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)  
    • {  
    • ...
    • KrnlCopy();
    • IDTCopy();
    • ReadMsrSysenter();
    • ...
    • }
    • /*
    •   内核拷贝
    • */
    • VOID KrnlCopy()
    • {
    • PVOID Buffer;
    • ULONG Size;
    • ULONG RetSize;
    • PSYSTEM_MODULE_INFORMATION InfoBuffer;
    • NTSTATUS Status;
    • PVOID ModuleBase;
    • ULONG ModuleSize;
    • Size=0x1000;
    • do {
    • Buffer=ExAllocatePool(NonPagedPool,Size);
    • Status=ZwQuerySystemInformation(SystemModuleInformation,Buffer,Size,&RetSize);
    • if (Status == STATUS_INFO_LENGTH_MISMATCH)
    •        {
    •            ExFreePool(Buffer);
    •            Size = RetSize;
    •        }   
    • }while(Status == STATUS_INFO_LENGTH_MISMATCH);
    • InfoBuffer = (PSYSTEM_MODULE_INFORMATION)Buffer;
    • ModuleBase=(PVOID)(InfoBuffer->ModuleInfo[0].Base);
    • Orig_krnl=(ULONG)ModuleBase;
    • DbgPrint("AvlBoot:Orig_krnl Base=%x\n",ModuleBase);
    • ModuleSize=InfoBuffer->ModuleInfo[0].Size;
    • makeKernelCopy((ULONG)ModuleBase,ModuleSize);
    • DbgPrint("AvlBoot:Avl_krnl Base=%x\n",Avl_krnl);
    • ExFreePool(Buffer);
    • }

    等初始化之后,其他部件就可以通过访问Avlboot.sys来获得伪内核的信息和内核原始信息。

    二、抄来的虚拟化

    这里先简单的向大家介绍下,Intel vt硬件虚拟化的步骤:

    1、检查vt环境

    2、开启vt功能

    3、填充vt,存储虚拟机状态

    4、设定需要拦截项目

    5、设定从虚拟机中退出时返回的地址

    6、启动虚拟机,等待拦截项目触发

    7、拦截项目被触发,进入相关项目的处理例程

    8、恢复虚拟机继续运行

    接下来是一些坑爹的代码:

    • /*
    •   Vmx初始化
    • */
    • NTSTATUS NTAPI VmxInitialize (
    •    PCPU Cpu,
    •    PVOID GuestEip,
    •    PVOID GuestEsp
    • )
    • {
    •    PHYSICAL_ADDRESS AlignedVmcsPA;
    •    ULONG VaDelta;
    •    NTSTATUS Status;
    •    // 为 VMXON region 申请内存空间
    •    Cpu->Vmx.OriginaVmxonR = MmAllocateContiguousPages(
    •        VMX_VMXONR_SIZE_IN_PAGES,  
    •        &Cpu->Vmx.OriginalVmxonRPA);
    •    if (!Cpu->Vmx.OriginaVmxonR)  
    •    {
    • DbgPrint("VmxInitialize(): Failed to allocate memory for original VMCS\n");
    •        return STATUS_INSUFFICIENT_RESOURCES;
    •    }
    •    DbgPrint("VmxInitialize(): OriginaVmxonR VA: 0x%x\n", Cpu->Vmx.OriginaVmxonR);
    •    DbgPrint("VmxInitialize(): OriginaVmxonR PA: 0x%llx\n", Cpu->Vmx.OriginalVmxonRPA.QuadPart);
    •    // 为 VMCS 申请内存空间  
    •    Cpu->Vmx.OriginalVmcs = MmAllocateContiguousPages(
    •        VMX_VMCS_SIZE_IN_PAGES,  
    •        &Cpu->Vmx.OriginalVmcsPA);
    •    if (!Cpu->Vmx.OriginalVmcs)  
    •    {
    • DbgPrint("VmxInitialize(): Failed to allocate memory for original VMCS\n");
    •        return STATUS_INSUFFICIENT_RESOURCES;
    •    }
    •    DbgPrint("VmxInitialize(): Vmcs VA: 0x%x\n", Cpu->Vmx.OriginalVmcs);
    •    DbgPrint("VmxInitialize(): Vmcs PA: 0x%llx\n", Cpu->Vmx.OriginalVmcsPA.QuadPart);
    •    // 开启vmx
    •    if (!NT_SUCCESS (VmxEnable (Cpu->Vmx.OriginaVmxonR)))
    •    {
    •        DbgPrint("VmxInitialize(): Failed to enable Vmx\n");
    •        return STATUS_UNSUCCESSFUL;
    •    }
    •    *((ULONG64 *)(Cpu->Vmx.OriginalVmcs)) =  
    •        (MsrRead (MSR_IA32_VMX_BASIC) & 0xffffffff); //set up vmcs_revision_id      
    •    // 填充VMCS结构
    • Status = VmxSetupVMCS (Cpu, GuestEip, GuestEsp);
    •    if (!NT_SUCCESS (Status))  
    •    {
    •        DbgPrint("VmxSetupVMCS() failed with status 0x%08hX\n", Status);
    •        VmxDisable();
    •        return Status;
    •    }
    •    DbgPrint("VmxInitialize(): Vmx enabled\n");
    •   // 保存EFER
    •    Cpu->Vmx.GuestEFER = MsrRead (MSR_EFER);
    •    DbgPrint("Guest MSR_EFER Read 0x%llx \n", Cpu->Vmx.GuestEFER);
    •   // 保存控制寄存器
    •    Cpu->Vmx.GuestCR0 = RegGetCr0 ();
    •    Cpu->Vmx.GuestCR3 = RegGetCr3 ();
    •    Cpu->Vmx.GuestCR4 = RegGetCr4 ();
    •    CmCli ();
    •    return STATUS_SUCCESS;
    • }
    • /*
    •   开启vmx
    • */
    • NTSTATUS NTAPI VmxEnable (
    •    PVOID VmxonVA
    • )
    • {
    •    ULONG cr4;
    •    ULONG64 vmxmsr;
    •    ULONG flags;
    •    PHYSICAL_ADDRESS VmxonPA;
    • // 设置cr4位,为启用VM模式做准备
    •    set_in_cr4 (X86_CR4_VMXE);
    •    cr4 = get_cr4 ();
    •    DbgPrint("VmxEnable(): CR4 after VmxEnable: 0x%llx\n", cr4);
    •    if (!(cr4 & X86_CR4_VMXE))
    •        return STATUS_NOT_SUPPORTED;
    • // 检测是否支持vmx
    •    vmxmsr = MsrRead (MSR_IA32_FEATURE_CONTROL);
    •    if (!(vmxmsr & 4))  
    •    {
    •        DbgPrint("VmxEnable(): VMX is not supported: IA32_FEATURE_CONTROL is 0x%llx\n", vmxmsr);
    •        return STATUS_NOT_SUPPORTED;
    •    }
    • //bochs的bug,要改IA32_FEATURE_CONTROL的Lock为1
    • #if bochsdebug
    • MsrWrite(MSR_IA32_FEATURE_CONTROL,5);
    •    #endif
    •    vmxmsr = MsrRead (MSR_IA32_VMX_BASIC);
    •    *((ULONG64 *) VmxonVA) = (vmxmsr & 0xffffffff);       //set up vmcs_revision_id
    •    VmxonPA = MmGetPhysicalAddress (VmxonVA);
    •    DbgPrint("VmxEnable(): VmxonPA:  0x%llx\n", VmxonPA.QuadPart);
    • //开启VMX
    • VmxTurnOn(VmxonPA);
    •    flags = RegGetEflags ();
    •    DbgPrint("VmxEnable(): vmcs_revision_id: 0x%x  Eflags: 0x%x \n", vmxmsr, flags);
    •    return STATUS_SUCCESS;
    • }
    • /*
    •   进入虚拟机
    • */
    • NTSTATUS NTAPI VmxVirtualize (
    • PCPU Cpu
    • )
    • {
    •    ULONG esp;
    •    if (!Cpu)
    •        return STATUS_INVALID_PARAMETER;
    • *((PULONG) (g_HostStackBaseAddress + 0x0C00)) = (ULONG) Cpu;
    •            
    •    VmxLaunch ();
    •    // never returns
    •    return STATUS_UNSUCCESSFUL;
    • }

    三、蛋疼的拦截处理

    sysenter的处理方法:

    由于硬件虚拟化(HVM)无法直接拦截sysenter指令,所以只能使用其他方法来获得控制权。

    这里有三种方法:

    1、在kifastcallentery的头部写入cpuid,int3等利用中断或特权指令进入vm。

    2、使用调试寄存器在kifastcallentery下硬件执行中断,利用中断进入vm

    3、进入VMM后直接修改guest的sysenter_eip地址,通过控制msr的读写来欺骗其他访问msr的程序。

    为了不被内存检测和充分利用调试寄存器,Avalon中我选用了方案3来控制进程执行sysenter后的运行流向。

    部分代码:

    • static BOOLEAN NTAPI VmxDispatchMsrRead (
    • PCPU Cpu,
    • PGUEST_REGS GuestRegs,
    • PNBP_TRAP Trap,
    • BOOLEAN WillBeAlsoHandledByGuestHv
    • )
    • {
    • ...
    • switch (ecx) {
    • case MSR_IA32_SYSENTER_CS:
    •    MsrValue.QuadPart = VmxRead (GUEST_SYSENTER_CS);
    •    break;
    • case MSR_IA32_SYSENTER_ESP:
    •    MsrValue.QuadPart = VmxRead (GUEST_SYSENTER_ESP);
    •    break;
    • case MSR_IA32_SYSENTER_EIP:
    •    MsrValue.QuadPart = Avlkrnlinfo->SysenterAddr;
    • ...
    • }

    idt重定向处理方法:

    1、idt地址欺骗

    2、idt模拟投递

    第一种是指方案拦截sidt,lidt指令填充一份伪造的idt地址误导访问者(由系统投递相对稳定)。

    第二种是指方案模拟idt的处理过程自己写程序投递idt。

    因为方案一需要使用反汇编引擎分析具体的保存地址体积过大,所以本版的Avalon使用第二种方案即idt模拟投递。

    部分代码:

    • static BOOLEAN NTAPI VmxDispatchException (
    • PCPU Cpu,
    • PGUEST_REGS GuestRegs,
    • PNBP_TRAP Trap,
    • BOOLEAN WillBeAlsoHandledByGuestHv
    • )
    • {
    • ...
    • //SETP 7. SET EIP
    • if((uIntrInfo & 0xff) == 1){
    •   ComPrint("VmxDispatchException():#BD hit  /n");
    •   VmxWrite(GUEST_RIP,Avlkrnlinfo->Fake_IDTMap[0]);
    • }
    • else if ((uIntrInfo & 0xff) == 3){
    •   ComPrint("VmxDispatchException():#BP hit /n");
    •   VmxWrite(GUEST_RIP,Avlkrnlinfo->Fake_IDTMap[1]);}
    • ...
    • }

    第三章 理想乡的黄昏

    一、(Avalon)阿瓦隆的检测

    对于基于硬件虚拟化(HVM)的程序,首先想到的方法必然就是直接检测和对抗硬件虚拟化。

    对硬件虚拟化的检测主要有:efer的检测,vme的检测。

    对于处理了中断的vmm还能通过计算中断前后的时间差来判断自身是否在虚拟机中。

    当然针对Avalon还有其他的检测方法(此处省略xx字)

    二、未来的更新

    Avalon才刚刚开始功能并不完善,还有好多功能想加进去:

    1、将内核移入EPT(NPT)让你完全看不到

    2、 和ring3程序交互…

    3、其他隐藏功能

    总结

    Avalon只是硬件虚拟化应用的冰山一角,还有更多的应用等待着我们去探索,小弟的水平有限以后还要向各位高手多多请教继续努力学习。

    该bin测试环境如下:

    bochs2.4.5

    windows xp sp3

    注意:这个bin只是个简单的样品,真机上运行必蓝,且只针对ring0的中断,ring3有3处bug未修复。


    [发帖际遇]: 我是程序猿 捡了钱没交公 威望 降了 2 . 幸运榜 / 衰神榜
    楼主热帖排行榜
    搜搜吧社区温馨提示:
    搜搜吧(www.sosoba.org)十分重视网络版权及其他知识产权的保护,针对网络侵权采取如下版权政策:
    1、本站有理由相信网友侵犯任何人的版权或作品,(图文,文字,下载,视频,非法传播),本站有权不事先通知即删除涉嫌侵权的作品和内容!
    2、本站将采取必要的网络技术手段,确认为侵权作品或内容的用户有权进行警告、屏蔽、删除的行为,尽可能的防止侵权行为的发生!
    3、如若您的作品或内容在搜搜吧被侵权,请及时联系我们并提供能证明版权所有的物品,我们将及时进行处理,给您造成不便,敬请谅解!
    4、搜搜吧删帖,投诉,举报,侵权,账号解封唯一指定快速受理频道,请直接发送邮件到 kefu-sosoba@qq.com 一个工作日内核实并邮件通知立即删除
    soso搜搜吧社区是聚合百度搜索,搜狗搜索,360搜索,新闻,教育,站长,广告,娱乐,影视,微信,网盘,营销,手机,汽车,游戏,论坛综合为一体的大型门户社区www.sosoba.org
    Powered by www.sosoba.org X3.4© 2013-2019 搜搜吧社区 小黑屋|手机版|地图|关于我们|新闻资讯|soso搜搜吧社区官网
    搜搜吧社区官网创建于2013年07月23日,本站内容均为会员发表,并不代搜搜吧社区立场,请遵守当地相关法律,客服邮箱: kefu-sosoba@qq.com
    本站所有的内容均来自互联网以及第三方作者自由发布、本站soso搜搜吧不承担任何的法律责任、若有侵权请来信告知,我们在收到举报后的一个工作日内立即删除
    推荐使用:chrmoe谷歌浏览器,搜狗浏览器,QQ浏览器,360极速浏览器,360安全浏览器,猎豹浏览器,火狐浏览器,世界之窗,百度浏览器,Safari浏览器,ios,Android

    GMT+8, 2018-12-12 07:06 , Processed in 1.140625 second(s), 31 queries , Gzip On.

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