首页
论坛
课程
招聘
[原创]南极动物厂 游戏高校竞赛决赛分析 之 Ring0
2020-4-13 13:28 2969

[原创]南极动物厂 游戏高校竞赛决赛分析 之 Ring0

2020-4-13 13:28
2969

0x01 前言

Ring0的还算可以 有几个小坑 主要是Part2 上infhook浪费了太多时间 做完就超时了 没有提交完美的答案就有点可惜

0x02 ring0 驱动分析

题目描述

Part1:
(1) 成功加载Driver.drv至驱动模块链表(0.5分)
(2) 自编写驱动加载程序,使用非服务方式加载Driver.drv驱动,加载后需要保证驱动路径为C:\Driver.drv(0.5分)
(3) 分析驱动接口,给出每个功能的调用控制码,输入,输出数据的结构(0.5分)
(4) 分析驱动接口,分析每个接口的作用(0.5分)
(5) 调用驱动接口,使Driver.drv在驱动模块中断链隐藏(只允许在应用层调用Driver.drv接口实现)(2分)
(6) 从Flag.fg中分析出Flag,此flag用于解密Part2.7z(1分)

题目分析

Patr1

对Driver.Drv的详细分析

使用工具:Vmware15.0Virtual KD 3.0Windbg x64IDA Pro 7.2CheatEngine 6.4

  1. 在虚拟机中手动加载驱动 打印了hello 并且返回了 一个错误 对应的错误码为0xC0000906

  2. IDA载入分析 找到DriverEntry 一路查看执行的流程

    对代码前后逻辑分析完以后 发现这个错误码就是执行失败的罪魁祸首。

    此处为驱动加载错误的逻辑。用IDA把错误码改成0以后 重新保存一份驱动 驱动加载成功。

  3. 非服务方式加载驱动 常识 木有解释 使用NtLoadDriver或ZwLoadDriver 具体看附录代码

  4. 在DriverEntry往下 在IDA里 找到驱动分发信号的地方

1.sub_1400023F0 与CR4第二十标志位SMEP相关 有关原理参考下面链接

 

SMEP 标志位 低环执行高环代码是否会产生异常

github参考:https://github.com/RDTCREW/UPGDSED_reset/blob/29d9f7edbbdff004b6cb49416ec14ec37ae67354/src/tests/BadRkDemo/drv/dummy/main.c


 

SMEP参考:
https://en.wikipedia.org/wiki/Control_register#SMEP

 

 

5.v5(sub_1400022A0) v6(sub_140002310) v7(sub_140002380) 均为解密函数 需要Ring3跟驱动通信传入数据 解密出真实数据。第二个函数貌似还上了OLLVM

 

此时题目并没有给出其他有用的信息 但 看见题目中 flag.fg中可以得出flag 猜测由驱动的此处解密出flag 然后我就跑去分析flag.fg了

 

用进制分析文件 打开flag.fg扫了一眼 发现头部的前几个字节 有点像汇编代码 于是猜测这个是shellcode,ida拖进去 先x64模式看看
此处并没有很顺利 一开始以为是调用shellcode某函数 得出返回值 进行了很多尝试
又发现了x86的汇编 又用x86模式看了一遍 尝试找到入口点进行分析

 

最后 想起Battleeye流式加载dll的方式 猜测shellcode入口点 即为 addres:0,因为题是ring0 CTF,尝试把shellcode打包到Ring0 然后执行 直接蓝屏,进行了调试与多次尝试之后,又把shellcode拿到R3执行 代码如下

 

 

弹出了5个信息框 均为0,最后一个为Your flag. (下断分析 看看这个0是怎么获取的)

 

 

很明显要跟驱动通信 我们加载一波前面的驱动 run shell

 

 

坑爹的地方来了:把这个完整的输入到压缩包 显示密码错误。 起初以为是shellcode做了手脚又是各种分析 最后在MessageBoxA下断 跟到弹出you flag的地方

 

 

发现 前后一个空格。 输入flag解压缩成功。
( 16447126361811417937 ) 括号内为flag

对flag.fg的详细分析

因为当时分析的时候没有保存截图 懒得重新跑一遍截图了 就口头说说吧

 

这段shellcode主要是从内存中解密出一个EXE然后修复节表啥的 还hook了几个很不常见的API

 

然后内存加载EXE。

 

搜了一下hook的API 貌似都跟反病毒有关的 (奇怪的知识)

 

首先如果你是使用x86模式去跑这段shellcode 他会以x86模式去执行代码

 

但是不知道是shellcode在x86模式下有bug还是什么 在修复导入表 完成一系列的初始化之后 就退出了。

 

如果使用x64模式去跑 就可以正常内存加载这个EXE 在shellcode对EXE解密完成的时候我们dump出原文件

 

 

确实是个EXE 此时用IDA反编译 代码就好看多了。

 

 

