re | [WUSTCTF2020]level3

这是一个x64的elf逆向题。

被坑的很惨,也学到不少。

主程序是如下一个逻辑:

通过随机的方式选择是加密你给的字符串还是输出提示信息。

提示的信息里是base64编码以后的东西,猜测是flag。

我一开始的思路是上图中的base64_encode函数有问题,加密的过程可能有问题,做了特殊处理,所以进入base64函数进行分析:

如果出问题的话,问题片段应该就在其中,但是我来回分析了几遍,甚至重新复习了一下base64的编码原理,甚至想到了会不会是算数右移导致的误差,但是还是没能找到问题所在:

之后选择使用ubuntu来进行动态调试,被逼无奈,重新学了一下gdb的调试方法,我的gdb装了peda的插件:

附上一篇简明的peda调试指令汇总文章:https://blog.csdn.net/weixin_30920853/article/details/97711357

发现程序加密Mz1的时候出来是AX0x而不是TXox,更是纳闷了。

这才反应过来被坑了,应该是有的函数执行了修改了base64的表格,而我从主程序跟进的时候早就执行完了。

动态调试查看base64表的位置:

果然是被修改过了。【气炸,看了好半天以为是加密的问题】

再回到IDA,发现这样一个函数:

就是这个坏东西对base表进行了修改。

由于我还没深入学习linux,所以对这个函数执行的时机和流程并不了解,不过好歹下次有经验了。

最终的处理办法是,对加密后的字符串按表的替换顺序进行替换,我写了如下脚本:

 1 encoded_flag = "d2G0ZjLwHjS7DmOzZAY0X2lzX3CoZV9zdNOydO9vZl9yZXZlcnGlfD"
 2 
 3 #TSRQPONMLKJIHGFEDCBAUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
 4 #ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
 5 _list = list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
 6 
 7 _flag = ""
 8 
 9 for i in encoded_flag:
10     _in = _list.index(i)
11     if _in <= 19:
12         _in = 19-_in
13     _flag += _list[_in]
14     
15 print(_flag)

然后丢进工具解码就可以了。

原文地址:https://www.cnblogs.com/Mz1-rc/p/13687361.html