Nmap Results
# Nmap 7.93 scan initiated Sat Mar 18 19:43:18 2023 as: nmap -Pn -p- -A -T5 -oN scan.txt 10.10.10.17
Nmap scan report for 10.10.10.17
Host is up (0.012s latency).
Not shown: 65530 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 94d0b334e9a537c5acb980df2a54a5f0 (RSA)
| 256 6bd5dc153a667af419915d7385b24cb2 (ECDSA)
|_ 256 23f5a333339d76d5f2ea6971e34e8e02 (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: SASL(PLAIN) RESP-CODES PIPELINING CAPA TOP AUTH-RESP-CODE UIDL USER
143/tcp open imap Dovecot imapd
|_imap-capabilities: ENABLE ID IDLE more have AUTH=PLAINA0001 SASL-IR listed Pre-login capabilities post-login LITERAL+ IMAP4rev1 OK LOGIN-REFERRALS
443/tcp open ssl/http nginx 1.10.0 (Ubuntu)
|_http-title: Welcome to nginx!
|_ssl-date: TLS randomness does not represent time
| tls-nextprotoneg:
|_ http/1.1
| 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
|_http-server-header: nginx/1.10.0 (Ubuntu)
| tls-alpn:
|_ http/1.1
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.10 - 4.11 (92%), Linux 3.12 (92%), Linux 3.13 (92%), Linux 3.13 or 4.2 (92%), Linux 3.16 (92%), Linux 3.16 - 4.6 (92%), Linux 3.18 (92%), Linux 3.2 - 4.9 (92%), Linux 3.8 - 3.11 (92%), Linux 4.2 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Host: brainfuck; OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 443/tcp)
HOP RTT ADDRESS
1 11.41 ms 10.10.14.1
2 11.48 ms 10.10.10.17
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Mar 18 19:45:07 2023 -- 1 IP address (1 host up) scanned in 109.19 seconds
Service Enumeration
TCP/443
443/tcp open ssl/http nginx 1.10.0 (Ubuntu)
|_http-title: Welcome to nginx!
|_ssl-date: TLS randomness does not represent time
| tls-nextprotoneg:
|_ http/1.1
| 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
|_http-server-header: nginx/1.10.0 (Ubuntu)
| tls-alpn:
|_ http/1.1
Some immediate observations:
- The TLS cert has a CN of
brainfuck.htb
- There are two SANs:
www.brainfuck.htb
andsup3rs3cr3t.brainfuck.htb
Let's add those SANs to the /etc/hosts
file on our attack box.
sudo nano /etc/hosts
# HTB brainfuck
10.10.10.17 brainfuck.htb
10.10.10.17 www.brainfuck.htb
10.10.10.17 sup3rs3cr3t.brainfuck.htb
The reasoning behind this is that the web server running on TCP/443
on the target could be serving different applications and/or directories depending on the hostname
. This is known as virtual hosts.
Enumerate Virtual Hosts
Sure enough, this web server is serving applications by hostname. www.brainfuck.htb
redirects to brainfuck.htb
.
brainfuck.htb
orestis@brainfuck.htb
— This will likely come in handy for the mail services and potential bruteforcing. Looks like here, the blog user is admin
, orestis@brainfuck.htb
could be the admin user's email, but will enumerate some more.
Enumerate WordPress
Version
Plugins
This WordPress site is using a plugin called wp-support-plus-responsive-ticket-system
and is at version 7.1.3
.
Possible Exploits
I am going to copy both exploits to my current directory, so that I can inspect them further.
# Copies 40939.txt to $PWD
searchsploit -m 40939
# Copies 41006.txt to $PWD
searchsploit -m 41006
I felt like the details in the Exploit DB write-up were a bit inadequate to understand the exploit, so I found the researcher's blog with a more technical write-up.
This exploit requires a HTTP POST
request to https://brainfuck.htb/wp-admin/admin-ajax.php
with the form data shown in the Exploit DB (or blog) write-up.
This exploit works based on the functionality of loginGuestFacebook.php
. This PHP script is going to HTTP POST
with the form values shown in the exploit. The wp_set_auth_cookie()
function allows us to be authenticated to the WordPress site as long as we know two things:
- Username
- Email Address
I have a pretty good guess at this point about what those would be based on my enumeration.
- Username =
admin
- Email Address =
orestis@brainfuck.htb
Exploiting WordPress
Looking at this form from the exploit POC, it has four input points that we need to provide:
username
(change this)email
(change this)action
submit
I am going to save this form to pwn.html
and serve it using a Python HTTP server.
Now, in my browser, I am going to to http://127.0.0.1/pwn.html
, click Login
, and POST
it to the target PHP script. After that, I should be able to hit the admin panel.
More Enumeration
If we look at the plugins, we can see two are active. Let's check the settings on the SMTP plugin.
I bet I can catch that password if I listen on TCP/25
, point the SMTP Host to my IP address, and try sending a test email.
The stage is set. When ready, click the Send Test Email
button in the SMTP Settings interface.
Whew! We got a credential! orestis
kHGuERB29DNiNE
.
sup3rs3cr3t.brainfuck.htb
The password I obtained from the WordPress server did not work for the forum login, but it did allow me to map Orestis' mailbox from the IMAP server running on the target — see TCP/143 — where I was able to find a possible forum password. Let's see if it will let me in now.
Looking at the threads, SSH is key based only (no password logon — as I found out early on). The thread called, "Key" is "encrypted", but there are some decipherable aspects to the posts.
If I had to guess:
Pieagnm - Jkoijeg nbw zwx mle grwsnn
Wejmvse - Fbtkqal zqb rso rnl cwihsf
Qbqquzs - Pnhekxs dpi fca fhf zdmgzt
Orestis - Hacking for fun and profit
(Orestis' tagline seen in other posts)
mnvze://zsrivszwm.rfz
:https://brainfuck.htb
ub_sja
:id_rsa
Inspect Ciphers with CyberChef
Looking at the ciphertext, it looks like some kind of substitution cipher. But, it doesn't look like a simple Caesar cipher. I start off with a Vignere decoder and use Orestis
as the key, since there's not much else I know about the user.
Interesting that the first word almost spells Brainfuck
.
I put the first word from each of Orestis' encoded taglines into the decoder and I think I have an idea. I am going to try a key of fuckmybrain
.
Grab the SSH Private Key
I should be able to pull the SSH private key using cURL
.
curl -ks https://brainfuck.htb/8ba5aa10e915218697d1c658cdee0bb8/orestis/id_rsa -o ./orestis.key
cat orestis.key
chmod 600 ./orestis.key
The SSH encryption headers are embedded in the key file.
DEK-Info: AES-128-CBC,6904FEF19397786F75BE2D7762AE7382
We can use ssh2john
to create a hash file and attempt to crack it:
Nice! I should now be able to SSH into the target as orestis
using this SSH key.
ssh -i ./orestis.key orestis@10.10.10.17
TCP/143
The username and password I discovered on the WordPress site did not work as a login for sup3rs3cr3t
web server. So, I am going to try mapping Orestis' mailbox using the credential and the mutt
program.
I am using the sample IMAP configuration from the Debian wiki as a template for this one-off mailbox access, as mutt
will take a configuration file as an argument instead of using the default configuration paths.
We got another credential and this time it's for the forum! orestis
kIEnnfEKJ#9UmdO
.
Exploit
An out-of-date WordPress installation had installed an unpatched WP Support plugin which allows any user to authenticate as a valid user given they know the username and email of the account. Using this vulnerability, I was able to "pass back" the SMTP credentials of the administrative user, orestis
and access said user's mailbox.
In the mailbox was a password for another web account belonging to orestis
. I accessed this additional account and found a thread containing sensitive information using weak "encryption". I was able to reverse the encoded text and reveal a globally-readable SSH private key hosted on a web URL.
The SSH key file was password protected, but poorly so, as the password was cracked using a wordlist. Now in possession of the key file and the password, I was able SSH into the target as orestis
.
Post-Exploit Enumeration
Operating Environment
OS & Kernel
NAME="Ubuntu"
VERSION="16.04.2 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.2 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial
Linux brainfuck 4.4.0-75-generic #96-Ubuntu SMP Thu Apr 20 09:56:33 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Current User
uid=1000(orestis) gid=1000(orestis) groups=1000(orestis),4(adm),24(cdrom),30(dip),46(plugdev),110(lxd),121(lpadmin),122(sambashare)
Sorry, user orestis may not run sudo on brainfuck.
Users and Groups
Local Users
orestis:x:1000:1000:Orestis Makrogiannis,,,:/home/orestis:/bin/bash
Local Groups
orestis:x:1000:
Network Configurations
Interfaces
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:50:56:b9:ac:01 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.17/24 brd 10.10.10.255 scope global ens160
valid_lft forever preferred_lft forever
inet6 dead:beef::250:56ff:feb9:ac01/64 scope global mngtmpaddr dynamic
valid_lft 86400sec preferred_lft 14400sec
inet6 fe80::250:56ff:feb9:ac01/64 scope link
valid_lft forever preferred_lft forever
Open Ports
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
Interesting Files
/home/orestis/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')
/var/www/secret/config.php
<?php return array (
'debug' => true,
'database' =>
array (
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'forum',
'username' => 'forum',
'password' => 'hfieINFEIJncIldj',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => 'sf',
'strict' => false,
),
'url' => 'https://sup3rs3cr3t.brainfuck.htb',
'paths' =>
array (
'api' => 'api',
'admin' => 'admin',
),
);
Privilege Escalation
After some lengthy enumeration, there appear to be two paths to privilege escalation:
- LXD group membership (which I've used on other CTFs)
- The
encrypt.sage
script in/home/orestis
I am fairly certain the intended challenge is the script file. Looking at the script, we know these things:
- The script has encrypted
/root/root.txt
- The encrypted string is in
/home/orestis/output.txt
- The script output debug info for
p
,q
, ande
in/home/orestis/debug.txt
I consulted Google with: p q e encryption
...
So, it looks like this script is encrypting the /root/root.txt
file with 1024-bit RSA encryption. I then searched on Google for: Given p q e decrypt rsa
and I got this result back that looks promising.
I'm only going to add here the code that I modified:
p = 7493025776465062819629921475535241674460826792785520881387158343265274170009282504884941039852933109163193651830303308312565580445669284847225535166520307
q = 7020854527787566735458858381555452648322845008266612906844847937070333480373963284146649074252278753696897245898433245929775591091774274652021374143174079
e = 30802007917952508422792869021689193927485016332713622527025219105154254472344627284947779726280995431947454292782426313255523137610532323813714483639434257536830062768286377920010841850346837238015571464755074669373110411870331706974573498912126641409821855678581804467608824177508976254759319210955977053997
# ct is the ciphertext
ct = 44641914821074071930297814589851746700593470770417111804648920018396305246956127337150936081144106405284134845851392541080862652386840869768622438038690803472550278042463029816028777378141217023336710545449512973950591755053735796799773369044083673911035030605581144977552865771395578778515514288930832915182
Flags
User
2c11cfbc5b959f73ac15a3310bd097c9
Root
6efc1a5dbb8904751ce6566a305bb8ef