-
-
[原创][JarvisOJ] Broken Drivers -Writeup
-
发表于:
2017-12-10 13:54
4829
-
[原创][JarvisOJ] Broken Drivers -Writeup
来自360ctf2015的Rev第一题(上来就是个驱动XD),这个学期正好开始接触WindowsDriver,拿来练练手还是不错。本题其实网上是有wp的(via.安全客),但个人认为小白理解起来难度不小(比如我),故本篇尽量写的详细点,也给自己做个记录。
涉及的知识:驱动基础,PE,双机调试,WinDbg使用。
Keyword:WindowsDriver|Debug|Rev
Winx86驱动,ida载入。
本题是一个有问题的驱动,要求我们patch。如果无法一眼就看出来哪里有问题,可以扔到虚拟机跑一下。首先发现安装成功,启动失败,打开Windows事件管理器(cmd: eventvwr->系统),看到报错:"并非有效的win32程序"。恭喜,撞到第一个坑。
网上找了一圈,发现是PE-checksum字段有问题,一般exe的校检为0,而重要的系统dll和驱动是要检查的,于是用LoadPE修改正确后,成功启动。接着停止驱动,ok,蓝了。
这边说下虚拟机环境,Win7x86x64原版镜像就算开启禁用签名强制模式也加载不上驱动,无奈只好选用ghost版本。
停止驱动蓝屏,肯定就去找找DriverUnload函数了,一看,没有调用。
那我们肯定是要把DriverUnload函数加到_Driver_Object-> DriverUnload处了,用WinDbg查看下结构,发现0x34是目标位置。
如果patch之后成了这样:
恭喜,撞到第二个坑。
这其实是重定位表出现了问题,mov的是个绝对地址。我们需要手动改重定位表。
可以参考两行指令,以MJ_Create为例:
需要重定位的位置为00011185,其中00010000为ImageBase,00001000为IMAGE_BASE_RELOCATION的其中一个VirtualAddress(rva),00000185为偏移,查看pe结构可以找到该字段:
顺藤摸瓜,找到重定位需要修改值的位置:
到这里就看出了,我们需要重定位的位置是00011193,但字段为192,修改为193就可以了。
再次载入,反编译ok:
这时就可以看看驱动到底做了什么
1. MJ_create:
先判断PID是不是360,如果不是直接报错,是则分配内存,并对其进行一个加密操作。
里面有起来是MD5的幻数,推测是生成一个key。
2. MJ_close:
没什么特别操作,不赘述了。
3. Driver_Unload:
对unk_14000进行操作的只有这一处,推测是利用src对其进行解密操作。
大致思路已经有了,可以先把判断pid==360的那处nop掉,再次调整checksum放到虚拟机准备双机调试,为此还需要一段代码来触发MJ_create,代码很简单只要CreateFile打开设备就可以,自己写吧。
双机调试的环境还算好配,放上一遍比较不错的blog: http://blog.csdn.net/sagittarius_warrior/article/details/51305046
开始双机调试时,遇到第三个坑点,我们该如何对DriverEntry下断。
自己观察出一个简单点的方法:
1. WinDbg首次断下后设置异常sxe ld MyDriver.sys
,然后g
跑起来。
2. 用驱动加载工具安装Driver后,C+break断下,lm
查看当前已加载的模块,此时可得到最后一个模块的end地址。观察出最后一个模块地址的末地址即为新模块的始地址。
3. 用PEview得到AddressofEntryPoint字段,bp end_address + AddressofEntryPoint
即可。
以下为步骤截图
kd>g让虚拟机跑起来,启动驱动...
OK! 成功断在DriverEntry
差最后一步了,对DriverUnload地址下断后再触发MJ_Create,停止驱动即可断下,查看解密数据即拿到flag。
做出来还是比较爽的,因为以前根本不知道怎么DebugDriver,学到了不少。
本人驱动萌新,如果有错误望指正。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2018-10-10 10:03
被vvv_347编辑
,原因: 图挂了,修复done