这题对自己也是挑战,因为它用到了驱动。
驱动之前了解过,就是在内核编程,里面比较复杂,而且容不得错误,所以一直没深入,仅限于了解。
这次用到了硬着头皮上吧
工具: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
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界