VulnHub – Stapler 1

Walkthrough of the exploitation of Stapler 1 from VulnHub.

After exploiting the first three targets (VulnHub – Basic Pentesting 1, VulnHub – Basic Pentesting 2, and VulnHub – Photographer), I will go through the curated list of OSCP-like machines to improve and get a better feeling for the OSCP level of machines.

Note: I’ll use the “we” form for the writeups, as that’s how I intend to write the reports. For these blurps about my progress etc. I’ll stick with the first person.


Our attacking box is a virtual machine that has the IP and runs an updated Kali Linux 2020.3. Throughout the penetration test, we will try to avoid using any automated exploitation tools. The target is VulnHub’s Stapler 1, a vulnerable virtual machine to practice penetration testing.

Information Gathering


The first thing we do is find the IP of our target by running nmap against the subnet.

nmap -sn

We learn, that the target IP is and run an nmap scan against that IP against all TCP ports (-p-).

nmap -sV -p- -Pn -n
Image 1: Results of the nmap scan against all TCP ports.

We also scan for the most common open UDP ports (note: this takes a bit of time so we did it while executing some of the steps below).

Image 2: nmap scan of UPD ports.


Port 80

Running dirb on the webserver on port 80 reveals two files that we can download (nikto yields the same result).

sudo dirb -f -r
Image 3: Results of running dirb against the webserver on port 80.
curl > bashrc.txt
curl > profile.txt

Browsing and looking at the source code yielded nothing interesting.

Image 4: Browsing

Port 12380

Running nikto on the webserver running on port 12380 yields some directories (dirb didn’t return any results).

nikto -h
Image 4: Running nikto against the webserver on port 12380.

Seems like there’s a misconfiguration of SSL and there’s also a user “dave” that shows up in the headers with a comment. There’s also three interesting directories: /admin112233, /blogblog and /phpmyadmin.

We opened in a browser.

Image 5: Browsing

The title of the page was “Tim, we need to-do better next year for Initech”, so we can add “Tim” as another potential user. Viewing the source code gave us something interesting.

Image 6: Viewing the source of

So we have another potential user “Zoe” (from HR) as well as an interesting string. It seems to be a base64 encoded jpeg image, but we were not able to decode it in any meaningful way.


Because we saw port 139 open, we run enum4linux to fish for account names and save them to enum.txt.

enum4linux -vr | grep 'Local\|Domain' > enum.txt
Image 7: Enumerating account names with enum4linux.

We’ll also get a listing of the shares.

enum4linux -vS
Image 8: Listing smb shares with enum4linux.

From the comments, it seems like there are two users, “Fred”, who is on the list (fred) and kathy who doesn’t show up in our enumeration. Let’s try to connect to the kathy and tmp shares and explore them.

smbclient -W 'WORKGROUP' //''/'kathy' -U''%'' -c 'ls'
smbclient -W 'WORKGROUP' //''/'tmp' -U''%'' -c 'ls'
Image 9: Available smaba files and directories.

Lets’ quickly check the contents of the two subdirectories kathy_stuff and backup as well and then download everything.

Image 10: Subdirectory contents of the kathy share.
smbclient -W 'WORKGROUP' //''/'kathy' -U''%'' -c 'recurse ON; prompt OFF; mget *'
smbclient -W 'WORKGROUP' //''/'tmp' -U''%'' -c 'recurse ON; prompt OFF; mget *'
Image 11: Getting all files from the samba shares.

The todo-list.txt contains the following information: “I’m making sure to backup anything important for Initech, Kathy”. So we keep in mind, that Initech might be relevant. Using cat to display the ls file, we can see that there used to be another file called “systemd-private-df2bff9b90164a2eadc490c0b8f76087-systemd-timesyncd.service-vFKoxJ” in the tmp directory.

Image 12: Content of the ls file.

Searching a bit on Google reveals, that these files are created by systemd if the private temp feature is activated [1]. In this case for the timesyncd.service.

We unzipped the wordpress-4.tar.gz file but didn’t find a wp-config.php file inside (which usually contains the database password). The wp-config-sample.php didn’t leak any information.

Let’s get all activated options for vsftpd.

cat vsftpd.conf | grep -v '#'
Image 13: Content of the vsftpd.conf backup.

Lastly, let’s save all the enumerated local usernames in a file (users_enum.txt) for later use.

