moectf2020 write up for RxEncode

前言

很难很难很难很难的一道逆向题QAQ非新手友好向QAQQQ

不敢想象后面的easyC++有多难Or2

逻辑分析

拖入IDA中进行分析:

image.png

程序里头s2 + v15 + v16的地址是连在一起的,整体应当是一个被IDA解析成碎片的字符串

分析主函数逻辑可知程序会将我们输入的flag经过RxEncode()函数处理后与前面的那个字符串进行比对

核心函数:RxEncode()

接下来分析RxEncode()

image.png

一堆看不懂的操作QAQ

不过我们可以发现其用到了一个find_pos()函数,里面有一个类似base64码表的东西

image.png

大胆猜测RxEncode()应当是一个换表base64解码(decode)函数

所以说这个起名方式…

写一个换表base64程序就能够得到flag啦~

解码程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <cstdlib>
#include <cstring>

using namespace std;

char key_form[100] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234{}789+/=";

char * encode(char * str);

int main(void)
{
//initialize the encoded flag
char decoded_flag[100];
long long *ptr = static_cast<long long*>((void*)decoded_flag);
*ptr = 0x4AD158FEB59C879ALL;
*(ptr + 1) = 0xCBEBFDFA6CED0BFELL;
*(ptr + 2) = 0x7A47A38E43A334E8LL;
*(ptr + 3) = 0x0000000000000000LL;
*(ptr + 4) = 0;
char * flag;

//decode the flag
flag = encode(decoded_flag);
cout << "flag: " << flag << endl;s

//return 0 to the system
return 0;
}

char * encode(char * str)
{
int len = strlen(str);
int bins_used = 0;
int index = 0;
char * flag = static_cast<char*>(malloc(0x80));

for(int i=0;str[i];)
{
if(bins_used == 0)
{
unsigned char ch = str[i];
ch >>= 2;
flag[index++] = ch;
//flag[index++] = (str[i] >> 2);
bins_used = 6;
}
else if (bins_used == 6)
{
unsigned char ch1 = str[i];ch1 <<= 6;ch1 >>= 2;
unsigned char ch2 = str[i+1];ch2 >>= 4;
flag[index++] = ch1+ ch2;
//flag[index++] = (((str[i] << 6) >> 2) + (str[i+1] >> 4));
bins_used = 4;
i++;
}
else if (bins_used == 4)
{
unsigned char ch1 = str[i];ch1 <<= 4;ch1 >>= 2;
unsigned char ch2 = str[i+1];ch2 >>= 6;
flag[index++] = ch1+ ch2;
//flag[index++] = ((str[i] << 4) >> 2) + (str[i+1] >> 6);
bins_used = 2;
i++;
}
else if(bins_used == 2)
{
unsigned char ch = str[i];
ch <<= 2;
ch >>= 2;
flag[index++] = ch;
//flag[index++] = ((str[i] << 2) >> 2);
bins_used = 0;
i++;
}
}
flag[index] = '\0';

for(int i=0;i<index;i++)
{
flag[i] = key_form[flag[i]];
}

return flag;
}

image.png

得到flag

1
moectf{Y0Ur+C+1s+v3ry+g0o0OOo0d}

后面才发现python有好多可以用的库…好气啊…

不过我也不会python T T..

以及还需要注意大小端序(wsm倒着存啊…以前的程序员思路好奇怪欸…)

1
2
3
4
5
6
7
8
from base64 import *
from string import *

decoded_flag = b'\x9A\x87\x9C\xB5\xFE\x58\xD1\x4A\xFE\x0B\xED\x6C\xFA\xFD\xEB\xCB\xE8\x34\xA3\x43\x8E\xA3\x47\x7A'

flag = b64encode(decoded_flag).decode().translate(str.maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234{}789+/"))

print(flag)
Posted on

2020-11-22

Updated on

2020-11-22

Licensed under

Comments

:D 一言句子获取中...

Loading...Wait a Minute!