奇怪的知识又增加了。查看main

 

Bug警告

 

 

 

这个判断 作者应该想的是 如果v3=False 会 报错(驱动未加载) 但是无论在驱动是否加载了的情况下均不报错 CreateFileW在调用失败的情况下 会返回INVALID_HANDLE_VALUE
会返回 -1 不是0 所以导致判断失效 造成在驱动未加载的情况下 仍然不会弹出那个错误信息框来提示解题者 (暂不知是作者的bug 还是故意留的坑)手动狗头保命

通信码输入输出结构分析 驱动自断链实现

80002003|Function:sub_1400023F0
80002007|Function:sub_1400022A0
8000200B|Function:sub_140002310
8000200F|Function:sub_140002380

结合前面驱动 分发事件可以知道四个函数对应的通信码分别为这几个

 

 

第四个信息框没有调用驱动里面的解密 生成key因为压根没这个通信码 0x80002017 不知道这段没有用处的代码要拿来干嘛 反正没用上

 

对应输入输出结构
第一个函数(SMEP标志位相关):
输入结构

struct payload
{
    PVOID function;
    PVOID a2;
};

输出结构 您的shellcode执行的结果(int型)

 

 

二三四都相同主要负责解密ring3传过来的key
第二个函数(解密相关):
第三个函数(解密相关):
第四个函数(解密相关):
输入结构

ULONG64 Key;

输出结构

ULONG64 DecryptKey;

 

断链相关:

 

获取DriverObject(找了比较久 找到了下面这个IoGetDeviceObjectPointer 一开始想用ObReferenceObjectByName后来发现太麻烦 不太可以 参考了很多文章 百度谷歌 MSDN UnknownCheat)

 

参考:
https://github.com/not-wlan/drvmap
https://www.unknowncheats.me/forum/anti-cheat-bypass/252685-drvmap-driver-manual-mapper-using-capcom.html
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-iogetdeviceobjectpointer.
https://github.com/RDTCREW/UPGDSED_reset/blob/29d9f7edbbdff004b6cb49416ec14ec37ae67354/src/tests/BadRkDemo/drv/dummy/main.c

 

对第一个函数的详细分析:SMEP相关 关闭CR4的SMEP标志位 R0执行R3代码

 

 

从Ring3传过来的参数里 拿了两个成员 **a1*(*a1+8)

 

 

传进来的参数a1用来作为函数调用 v2作为 函数的第二参数
第一个参数为GetProcessAddress()的地址

 

 

调用a1以后 把返回值存放到v6为整型

 

 

存放到*(a1+8) 里面

 

然后我们构建好断链的代码

 

 

 

 

至此Ring0的Part1部分已经完全解完了。

Part2

题目描述

Part2:
运行RunGame.bat将启动一个游戏demo, 以管理员权限运行外挂程序DemoEsp.exe, 外挂程序将对游戏产生透视效果。
请编写驱动程序阻止外挂透视行为,按照符合以下(1)~(5)的条件限制来给分。
按照反外挂的思路实现,不可直接攻击外挂进程(例如结束进程、结束线程等),可从内存/文件/绘制等方面入手。
(1) 在未开启外挂的情况下游戏正常运行;
开启外挂后,游戏也正常运行;
开启游戏,开启外挂,开启编写的驱动程序后,游戏正常运行,但是外挂失效;(1分)
(2) 该驱动程序可以做到,非句柄回调保护,非句柄降权,非特征码定位,非文件样本;(1分)
(3) 该驱动程序可以做到,非内核函数代码段hook; (1分)
(4) 可以运行在WIN10 X64(1909-20H1范围);(1分)
(5) 可以兼容(1903~20H1范围)内的HVCI. (1分)
以详细文档、源代码(part2可选,建议提供)、构建好的bin的方式提供答案。

题目分析

外挂DemoEsp.exe主要是使用了ReadVIrtualMemory函数来读取内存 然后绘制使用了Dx9

 

 

外挂运行截图

 

奥利给 带手子辅助

 

保护游戏 首先想到了BB,上去就先抄一份。

 

https://github.com/DarthTon/Blackbone by:DarthTon

 

 

 

一开始以为这样就奥利给了 细看题目

 

开启游戏,开启外挂,开启编写的驱动程序后,游戏正常运行,但是外挂失效;(1分)

 

好吧 这个方案并不完美 只能游戏 驱动 外挂 这个顺序才能导致外挂失效

 

根据题意 这里可能要丢分

 

然后认真看了下题目

 

 

一开始以为驱动不能用特征码定位要用的偏移跟未导出函数 让我脑子都给想爆了 都想不到其他方法 浪费了大半天 后来问了工作人员。

 

 

好吧 只能上传说中的infhook了 但是在最新的20H1 infhook已被安排。

 

遂搜索资料 发现老外早已把20H1给安排了 下面是有关infhook的参考链接
使用(传统艺能copy-paste)

 

