-
-
[原创]看雪CTF2017第七题 不问少年crackme writeup
-
2017-6-15 11:51 3576
-
所用工具:OllyDbg,CFF Explorer,ResourceHacker
说明:本人初学,写得不对的地方还请大家指正。
解题过程:
1,程序刚载入OD1.10就报错,提示“Don't know how to bypass command at address 00414429.后面省略”,但使用OD2.01不会报错,观察发现在EP(00414422)处的字节在OD1.10中为03H,但在OD2.01中为E8H。使用CFF Explorer查看程序后发现使用了TLS,只有一个callback,地址是0040C120,在OD中查看该函数,发现其主要作用是对EP开始的C8H个字节进行异或,EP处的字节异或后就应该是E8H,不明白为什么OD1.10中会变成03H?由于OD2使用不太方便,于是便将程序在TLS执行后,停在EP处时,将EP处的字节改为E8H,然后使用OllyDump插件将程序dump出来,再用CFF Explorer将PE头中TLS相关的两个字段TLS Directory RVA和TLS Directory Size的值清0,再保存后便可在OD1.10中正常运行。
2,将上一步得到的程序载入OD后运行,直接terminate,最终发现程序中使用MapFileAndCheckSumW计算校验和,如不符就退出,因为已经修改了程序,校验和自然不相等,于是绕过判断,再次保存为新程序。
3,将上一步得到的新程序载入OD,查看程序调用的API发现有GetDlgItemText,且调用时的控件ID为3E8H,和用ResourceHacker查看的输入框的控件ID一致,基本确定就是使用GetDlgItemText来获取用户输入(除非这个调用是幌子,根本不会被执行?)。GetDlgItemText上断点,随便输入key后敲回车,但并没有断下来,查找后发现GetDlgItemText只有在程序接收到0x464消息后才会执行,而0x464并非标准Windows消息,应该程序作者自定义的,查找后发现程序只有在0040DEE2开头的一个函数中会产生0x464消息,而0040DEE2在程序中被SetUnhandledExceptionFilter设置为异常处理函数,查看SetUnhandledExceptionFilter发现其所设置的异常处理函数只有进程在未被调试时才会执行,所以在OD中调试时自然不会执行,也就不会执行GetDlgItemText了,经过网上搜索发现HideOD这个插件可以解决这个问题(感谢作者)。
4,使用HideOD插件后,已经能够在GetDlgItemText断下,断下后便开始单步跟踪,过程中发现程序使用“PEDIY”对00411B30开始的1AAH个字节进行异或,而00411B30正是在对输入Key进行处理时会被调用的一个函数。
5,接下来分析程序对输入Key的处理:
1) 将输入的key记为key1,将key1的每个字节和0xCC异或,结果记为key2;
2) 查找key2的每个字节在下面数组a中的偏移量,将此偏移记为t,执行运算:t = t + (t / 5 + 5),且当前处理的是key2的第几个字节(从1数起),这个运算就执行几次,最后记下key2[t];
a=[0x89,0xBC,0x95,0xFC,0xFB,0xBA,0xED,0x9A,0xBB,0xAE, 0xFE,0x99,0xA2,0x98,0xB9,0xF9,0x9F,0x84,0x9C,0xFD, 0x83,0xAD,0xB6,0xA9,0xA5,0xF5,0x8C,0xA7,0x9E,0x96, 0x8A,0xF4,0x85,0xBE,0xA8,0x8F,0x86,0xAF,0x88,0x9D, 0x87,0xBF,0xFF,0xA1,0x8B,0x81,0xA0,0xAB,0x8E,0xBD, 0xB5,0xAA,0x82,0x94,0xA4,0x8D,0xA3,0xF8,0xB4,0xFA, 0x9B,0xA6,0xB8,0x80]
(将数组a中每个字节和0xCC异或,发现其实是0-9A-Za-z!@这个64个字符,所以出入key时的字符也应该在这范围中)
3) 将上一步中得到的所有key2[t]按先后顺序连接在一起,记为key3;
4) 将key3中的每个字节先和0xCC异或,再循环左移3位,结果记为key4;
5) 接下生产key5,key5的长度为key1长度的4倍。
规则为:key5[0]=key4[0]的高四位 / 4
key5[1]=key4[0]的高四位 % 4
key5[2]=key4[0]的低四位 / 4
key5[3]=key4[0]的低四位 % 4
key5[4]=key4[1]的高四位 / 4
……
key的处理到此结束;
6, 接下来程序判断key5的长度是否为80(即key1的长度是否为20),若是,判断key5的每个元素是否和下面的数组b相等,若相等,将00411A9C开始的94H个字节复制到一块动态内存,然后使用key1异或动态内存中的这94H个字节,然后用key1[8]异或动态内存的第94个字节,然后程序转到该这个动态内存执行。
b=[02,02,00,03,00,00,02,03,00,01,02,03,02,00,00,02,02,00,02,02 02,03,02,03,01,00,02,02,02,01,02,03,02,02,02,01,02,03,02,03, 02,01,00,03,02,02,02,02,02,02,00,03,01,02,02,03,02,00,00,02, 02,02,02,02,00,00,00,02,01,00,02,02,02,03,00,02,01,00,00,03]
经过上述分析,可以看出key长度需为20,且通过数组b可以倒推出正确的key,但由于一个key3可能倒推出多个key2,最终倒推出以下20个集合,按顺序每个集合对应key的1位:
c0 = ['B'] c1 = ['w','j'] c2 = ['n'] c3 = ['d','s'] c4 = ['Y','l','A'] c5 = ['b','t'] c6 = ['P','i'] c7 = ['H','e'] c8 = ['d','c','s'] c9 = ['P','i'] c10 = ['y'] c11 = ['2','5'] c12 = ['0','g','o'] c13 = ['1','a'] c14 = ['7','B','4'] c15 = ['@','r','K'] c16 = ['J','G','X'] c17 = ['9','I','D'] c18 = ['O'] c19 = ['k','F']
经过排列组合、观察猜测、尝试,最终得到正确Key:BwnsAtPediy2017KX9Ok
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课