2020腾讯游戏安全技术初赛ring0题wp

题目链接在https://gslab.qq.com/html/competition/2020/race-before.htm

本文相关文件在:
https://pan.baidu.com/s/14_bPIwp6CNq_NQm4rq57Fw
1.分析过程:
由于加了vmp的壳。通过ida查看导入表,还是有一些导入表的:
Address Ordinal Name Library
000000014023E000 MmGetSystemRoutineAddress ntoskrnl
000000014023E010 ExAllocatePool ntoskrnl
000000014023E018 NtQuerySystemInformation ntoskrnl
000000014023E020 ExFreePoolWithTag ntoskrnl
000000014023E028 IoAllocateMdl ntoskrnl
000000014023E030 MmProbeAndLockPages ntoskrnl
000000014023E038 MmMapLockedPagesSpecifyCache ntoskrnl
000000014023E040 MmUnlockPages ntoskrnl
000000014023E048 IoFreeMdl ntoskrnl
000000014023E050 KeQueryActiveProcessors ntoskrnl
000000014023E058 KeSetSystemAffinityThread ntoskrnl
000000014023E060 KeRevertToUserAffinityThread ntoskrnl
000000014023E068 DbgPrint ntoskrnl
000000014023E078 KeQueryPerformanceCounter HAL
对MmGetSystemRoutineAddress下断,发现该驱动会调用这个函数获取KdDisableDebugger,并调用禁止内核调试。后来才发现仅仅将该函数ret是不够的(无法在windbg ctrl+break),还好之前研究过tp的反双机调试,直接把之前写好的往上套过了反双机调试。断下后通过“.writemem 路径 startaddr size“命令dump该驱动。此时已经是脱壳后的sys,可以看到一些没有被vm的代码来静态分析。
Dump后的字符串信息:

image.png

一些重要函数:
image.png

根据编写驱动的习惯,一般再DriverEntry里面设置驱动对象的分发函数。所以上图代码至少是DriverEntry的一部分代码。观察函数sub_FFFFF80277E06A00:
image.png

证明了之前猜测使用KdDisableDebugger函数来禁止内核调试。再看sub_FFFFF80277E06B60:
image.png

里面是一长串注册表地址:
\REGISTERY\MACHINE\SOFTWARE\AppDataLow\Tencent\{61B942F7-A946-4585-B624-B2C0228FFEBC}和一个”key“
通过动态调试分析,该函数返回后执行下面代码:
image.png

该函数如果返回0则加载驱动失败,否则成功。
仔细动态调试该内部,首先通过ZwOpenKey看上述地址是否存在,存在则调用ZwQueryValueKey得到buf长度( cmp dword ptr [rsp+188h+var_158+4], 0C0000023h
0C0000023h==STATUS_BUFFER_TOO_SMALL。)。调用ExAllocatePoolWithQuotaTag动态申请内存:

.vmp2:FFFFF80277E0712E mov eax, dword ptr [rsp+188h+NumberOfBytes]
.vmp2:FFFFF80277E07132 mov r8d, 'rega' ; Tag
.vmp2:FFFFF80277E07138 mov edx, eax ; NumberOfBytes
.vmp2:FFFFF80277E0713A mov ecx, 1 ; PoolType
.vmp2:FFFFF80277E0713F call ExAllocatePoolWithQuotaTag

再次ZwQueryValueKey调用获取数据
将得到的数据和‘\x01’比较,如果相同则返回1.最后调用ExFreePoolWithTag释放内存。因此在注册表编辑如下:


image.png

分析IRP_MJ_DEVICE_CONTROL例程


image.png

IRP_MJ_CLOSE和IRP_MJ_CREATE很简单没做什么,就不分析了。
这3个分发函数都不能实现输出Hello Word。于是通过ida的交叉引用功能对


image.png

进行引用,直接在hello处引用失败,原来是前面有个\r\n。于是找到
image.png

(里面的函数名被修改成实际的api,这是通过动态调试发现的。)
一直回溯发现到


image.png

对该函数进行动态调试发现其实该驱动创建一个系统线程,该线程的函数就是上面的引用helloworld的地方。
继续回溯发现
image.png

驱动创建了一个事件,而且该事件初始被reset了,结合上述分析。线程函数其实就是在wait这个事件。只要通过打开这个事件并对其进行set就能触发输出Hello World!
image.png

触发该事件的驱动代码:
#include <ntddk.h>
#define EventName L"\\BaseNamedObjects\\tp2020"
VOID UnLoadDriver(PDRIVER_OBJECT pDriverObject)
{
    PDEVICE_OBJECT pDevObj;
    UNICODE_STRING sysLinkName;
    KdPrint(("[MyProtect_Unload] ==>\n"));


    KdPrint(("delete device! unload!\n"));
}
NTSTATUS DriverDefaultDisPatch(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
    PIO_STACK_LOCATION pIrpStack;
    NTSTATUS status = STATUS_SUCCESS;

    pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
    pIrp->IoStatus.Information = 0;
    pIrp->IoStatus.Status = status;

    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING pPath)
{

    NTSTATUS status = STATUS_SUCCESS;
    UNICODE_STRING devName;
    UNICODE_STRING linkName;
    PDEVICE_OBJECT pDevObj;
    UNICODE_STRING ustrEventName;
    UNICODE_STRING ustrEventName_2;
    ULONG i;

    DriverObject->DriverUnload = UnLoadDriver;
    for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    {
        DriverObject->MajorFunction[i] = DriverDefaultDisPatch;
    }

    //DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverControlIo;
    UNICODE_STRING u_e_name;
    RtlInitUnicodeString(&u_e_name, EventName);
    HANDLE hEvent=0;
    PRKEVENT pEvent= IoCreateNotificationEvent(&u_e_name, &hEvent);
    if (pEvent)
    {
        KeSetEvent(pEvent, 0, 0);
    }
else
        DbgPrint("IoCreateNotificationEvent error");
    return status;
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容