BrainFuck HTB
Brainfuck HTB Objective Brainfuck is an old, well-known HTB box, and it earns its reputation. The path runs through a WordPress authentication bypass, an email account, a custom Vigenère cipher hidden in forum posts, an encrypted SSH key, and finally a hand-rolled RSA implementation with weak key generation. Nothing about this box hands you anything, every step has to be worked out. Enumeration Nmap Scanning Nmap Scan Analysis | Port | Service | |------|---------| | 22 | SSH | | 25 | SMTP | | 110 | POP3 (Dovecot) | | 143 | IMAP (Dovecot) | | 443 | HTTPS - nginx | A full mail stack alongside a web server is a strong hint that email access is going to matter somewhere in this chain. The SSL certificate also leaks a second hostname in its Subject Alternative Name field: sup3rs3cr3t.brainfuck.htb, worth remembering for later. Enumerating the Website Brainfuck homepage A basic page announcing it's "just another WordPress blog," with a username sitting right on the page: [email protected]. Ran a WPScan against it to see what's actually installed. The WP Support Plus Responsive Ticket System plugin, version 7.1.3, has a known authentication bypass: exploit-db 41006 WordPress Authentication Bypass The plugin had a feature for Facebook-based guest login that trusted the client too much. Built the PoC form for it: Here's how it actually works: the plugin's loginGuestFacebook AJAX action was meant to log a user in automatically after a legitimate Facebook OAuth handshake, trusting that only Facebook's own callback could trigger it with a valid username. The bug is that the endpoint never actually verified any Facebook token, it just took whatever username value was POSTed and logged that account in directly, no password, no verification step at all. So submitting this form with any known WordPress username is enough to get authenticated as that user. Filled in the username we'd already found, [email protected], and pointed the form's action at the real target. Served the PoC locally: Opened http://127.0.0.1:8000/poc.html in the browser: PoC form loaded locally Also worth trying with admin, the username WPScan had already confirmed existed on the site: Admin username from WPScan Submitting the form should return 0 as the raw AJAX response, which is this particular endpoint's way of saying "handled successfully" even though it looks like a failure code at first glance. Opened a new tab to https://brainfuck.htb afterward: Logged in as admin Logged in as admin, no credentials needed. Finding SMTP Credentials With admin access to the WordPress dashboard, went to Brainfuck Ltd. (top left) → Themes → Installed Plugins, and found an SMTP plugin. Opening its configure screen and checking the page in the browser's inspect tab revealed the stored password in the form field. SMTP plugin configuration revealing password Username: orestis Password: kHGuERB29DNiNE Accessing the Mail Server With SMTP and IMAP both open on the box per the nmap scan, these credentials were worth trying directly against the mail server. Used Evolution as a mail client for this. Evolution mail client Configured the account with the target's details: Account configuration Set security to "No encryption" since this is an old box without TLS configured on the mail services, then entered the password when prompted. The mailbox connected successfully. Mailbox connected One of the emails contained a hint that the credentials were meant for "secret" access, pointing straight at the second vhost from the SSL certificate earlier: sup3rs3cr3t.brainfuck.htb. Email hint about secret subdomain The Secret Subdomain Browsing to sup3rs3cr3t.brainfuck.htb presented a login page, and the same SMTP credentials worked there too. Login to secret subdomain Inside, three forum-style posts. Three forum posts Reading through them, the discussion was about an SSH key, and every post from Orestis ended with the same fixed signature: "Orestis - hacking for fun and profit." That consistent phrase turned out to be the key to breaking the encryption used elsewhere on the site. Consistent signature across posts Opening the admin profile page showed a block of encrypted text, a chat-looking conversation that needed decrypting. Encrypted text on admin profile Breaking the Vigenère Cipher Since the signature phrase appears in plaintext in every forum post, and encrypted text using the same phrase showed up elsewhere on the site, this is a known-plaintext situation. Having both the ciphertext and the plaintext for the same string is exactly what's needed to recover a Vigenère key, since a Vigenère cipher just shifts each plaintext letter by a fixed amount determined by the corresponding key letter. Subtracting plaintext from ciphertext, letter by letter, hands back the key stream directly. Wrote a script to derive the key from this pair, find the shortest repeating pattern in the recovered key stream, and verify it against the known plaintext: The script correctly derives a repeating key stream, but since a Vigenère key can be read starting from any point in that repeating pattern, the rotations needed checking by hand. After trying them, the real key turned out to be FUCKMYBRAIN, fitting with the box's name and tone. Decrypting with the correct key Used cryptii's Vigenère cipher tool to decrypt the full encrypted URL from the admin profile with the confirmed key. That gave: Visiting that URL downloaded an id_rsa private key file directly. id_rsa download confirmation Cracking the SSH Key Passphrase The private key is passphrase-protected. Used ssh2john to convert it into a crackable hash format, then ran it through John with rockyou. Passphrase: 3poulakia! SSH Access Logged in as orestis. User Flag Privilege Escalation Some files in the home directory stood out immediately. output.txt: encrypt.sage: debug.txt: This is a custom RSA setup, the sage script encrypts root's password using the exact textbook RSA formula: generate two primes p and q, compute n = pq, pick a public exponent e, and encrypt with c = m^e mod n. The catch is that debug.txt leaks p, q, and e directly, the exact values that are supposed to stay private. With those three numbers exposed, computing the private exponent d and decrypting the ciphertext is a completely standard RSA operation. This is a textbook demonstration of why RSA's security depends entirely on keeping the prime factors secret, if an attacker has p and q, the "encryption" provides no protection at all. (Background on how the math behind this works: RSA cryptosystem overview)) Wrote a script to reconstruct the private key from the leaked primes and decrypt the ciphertext: That decrypted value is root's flag directly, since the script encrypted the contents of /root/root.txt itself as the "password." Root Flag Final Thoughts Brainfuck earns its difficulty rating honestly. Nothing about this box is a single exploit chain, it's a long sequence of small discoveries that only make sense once you've already found the next piece. The WordPress auth bypass was almost too easy by comparison, a plugin trusting a client-supplied username with zero verification behind it. The part that really stuck with me was the Vigenère cipher. Spotting that the same signature phrase appeared both encrypted and in plaintext, and realizing that was enough to recover the entire key, felt like actual cryptanalysis instead of just running a tool. Writing the script to derive the key stream and then manually working through the rotations to land on the real key was slow, but it's the kind of exercise that actually teaches you how the cipher works instead of just decrypting a string and moving on. The RSA privesc at the end was a nice callback to the same theme. It looks intimidating with giant prime numbers sitting in a debug file, but once you realize those primes were never supposed to be exposed in the first place, the whole thing collapses into a handful of lines of Python. A good reminder that RSA's entire security model lives or dies on keeping p and q secret. This box rewards patience more than skill. Every step gives you exactly what you need to find the next one, you just have to actually read everything carefully. See you in the next writeup. Until then, keep enumerating and stay curious. By Madhav ```