CTF--入门级栈溢出漏洞

0x01 源码程序

gcc -o test test.c 即可在linux中编译成ELF文件。这段源码其实也很简单,只要看结构体都可以看出漏洞大概在哪。

#include

struct Student {
    char name[8];
    int birth;
};

int main(void) {
    setbuf(stdin, 0);
    setbuf(stdout, 0);
    setbuf(stderr, 0);
    struct Student student;
    printf("What\'s Your Birth?\n");
    scanf("%d", &student.birth);
    while (getchar() != '\n') ;
    if (student.birth == 1926) {
        printf("You Cannot Born In 1926!\n");
        return 0;
    }
    printf("What\'s Your Name?\n");
    gets(student.name);
    printf("You Are Born In %d\n", student.birth);
    if (student.birth == 1926) {
        printf("You Shall Have Flag.\n");
        system("cat flag");
    } else {
        printf("You Are Naive.\n");
        printf("You Speed One Second Here.\n");
    }
    return 0;
}

 

0x02 基本分析

* 上面的运行程序是正常人的输入,下方是黑客不正规的输入,很显然当输入不正规的数据时,会返回异常的数据,大概就可以断定,这是一个栈溢出漏洞。

CTF--入门级栈溢出漏洞_第1张图片

* 由于我们是调试没有源码的程序,所以先找到入口地址,或者找到main地址,然后断在那。

CTF--入门级栈溢出漏洞_第2张图片

* 下图就是断点处的地址。r 是运行程序,按 ni 是一步步执行

* 以下是根据经验可以找出main函数的入口在哪,或者自己多调试熟悉这个程序,在没有源码的情况下,逆向思维大概这段程序源码是什么样的。在call处可以按 s 进入程序中。

CTF--入门级栈溢出漏洞_第3张图片

CTF--入门级栈溢出漏洞_第4张图片

* 经过多次调试可以得出,这个就是第一次输入的地方。

CTF--入门级栈溢出漏洞_第5张图片

* 这个是第二次输入的地方,然后输入了一堆a

CTF--入门级栈溢出漏洞_第6张图片

* 此时我们看见0x4008ab这处是一个比较,正好和0x786也就是1926比较,这正是和源码中正好匹配,我们就猜测这里八成就是最主要的跳转点了。

CTF--入门级栈溢出漏洞_第7张图片

* 此时我们查看了一下上方栈的数据,x/20gx,x是查看内存,20个,g是8个字节,x是十六进制。我们看到这个地址的数据是61,刚好是a的ascii码十六进制的值。

CTF--入门级栈溢出漏洞_第8张图片

······不说了 看图。

CTF--入门级栈溢出漏洞_第9张图片

将eax的值改成0x786。

一步步调试,这里发现 You Shall Have Flag,证明没有猜错,只要能进入这里,就证明拿到了flag。

 

* 用Python手动编写exploit程序。需要先安装pwntools这个模块。

sudo pip install pwntools

CTF--入门级栈溢出漏洞_第10张图片

 

0x03测试结果:

CTF--入门级栈溢出漏洞_第11张图片

 

0x04总结:

这段程序并不难,尤其还有源码,再加上struct结构体,完全可以看出栈溢出漏洞在哪。虽然有源码,但是我还是建议多多动手调试,从反汇编逆推出源码大概是怎样的,这样非常有助于新手成为逆向工程师或者有关的工程师。这段python也是需要多百度,百度有非常多的例子,也建议不会的多百度,直到找到答案为止。

你可能感兴趣的:(CTF)