BUUCTF-[2019红帽杯]easyRE
下午马上就写完的没保存全没了,哭死,没办法那也得重新写呜呜呜
载入 IDA,搜索字符串
看到 "You found me!!!" 长的像是在主函数里出现的,跳转过去
可以发现关键的比较判断部分,将 v14 数组的每一位与其下标异或后的结果与 v12 数组进行比较,如果一致则程序继续运行
不难看出 v14 的长度是 36,以及通过查看地址可以发现 v12 与 v13 其实是同一个数组,所以通过前面的赋值语句可以得到 v12 的值为:
Iodl>Qnb(ocy\x7Fy.i d`3w}wek9{iy=~yL@EC
然后写逆向脚本得到 v14 的值
#include <bits/stdc++.h>
using namespace std;
string v12 = "Iodl>Qnb(ocy\x7Fy.i d`3w}wek9{iy=~yL@EC";
int main() {
for (int i = 0; i < 36; i++)
cout << (char)((int)v12[i] ^ i);
return 0;
}
输出:
Info:The first f0ur chars are `flag`
继续往下看
不难看出 sub_400E44 函数是一个 base64 加密的过程,这段程序将数据进行 10 次 base64 后与 off_6CC090 作比较,一致则输出 "You found me!!!",查看 off_6CC090 的值
进行十次 base64 解密得到
一头文章:https://bbs.pediy.com/thread-254172.htm
所谓“让对手不要走正确的破解之路”
讲人话 就是“把对手往沟里带”
嗯,被坑了
看了看网上的 wp,得知关键的函数在主函数的下一个,难怪之前是 continue,查看这个函数并简单分析一下
看到关键部分也就是中间的那个 if 部分,if 判断内将 byte_6CC0A0 数组的第一位与 key 的第一位异或,将 byte_6CC0A0 数组的第四位(也就是byte_6CC0A3)与 key 的第四位异或(因为 HIBYTE() 函数的作用是获取高字节也就是数组的最后一位),并将两者的异或后的结果与 "f" 与 "g" 作比较,所以可以推理出 v4 其实是一个长度为 4 的数组,也就是 key,它按照一定的规律与 byte_6CC0A0 数组中的每一位异或最后生成一串开头为 flag 的字符串
byte_6CC0A0 如下
所以我们可以根据 byte_6CC0A0 的值以及 "flag" 推测出 key 的每一位,然后再根据原程序对其异或,最终解得 flag
题目完整 exp 如下:
#include <bits/stdc++.h>
using namespace std;
string v12 = "Iodl>Qnb(ocy\x7Fy.i d`3w}wek9{iy=~yL@EC";
int num[] = {0x40, 0x35, 0x20, 0x56};
string ch = "flag";
int v[5];
int flag[] = {0x40, 0x35, 0x20, 0x56, 0x5D, 0x18, 0x22, 0x45, 0x17, 0x2F, 0x24, 0x6E, 0x62, 0x3C, 0x27, 0x54, 0x48, 0x6C, 0x24, 0x6E, 0x72, 0x3C, 0x32, 0x45, 0x5B};
int main() {
for (int i = 0; i < 36; i++)
cout << (char)((int)v12[i] ^ i);
cout << endl;
for (int i = 0; i < 4; i++)
v[i] = ((int)ch[i] ^ num[i]);
for (int i = 0; i < 25; i++)
cout << (char)(flag[i] ^ v[i % 4]);
return 0;
}
flag{Act1ve_Defen5e_Test}