【问题标题】:"/usr/bin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";?"/usr/bin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";?
【发布时间】:2015-02-26 15:11:59
【问题描述】:

我在 unix 版本 6 的 if.c 中找到了这一行。

ncom = "/usr/bin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

为什么有这么多x? 为什么要设置这个?

【问题讨论】:

    标签: command c


    【解决方案1】:

    您所说的代码如下所示:

    ncom = "/usr/bin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    while(c=nargv[0][i])  {
        ncom[9+i++] = c;
    }
    ncom[9+i] = '\0';
    

    所有这些 x 都充当缓冲区,它们被以下循环覆盖。 因此代码有效地将“/usr/bin/”添加到nargv[0] 中的命令中。

    有了更多的上下文,代码就是这样做的:

    execv(nargv[0], nargv, np);
    execv(ncom+4, nargv, np);
    execv(ncom, nargv, np);
    

    如果nargv[0] 中的给定命令是"foo",它将首先尝试运行"foo",然后是"/bin/foo",最后是"/usr/bin/foo"


    请注意,上面是一个很好的例子,如何做这样的事情:

    如果nargv[0] 中的字符串恰好比x 的个数长,代码将愉快地继续复制数据。这将覆盖堆栈的其他部分。结果是缓冲区溢出的一个很好的例子。 (您分配了一些大小的缓冲区并写入了比分配更多的数据。)

    这个例子将演示这个问题:

    #include <stdio.h>
    int main(){
      char s[]="abcde";
      int i;
      for(i=0;i<100;i++){
        printf("position %2d contains value %3d\n",i,s[i]);
        s[i]=0;
      }
      puts(s);
      return 0;
    }
    

    如果你运行它,它(很可能)会输出这个:

    position  0 contains value  97
    position  1 contains value  98
    position  2 contains value  99
    position  3 contains value 100
    position  4 contains value 101
    position  5 contains value   0
    position  6 contains value   0
    position  7 contains value   0
    position  8 contains value   0
    position  9 contains value   0
    position 10 contains value   0
    position 11 contains value   0
    position 12 contains value  12
    position  1 contains value   0
    position  2 contains value   0
    position  3 contains value   0
    position  4 contains value   0
    position  5 contains value   0
    position  6 contains value   0
    position  7 contains value   0
    [...]
    

    它将用零填充字符串(包含 ASCII 值 97 到 101)并继续写入内存,它将找到变量 i 的位置,它还将它设置为零。现在i 为零,因此循环再次开始,一次又一次地覆盖已经覆盖的字符串。

    不仅局部变量可以被覆盖,函数的返回地址也可能被覆盖,导致“分段错误”或执行任意代码,这通常被恶意软件使用。

    【讨论】:

    • 为什么是 +9 和 +4?谢谢你 michas :)
    • 数字是字符串中的位置:“/usr”是4个字符。 “/usr/bin/”是 9 个字符。
    • 如果我们需要尝试运行名称超过 35 个字符的命令怎么办?
    • 更不用说,ncom 指向一个 字符串文字,然后对其进行修改 - 现代 C 中的一个大禁忌,其中字符串文字通常被存储在只读存储器中。
    • 虽然这里的ncom 代码不是一个好的防御性编程示例,但实际上该字符串足够长,用户可以正确使用该程序,因为在 V6 中,您永远不需要运行长度超过 14 个字符的无路径名命令(命令名称中某处没有“/”字符的命令),因为这是目录中最长的条目。使用不当,估计会覆盖libc使用的数据。
    猜你喜欢
    • 2013-04-22
    • 2014-08-05
    • 2011-05-21
    • 2014-12-17
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2021-05-07
    • 2018-01-15
    相关资源
    最近更新 更多