【问题标题】:snprintf - security risksnprintf - 安全风险
【发布时间】:2013-04-16 09:33:08
【问题描述】:

unwindmy previous question 的回答引出了我另一个问题。我曾经问过关于

的问题
const char *INTERFACE        = "wlan0";
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), INTERFACE);

unwind回复为

值得警告,因为它可能存在安全风险,如果字符串参数在运行时可更改,则 % 可能会“潜入”,这将导致问题。因此,最好将格式化字符串硬编码为“做你想做的事”。

我想知道如何在运行时更改字符串参数?

编辑:为了更清楚,谁能给我一个例子,如何在运行时更改字符串参数?

【问题讨论】:

    标签: c linux security posix printf


    【解决方案1】:

    unwind 无疑是指INTERFACE 变量。

    如果出于某种原因你问用户他们应该使用哪个界面(使用类似fscanf() 的东西到可写缓冲区中)并且他们输入"wlan0 %s",那么所有的地狱都可能会崩溃,因为你会遇到这样的情况重新有效执行:

    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "wlan0 %s");
    

    带有 no 额外参数,对应于格式字符串中的 %s

    防止这种情况的方法是使用:

    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", INTERFACE);
    

    这样篡夺INTERFACE 的人除了更改ifr.ifr_name 中的内容外,不会对该声明产生任何影响。

    在您的特定情况下:

    #include <stdio.h>
    #include <net/if.h>
    #include <string.h>
    
    int main(int argc,char *argv[]){
        const char *INTERFACE        = "wlan0";
        struct ifreq ifr;
    
        memset(&ifr, 0, sizeof(ifr));
        snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), INTERFACE);
    
      return 0;
    }
    

    您仍然可以完全控制 INTERFACE,因此没有危险,但编译器没有进行该级别的分析 - 它只知道非文字格式字符串是一种风险。

    【讨论】:

    • 感谢您的澄清。如果我误解你,你能纠正我吗,在运行时更改字符串参数INTERFACE的唯一方法是,只有程序要求用户输入字符串值,否则不可能做一些黑客然后在运行时更改参数
    • @sven,有很多个攻击向量,用户输入就是其中之一。可能有一些方法可以在进程运行时附加到进程并修改它的内存,或者在它运行之前修改可执行文件中的字符串,或者使用输入缓冲区溢出到一个完全不相关的变量中来影响 INTERFACE。可能性肯定比你(或我)一个人能想到的要多:-)
    • @paxdiablo:如果有人可以在进程运行时攻击进程并修改内存,则该进程已经拥有。这不是攻击媒介。
    猜你喜欢
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    • 2011-09-14
    • 2010-11-24
    • 2013-07-07
    • 2012-08-17
    • 2017-08-07
    • 2017-06-09
    相关资源
    最近更新 更多