You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

bash空字节输入警告与格式化字符串漏洞C程序技术咨询

嘿,我来帮你搞定这两个问题——先解决bash的空字节警告,再分析修复那个C程序的漏洞:

1. 解决bash的“忽略输入中的空字节”警告

这个警告的根源是bash不支持命令行参数里包含空字节(\x00):C语言里的字符串是以空字节作为结束标志的,bash处理命令行参数时,会把空字节当作参数的终止符,同时抛出警告告诉你它忽略了空字节后面的内容。

解决方法分两种场景:

  • 如果只是测试格式化字符串漏洞,不需要用到空字节:那只要避免在输入里加入\x00即可,警告会自动消失。
  • 如果确实需要传递包含空字节的参数(比如复杂漏洞利用场景):直接用bash传参做不到,得绕开bash的参数解析。比如用Python的subprocess模块直接调用程序,这样可以传递包含空字节的字节数组:
import subprocess
# 构造带空字节的测试参数,比如 b"test\x00%x%x"
subprocess.run(["./your_program_name", b"test\x00%x%x"])

或者用Perl:

use IPC::Cmd qw(run);
run ["./your_program_name", "test\x00%x%x"];

这种方式不会经过bash的命令行处理,自然不会触发警告。

2. 分析并修复C程序的格式化字符串漏洞

先看你的代码,核心问题出在这一行:

printf(text);

漏洞分析

printf的第一个参数是格式字符串,当你把用户可控的内容(这里是argv[1],也就是用户输入的命令行参数)直接作为格式字符串时,攻击者可以构造恶意输入做两件坏事:

  • 信息泄露:比如输入%x%x%x%x,printf会从栈上读取额外的4个整数并打印出来,攻击者可以用这个方式泄露栈上的敏感信息(比如函数返回地址、栈内变量值)。
  • 内存写入:如果输入包含%n占位符,printf会把已经打印的字符数写入到对应指针指向的内存地址。结合其他占位符,攻击者可以修改程序里的变量(比如你代码里的test_val静态变量),甚至篡改函数返回地址来执行恶意代码。

而代码里已经给出了正确的写法:

printf("%s", text);

这里%s告诉printf把text当作普通字符串输出,不管里面有什么占位符,都会原样打印,完全规避了格式化字符串风险。

另外,你的代码还有一个潜在的缓冲区溢出漏洞:

strcpy(text, argv[1]);

如果用户输入的字符串长度超过text的大小(1024字节),strcpy会把超出的部分写到text后面的内存区域,可能覆盖栈上的关键数据(比如返回地址),导致程序崩溃或被利用。

修复方案

  1. 彻底修复格式化字符串漏洞:永远不要让用户可控内容成为printf(或sprintf、fprintf等格式化函数)的第一个参数。所有输出用户输入的场景,都要用%s占位符:
    把printf(text);替换成printf("%s", text);。
    如果需要混合固定文本和用户输入,比如加前缀,应该写成:

    printf("User input: %s\n", text);
    
  2. 修复缓冲区溢出漏洞:把不安全的strcpy换成strncpy并手动添加字符串结束符,或者更省心的snprintf:
    用strncpy的写法:

    strncpy(text, argv[1], sizeof(text) - 1);
    text[sizeof(text) - 1] = '\0'; // 确保字符串以空字节终止
    

    用snprintf的写法(更简洁安全):

    snprintf(text, sizeof(text), "%s", argv[1]);
    

    这两种方式都会限制复制的字符数,避免溢出。

内容的提问来源于stack exchange,提问作者J0rdan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:37:13