https://bbs.pediy.com/thread-253450.htm by:Sprite雪碧

 

https://bbs.pediy.com/thread-258352.htm by:hzqst

 

https://bbs.pediy.com/thread-258664.htm

 

https://github.com/everdox/InfinityHook by:Everdox

 

https://github.com/kagasu/InfinityHookExample by:kagasu

 

https://github.com/p4xon/SyscallHook by:p4xon

 

https://bbs.pediy.com/thread-249730.htm by:basketwill

 

https://bbs.pediy.com/thread-246878.htm

 

https://bbs.pediy.com/thread-218907.htm

infhook处理

 

至此 已经所有的题全部解完

 

 

有关代码跟bin已经打包上传 有关InfinityHook的bin跟代码未上传

 

还想了个办法 就是把游戏窗口强制置顶 让绘制没法覆盖 没去实现。

 

以上全部分析可能有说的不对的地方 或者 解释的不对的地方。欢迎指正啦。


[公告]《使用DCI技术进行全栈调试》训练营,硬件调试器你的,《软件调试》作者张银奎亲自授课!

最后于 2020-4-14 03:33 被淡然他徒弟编辑 ,原因:
上传的附件:
收藏
点赞3
打赏
分享
最新回复 (12)
雪    币: 6032
活跃值: 活跃值 (153)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
二娃 活跃值 2020-4-13 13:50
2
0
厉害
雪    币: 3894
活跃值: 活跃值 (238)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
如斯咩咩咩 活跃值 2020-4-13 13:54
3
0
稳健
最后于 2020-4-13 13:54 被如斯咩咩咩编辑 ,原因:
雪    币: 637
活跃值: 活跃值 (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mihacker 活跃值 2020-4-13 17:59
4
0
膜拜
雪    币: 195
活跃值: 活跃值 (116)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdjytony 活跃值 2020-4-13 21:01
5
0
整挺好..
TX成功套娃..
雪    币: 55
活跃值: 活跃值 (177)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
killpy 活跃值 2 2020-4-13 22:48
6
0
ida拖进去 先x64模式看看
此处并没有很顺利 一开始以为是调用shellcode某函数 得出返回值 进行了很多尝试
你这段话啥意思  ida以x64模式不能查看他的汇编?那你后面怎么说64位模式可以运行这个shellcode呢?那个7z压缩包就是用flag解密出来 里面的exe 修复以后运行  它才是和驱动通信的吧 这个exe就是64位的 你用32位模式shellcode去运行64位exe 肯定最后莫名其妙退出了
雪    币: 2251
活跃值: 活跃值 (30)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
刘铠文 活跃值 2020-4-13 23:23
7
0
写的不错,言简意赅废话少,舒服美汁儿汁儿
雪    币: 2232
活跃值: 活跃值 (222)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
淡然他徒弟 活跃值 2020-4-14 01:31
8
0
killpy ida拖进去 先x64模式看看 此处并没有很顺利 一开始以为是调用shellcode某函数 得出返回值 进行了很多尝试 你这段话啥意思 ida以x64模式不能查看他的汇编?那你后面怎么说64位模 ...
flag.fg 是shellcode 然后这段shellcode你怎么知道他是x64的还是x86的 ida会让你选择x64bit 还是x86bit 模式看汇编 那个压缩包里面的内容是第二题 flag是解压密码 我说的某个函数的返回值 就是这段shellcode 有很多函数的  其实 一开始是没想到他会以弹信息框的形式来告知答案 所以猜测是调用shellcode中的某个函数然后那个函数给我返回flag 另外这段shellcode开头没多远会有个跳转 假如你x86去跑就会执行一块 x64跑就执行另一块 这两块的执行流程汇编是不一样 x86那一块执行流程可以很明显的看出来调用call的方式是stdcall x64那一块执行流程是fastcall 所以这段shellcode应该是有两种执行方式的 
雪    币: 2232
活跃值: 活跃值 (222)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
淡然他徒弟 活跃值 2020-4-14 01:33
9
0
最后程序莫名其妙退出 其实也不能说是莫名奇妙 是他自己结束的自己 不是崩溃什么导致的 
雪    币: 2232
活跃值: 活跃值 (222)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
淡然他徒弟 活跃值 2020-4-14 01:34
10
0
刘铠文 写的不错,言简意赅废话少,舒服美汁儿汁儿
么么哒 基佬
雪    币: 31
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
flappy 活跃值 2020-4-14 10:55
11
0
雪    币: 146
活跃值: 活跃值 (93)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
吴俊 活跃值 2020-4-29 17:50
12
0
原题在哪里呀,哥?
雪    币: 190
活跃值: 活跃值 (58)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wem 活跃值 2020-5-2 22:57
13
0
谢谢分享
游客
登录 | 注册 方可回帖
返回