[原创]CTF2017第五题分析
这题对自己也是挑战,因为它用到了驱动。
驱动之前了解过,就是在内核编程,里面比较复杂,而且容不得错误,所以一直没深入,仅限于了解。
这次用到了硬着头皮上吧
工具:vmware, od, ida, lordpe, winhex, masm
在虚拟机内,用OD加载,不能下断点了,有反调试,根据题目描述,应该是用到驱动了,是不熟的领域。因为程序只有一个文件,猜想是动态释放,就想把这个驱动摘出来。
因为程序没加壳,用winhex打开,搜索MZ文件头,能找待释放的文件。但一开始走弯路了,从MZ头整个到文件尾都复制下来,大于应有的文件,是不能运行的。后来下断点CreateFileA,可以拦到建立vmxdrv.sys的过程,得到正确的结果。
用IDA分析这个文件
这里是清debug端口的,nop掉
.text:00010486 s_clear_debug proc near ; CODE XREF: sub_1071A+65p .text:00010486 call ds:IoGetCurrentProcess .text:0001048C mov ecx, dword_114E0 .text:00010492 mov edx, eax .text:00010494 jmp short loc_104A5 .text:00010496 ; --------------------------------------------------------------------------- .text:00010496 .text:00010496 loc_10496: ; CODE XREF: s_clear_debug+21j .text:00010496 mov eax, [eax+88h] .text:0001049C sub eax, 88h .text:000104A1 cmp eax, edx .text:000104A3 jz short locret_104B0 .text:000104A5 .text:000104A5 loc_104A5: ; CODE XREF: s_clear_debug+Ej .text:000104A5 cmp eax, ecx .text:000104A7 jnz short loc_10496 .text:000104A9 nop .text:000104AA nop .text:000104AB nop .text:000104AC nop .text:000104AD nop .text:000104AE nop .text:000104AF nop .text:000104B0 .text:000104B0 locret_104B0: ; CODE XREF: s_clear_debug+1Dj .text:000104B0 retn .text:000104B0 s_clear_debug endp
这里是触发蓝屏的,跳转nop掉
.text:00011243 s_BSOD proc near ; CODE XREF: sub_104B6+9Fp .text:00011243 ; sub_1071A+84p ... .text:00011243 cmp ecx, d_tick1 .text:00011249 nop .text:0001124A nop .text:0001124B retn 0 .text:0001124B s_BSOD endp .text:0001124B .text:0001124E ; --------------------------------------------------------------------------- .text:0001124E jmp loc_11258 .text:0001124E ; --------------------------------------------------------------------------- .text:00011253 align 8 .text:00011258 .text:00011258 loc_11258: ; CODE XREF: .text:0001124Ej .text:00011258 mov edi, edi .text:0001125A push ebp .text:0001125B mov ebp, esp .text:0001125D push ecx .text:0001125E mov [ebp-4], ecx .text:00011261 push 0 .text:00011263 push d_tick2 .text:00011269 push d_tick1 .text:0001126F push dword ptr [ebp-4] .text:00011272 push 0F7h .text:00011277 call ds:KeBugCheckEx
sys文件要计算校验值,否则是不能运行的,用lordpe算出正确的校验值,把上述改动和校验值写回exe文件,就可以调试了
程序的流程大家分析的比较多了,判断call在401760,就是判断注册码应该是6位,转为小写,再换成逆序,发送到驱动(用的writefile),读驱动返回值(readfile),转为string后再做标准MD5,转string后,舍去第1字节比较接下来的5字节,如比较成功,会拼出success
程序对输入内容不做判断,根据规则,应为数字和字母,空间为36^5,因为36*36约等于1024,即枚举空间略大于2^30,对单机是可行的
试图改过程序穷举,因为不能解决堆申请后的释放问题,跑一会内存就溢出了,最后还得自己编程实现。
因为没看懂驱动里面的读写功能,所以就带驱动工作了。考虑到C语言的类型转换太严格,一时半会调不通,就全用汇编了
仿照crackme用到的代码,用驱动文件建立服务,枚举变量从39aa400到81BF1000,转成string,送驱动,读驱动,做MD5,比较结果。因为带驱动,来回读写通信,运行效率比较低,从开始到找到解大概10个小时
正确的解是:su1986
