-
-
[原创]2017CTF秋季赛第二题WriteUp
-
2017-10-28 14:35
4032
-
解题过程
1. 首先运行程序,随意输入字符串
很不给面子的直接崩溃了,怀疑没有检查输入字符串的长度,打开pe文件看一下,发现并没有随机基址,那么可能会存在可利用的溢出漏洞。
2.先用ida看看
很明确的代码逻辑,输入经过Change_1和Change_2函数运算之后,满足条件就能到达“You get it!”,行,那我们来分析这两个函数把。
Change_1:
if ( v1 && v0 && v1 != v0 && 5 * (v1 - v0) + v1 == -1890567614 && 13 * (v1 - v0) + v0 == -279954878 )
Change_2:
if (v1 && v0 && v1 != v0 && 5 * (v1 - v0) + v1 == -1890567614 && 13 * (v1 - v0) + v0 == -279954878)
真简单啊!这题只要解两个初中生都会的方程就行了,不过很可惜,回想起当年体育老师教导我的数学知识后,这个方程式应该是无解。
3.从溢出的角度出发
观察一下输入函数,确实是存在够溢出漏洞的,这下就简单了(又掉坑里了),构造任意字符串,满足条件:字符最后是构造好的地址,溢出到栈内的返回地址,程序执行retn的时候就能跳到:
可是这样一来,题目就形成了多解,最关键的0040102f是存在不能输入的ascii值的。和比赛规则不符。那么问题来了,怎么才能验证输入的字符呢?怀疑存在另外的shellcode来验证之前的输入字符。并且这个shellcode的地址拆分开后,16进制ascii码是字母或数字,带着这样的条件,去ida里浏览一下代码。
这么多代码里,就你画风不一样,不是你还是谁?光从静态分析上了看,我首先怀疑的是这是段加密代码,顺着这个思路去找解密函数花费了我大量时间。事后发现果然还是太年轻了。
4.管那么多干嘛,开od调啊
构造字符串
1234657890ab11A
接着往下走几步,就发现原来不是加密函数,是花指令,既然这样,剩下的就是体力活了,10分钟之后,验证函数就还原了:
赋值:
xor eax eax
mov dword ptr [41b034], eax
004131ba pop eax
004131eb mov ecx, eax
0041321f pop eax
00413254 mov ebx, eax
00413289 pop eax
004132b5 mov edx, eax
004132ad mov edx, eax
004132e2 mov eax, ecx
设x,y,z,n:
1234 5678 90ab 11A
x y z n
第一个段验证公式:
00413316 sub eax, ebx
00413349 shl eax, 2
00413380 add eax, ecx
004133b5 add eax, edx
004133e9 sub eax, EAF917E2
还原:((x - y) << 2) + x + z == EAF917E2
如果正确,来到第二段验证:
00413455 add eax, ecx
00413489 sub eax, ebx
004134bf mov ebx, eax
004134f3 shl eax, 1
00413525 add eax, ebx
00413559 add eax, ecx
0041358f mov ecx,eax ;保存((x-y)<<1)+(x-y)+x
004135c3 add eax, edx
004135f7 sub eax, e8f508c8
还原:((x - y) << 1) + (x - y) + x + z == E8F508C8
如果正确,来到第三段验证:
00413665 mov eax, ecx
004136a7 sub eax, edx
还原:((x - y) << 1) + (x - y) + x - z == 0C0A3C68
又是解方程,还是三元一次方程,太难了。万幸的是有解。
最后xyzn的值转换成ascii码拼凑起来:Just0for0fun11A
感想
第一次参加看雪的ctf大赛,第一次做CrackMe(第一题太简单了不算),能够解出这一题还是有些高兴的。题目设计的很精巧,坑都踩了也不亏。认真写下这篇wp留作纪念。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课