本文主要是介绍BUU [2019红帽杯]childRE1,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
这个题目比较难,一开始看了一下没有头绪。
首先用ida打开:
很长的一个程序,一步一步仔细分析。
首先是第一部分,这一部分是先进行了输入,然后判断是否是31字节,将我们的输入使用sub_14001290()函数。这个函数,我一开始以为是一个加密函数,看起来挺复杂的。通过下面的sub_1400015C0()函数有一些提示。if(v4)下面的部分完全就是一个后序遍历嘛?所以说,这个函数可以猜测是构造二叉树的函数。 (下面第二张图是后序遍历的代码)。
但是有个问题,这个sub_1400015C0(v6+16),在ida f5后的代码中,没看到对v6进行了赋值操作。这个v6对应的是r10,查看ida中的汇编代码发现,其实是有赋值操作的,但是F5后的C代码中却没有关于v6的赋值操作,ida难道有bug嘛?
上面的部分总结下来,其实就是先是要有一个31字节的输入,其次将输入利用二叉树后序遍历完成了置换操作。这一部分好说,毕竟只是置换了一下顺序嘛。
下面的操作,先是UnDecorateSymbolName函数,这个函数是反修饰指定已修饰的 C++ 符号名。随后利用62位的outputstring,进一步对比判断。
总体流程介绍完了。下面开始一步一步从下往上倒退。
首先是这一部分:
还是比较简单的,0x140003478和0x140003438处分别是两个字符串。总的来说就是用outputString中的值除以23,得到商和余数。将商和余数带入到 1234567890....这个大数组中,商和余数能满足 a1234567890Qwer[v14 / 23] 、a1234567890Qwer[v15]等于相应的 0x140003478和0x140003438 中的值。因此反推的字符=23*商+余数。
写出这部分的脚本:
s3478 = "(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&"
s3438 = "55565653255552225565565555243466334653663544426565555525555222"
s = '1234567890-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;,ASDFGHJKL:"ZXCVBNM<>?zxcvbnm,./'
p = ''
for i in range(62):p += chr(s.find(s3478[i]) + s.find(s3438[i])*23 )print (p)
结果:
接下来就是UnDecorateSymbolName()函数。
经过这个函数之后,得到的输出是 :
private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)。
可以上网查资料一步一步构造,参考了2019 红帽杯 Re WP - Hk_Mayfly - 博客园这个师傅的做法:
直接模拟构造了一波:
得到结果:?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z (刚好31个字节)
最后就是置换操作了。这部分使用动态调试的方法,输入31字节。
设置好断点后,可以找到相应输出的字符串,可以看到只是顺序变了。
python代码为
my_str = "?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z"
ori = "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_"
change = "PQHRSIDTUJVWKEBXYLZ[MF\]N^_OGCA"newstr=[0 for x in range(0,31)]
for i in range(31):newstr[ori.find(change[i])]=my_str[i]
for i in range(31):print (newstr[i],end="")
得到结果:
最后md5即可:
这篇关于BUU [2019红帽杯]childRE1的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!