【问题标题】:Lack of understanding of security engineering in simple C code缺乏对简单 C 代码中的安全工程的理解
【发布时间】:2020-05-01 14:47:41
【问题描述】:

我对 C 编程完全陌生。目前我正在为我的新课程 IT 安全做准备。在稍早的考试中,我发现了一项我无法解决的任务。任务是德语的。原则上,它是关于发现严重错误。

没有写传递的参数长什么样。

1) 我的意思是你不应该使用strcpy,因为它没有边界检查。

2) 如果要存储 10 个字符 (\0),则不应使用 char[10]。应该是 char[11]。

是否可以通过 printf(argv[1]) 命令读取地址或写入某事?

我想再次提一下,你个人在这里帮助我,而不是帮助在大学里收集积分。

#include <stdio.h>

int main(int argc, char *argv[])
{
    char code[10];

    if(argc != 2) return 1;
    printf(argv[1]);

    strcpy(code, "9999999999");
    for(int i = 0; i < 10; ++i){
        code[i] -= argv[1][i] % 10;
    }

    printf(", %s\n", code);

    return 0;
}

【问题讨论】:

  • 复制代码到问题中。
  • clang -Weverything为例进行编译。
  • 对于未来您可能会在此处发布的问题:请不要发布文字图片,将文字作为文字发布。如果你需要重新输入,那就去做吧。
  • @FiddlingBits code 被(错误地)初始化为strcpy
  • 而且使用strcpy并没有什么问题,只要确保目标缓冲区足够大。

标签: c security


【解决方案1】:

See related.

你不应该使用 strcpy() 因为它没有边界检查

C 中没有任何东西具有边界检查功能,除非

  • 编译器作者把它放在那里,

  • 你把它放在那里。

很少有编译器编写者在他们的产品中加入边界检查,因为这通常会导致生成的代码变得更大更慢。存在一些工具(例如 Valgrind, Electric Fence) 提供与边界检查相关的调试帮助,但由于它们施加的限制,它们通常不被合并到交付的软件中。

你绝对应该使用strcpy() if

  • 您知道您的来源是一个以 NUL 结尾的字符数组,也就是“字符串”,

  • 您知道您的目的地足够大,可以容纳所有源数组包括终止 NUL

因为允许编译器编写者使用编译器用户无法使用的幕后技巧,以确保strcpy() 具有最佳性能,同时仍提供标准所保证的行为。 p>

如果要存储 10 个字符 (\0),则不应使用 char[10]

正确。
要存储 10 个字符终止 NUL ('\0'),您必须至少有 11 个字符的可用空间。

是否可以通过 printf(argv[1]) 命令读取地址或写入某事?

原则上:也许。

printf() 的第一个参数是一个格式字符串,由printf() 解释以确定提供了哪些进一步的参数。如果格式字符串包含任何格式规范(例如"%d""%n"),那么printf() 将尝试检索相应的参数。 如果它们实际上没有传递给它,那么它会调用未定义的行为,这是不好的。 攻击者可以运行您的程序,并为其提供包含格式说明符的命令行参数,这将导致此类 UB。

使用printf() 打印这样的任意字符串的正确方法是printf("%s", argv[1]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    • 2012-08-01
    相关资源
    最近更新 更多