【问题标题】:C++ Buffer Overflow, strcpy, fgets, sprintf showing runtime errorC++ 缓冲区溢出、strcpy、fgets、sprintf 显示运行时错误
【发布时间】:2021-10-12 22:35:00
【问题描述】:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int check_authentication(char* password) {
    int auth_flag = 0;
    char* password_buffer;
    char* dept;
    password_buffer = (char*)malloc(16);
    dept = (char*)malloc(10);
    printf("Your department?");
    fgets(dept, 10, stdin); //line 11
    strcpy_s(password_buffer, 16, password); //line 12
    if (strcmp(password_buffer, "AsiaPacificInst") == 0) {
        if (strcmp(dept, "NSF") == 0) {
            auth_flag = 1;
        }
    }
    if (strcmp(password_buffer, "AsiaPacificUni") == 0) {
        if (strcmp(dept, "TM") == 0) {
            auth_flag = 1;
        }
    }
    return auth_flag;
}
int main(int argc, char* argv[]) {
    char errmsg[512];
    char outbuf[512];
    char user[20];


    printf("Username: ");
    fgets(user, 20, stdin); //line 32
    if (strcmp(user, "Adm1n") == 0) {
        printf("Authorised User\n"); sprintf_s(errmsg, "Authorised User %400s", user); sprintf_s(outbuf, errmsg);  //line 34

        if (argc < 2)
        {
            printf("Usage: %s <password>\n", argv[0]); exit(0);
        }

        if (check_authentication(argv[1]))
        {
            printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
            printf(" Access Granted.\n");
            printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
        }

        else {
            printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
            printf("\nAccess Denied.\n");
            printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
        }


    }
    else { printf("Unauthorised User!!\n"); exit(0); }

}

由于我不熟悉 C++,我需要帮助检查以下代码集是否以正确的方式编写。

  1. fgets(第 11 和 32 行)
  2. strcpy_s(第 12 行)
  3. sprintf_s(第 34 行)

因为这些代码行在我从其他来源获得它们时出现了错误。但是,我修复了这些错误,但在运行时程序无法正常工作。该程序实际上应该请求用户名和密码,并使用用户名验证用户是否被授权,并使用他们的密码验证用户的部门。但是,我只能在运行程序时输入用户名。它没有要求我输入密码。总体而言,还有其他可能导致程序无法正常运行的问题。

Program Result when executed

【问题讨论】:

  • 那是纯 C。虽然它应该可以编译为 C++,但大多数 C++ 程序员不会称它为“C++”。
  • 这不是 C++??
  • fgets 从缓冲区读取换行符,所以dept 永远不能是"NSF",而是"NSF\n"
  • 一些想法:您似乎在代码中混淆了身份验证和授权。这是两个完全不同的概念,您需要将它们分开。此外,默认情况下,身份验证代码处理不受信任的输入。您需要确保(如果不是“证明”,请阅读“单元测试”)您理解代码并且它确实有效,即使攻击者将 AVI 转储到您的任何缓冲区中也是如此。您还需要 DRY 并为缓冲区长度创建常量,以便与 fget 一起重用。

标签: c++ printf fgets buffer-overflow strcpy


【解决方案1】:

该程序不请求密码,因为它希望它作为这样的参数传递:'c:\yourapp.exe yourpass'。如果你想让它请求密码,你应该稍微修改一下。

在您的 main 函数中的 if (check_authentication(argv[1])) 行之前添加以下行。

char password[16];
printf("Password: ");
fgets(password, 16, stdin);

if (check_authentication(argv[1])) 行替换为if (check_authentication(password))

并删除或注释掉以下行:

if (argc < 2)
{
    printf("Usage: %s <password>\n", argv[0]); exit(0);
}

最后,请不要忘记在每次fgets 调用后删除换行符。 Removing trailing newline character from fgets() input

【讨论】:

    猜你喜欢
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-22
    相关资源
    最近更新 更多