首页
社区
课程
招聘
[原创]看雪.Wifi万能钥匙 CTF 2017 第7题Writeup
发表于: 2017-6-15 08:31 5915

[原创]看雪.Wifi万能钥匙 CTF 2017 第7题Writeup

2017-6-15 08:31
5915

拿到程序先运行了下(还是比较相信出题的大佬的),在win10系统中运行失败,放xp下运行正常,不过第二次点按钮会出错。此程序是窗口程序,输入错误注册码不提示任何信息。

拖入ida,发现入口代码被更改成错误代码,看导出除了start还有Tls_Callbase_0,原来用了Tls,代码如下:

先通过TEB获取自身两次,然后依次获取PEB、程序基址、PE的NT头、程序入口地址。然后调用xor_410DD6函数将入口入的0xc8个字节与eax指向的硬编码字串循环异或。直接patch。

由于是窗体程序,且没有出错弹窗,直接查看GetDlgItemTextA,只有一处调用,说明此处一定是验证的开始。直接看伪代码:

程序的传参方式受不了,特别是后面,看得有点蒙。 这里又出现了异或的这个函数,这次参数有:地址是sub_411B30,异或字节数是426,异或串是PEDIY,此字串也是硬编码的,不过伪代码不知道为什么没显示出来。

异或完直接调用sub_411B30,然后还原sub_411B30。 下面又看了下sub_411B30sub_411825,这时伪代码根本没法看了,完全看不出什么,而且里面还有些堆的申请释放等函数混杂在一起,静态看起来犹如天书。有一点看出来了,没有看到明显的比较或校验,sub_411825中使用了VirtualAlloc

sub_411B30顺便也patch了,而且把异或函数直接ret了,patch完了,程序再也不出错了。

OD载入程序,没有停在入口,直接运行了,无妨,直接GetDlgItemTextA下断,输入确定后停到了预期位置。大概走了下,sub_411B30函数对输入进行异或还有置换操作,再进行异或移位。此为第一次分析的结果。 输入先进行异或

异或后的输入进行查表置换,大概过程如代码示例:

相应的程序代码如下:

转换表为:

我顺便看了下置换表对应的输入字符,字符范围为数字+大小字母+!+@,共64个。

sub_411B30中还调用了sub_410F75,对转换后的结果再进行变换,变换公式为(a^0xcc<<3)|(a^0xcc>>5)

跟到这已经烦躁不行,有很多的堆函数什么的。所以就想直接看看整体过程。

然后直接进了sub_411825,静态的时候已经发现此处有VirtualAlloc,又翻看了下,没有明显弹窗的地方,此函数结束后就直接进入事件流程了。所以推测,弹窗在VirtualAlloc的空间的代码中。只跟了下流程,大概是:如果sub_411975函数返回真,则进行VirtualAlloc,拷贝411A9C处的0x94个字节数据,并循环与原始输入异或,最后执行代码。 只里有个细节,异或完成后,在复制过来的数据偏移0x61和0x8C处,分别加上了两个地址之间的dword偏移量,然后在数据后又加上了最后一次参加异或的输入后一位,后面就直接执行复制过来的数据了。据此猜测这两处是两个call,改的是操作数,也就是偏移,程序代码如下:

看到了这,我想偷个懒,尝试能不能直接通过代码的特点和规律,直接还原代码。先从入口,返回和那两个偏移入手。 原始的代码数据如下:

首先,入口通常为push ebp mov ebp,esp,对应机器码为55 8B EC,得到Bwn 再看返回,数据最后一位添加的不可能是C3,不在可输入范围,所以A6异或后就为C3C2,所以此处的异或字符为ed 再看两个call,B0 2B B9 94 BD6D 53 6E 73call的对应机器码是E8,所以B0对应的异或字符为X6D对应k,通常偏移是xx xx 00 00xx xx FF FF,所以94 BD对应Kb6E 73对应ns。 似乎没法进行下去了。尝试多次也不见效。继续跟踪。这次跟踪重点是进VirtualAlloc的条件,即sub_411975函数。

反复跟踪,终于明白,转换后的输入先转成16进制,再将此转换成4进制,最后与一串常量比较,校验的函数为sub_41612A,主要校验是经过两轮,每轮比较0x20个四进制数。 常量串为:

那反算回来不就是key了。动手操作,发现我想到了,最后结果多处有多值。反变换脚本如下:

结果如下,前面是序号,后面为可能值:

还是上ida,用上面的xor1脚本函数,慢慢对。 结合前面已经分析的字串和此次的结果,整理下: 前三位是Bwn比较确定;输入应该是20位,那0x60,0x63,0x64处对应的异或数XkB应该是输入的第17、20、1位;0x8B,0x8E,0x8F处对应的异或数kns应该是输入的第20、3、4位。条件符合。所以此时的输入串为Bwns????????????X??k。 但是反算结果中还有个别位是唯一解的,第11位,第19位,那输入为Bwns??????y?????X?Ok

再看看返回,猜测返回应该是C3而不是C2,因为我们的输入都大于0x20,一般返回中没有这么大的偏移,所以暂定为C3,对应输入为e,返回的前一个应该是pop ebp,字节码为5D,对应异或码为P,这两个分别对应输入的第7、8位。判定后对照反算结果,条件符合。所以此时已得到的输入为Bwns??Pe??y?????X?Ok

再往pop ebp上面看,上面一条应该是mov esp,ebp,与开头对应,保持栈平衡,机器码为8B E5,异或值为At,对应输入的第5、第6位,这样,开头的指令也比较正常。此时已得到的输入为BwnsAtPe??y?????X?Ok

下面就比较难看了。对照了下反解结果,第10位可选值有Pi,但是从程序的校验码来看,20个字符各不相同,因此第10位为i,所以此时已得到的输入为BwnsAtPe?iy?????X?Ok。已经出现MessageBoxA的偏移。

似乎没有特别明显的了,那从头开始试吧,第9位对应一个操作码,有三个可选值dcs。 在函数开头,能影响一个push的值。选择d时,push了一个函数地址,一看是cookie检验的。所以此时已得到的输入为BwnsAtPediy?????X?Ok。出现了Pediy,呵呵。

411B1A出现mov fs:30320000h, ecx,一看偏移有问题,改成00,异或值为0x32,0x30,分别对应输入第12,13位。所以此时已得到的输入为BwnsAtPediy20???X?Ok


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 10072
活跃值: (3008)
能力值: ( LV15,RANK:515 )
在线值:
发帖
回帖
粉丝
2
2017-6-15 12:29
0
雪    币: 48
活跃值: (328)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
666
2019-2-14 16:43
0
游客
登录 | 注册 方可回帖
返回
//