有人可以解释一下这个缓冲区溢出是如何工作的吗?

Can someone explain how this Buffer Overflow works?

我试图通过向工作中的同事展示工作缓冲区溢出示例来举例说明该堆栈的工作原理。很难找到有效的现代示例,但我有一个有效的示例,唯一的问题是我不明白!

我认为通过提供比缓冲区长的字符串作为密码,它会覆盖比较变量。该示例说要提供 zzzzzzzzzzzz 的密码,但我不明白它是如何将 1 变成 0 的。

有人可以帮忙吗?

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

#define PASSWORD "secret233"
#define BUFFER_SIZE 10

int check_pass(char *input)
{
    int compare = 1;
    char buffer[BUFFER_SIZE];

    compare = strcmp(input, PASSWORD);
    printf("[matched value]:%d\n", compare);

    strcpy(buffer, input);
    printf("[matched value]:%d\n", compare);

    return !compare;
}

main()
{
    int passed = 0;
    char input[1024];

    while (1) {
        printf("Enter password: ");
        scanf("%s", input);

        passed = check_pass(input);
        if (passed) {
            printf("--Password correct!\n");
            break;
        }
        else
            printf("--Wrong password. Try again.\n\n");
    }
}

 

Buffer Overflow 的最佳示例如下:

以下程序获取用户的输入并将其与密码进行比较。这很容易证明。

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

int main(void)
{
    char my_input[12];
    char my_password[12] = "password123";
    scanf("%s", my_input);

    if (strcmp(my_input, my_password) == 0)
        printf("PASS\n");
    else
        printf("ERROR\n");
    return 0;
}

现在,像这样编译上面的程序:

gcc main.c -o main

然后,输入以下命令:

./main < <(python -c "print('AAAAAAAAAAA' + '\x00' + 'AAAAAAAAAAA' + '\x00')")

结果将是:

PASS

问:这是怎么发生的?

回答:scanf() 函数不检查字符串的长度,如果它超过某个限制,那么它只会覆盖下一个堆栈存储的变量。 (my_password)

问:如何解决这个问题?

回答:使用%<LIMIT>s代替%s以防止缓冲区溢出。或者简单地使用 fgets() 函数,这是一个更好的选择。

所以,你的最终代码应该是这样的:

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

int main(void)
{
    char my_input[12];
    char my_password[12] = "password123";
    scanf("%12s", my_input); // limit is now only 12

    if (strcmp(my_input, my_password) == 0)
        printf("PASS\n");
    else
        printf("ERROR\n");
    return 0;
}

现在re-run上面的命令:

./main < <(python -c "print('AAAAAAAAAAA' + '\x00' + 'AAAAAAAAAAA' + '\x00')")

结果:

ERROR