A few days ago, HackTheBox updated the list of available retired boxes, deactivating some while re-activating others. One of the boxes they reactivated happened to be the second box in my list of OSCP-Like Linux systems, affectionately named “Brainfuck.” With such a monicker, I assumed this machine would be quite challenging, and based on the reviews by other users who had completed the challenge, it seemed my predictions were correct:
I also saw that Brainfuck was considered a more “CTF-Like” system than the boxes I’d targeted so far:
For those of you who aren’t a part of the hacker/gamer crowd, “CTF” stands for Capture the Flag. Capture the Flag began as an outdoor game wherein two opposing teams attempted to defend their “home base” while also trying to infiltrate their opponent’s base and steal their flag. This game was later adapted into computer games, where users could play against each other on the internet in virtual arenas. Most recently, this game was adopted by hackers and became an incredibly popular competitive sport at hacker conventions and online.
In a hacker CTF, a computer is configured with certain vulnerabilities, such as outdated software or weak passwords, and “flags” are planted on the system in various places, each worth a different number of points based on the difficulty of collecting each flag. Hackers compete against each other to try to hack into the machine and collect the flags, aiming to be the first to collect all the flags and/or achieve the highest score.
Hacker CTFs are often more tricky than what you might find “in the wild,” as they’re designed to be more like a game than a real-world simulation. With that in mind, when I saw that Brainfuck was more “CTF-Like” than some the previous systems I’d attacked, I figured I was in for quite a challenge. (After all, they wouldn’t call it “Brainfuck” for nothing.)
I started this challenge as I always do, by scanning the target IP with
nmap to see what services were running and look for possible avenues of attack. I executed my typical script scan using
nmap -A 10.10.10.17 and also performed a UDP scan with
nmap -sU 10.10.10.17. It would be helpful to do a full-range TCP scan as well, but that scan would take longer, so I went for the faster scans first, so I could start working on those results before the full-range scan came back. When I received the results of my script-scan, I found a few points of interest:
root@kali:~# nmap -A 10.10.10.17 Starting Nmap 7.70 ( https://nmap.org ) at 2019-04-22 20:30 EDT Nmap scan report for 10.10.10.17 Host is up (0.068s latency). Not shown: 995 filtered ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.1 (Ubuntu Linux; protocol 2.0) [...] 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: CAPA USER SASL(PLAIN) AUTH-RESP-CODE UIDL TOP RESP-CODES PIPELINING 143/tcp open imap Dovecot imapd |_imap-capabilities: more IMAP4rev1 Pre-login IDLE AUTH=PLAINA0001 LITERAL+ have OK post-login ENABLE capabilities listed ID LOGIN-REFERRALS SASL-IR 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 [...] Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port [...] Service Info: Host: brainfuck; OS: Linux; CPE: cpe:/o:linux:linux_kernel [...] OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 53.69 seconds
The first thing I noticed was that while port 80 wasn’t open, port 443 (HTTPS) was, and it was running
nginx 1.10.0. I also noticed that nmap had returned a few interesting DNS entries. It’s not uncommon for HTB machines to use the
.htb Top-Level Domain (TLD), and sure enough, this machine identified itself as
brainfuck.htb in its SSL certificate. However, it also had entries for
sup3rs3cr3t.brainfuck.htb, the latter of which I was most interested in. Based on the results, it appeared as if the HTTPS server returned the default nginx welcome page, since the title of the page was
Welcome to nginx! However, it was quite possible that browsing to the page with one of the specified domains would return different results.
After starting the full-range SYN scan using
nmap -sS -p- 10.10.10.17, I checked on my UDP scan to see if it had finished. Sure enough, it had, but there were no interesting results. I decided to go ahead and check the website to see if my suspicions were correct. I edited my
/etc/hosts/ file to set the IP address for
brainfuck.htb, then opened my browser and visited
What I found was a WordPress page, with a single post that mentioned SMTP integration and listed an email address:
firstname.lastname@example.org. I saved the username
orestis in a file called
usernames.txt in case I needed to use it for brute-forcing the open SSH service later. I also added
admin to the user list, since the post itself was made by a user named
Since this was a WordPress installation, I knew there would be a login page at
https://brainfuck.htb/wp-login.php, so I went there to check it out. It was as I expected, a basic WordPress login page:
Looking at the page source, I saw that this appeared to be WordPress version 4.7.3:
I made a note to check for vulnerabilities in this version of wordpress, but I first wanted to see if there was something interesting at
sup3rs3cr3t.brainfuck.htb. As before, I had to add an entry to the
/etc/hosts file, but with that completed, I directed my browser to open
https://sup3rs3cr3t.brainfuck.htb/, where I found a Super Secret Forum:
In the source code to this page, I found multiple references to
flarum, which sounded to me like the name of a forum software. Sure enough, a quick Google search led me to the Flarum Homepage, with the tagline “Forums made simple.” I added another note to check for vulnerabilities in the Flarum software, but first I would need to look for version information and investigate the rest of the site to see what other information I might uncover.
While I wasn’t able to find any obvious version information, I was able to see that the usernames
orestis had both been used on the forums, further reinforcing my belief that they might be usernames worth investigating.
I took a moment to re-visit the Flarum Homepage, where I saw a Documentation page. There was a section called “Troubleshooting,” where I found that Flarum records its logs in
storage/logs/flarum.log, so I checked the
/storage/logs/ directories, both of which returned 403 Forbidden errors. But sure enough, when I checked
/storage/logs/flarum.log, it prompted me to download a file. I saved the file and browsed the logs, noticing that there were some problems with the Zend framework. There were a few lines mentioning errors in a file called
DispatchRoute.php, so I opened that script in my browser and got an error message saying “No input file specified.” If the script required a file as input, could I abuse that to execute malicious code somehow? I made a note to check it out.
There were many other files mentioned in the
flarum.log file, most related to the Zend framework. I made another note to check on this framework to see if there were any vulnerabilities, and wrote a quick script to parse the log for a list of PHP files mentioned in the log. It returned the following entries, all located in the web server’s root directory (
root@kali:~# cat urls.txt | sed 's/\/var\/www//g' /secret/admin.php /secret/index.php /secret/vendor/flarum/core/src/Admin/Middleware/RequireAdministrateAbility.php /secret/vendor/flarum/core/src/Core/Access/AssertPermissionTrait.php /secret/vendor/flarum/core/src/Http/AbstractServer.php /secret/vendor/flarum/core/src/Http/Middleware/AuthenticateWithSession.php /secret/vendor/flarum/core/src/Http/Middleware/DispatchRoute.php /secret/vendor/flarum/core/src/Http/Middleware/ParseJsonBody.php /secret/vendor/flarum/core/src/Http/Middleware/RememberFromCookie.php /secret/vendor/flarum/core/src/Http/Middleware/SetLocale.php /secret/vendor/flarum/core/src/Http/Middleware/StartSession.php /secret/vendor/zendframework/zend-diactoros/src/Server.php /secret/vendor/zendframework/zend-stratigility/src/Dispatch.php /secret/vendor/zendframework/zend-stratigility/src/MiddlewarePipe.php /secret/vendor/zendframework/zend-stratigility/src/Next.php
I browsed to
https://sup3rs3cr3t.brainfuck.htb/secret/index.php and again received the “No input file specified” error. The same happened when I visited
/secret/admin.php. I decided to put this route of inquiry aside, and see if there were any known exploits for the services I’d uncovered so far.
As usual, I turned to
searchsploit to help me find applicable exploits to known services. I found a couple interesting results, but nothing I could truly leverage. I discovered that the OpenSSH 7.2p2 service was vulnerable to a username enumeration attack, but after attempting to use this vulnerability to verify the usernames I’d saved in my
usernames.txt file, I found that the enumeration was unreliable. (I would later discover that this was likely due to the fact that OpenSSH had been configured to disallow password-based logins.)
I also found a couple vulnerabilities in the Zend framework, but nothing I could use right away.
After an hour and a half of browsing through searchsploit results, I felt I’d been chasing after phantoms. Nothing seemed to jump out at me.
I decided that perhaps I needed a little more enumeration. I saw that the Postfix SMTP server had the
VRFY option enabled, which would allow me to check whether users were registered with the email system. I logged in and requested some information:
root@kali:~# telnet 10.10.10.17 25 Trying 10.10.10.17... Connected to 10.10.10.17. Escape character is '^]'. HELO brainfuck.htb 220 brainfuck ESMTP Postfix (Ubuntu) 250 brainfuck VRFY root 252 2.0.0 root VRFY admin 550 5.1.1 <admin>: Recipient address rejected: User unknown in local recipient table VRFY orestis 252 2.0.0 orestis ^] telnet> q Connection closed.
Based on this response, I could see that the
orestis user was registered to the mail system, but the
admin user was not. This suggested that the
orestis user would be more likely to have an SSH account as well.
Deciding to scan the web server for interesting directories, I fired up
dirbuster and set it to scan
https://sup3rs3cr3t.brainfuck.htb/ to see what information it could dig up. Meanwhile, I checked up on the full-range nmap scan I’d started earlier, only to find that there were no additional ports that weren’t already in my previous search. So I turned back to
searchsploit to see if I could find anything relating to
dovecot while dirbuster was doing its work.
I found a reference to
Shellshock, and decided to check it out. I didn’t know what version of Postfix was running, so it was a shot in the dark, but I figured it couldn’t hurt to try. I copied the script to my local folder with
searchsploit -m exploits/linux/remote/34896.py, renamed the file to
shellshock_smtp.py, and took a look.
root@kali:~# python shellshock_smtp.py shellshock_smtp.py <target> <command>
Simple enough. I just needed a way to test whether it would work. I opened
wireshark and set it to monitor my HackTheBox VPN connection for ICMP ping packets. First, I tested to make sure wireshark was working by pinging the target machine with
ping -c3 10.10.10.17. Sure enough, the traffic appeared in wireshark:
It was time to test out the Shellshock script.
root@kali:~# python shellshock_smtp.py 10.10.10.17 "ping -c 3 10.10.14.8"
I watched as the request was sent and accepted by the remote SMTP server. I waited for those incoming ICMP packets… And nothing came. It appeared as if Shellshock wouldn’t work. I set the script aside and moved on.
I went online and searched for “WordPress vulnerabilities” and after some searching discovered a tool I hadn’t heard of before called wpscan, which (lucky me) was included with Kali. I set it to scan the target site, then went back to dirbuster to see what it had found. Unfortunately, it hadn’t found much on the sup3rs3cr3t subdomain, so I started it up again scanning the base
brainfuck.htb domain. Then I turned back to
wpscan. It returned a pretty long list of results, including a few interesting potential exploits. Most of them seemed to require authentication or were XSS attacks, neither of which would be of much use to me. I noticed, however that wpscan had identified a plugin:
WP Support Plus Responsive Ticket System. I remembered seeing some plugins listed when I did my
searchsploit scan, so I went back and repeated the search, targeting
WP Support Plus:
root@kali:~# searchsploit wordpress 7.1 wp support plus --------------------------------------- ---------------------------------------- Exploit Title | Path | (/usr/share/exploitdb/) --------------------------------------- ---------------------------------------- WordPress Plugin WP Support Plus Respo | exploits/php/webapps/40939.txt WordPress Plugin WP Support Plus Respo | exploits/php/webapps/41006.txt --------------------------------------- ---------------------------------------- Shellcodes: No Result Papers: No Result
There were two results, a privilege escalation (privesc) and an SQL injection (SQLi). I decided to check them both out, so I copied them to my local folder and read their contents. I expected that the privesc attack wouldn’t be of much use, since it would typically require me to be logged in as a user, but perhaps the SQLi would be useful.
The SQLi exploit included a proof-of-concept (PoC) in the form of an HTML form that could be included on the page. To test this out, I used Firefox’s developer tools to edit the HTML of the page in-place, replaced the content of the post with the form, and clicked the submit button.
After submitting the form, the response I got was underwhelming… It was simply the number
0, by itself, on the page. I tried a number of possible queries, but each time the result was simply
0. Some queries took longer than others, and I wondered if perhaps the queries were running successfully without returning visible results. So I tried a query to create an admin user in the database, as detailed in a tutorial I read. Then I attempted to login… With no success.
I’d been barking up the wrong tree yet again. This challenge was definitely living up to its name.
I decided to check out the second exploit, involving privilege escalation. As it happens, the exploit claimed to allow the attacker to log in as any user, without using any credentials. Worth a shot! So I went back to the WordPress page, once again edited the HTML to add the form specified in the exploit, and clicked submit. After the exploit was completed, I returned to the main page, and (much to my surprise), I was logged in as the admin!
Finally, I was one step closer to my goal. While it took a lot of searching, it felt good to have achieved something, no matter how small.
It was around this time that my internet connection died and I had to reboot and re-exploit the wordpress page. This wasn’t the first time I’d experienced such an issue, but it was frustrating that it had to happen right as I was making some progress. Before rebooting, I checked dirbuster; it hadn’t found anything of which I wasn’t already aware.
With admin access to the WordPress page, I proceeded to explore what new information was available to me. I went to the Plugins page and found that
Easy WP SMTP was installed, allowing users to send email via SMTP. I recalled some of the email vulnerabilities I’d seen prior, and decided to investigate whether I could abuse this service.
I went to the settings page for the Easy WP SMTP plugin, and found that there was a SMTP password field that had been auto-populated. By viewing the source code to the page, I was able to find the password entered therein:
kHGuERB29DNiNE. I added this to a
passwords.txt file for later, noting that the password had been assigned to the
orestis user for accessing SMTP. I also noticed that I could manually update the
From Email Address field, which meant that I might be able to exploit one of the vulnerabilities I’d seen before in order to get a shell.
But first, with a username and password combination in-hand, I decided to see if I could log into SSH:
root@kali:~# ssh email@example.com 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)? yes Warning: Permanently added '10.10.10.17' (ECDSA) to the list of known hosts. firstname.lastname@example.org: Permission denied (publickey).
It would seem that I could only gain access with orestis’ public key. I would either need to find a way to download the user’s key or upload one of my own. I made a note of it, and went back to investigating the SMTP exploit.
Unfortunately, the scripts I’d found didn’t work, and neither did any of my attempts to exploit the Easy WP SMTP plugin by hand. But I wouldn’t let this discourage me. With admin access to the WordPress page, I decided to see if it would be possible to upload a new plugin to the site. If so, I could upload a wordpress shell plugin and gain command-line access that way.
No such luck; the upload directory was restricted.
I decided to try accessing the user’s email account with an email client. I had the user’s credentials, after all. Perhaps there was some email stored that might offer me some insight?
I installed sylpheed, a lightweight email client, and logged into Orestis’ account, where I found two emails waiting for me. The first was about the WordPress site, telling me how to log in. What stood out to me, however, was the X-Mailer header, which specified that the email had been sent via
No wonder my previous exploit attempts hadn’t worked! The PHPMailer exploit I’d been using only worked for versions prior to 5.2.20. Returning to searchsploit, I checked for PHPMailer vulnerabilities, and discovered that none were applicable to the installed version.
Moving on, I checked the next email. It was a message regarding the secret forum, informing me of the admin username/password:
This password was probably randomly-generated, but I added it to my
passwords.txt file anyway. One step closer! It was time to log in to the forum and see what I could learn.
Accessing the forum with the username/password I’d learned from the email account, I was presented with some new forum topics:
First, I visited the
SSH Access thread, where I found the following discussion:
Just as I had discovered, the SSH password login had been disabled, and the only way to gain access was with SSH keys. Yet the thread where they discussed SSH keys was “encrypted”:
It looked like I had a crypto challenge on my hands. I noticed that every post made by Orestis had the tagline
Orestis - Hacking for fun and profit, and in the encrypted text there was a similar tagline after every post Orestis made, though the text was different in each one. Clearly it wasn’t a direct substitution cipher, so I went online and did some research regarding rolling ciphers, and stumbled upon the Vigenere Cipher, which was aptly explained on the dcode.fr website. With their handy decoder grid on-hand, I went to work reversing the key used to encrypt their text. Sure enough, I found the key:
FUCKMYBRAIN. Go figure. Here’s a transcript:
Orestis: Hey give me the url for my key bitch :) Orestis - Hacking for fun and profit Admin: Say please and i just might do so... Orestis: Pleeeease.... Orestis - Hacking for fun and profit Admin: There you go you stupid fuck, I hope you remember your key password because I dont :) https://10.10.10.17/8ba5aa10e915218697d1c658cdee0bb8/orestis/id_rsa Orestis: No problem, I'll brute force it ;) Orestis - Hacking for fun and profit
Right away I copy-pasted the URL into my browser and downloaded the
id_rsa file and put it in my
~/.ssh directory. As Orestis had stated, I still didn’t have the password for the key, so I would have to brute-force it. First things first, though; I wanted to set up my
~/.ssh/config file so that I would automatically use the key when logging in to the remote host. I created the file and configured it as follows:
root@kali:~/.ssh# cat config Host brainfuck.htb Hostname brainfuck.htb Port 22 User orestis IdentityFile ~/.ssh/id_rsa
Before I could use the key, I needed to change its permissions, so I ran
chmod 700 ~/.ssh/id_rsa to ensure they were set properly. With that done, I needed to find a way to brute-force the passphrase. Looking online, all the guides I found used a tool called
ssh2john to convert the SSH key into a format readable by
John the Ripper, but unfortunately this tool wasn’t available on Kali by default. After a little Googling, however, I was able to find the tool on github. With this tool, I was able to convert the key into a format that John could read:
root@kali:~/.ssh# ./ssh2john.py id_rsa > john.key
Now it was simply a matter of letting John do all the heavy lifting. I decided to start with a wordlist first, rather than a full brute-force attack, as it would be faster. I unzipped the
/usr/share/wordlists/rockyou.txt.gz file and used it as my wordlist:
root@kali:~/.ssh# gunzip /usr/share/wordlists/rockyou.txt.gz root@kali:~/.ssh# john --wordlist=/usr/share/wordlists/rockyou.txt john.key 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) 1g 0:00:00:10 DONE (2019-04-23 08:14) 0.09794g/s 1404Kp/s 1404Kc/s 1404KC/sa6_123..*7¡Vamos! Session completed
Much to my surprise, John seemed to find the password right away:
3poulakia! I attempted to SSH into the target system using the new-found password, and bingo! I had access:
root@kali:~# ssh brainfuck.htb Enter passphrase for key '/root/.ssh/id_rsa': 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:~$
Of course, at this point, my first action was to get the user flag:
orestis@brainfuck:~$ ls -l total 20 -rw------- 1 orestis orestis 619 Apr 29 2017 debug.txt -rw-rw-r-- 1 orestis orestis 580 Apr 29 2017 encrypt.sage drwx------ 3 orestis orestis 4096 Apr 23 13:43 mail -rw------- 1 orestis orestis 329 Apr 29 2017 output.txt -r-------- 1 orestis orestis 33 Apr 29 2017 user.txt orestis@brainfuck:~$ cat user.txt 2c11cfbc5b959f73ac15a3310bd097c9
With the user flag properly claimed, I felt exhausted. I’d spent hours getting to this point, and needed to take a break. I logged out of the system, disconnected from HTB, and shut down for the night.
(To see the thrilling conclusion, please read Part 2 of the walkthrough.)