黑客挑战 - 定位代码中的漏洞

Hacking Challenge - locating vulnerability in the code

我的朋友最近完成了一项黑客挑战并将其发送给我(二进制文件和源代码)。在向他询问提示之前,我想在这里问一下,因为我想自己做:)

我一直在研究它,但我正在努力寻找漏洞。

#include <alloca.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static void usage(const char *argv0) {
    printf("Build your own string!\n");
    printf("\n");
    printf("Usage:\n");
    printf("  %s length command...\n", argv0);
    printf("\n");
    printf("Each command consist of a single character followed by it's index.\n");
    printf("\n");
    printf("Example:\n");
    printf("  %s 11 h0 e1 l2 l3 o4 w6 o7 r8 l9 d10\n", argv0);
    exit(1);
}

int main(int argc, char **argv) {
    char *buffer;
    unsigned short buffersize, i, index, length;

    if (argc < 2) usage(argv[0]);

    length = atoi(argv[1]);
    if (length <= 0) {
            fprintf(stderr, "bad length\n");
            return 1;
    }

    buffersize = length + 1;
    buffer = alloca(buffersize);
    memset(buffer, ' ', buffersize);
    buffer[buffersize - 1] = 0;

    for (i = 2; i < argc; i++) {
            if (strlen(argv[i]) < 2) {
                    fprintf(stderr, "bad command \"%s\"\n", argv[i]);
                    return 1;
            }

            index = atoi(argv[i] + 1);
            if (index >= length) {
                    fprintf(stderr, "bad index in command \"%s\"\n", argv[i]);
                    return 1;
            }

            buffer[index] = argv[i][0];
    }

    printf("%s\n", buffer);
    return 0;
}

我认为漏洞在于 short int 和 alloca 的使用。

输入 ./app 65535 65535 可能会导致段错误,但实际上我无法覆盖任何内容,因为缓冲区只会被设置为最大 65535 或循环。这让我觉得我不能覆盖 EIP 来注入 shellcode。

谁能帮我看看在哪里看?

谢谢!

实际上,漏洞在于您可以在分配给 alloca 的缓冲区中的任意偏移处存储一个字符,但测试是在 length 而不是 size 上完成的].传递 65535a1 的参数会调用未定义的行为:size 作为值 0 因为如果 unsigned short 有 16 位则算术回绕。

您可以尝试传递第一个参数 65535 和后续参数并增加偏移量,这将使值超出 buffer 的末尾,可能会覆盖 return 地址 main并导致崩溃:

myprog 65535 a3 a7 a15 a19 a23 a27 a31 a35 a39 a43 a47 a51 a55 a59 a63 ...

根据实际的局部变量布局,需要的偏移量可能大于17,但应小于80