QA测试:该Bash脚本是否存在命令注入漏洞?
我正在对同事开发的Bash脚本进行QA测试,脚本内容如下:
#!/bin/bash TERM=`cat ./termName.txt` || exit $? ./other-script.sh $TERM由于最后一行的TERM变量未加引号,我认为恶意用户可通过篡改termName.txt文件内容实施命令注入,但初步尝试未能成功注入可执行命令。我的问题:
- 该脚本是否存在命令注入漏洞?
- 若存在,请给出执行任意命令的示例;若不存在,请说明安全原因。
让我来帮你拆解这个问题:
1. 该脚本确实存在命令注入漏洞
问题的核心在于没有用双引号包裹$TERM变量。在Bash的语法规则里,未加引号的变量会触发一系列危险的解析行为:
- 按空格、制表符或换行符拆分内容为多个独立参数
- 解析通配符(比如
*会匹配当前目录下的所有文件) - 执行命令替换(
$()或反引号包裹的内容)和算术运算
这就给了恶意用户可乘之机——只要能篡改termName.txt,就能插入Bash能识别的元字符,把原本的参数变成独立的执行命令。
2. 成功注入任意命令的示例
你初步尝试失败可能是因为注入的格式没踩中Bash的解析点,下面几个例子能直接触发命令执行:
示例1:用分号分割独立命令
在termName.txt里写入:
test; id
脚本执行时,$TERM会被展开成test; id,Bash会把它拆成两个命令执行:
./other-script.sh test; id
先运行other-script.sh并传入test参数,紧接着就会执行id命令(输出当前用户的UID、GID等身份信息)。
示例2:用命令替换直接嵌入命令
在termName.txt里写入:
dummy $(whoami)
展开后的命令变成:
./other-script.sh dummy $(whoami)
Bash会先执行whoami,把输出结果作为第二个参数传给other-script.sh。如果想让注入的命令完全脱离other-script.sh的上下文,也可以这么写:
dummy; rm -rf /tmp/test_demo_file
这会在other-script.sh执行完成后,自动删除/tmp/test_demo_file(注意:仅作演示,请勿在生产环境测试破坏性命令)。
示例3:用&&串联命令(条件执行)
在termName.txt里写入:
valid_input && echo "Injected command ran successfully"
展开后:
./other-script.sh valid_input && echo "Injected command ran successfully"
只有当other-script.sh valid_input执行成功(返回码为0)时,才会执行后面的echo命令,适合用来验证注入是否生效。
快速修复方案
要彻底堵上这个漏洞,只需要给$TERM加上双引号,让Bash把它当成单个完整参数传递,避免解析元字符:
./other-script.sh "$TERM"
另外,建议用$()代替老式的反引号`来执行命令(可读性更强,还支持嵌套):
TERM=$(cat ./termName.txt) || exit $?
内容的提问来源于stack exchange,提问作者Chris Knight

