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}

posted @ 2021-10-23 11:52  Moominn  阅读(519)  评论(0编辑  收藏  举报