This is a walkthrough of the CTF machine “Stapler” on Vulnhub. This is a great machine for practicing enumeration :)

  ****Spoiler Alert****          ****Spoiler Alert****

Let’s jump all in with an extended TCP Nmap scan (nmap -A recommended, but too much info to list here):

Stapler NmapOutput

Wow, ports a-plenty! For these CTF machines this result is always bittersweet since that’s just that much more possible dead ends. For brevity here, I’ll list some of the avenues I followed here:

  1. FTP. Anonymous logins worked, with some banner info and a note. Local usernames gained, but no other foothold.
  2. SSH. I don’t like trying Hydra, Medusa, or other crackers this early so I opted not to try brute forcing any logins just yet for either this service or any others.
  3. DNS. Nothing exploitable from the dnsmasq version that I could gather that would be beneficial to this CTF.
  4. NTP. Not much here unless I was interested in DoS.
  5. NetBios. Running enum4linux garnered all of the other local usernames. This would have been a great time for a brute-force event, however I still wanted to probe a bit deeper first.
  6. Doom/666. This service ended up extracting to a JPG file containing another note/username.
  7. MySQL. I did not enumerate this service at all seeing as I had other services to occupy my time. Had one of those options fell through I would have focused on this avenue more.

After this quick runthrough I was left with 80 & 12380. The typical web port brought me to an unfinished page, and scanning it with Nikto showed that .profile and .bashrc were available so perhaps this was being served by a local profile?

Stapler Nikto_80

Setting this aside I went looking at 12380:


Nice looking, but not much here either or in the source, other than another note (this seems to be quite the chatty bunch). Let’s run it through Nikto:


Much more info to go on and this is how rabbit holes get dug but following the path of least resistence here, we can see a few directories that need further exploration:

  • admin112233
  • blogblog
  • phpmyadmin

We also see something else of interest. An SSL certificate (with of course a note). So we’ll add HTTPS as a vector to these directories.

  • admin112233 - Tester for BEEF toolkit.
  • blogblog - Wordpress page for Initech - Down the Rabbit Hole we go!
  • phpmyadmin - Standard PHPMyAdmin page.


It looks like John is the main admin on this page, but no other interesting details are being given. Let’s use wpscan to find some additional details about the site:

So it looks like directory browsing is enabled on the wp-content/uploads directory (this may be useful):


Nothing else overtly. Hmm. Can we enumerate the users on this site using wpscan?


…and wpscan’s brute-forcer (using a common 10k list):


Nice, but we’re missing John. He’s the admin so we need to focus on him….just trying with a larger wordlist……..aaaaaannnnnnndddddddd….bingo.


My normal routine in this case would be to create and upload a malicious plugin for a reverse shell. This is done using WordPwn and I tried this several times, but was not able to get the plugin to install and wasn’t sure what wa going on.
In enumerating the list of plugins I ran across the Advanced Video Embed v1.0 exploit which may work for some but I could not get to work, even though it looked as if not LFI but RFI was a possibility (the server was hitting my pages but not rendering them):


After too many failed attempts I went back to the inital failed plugin upload. I remembered that the upload directory was viewable and took a look to see if there was anything of interest there. Sure enough my malicious plugin package was there, just not unzipped. So if I had a working uploader, let’s try using it for a PHP reverse shell.



Well that was easier than expected. Moving on to PrivEsc.

One of the first things I do after obtaining a limited shell is to run and analyze: ps aux | grep root to see all root processes. On this server this particular line stood out:


Nothing out of the ordinary was in /home/JKanode, but .bash_history was available so we’ll take a look at that:


This is killer. Not only do we have the password for the jkanode account, but also for the peter account. Now we spawn a PTY shell: python -c ‘import pty; pty.spawn("/bin/bash")'

Next we su to JKanode and test our sudo permissions, but it appears we don’t have any. No problems because we have another account to test so we su to the peter account and find we can run ANY sudo command. Upon logging into peter’s account it looks like we’re directed into the Z shell (ZSH).


After accepting the default we’re able to sudo to su and get our flag.


As previously mentioned this was a great machine for enumeration and learning which paths to take.