Postfix


kyle@writer:/var$ id
uid=1000(kyle) gid=1000(kyle) groups=1000(kyle),997(filter),1002(smbgroup)

After making lateral movement to the kyle user, I discovered that the user is part of the filter group

kyle@writer:/var$ find / -group filter -ls -type f 2>/dev/null
    16282      4 -rwxrwxr-x   1 root     filter       1021 apr 19 19:20 /etc/postfix/disclaimer
    16281      4 drwxr-x---   2 filter   filter       4096 May 13  2021 /var/spool/filter

Searching the system for the relevant file reveals 2 entries Whole these 2 files are relevant to the Postfix instance, the current user is able to write to the /etc/postfix/disclaimer file

disclaimer


The disclaimer file is a script used by Postfix to add a standard message to the end of all outgoing emails. This message usually contains legal or informational content, and can be configured to appear in different languages or formats. The disclaimer script is typically located in the /etc/postfix directory on the server running Postfix.

I also saw that that the disclaimer file is being replaced by the root user every minute along with the master.cf file

kyle@writer:~$ cat /etc/postfix/disclaimer
#!/bin/sh
# Localize these.
INSPECT_DIR=/var/spool/filter
SENDMAIL=/usr/sbin/sendmail
 
# Get disclaimer addresses
DISCLAIMER_ADDRESSES=/etc/postfix/disclaimer_addresses
 
# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_UNAVAILABLE=69
 
# Clean up when done or when aborting.
trap "rm -f in.$$" 0 1 2 3 15
 
# Start processing.
cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit
$EX_TEMPFAIL; }
 
cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }
 
# obtain From address
from_address=`grep -m 1 "From:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1`
 
if [ `grep -wi ^${from_address}$ ${DISCLAIMER_ADDRESSES}` ]; then
  /usr/bin/altermime --input=in.$$ \
                   --disclaimer=/etc/postfix/disclaimer.txt \
                   --disclaimer-html=/etc/postfix/disclaimer.txt \
                   --xheader="X-Copyrighted-Material: Please visit http://www.company.com/privacy.htm" || \
                    { echo Message content rejected; exit $EX_UNAVAILABLE; }
fi
 
$SENDMAIL "$@" <in.$$
 
exit $?

While it contains some information, it’s important to note that

This particular line above dictates addresses that the disclaimer get issued from

kyle@writer:~$ cat /etc/postfix/disclaimer_addresses 
root@writer.htb
kyle@writer.htb

This means that any email sent to these addresses through the Postfix mail server will have the disclaimer message added to it before being delivered to the recipient’s inbox.

Now, let’s check the primary configuration file of Postfix, master.cf, which also gets restored every minute by the root cronjob process

master.cf


kyle@writer:/etc/postfix$ grep -v '^#' master.cf
smtp      inet  n       -       y       -       -       smtpd -o content_filter=dfilt:
 
pickup    unix  n       -       y       60      1       pickup
cleanup   unix  n       -       y       -       0       cleanup
qmgr      unix  n       -       n       300     1       qmgr
tlsmgr    unix  -       -       y       1000?   1       tlsmgr
rewrite   unix  -       -       y       -       -       trivial-rewrite
bounce    unix  -       -       y       -       0       bounce
defer     unix  -       -       y       -       0       bounce
trace     unix  -       -       y       -       0       bounce
verify    unix  -       -       y       -       1       verify
flush     unix  n       -       y       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       y       -       -       smtp
relay     unix  -       -       y       -       -       smtp
        -o syslog_name=postfix/$service_name
showq     unix  n       -       y       -       -       showq
error     unix  -       -       y       -       -       error
retry     unix  -       -       y       -       -       error
discard   unix  -       -       y       -       -       discard
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       y       -       -       lmtp
anvil     unix  -       -       y       -       1       anvil
scache    unix  -       -       y       -       1       scache
postlog   unix-dgram n  -       n       -       1       postlogd
maildrop  unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
uucp      unix  -       n       n       -       -       pipe
  flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
ifmail    unix  -       n       n       -       -       pipe
  flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp     unix  -       n       n       -       -       pipe
  flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix	-	n	n	-	2	pipe
  flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman   unix  -       n       n       -       -       pipe
  flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
  ${nexthop} ${user}
dfilt     unix  -       n       n       -       -       pipe
  flags=Rq user=john argv=/etc/postfix/disclaimer -f ${sender} -- ${recipient}

the /etc/postfix/master.cf file is the primary configuration file for Postfix. There is an interesting entry at the bottom; flags=Rq user=john argv=/etc/postfix/disclaimer -f ${sender} -- ${recipient} This essentially specifies that the /etc/postfix/disclaimer script will be executed if the john user receives a new mail

This is clearly a lateral movement vector as I do have write access to the /etc/postfix/disclaimer script Moving on to Lateral Movement phase