-
-
[原创]看雪CTF2017第五题 独行孤客CrackMe writeup
-
2017-6-12 11:53 3102
-
所用工具:OD
说明:程序载入OD后,发现下了断点会报错退出,进过一番摸索,发现进行以下2处修改似乎可绕过反调试(新人能力有限,对其中原理还不太清除):
然后就开始跟踪程序对输入key的处理,初步分析有如下发现:key会被逆序、长度为6、字母数字符号均可(大写字母会被转成小写,由于按照出题要求key不应包含符号故后续不再考虑符号)、程序中还使用了IsDebuggerPresent 。见图:
程序接下来会把上述处理过的key写进设备\Device\vmxdrv(通过vmxdrv.sys模拟出来的设备?),然后再从该设备读16字节的内容出来,见图:
观察读出来的16字节内容,似乎为MD5值(PEID发现程序也确实使用了MD5),但并不是在WriteFile时所写内容的MD5,通过某MD5解密网站查询明文,发现程序似乎是把WriteFile时的key进行了某种变化,然后计算其MD5,经过多次选取不同输入(字母、数字)并观察输出,发现变化规律为:对key的第一个字符ASCII码加1,后面5个字符分别对ASCII码加1、2、3、4、5,例如变换前key为"000000",则变换后为"112345";变换前为"999999",变换后为"::;<=>"。
然后程序会对刚才得到MD5再进行一次MD5运算,取结果的第2到11位(共10位)与888aeda4ab进行比较,若相等,则key正确。见图:
最后开始暴力破解,字符范围是数字及小写字母,长度6位,Python代码如下:
# -*- coding: utf-8 -*- #代码省去了反转的操作,故找到key后手工反转一次 import hashlib loop = '0123456789abcdefghijklmnopqrstuvwxyz'#字符包含数字和小写字母 def conv(n): a = [] while n != 0: a.append( loop[n % 36] ) n = n / 36 a.reverse() return ''.join(a) def check(num): snum = conv(num) if(len(snum) < 6): snum = snum.rjust(6, '0') print snum snum = plus(snum) m = hashlib.md5() m.update(snum) m2 = hashlib.md5() m2.update(m.hexdigest()) if(m2.hexdigest()[2:12] == '888aeda4ab'): return True return False def plus(s): ll = list(s) ll[0] = chr(ord(ll[0])+1) for i in range(1,6): ll[i] = chr(ord(ll[i])+i) return ''.join(ll) #共有36^6=2176782336种可能,但2176782336超过了xrange范围, #故分2次计算,注释起来的为第二次的 #for i in xrange(0,1088391168): # i += 1088391169 # if(check(i)): # print 'key:',i # break for i in xrange(0,1088391169): if(check(i)): print 'key:',i break print 'done'
最后得到正确key:su1986
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
看原图