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

Posted

技术标签:

【中文标题】黑客挑战 - 定位代码中的漏洞【英文标题】:Hacking Challenge - locating vulnerability in the code 【发布时间】:2016-06-10 19:45:31 【问题描述】:

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

我一直在经历它,但我正在努力寻找漏洞。

#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。

谁能帮我看看在哪里看?

谢谢!

【问题讨论】:

尝试在您的环境中为第一个参数输入定义为USHRT_MAX 的数字, @MikeCAT 是的,我试过了,我可以得到一个段错误,但不能覆盖任何值,因为如果我将它设置为大于最大值,int 只会循环。 @JDoby,你将如何得到分段错误? 调试器应该有助于查看变量和返回地址的位置,buffer 中的值是什么。 因为buffersizelengthunsigned int:将length 设置为65535 将导致buffersize 为0,因此不会在堆栈上为buffer 分配任何内容。但是,由于将indexlength 进行比较,因此可以使用buffer[index] 覆盖堆栈的前64Kb。 【参考方案1】:

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

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

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

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

【讨论】:

太棒了,我实际上尝试了这个,但没有输入足够的内容导致崩溃!我将如何输入“A”来用 x414141 覆盖 EIP,因为我似乎只能像你说的那样输入偏移量。 @JDoby:您将首先找到返回地址,例如 24,然后传递参数 A24 A25 A26 A27... 4 或 8 个,具体取决于架构。但是单次插入返回地址的更重要字节就足够了,而且会更优雅。

以上是关于黑客挑战 - 定位代码中的漏洞的主要内容,如果未能解决你的问题,请参考以下文章

最新Zip压缩文件漏洞,黑客可以触发目录遍历攻击

计算机爱好者李开拓

Linux 杀毒软件发现的漏洞可使得黑客获得 root 权限

Linux 杀毒软件发现的漏洞可使得黑客获得 root 权限

SDK漏洞可能让黑客监视超过100万个物联网设备

黑客的等级是如何划分的?