Brainfuck Writeup - HackTheBox
Brainfuck is an insane-rated Linux box built around a credential chain rather than a single exploit. An unauthenticated WordPress plugin bug hands over admin access, admin access leaks an SMTP password, the SMTP password opens a mailbox with forum credentials, the forum hides an SSH key behind a Vigenère cipher, and the home directory contains the RSA parameters needed to decrypt the root flag without ever getting a root shell.
Reconnaissance
Port scan
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.1 25/tcp open smtp Postfix smtpd 110/tcp open pop3 Dovecot pop3d 143/tcp open imap Dovecot imapd 443/tcp open ssl/http nginx 1.10.0 (Ubuntu) |_http-title: Brainfuck Ltd. - Just another WordPress site |_http-generator: WordPress 4.7.3 | ssl-cert: Subject: commonName=brainfuck.htb | Subject Alternative Name: DNS:www.brainfuck.htb, DNS:sup3rs3cr3t.brainfuck.htb
The SSL certificate's SAN field leaks a hidden vhost: sup3rs3cr3t.brainfuck.htb. Add both names:
WordPress fingerprinting
WordPress[4.7.3], Email[orestis@brainfuck.htb], nginx[1.10.0]
Valid email address confirmed: orestis@brainfuck.htb. Run WPScan to enumerate plugins:
[+] WordPress version 4.7.3 (Insecure, released 2017-03-06) [+] wp-support-plus-responsive-ticket-system | Version: 7.1.3
wp-support-plus-responsive-ticket-system 7.1.3 is vulnerable to an unauthenticated admin login bypass documented at https://www.exploit-db.com/exploits/41006.
Initial Access
WordPress admin bypass
The plugin exposes an admin-ajax.php action (loginGuestFacebook) that logs in as any existing user given only a username, with no password check:
The response sets a valid authenticated session cookie for admin. Use it to browse the WordPress dashboard. A "Dev Update" post references SMTP integration for orestis@brainfuck.htb, which points to the next credential.
SMTP credential leak via Settings
Under Settings > Easy WP SMTP, the password field is masked with type="password". Switching it to type="text" in browser dev tools reveals the stored cleartext value $ORESTIS_SMTP_PASSWORD.
POP3 mail enumeration
+OK Dovecot ready. USER $USER +OK PASS $ORESTIS_SMTP_PASSWORD +OK Logged in. LIST +OK 2 messages: 1 977 2 514 RETR 2
Message 2, from root@brainfuck.htb, subject "Forum Access Details":
Hi there, your credentials for our "secret" forum are below :)
username: orestis
password: $ORESTIS_FORUM_PASSWORD
Credential Chain
Hidden forum
Log into https://sup3rs3cr3t.brainfuck.htb as orestis with $ORESTIS_FORUM_PASSWORD. Two threads are visible. The general thread contains multiple posts from orestis, all signed with a consistent catchphrase in cleartext: "Orestis - Hacking for fun and profit". A second thread contains encrypted versions of that same phrase.
That repeating phrase is a known-plaintext attack surface for the Vigenère cipher. Aligning the known plaintext against the ciphertext and XOR-stepping through the alphabet at each position recovers the key: $VIGENERE_KEY.
Decrypt the secret post using any Vigenère tool (e.g. rumkin.com/tools/cipher/vigenere). The plaintext reveals a URL pointing to an SSH private key:
https://brainfuck.htb/8ba5aa10e915218697d1c658cdee0bb8/orestis/id_rsa
SSH key passphrase
Download the key and confirm it is passphrase-protected:
Enter passphrase for key 'id_rsa':
Crack it offline:
$ORESTIS_KEY_PASSPHRASE (id_rsa) 1g 0:00:00:17 DONE
orestis@brainfuck:~$
Shell as orestis. User access reached.
Privilege Escalation
RSA decryption from leaked parameters
The home directory holds three relevant files:
encrypt.sage generates a 1024-bit RSA keypair from random p, q, and e, reads /root/root.txt, encrypts it, and writes the ciphertext to output.txt and the parameters to debug.txt.
debug.txt contains the actual p, q, and e used.
output.txt contains the ciphertext.
Since all three RSA parameters are known, the private exponent d is recoverable directly via the extended Euclidean algorithm with no factoring attack required.
def egcd(a, b):
x, y, u, v = 0, 1, 1, 0
while a != 0:
q, r = b // a, b % a
m, n = x - u * q, y - v * q
b, a, x, y, u, v = a, r, u, v, m, n
gcd = b
return gcd, x, y
def main():
p = <value from debug.txt>
q = <value from debug.txt>
e = <value from debug.txt>
ct = <value from output.txt>
n = p * q
phi = (p - 1) * (q - 1)
gcd, a, b = egcd(e, phi)
d = a
pt = pow(ct, d, n)
print("pt:", pt)
if __name__ == "__main__":
main()
pt: 24604052029401386049980296953784287079059245867880966944246662849341507003750
Convert the decimal to hex and decode as ASCII:
The output is the root flag. Root access reached without requiring a root shell.
Related
References
-
Unauthenticated privilege escalation in wp-support-plus-responsive-ticket-system 7.1.3.
-
Crypto StackExchangeLINK: Crypto StackExchange, crypto.stackexchange.com/a/19530 (opens in new tab)
RSA private key reconstruction from known p, q, and e using the extended Euclidean algorithm.
-
Rumkin Vigenere ToolLINK: Rumkin Vigenere Tool, rumkin.com/tools/cipher/vigenere (opens in new tab)
Vigenere encryption and decryption used to recover the forum post plaintext.