-
-
[原创]看雪CTF.TSRC 2018 团队赛 第十一题 伊甸园
-
发表于: 2018-12-22 16:35 5128
-
看雪CTF.TSRC 2018 团队赛 第十一题 伊甸园 题目做完,感觉靠的是幸运,像是在玩找茬游戏或者连连看,逆向写算法什么的都是不存在的。 从这里开始: .text:0040342F mov [ebp+var_94], offset ??_7Base62@@6B@ ; const Base62::`vftable' .text:00403439 mov [ebp+var_7C], 0Fh .text:00403440 mov [ebp+var_80], 0 .text:00403447 mov [ebp+var_90], 0 .text:0040344E push 3Dh ; size_t .text:00403450 push offset aAbcdefghijklmn ; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm"... .text:00403455 lea ecx, [ebp+var_90] .text:0040345B mov byte ptr [ebp+var_4], 2 .text:0040345F call sub_401DD0 .text:00403464 mov [ebp+var_78], 39h .text:00403468 lea ecx, [ebp+var_10D0] .text:0040346E call sub_408CF0 .text:00403473 mov edx, offset aPleaseInputThe ; "please input the key" .text:00403478 mov byte ptr [ebp+var_4], 4 .text:0040347C mov ecx, offset unk_4570F8 .text:00403481 call sub_4040C0 .text:00403486 push eax .text:00403487 call sub_404370 .text:0040348C add esp, 4 ... 读取输入,然后在输入前面拼接了0x3E8长度的固定内容,输入后面拼接了0x1F40和0x208F长度的固定内容 判断总长度需要是0x4407 所以自己输入的长度是0x4407-0x3E8-0x1F40-0x208F=0x50 .text:00403623 cmp [ebp+var_4C], 4407h .text:0040362A jnz loc_40392D ... .text:0040365F lea eax, [ebp+var_2C] .text:00403662 push eax ; int .text:00403663 lea ecx, [ebp+var_94] .text:00403669 call sub_4017C0 //这里面输入的解码,表面看是base62,其实算上9开头的转义,实际相当于base64:9A对应9,9B对应+,9C对应/,9D对应= .text:0040366E push eax ; void * .text:0040366F lea ecx, [ebp+var_5C] ; void * .text:00403672 call sub_403B40 .text:00403677 lea ecx, [ebp+var_2C] .text:0040367A call sub_401C40 .text:0040367F mov edx, offset aCheckingTheRes ; "checking the result ..." .text:00403684 mov ecx, offset unk_4570F8 .text:00403689 call sub_4040C0 .text:0040368E push eax .text:0040368F call sub_404370 .text:00403694 add esp, 4 .text:00403697 cmp [ebp+var_4C], 31ABh //判断base64解码后的长度 .text:0040369E jnz loc_40392D .text:004036A4 cmp [ebp+var_48], 10h .text:004036A8 lea edx, [ebp+var_5C] .text:004036AB mov [ebp+var_A0], 0 .text:004036B5 cmovnb edx, [ebp+var_5C] .text:004036B9 mov [ebp+var_9C], 0 .text:004036C3 sub esp, 8 .text:004036C6 mov byte ptr [ebp+var_4], 8 .text:004036CA mov ecx, esp .text:004036CC sub esp, 8 .text:004036CF mov eax, esp .text:004036D1 mov dword ptr [eax], 0 .text:004036D7 mov dword ptr [eax+4], 0 .text:004036DE call sub_40C720 //处理解码后的逆波兰表达式,按树结构存储 .text:004036E3 add esp, 8 .text:004036E6 lea ecx, [ebp+var_A8] .text:004036EC call sub_405160 .text:004036F1 lea ecx, [ebp+var_A8] .text:004036F7 mov byte ptr [ebp+var_4], 9 .text:004036FB call sub_40B580 //对表达式进行自定义的运算处理 ... .text:004037D9 cmp dword_457FAC, 10h .text:004037E0 lea ecx, [ebp+var_5C] .text:004037E3 push dword_457FA8 .text:004037E9 mov edx, [ebp+var_4C] .text:004037EC mov eax, offset zz_exp_all .text:004037F1 cmovnb eax, zz_exp_all .text:004037F8 cmp [ebp+var_48], 10h .text:004037FC push eax .text:004037FD cmovnb ecx, [ebp+var_5C] .text:00403801 call sub_403BF0 //处理结果和固定字符串比较,如果相同基本就算过关,后面的其它判断估计是防止多解的 .text:00403806 add esp, 8 .text:00403809 test eax, eax .text:0040380B jnz loc_40392D 题目中定义了3个常数: .rdata:004525AC off_4525AC dd offset asc_452500 ; "x" .rdata:004525B0 dd offset aE_1 ; "e" .rdata:004525B4 dd offset aPi ; "pi" 和9种运算操作: .rdata:004525B8 off_4525B8 dd offset asc_45250C ; "+" .rdata:004525BC dd offset asc_452510 ; "-" .rdata:004525C0 dd offset asc_452514 ; "*" .rdata:004525C4 dd offset asc_452518 ; "/" .rdata:004525C8 dd offset aPowerXa_3 ; "Power_xa" .rdata:004525CC dd offset aPowerAx_0 ; "Power_ax" .rdata:004525D0 dd offset aLog_1 ; "Log" .rdata:004525D4 dd offset aSin_1 ; "Sin" .rdata:004525D8 dd offset aCos_1 ; "Cos" 这些运算操作不要用字面含义去理解,只是个符号而已,实际运算关系是在sub_40B580里面自定义的 我并没有详细分析每种操作具体如何定义 由于输入的表达式和目标结果的表达式第一个操作都是 / ,所以我只是跟了一下 / 的操作过程,大概类似这样: a/b 相当于 (?*b-a)/b*b 这里面我写个?,是因为那些还要递归继续处理的,我只跟踪了最表面的一层关系 正规解法应该是把所有这些操作逆出来,对表达式做一次逆操作?感觉工作量有点大,还未必能成功,先尝试能不能投机取巧吧。 观察输入和目标输出发现,输入的片段都能在输出中找到相似的片段,那我们要求解的这部分也应该在面有相似的片段, 首先发现输入中的*,Log,x,x在输出中完全不存在,这应该是按*1处理直接优化掉了,所以先把输入中的*,Log,x,x组合全剔除 现在的问题就是整个表达式中间残缺的一段59个字节怎么补充,式子太长,我只截取前后一小段范围的数据,其中59个#就是要解决的: Power_ax,68,x,x,*,pi,75,38,x,88,/,+,/,Power_ax,44,-,+,*,pi,75,x,x,*,pi,75,+,*,Power_ax,68,x,x,x,x,Log,Power_xa,*,pi,75,37,Log,Power_ax,90,Log,/,Power_ax,36,x,x,*,Power_ax,68,x,x,*, ########################################################### pi,75,Log,*,-,Power_ax,23,-,Power_xa,*,Log,Power_ax,90,Log,/,Power_ax,36,x,x,*,Power_ax,68,x,x,*,pi,75 经过多次尝试,最后我盯上了38,x,88这一个小片段,按个小片段做个行对齐:
图中可以看出我标记的那几行(我当时并没有把输入后面部分放进去对比,现在在写WP时才全合到一起对比),输出中有多处对应最后一个#的位置是逗号,接下来是个/操作,说明下面结构合理: pi,75,Log,*,-,Power_ax,23,-,Power_xa,*,Log,Power_ax,90,Log, 把这个替换到输入处验证,发现失败 然后才想到把输入中也全放进去对比,结果看到输入中那行和输出差了一个符号,*变成了+: pi,75,Log,*,-,Power_ax,23,-,Power_xa,+,Log,Power_ax,90,Log, 把这个替换到输入处验证,OK了 最后把这部分base64编码回去,要注意base64的字节对齐位置,我开始也是失误了几次没做对 因为前面0x3E8长度中有30处9A转义,导致不是4的倍数,所以要把前面一个逗号借过来用 base64(",pi,75,Log,*,-,Power_ax,23,-,Power_xa,+,Log,Power_ax,90,Log,") =LHBpLDc1LExvZywqLC0sUG93ZXJfYXgsMjMsLSxQb3dlcl94YSwrLExvZyxQb3dlcl9heCw5MCxMb2cs 把前两个字符LH还给借用方,最后一个字符s送给后面了,然后把其中的9换成9A得到最后结果: BpLDc1LExvZywqLC0sUG9A3ZXJfYXgsMjMsLSxQb3dlcl9A4YSwrLExvZyxQb3dlcl9AheCw5MCxMb2c
本以为她在山的那边,却没想到她已在这边等候。
图中可以看出我标记的那几行(我当时并没有把输入后面部分放进去对比,现在在写WP时才全合到一起对比),输出中有多处对应最后一个#的位置是逗号,接下来是个/操作,说明下面结构合理: pi,75,Log,*,-,Power_ax,23,-,Power_xa,*,Log,Power_ax,90,Log, 把这个替换到输入处验证,发现失败 然后才想到把输入中也全放进去对比,结果看到输入中那行和输出差了一个符号,*变成了+: pi,75,Log,*,-,Power_ax,23,-,Power_xa,+,Log,Power_ax,90,Log, 把这个替换到输入处验证,OK了 最后把这部分base64编码回去,要注意base64的字节对齐位置,我开始也是失误了几次没做对 因为前面0x3E8长度中有30处9A转义,导致不是4的倍数,所以要把前面一个逗号借过来用 base64(",pi,75,Log,*,-,Power_ax,23,-,Power_xa,+,Log,Power_ax,90,Log,") =LHBpLDc1LExvZywqLC0sUG93ZXJfYXgsMjMsLSxQb3dlcl94YSwrLExvZyxQb3dlcl9heCw5MCxMb2cs 把前两个字符LH还给借用方,最后一个字符s送给后面了,然后把其中的9换成9A得到最后结果: BpLDc1LExvZywqLC0sUG9A3ZXJfYXgsMjMsLSxQb3dlcl9A4YSwrLExvZyxQb3dlcl9AheCw5MCxMb2c
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2018-12-22 21:25
被ccfer编辑
,原因:
赞赏记录
参与人
雪币
留言
时间
一笑人间万事
为你点赞~
2022-7-27 01:51
心游尘世外
为你点赞~
2022-7-26 23:47
飘零丶
为你点赞~
2022-7-17 03:23
赞赏
他的文章
看原图
赞赏
雪币:
留言: