本帖最后由 zjh16529 于 2019-6-6 18:50 编辑
0x01 哈希
1.首先拿到exe,载入exeinfo中,发现有附加数据,可以判断视频数据是存在附加数据中的。
2.字符串搜索,找到如下地方,并下断
3.断下来之后,发现一个函数,命名为hash2005,它接受一个字符串,并算出它的摘要值,对比正确的值,不对就弹框,在这里可得到正确的hash值0x1443
4.进入这个hash2005函数,通过IDA分析,发现这个函数很简单,也由此知道,一般而言密码长度越长,使用的字母越多,hash2005就越大,同时可以推测出密码大概长度7以上
5.那么通过尝试所有密码,对比它的hash值是否正确来判断是否是正确密码可不可行?很明显,跑出的hash值相同的密码有很多,无法确定哪个是正确密码。
0x02 解压
1.继续往下分析,把验证hash值那里强制改为跳转。
2.通过字符找到对应的地方下断,断在函数头,一步步跟踪,发现有一处是对输入密码进行xor的,一共xor 20个字节,密码长度不够用00扩展,密码xor的值在一个压缩块中总是不变的。
3.把得到的值memcpy到待解压数据的固定位置。
跟进去就是memcpy操作了,记下修改的数据相对于压缩数据头的偏移0x15ed,这里的技巧就是对xor的结果下内存读断点。
4.解压数据,用的是zlib的解压缩库
这是怎么判断出来的呢?,首先跟进去,这里有个字符串1.1.4
下面是zlib的代码片段,uncompress会使用zlib库的版本号进行inflate初始化操作
[C] 纯文本查看 复制代码 #define ZLIB_VERSION "1.1.4"
#define inflateInit(strm) \
inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
5.根据上面可以知道,待解压的数据里面的的20个字节是由输入的密码异或得到的,密码不对就会解压错误(强行跳转并不管用,得到的数据错误的,播放器也就根本无法播放)
由此我们可以得到一个简单的破解思路,先把待解压的数据dump下来,记下修改的那个20个字节的偏移,通过枚举来尝试出正确的hash值同时又能解压成功的密码。
算法很简单,几位密码就几个for,关键代码如下:
[C] 纯文本查看 复制代码
char c[]="0123456789abcdefghijklmnopqrstuvwxyz";
for(a7=0;a7<36;a7++)
for(a6=0;a6<36;a6++)
for(a5=0;a5<36;a5++)
for(a4=0;a4<36;a4++)
for(a3=0;a3<36;a3++)
for(a2=0;a2<36;a2++)
for(a1=0;a1<36;a1++)
for(a0=0;a0<36;a0++)
{
buf[0]=c[a0],buf[1]=c[a1],buf[2]=c[a2],buf[3]=c[a3],buf[4]=c[a4],buf[5]=c[a5],buf[6]=c[a6];buf[7]=c[a7];
hash=hash2005(buf);
if(hash==0x1443)
{
xordata(res,buf);
memcpy(pdata[*id]+offset, res, 20);
if(uncompress(dbuf, &dlen, pdata[*id], size)== Z_OK)
{ // crack success
printf("%s\n",buf);
return;
}
}
pcount[*id]++;
}
6.在选取dump数据时,由于软件是分块解压的,要选取比较小的块,解压才快,跑密码才快。我选的是size=0x2bdf这个块。
0x03 总结
1.在实际使用中,破解纯数字密码是可能的,但是如果是8位以上的数字+字符就比较久了,在我的笔记本跑8位密码跑了20个小时(代码写得太挫了),可以通过判断hash来看密码是否复杂,破解之前想想是否有必要去破解,代价是否过大?
2.耗费是时间主要集中在uncompress这个函数上,解压长度越小速度越快,由于没有合适的算法去验证这个数据是否为可解压的,导致只能用uncompress来尝试。
3.如果各位大神有啥好的想法,还望不吝赐教。
4.源码和例子所使用的exe程序
[HTML] 纯文本查看 复制代码 http://pan.baidu.com/s/1dEVZm6X
6o8p
|