大概的瞄一下函数的功能:有长度校验、错位异或、开启线程进行检测,最后通过变量判断flag是否正确。
flag{77e52c5b-b141-4f3b-92ec-aa680ca38,长度为38位,
第18~19行对输入进行错位异或,x[i] ^= x[i+1]。调试器跟踪一下:
从函数的功能来看,函数主体调用了某个函数对数据进行进一步的变换,我们在调试器里定位到调用函数sub_f1127b处,这里先从上一步异或变换后的数据中取2个字入栈,另外还从全局的数据中取了两个字入栈(后面分析可以知道是一个key)。
说明在这之前又进行了变换。回到错位异或后,在图5中对数据下硬件断点,F9。
中断在第52行伪代码的位置,为了简便,这里直接从OD和IDA进行了对应。
从函数的名字来看,这个函数是一个TLS回调函数,回调函数会在创建线程的前后被调用。
图8的函数是一个RC4的加密实现(主流加密算法也必须要熟练,不然打比赛很吃亏,哈哈),这里我们只要把密码抠出来就行了。
通过调试可以知道RC4的密码是JT8U9ptt,第52行对异或后的flag值进行了RC4加密。对比一下加密前后的数据:
接下来我们继续从图6第10行的位置开始分析,该变换函数比较复杂。
也没有出现特殊的加密字,不好猜测是什么算法。这个变换函数暂时不深入分析。知道该算法的同学请指教,谢谢。
我们回到题目本身,通过猜测flag的值是不可能的,那要解题,则必须可以通过图14的正确的值“逆变换”出正确的flag。
因此整个变换过程都是可逆的。从这个角度出发,我们大胆猜测第三次变换也肯定是可逆的。
我们在调试器里把第三次变换前的flag数据和变换后的flag数据记录下来,也就是图11和图13的数据。开启新一次调试,在第三次变换参数入栈之前用变换后的数据覆盖一下变换前的数据,执行完变换后,看输出是否是原来的输入。
看来该参数是有作用的。我们试着在对调变换的输入输出后,再把参数5换成0x64(选中指令二进制编辑)。奇迹发生了,变换后的输出果然是原来的输入。
这也就证明了第三步的变换是可逆的,而且通过参数5来控制加密和解密。
1、把正确的flag变换数据记为DATA_D(图14)通过第三步的逆变换解密,记为DATA_C。
2、把DATA_C RC4解密,密码为JT8U9ptt,解密的结果记为DATA_B。
3、把DATA_B逆错位异或,得到DATA_A,也就是明文flag。
把变换函数的第5个参数设置成100。变换完成之后是:
3F D8 A0 03 BB 66 8C FC 94 AF A9 EA 83 28 31 59 82 83 C9 92 9D B5 73 A4 8D 4C 7B 96 2B 74 6A A8 AE C8 C0 AE B2 D4 00 00
再逆向错位XOR,得到flag:flag{068d772e155448f0ba101abb62a2a837}
看雪ID:chence
https://bbs.kanxue.com/user-home-369739.htm
*本文为看雪论坛优秀文章,由看雪论坛 chence 原创,转载请注明来自看雪社区
原文始发于微信公众号(看雪学苑):贵阳大数据及网络安全精英对抗赛Reverse EZRE_0解题