[NPUCTF2020] 你好sao啊 题解

二进制文件信息获取

首先不废话,先直接上 Detect It Easy 来看看这个二进制文件。

可以知道这是一个没有加壳的 64 位 Linux 程序。

https://www.hualigs.cn/image/60bc9be9b154c.jpg

静态分析

之后拖入 IDA 进行静态分析,发现没有去除符号,直接就找到了 main 函数,然后对这个函数进行 F5

https://i0.hdslb.com/bfs/album/66ea0ffc5eabd65b5053c256ec00a57c92b12732.png

可以看到 RxEncode 这个函数就是关键点,这是一个加密函数,点进去看看。

最让人在意的是这部分伪代码

if (user_input[lengthPlusOne - 1] == '=') v4 = 1;
if (user_input[lengthPlusOne - 2] == '=') ++v4;
if (user_input[lengthPlusOne - 3] == '=') ++v4;
if (v4 == 3) {
    v3 += 2;
} else if (v4 <= 3) {
    if (v4 == 2) {
        v3 += 3;
    } else if (v4 <= 2) {
        if (v4) {
            if (v4 == 1) v3 += 4;
        } else {
            v3 += 4;
        }
    }
}

这部分伪代码统计了末尾 = 号的的个数,然后和 = 号有关的编码,似乎只有 base系列编码了,这下我们可以猜测这个地方的编码和 base64 有关。之后我们还能看到这个伪代码,这个伪代码表示结果数据的长度是用户输入数据的长度的 3 / 4 倍有关,这样一想,更像是 base64 了。

v3 = 3 * (a2 / 4);

———– 华丽的分割线 ——————————————-

https://i0.hdslb.com/bfs/album/be5f479071e7c39f6b6f7870222cc08374e314e0.png

然后这个地方就是对用户输入编码的最主要的部分的程序,我们可以看到这里这个程序用了 find_pos 来找输入的每一个字节的数据在一个字符串中的位子。我们来看看这个字符串是什么?

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234{}789+/=

很明显这就是一个魔改的 base64 表。从上面的那个编码逻辑中可以看出来,

v5(数组下标) < a2(输入总长度) - v4(结尾 = 号的个数)

所以这个表中的 = 是多余的。然后我们一数,发现和常见的 base64 表的长度刚好能对上,从 find_pos 的行为,到这个表,再加上 3 / 4 这个长度比,从这些迹象我们可以知道这个编码算法大概是在做 base64 解码的工作。