继续复现红帽杯逆向题。
输入并且检测长度,可以看到长度是31。
这是一组变换函数,搞了好长时间才弄懂。
对v2进行反修饰,得出的结果存入outputString,outputString长度为62.
取outputString的字符串进行除和取余,并且作为a12345670Qwer的索引,对指定索引进行明文比较。
这就是正确的程序流程。
因为最后的比较都是明文,所以可以写脚本得到正确的outputString。
a1 = '12345670-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;\'ASDFGHJKL:"ZXCVBNM<>?zxcvbnm,./'
b2 = '555656532555522255655655552434663346536634426565555525555222'
b1 = '(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&'
ops = ''
for i in range(len(b1)):
index1 = a1.index(b2[i])
index2 = a1.index(b1[i])
ops += chr(index1 * 23 + index2)
print(ops)
然后对outputString进行函数名修饰,这里给一个大佬的思路,C++代码:
#include<iostream>
using namespace std;
class ROPxx {
public:
ROPxx(){
unsigned char a;
My_Aut0_PWN(&a);
}
private:
char My_Aut0_PWN(unsigned char*) {
printf("%s", __FUNCDNAME__);
return '0';
}
};
int main() {
new ROPxx();
getchar();
return 0;
}
运行就能得到修饰结果。这样就拿到了正确的v2.
对v2进行逆变换得到输入的字符串,然后进行md5加密,就是最终的flag。
str1 = '?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z'
result = [''] * 31
index3 = [15, 16, 7, 17, 18, 8, 3, 19, 20, 9, 21, 22, 10, 4, 1, 23, 24, 11, 25, 26, 12, 5, 27, 28, 13, 29, 30, 14, 6, 2, 0]
print(len(str1))
for i in range(len(str1)):
result[index3[i]] += str1[i]
ss = ''.join(i for i in result)
print(ss)
print(hashlib.md5(ss.encode('utf-8')).hexdigest())
这道题当时比赛没看,复现的时候,发现明文比较,反修饰这些都能看懂。但是搞不懂对输入变换这部分。花了一点时间来解决这个问题。
两个点,
v1那个函数是什么用,
另外两个相同的函数又是干什么的。
网上的writeup都直接说动态调试发现是固定的位置变换,直接把索引提取出来了。思路好一致。。。。
看了官方writeup才知道:
v1后边那个函数是对输入建立一个二叉树,31个字符,是五层满二叉树。
另外两个相同的函数是后序遍历,
调试了一下
怎么识别是二叉树呢?
可以识别出是二叉树结构体。
这是进行后序遍历。
第一个是对左半边进行遍历,
第二个是对右半边进行遍历。
函数内进行递归。
找出索引如下,因为是从0开始,所以需要减一。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- stra.cn 版权所有 赣ICP备2024042791号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务