grep 'Unix' enum.txt | awk '{print $3}' | cut -d '\' -f2 > users_enum.txt


Anonymous login should be enabled, so let’s see what we can do by logging in as ftp and leaving the password empty.

Image 14: Anonymous FTP connection with message.

There seems to be an admin user named “Harry” and we can download the note file by issuing “get note”. The note contains the following text: “Elly, make sure you update the payload information. Leave it in your FTP account once your are done, John.” So there’s two more potential users that we can add.


Image 15: Default ssh connection.

There seems to be an admin user named “Barry” but we can’t get any further without logging in.

List of users

We found the following usernames from various sources…

  • dave – from misconfigured SSL
  • Tim – from webserver 2
  • Zoe – Head of HR – from webserver 2
  • Fred – from samba
  • kathy – from samba
  • Harry – from FTP
  • Elly – from FTP
  • John – from FTP
  • Barry – from SSH

We create a file called usernames.txt and add one user per line, lowercased to it. We also create a file usernames_cap.txt with the capitalized versions.

sed 's/^./\u&/g' usernames.txt > usernames_cap.txt

We combine all usernames into one master username list called user_list.txt.

cat usernames.txt usernames_cap.txt users_enum.txt >> user_list.txt

Just to make sure, we check that there are no duplicates.

uniq -D user_list.txt


Next, we run searchsploit for all open ports. There’s interesting results for OpenSSH, MySQL and dnsmasq.

searchsploit OpenSSH 7.2p2
Image 16: searchsploit results for OpenSSH.
searchsploit MySQL 5.7.12
Image 17: searchsploit results for MySQL.
searchsploit dnsmasq 2.75
Image 18: searchsploit results for dnsmasq.


Brute forcing

Let’s try a simple username == password brute force against both FTP and SSH with hydra.

hydra -L user_list.txt -P user_list.txt ftp
Image 19: Brute forced FTP password for user SHayslett.
hydra -L user_list.txt -P user_list.txt ssh
Image 20: Brute forced SSH password for user SHayslett.

Seems like the same user (SHayslett) has used his username as a password for FTP and SSH.

If we try to SSH into the machine, we get access to it (note: we also got an exchange_identification error before).

Image 21: Local priviliges as user SHayslett.

Post Exploitation

First, we check if there’s anything interesting in the /home directory.

ls -Ral /home

The user peter has a file called .zcompdump in his .cache directory which we can read. He can also sudo to become root as indicated by the .sudo_as_admin_successful file. There’s also an empty file in SHayslett‘s .cache directory which indicates that motd is used.

Next, we run LinEnum to check for common problems by copy&pasting the script from Github [2] into and using chmod +x to make it executable.

./ -r linenum
Image 22: Interesting .bash_history found by running LinEnum.

Seem like the user JKanode tried to run ssh in non-interactive mode with sshpass and he passed the passwords via the -p command line argument. We know from before that peter can sudo, so we try to ssh with that password.

Image 23: Full root access.

After an initial message about z-shell we get access and can become root. And that’s all. Mission accomplished 🙂


We can try to enumerate existing accounts in OpenSSH [3] before brute forcing. There’s a script for this /usr/share/exploitdb/exploits/linux/remote/ However, because our Kali uses Python 3.8 we have to change the two calls time.clock(), which was deprecated in 3.8 [4], to time.process_time(). For example, running this against our usernames.txt suggests, that only the user “zoe” from that file exists on the target.

python3 -U usernames.txt
Image 24: OpenSSH username enumeration against usernames.txt

We can double-check this by looking into /etc/passwd. Only “zoe” and “elly” exist as local users on the target. However, elly is explicitly forbidden to access the machine vie DenyUsers in sshd_config.

Lessons Learned

  • Keep it simple, stupid (KISS). I spend a couple of hours researching the exploits for dnsmasq and MySQL before I tried to simply use hydra to see if username == password was possible. I’m not 100% sure about the use of hydra but will keep using it for simple or targeted attacks (I’ll keep the runtime under 30 minutes).
  • Post exploitation scripts like LinEnum are pretty handy. I’m not 100% sure if they are allowed for OSCP or not. I think I’ll keep using them and manually reproduce the steps that found interesting information. In this case:
for i in $(ls /home) ; do echo "User: $i" && cat "/home/$i/.bash_history"; done
  • Actually look inside .bash_history, you never know what you might find. I didn’t do it during my manual exploration of /home and only saw it when running LinEnum.