Module: Msf::Exploit::Remote::Telnet

Includes:
Auxiliary::Login, Tcp
Defined in:
lib/msf/core/exploit/telnet.rb

Overview

This module exposes methods that may be useful to exploits that deal with servers that speak the telnet protocol.

Constant Summary collapse

IAC =

Borrowing constants from Ruby's Net::Telnet class (ruby license)

255.chr
DONT =

“377” # “xff” # interpret as command

254.chr
DO =

“376” # “xfe” # you are not to use option

253.chr
WONT =

“375” # “xfd” # please, you use option

252.chr
WILL =

“374” # “xfc” # I won't use option

251.chr
SB =

“373” # “xfb” # I will use option

250.chr
GA =

“372” # “xfa” # interpret as subnegotiation

249.chr
EL =

“371” # “xf9” # you may reverse the line

248.chr
EC =

“370” # “xf8” # erase the current line

247.chr
AYT =

“367” # “xf7” # erase the current character

246.chr
AO =

“366” # “xf6” # are you there

245.chr
IP =

“365” # “xf5” # abort output–but let prog finish

244.chr
BREAK =

“364” # “xf4” # interrupt process–permanently

243.chr
DM =

“363” # “xf3” # break

242.chr
NOP =

“362” # “xf2” # data mark–for connect. cleaning

241.chr
SE =

“361” # “xf1” # nop

240.chr
EOR =

“360” # “xf0” # end sub negotiation

239.chr
ABORT =

“357” # “xef” # end of record (transparent mode)

238.chr
SUSP =

“356” # “xee” # Abort process

237.chr
EOF =

“355” # “xed” # Suspend process

236.chr
SYNCH =

“354” # “xec” # End of file

242.chr
OPT_BINARY =

“362” # “xf2” # for telfunc calls

0.chr
OPT_ECHO =

“000” # “x00” # Binary Transmission

1.chr
OPT_RCP =

“001” # “x01” # Echo

2.chr
OPT_SGA =

“002” # “x02” # Reconnection

3.chr
OPT_NAMS =

“003” # “x03” # Suppress Go Ahead

4.chr
OPT_STATUS =

“004” # “x04” # Approx Message Size Negotiation

5.chr
OPT_TM =

“005” # “x05” # Status

6.chr
OPT_RCTE =

“006” # “x06” # Timing Mark

7.chr
OPT_NAOL =

“a” # “x07” # Remote Controlled Trans and Echo

8.chr
OPT_NAOP =

“010” # “x08” # Output Line Width

9.chr
OPT_NAOCRD =

“t” # “x09” # Output Page Size

10.chr
OPT_NAOHTS =

“n” # “x0a” # Output Carriage-Return Disposition

11.chr
OPT_NAOHTD =

“v” # “x0b” # Output Horizontal Tab Stops

12.chr
OPT_NAOFFD =

“f” # “x0c” # Output Horizontal Tab Disposition

13.chr
OPT_NAOVTS =

“r” # “x0d” # Output Formfeed Disposition

14.chr
OPT_NAOVTD =

“016” # “x0e” # Output Vertical Tabstops

15.chr
OPT_NAOLFD =

“017” # “x0f” # Output Vertical Tab Disposition

16.chr
OPT_XASCII =

“020” # “x10” # Output Linefeed Disposition

17.chr
OPT_LOGOUT =

“021” # “x11” # Extended ASCII

18.chr
OPT_BM =

“022” # “x12” # Logout

19.chr
OPT_DET =

“023” # “x13” # Byte Macro

20.chr
OPT_SUPDUP =

“024” # “x14” # Data Entry Terminal

21.chr
OPT_SUPDUPOUTPUT =

“025” # “x15” # SUPDUP

22.chr
OPT_SNDLOC =

“026” # “x16” # SUPDUP Output

23.chr
OPT_TTYPE =

“027” # “x17” # Send Location

24.chr
OPT_EOR =

“030” # “x18” # Terminal Type

25.chr
OPT_TUID =

“031” # “x19” # End of Record

26.chr
OPT_OUTMRK =

“032” # “x1a” # TACACS User Identification

27.chr
OPT_TTYLOC =

“e” # “x1b” # Output Marking

28.chr
OPT_3270REGIME =

“034” # “x1c” # Terminal Location Number

29.chr
OPT_X3PAD =

“035” # “x1d” # Telnet 3270 Regime

30.chr
OPT_NAWS =

“036” # “x1e” # X.3 PAD

31.chr
OPT_TSPEED =

“037” # “x1f” # Negotiate About Window Size

32.chr
OPT_LFLOW =

“ ” # “x20” # Terminal Speed

33.chr
OPT_LINEMODE =

“!” # “x21” # Remote Flow Control

34.chr
OPT_XDISPLOC =

“"” # “x22” # Linemode

35.chr
OPT_OLD_ENVIRON =

“#” # “x23” # X Display Location

36.chr
OPT_AUTHENTICATION =

“$” # “x24” # Environment Option

37.chr
OPT_ENCRYPT =

“%” # “x25” # Authentication Option

38.chr
OPT_NEW_ENVIRON =

“&” # “x26” # Encryption Option

39.chr
OPT_EXOPL =

“'” # “x27” # New Environment Option

255.chr

Constants included from Auxiliary::Login

Auxiliary::Login::CR, Auxiliary::Login::EOL, Auxiliary::Login::LF, Auxiliary::Login::NULL

Instance Attribute Summary collapse

Attributes included from Tcp

#sock

Instance Method Summary collapse

Methods included from Auxiliary::Login

#busy_message?, #command_echo?, #create_login_ivars, #login_failed?, #login_prompt?, #login_succeeded?, #password_prompt?, #raw_send, #recv_all, #send_pass, #send_recv, #send_user, #wait_for, #waiting_message?

Methods included from Tcp

#chost, #cleanup, #connect_timeout, #cport, #deregister_tcp_options, #disconnect, #handler, #lhost, #lport, #peer, #print_prefix, #proxies, #rhost, #rport, #set_tcp_evasions, #shutdown, #ssl, #ssl_cipher, #ssl_verify_mode, #ssl_version

Instance Attribute Details

This attribute holds the banner that was read in after a successful call to connect or connect_login.


248
249
250
# File 'lib/msf/core/exploit/telnet.rb', line 248

def banner
  @banner
end

Instance Method Details

#connect(global = true, verbose = true) ⇒ Object

This method establishes an Telnet connection to host and port specified by the RHOST and RPORT options, respectively. After connecting, the banner message is read in and stored in the 'banner' attribute. This method has the benefit of handling telnet option negotiation.


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/msf/core/exploit/telnet.rb', line 115

def connect(global = true, verbose = true)
  @trace = ''
  @recvd = ''
  fd = super(global)
  banner_timeout = (datastore['TelnetBannerTimeout'] || 25).to_i

  self.banner = ''
  # Wait for a banner to arrive...
  begin
  Timeout.timeout(banner_timeout) do
    while(true)
      buff = recv(fd)
      self.banner << buff if buff
      if(self.banner =~ @login_regex or self.banner =~ @password_regex)
        break
      elsif self.banner =~ @busy_regex
        # It's about to drop connection anyway -- seen on HP JetDirect telnet server
        break
      end
    end
  end
  rescue ::Timeout::Error
  end

  self.banner.strip!

  # Return the file descriptor to the caller
  fd
end

#initialize(info = {}) ⇒ Object

Creates an instance of a Telnet exploit module.


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/msf/core/exploit/telnet.rb', line 87

def initialize(info = {})
  super

  # Register the options that all Telnet exploits may make use of.
  register_options(
    [
      Opt::RHOST,
      Opt::RPORT(23),
      OptString.new('USERNAME', [ false, 'The username to authenticate as' ]),
      OptString.new('PASSWORD', [ false, 'The password for the specified username' ])
    ], Msf::Exploit::Remote::Telnet)

  register_advanced_options(
    [
      OptInt.new('TelnetTimeout', [ true, 'The number of seconds to wait for a reply from a Telnet command', 10]),
      OptInt.new('TelnetBannerTimeout', [ true, 'The number of seconds to wait for the initial banner', 25])
    ], Msf::Exploit::Remote::Telnet)

  register_autofilter_ports([ 23 ])
  register_autofilter_services(%W{ telnet })
end

#passObject


225
226
227
# File 'lib/msf/core/exploit/telnet.rb', line 225

def pass
  datastore["PASSWORD"]
end

#recv(fd = self.sock, timeout = datastore['TelnetTimeout']) ⇒ Object


146
147
148
# File 'lib/msf/core/exploit/telnet.rb', line 146

def recv(fd=self.sock, timeout=datastore['TelnetTimeout'])
  recv_telnet(fd, timeout.to_f)
end

#recv_telnet(fd, timeout) ⇒ Object

Handle telnet option negotiation

Appends to the @recvd buffer which is used to tell us whether we're at a login prompt, a password prompt, or a working shell.


156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/msf/core/exploit/telnet.rb', line 156

def recv_telnet(fd, timeout)

  data = ''

  begin
    data = fd.get_once(-1, timeout)
    return nil if not data or data.length == 0

    # combine CR+NULL into CR
    data.gsub!(/#{CR}#{NULL}/no, CR)

    # combine EOL into "\n"
    data.gsub!(/#{EOL}/no, "\n")

    data.gsub!(/#{IAC}(
        [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]|[#{DO}#{DONT}#{WILL}#{WONT}]
        [#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]|#{SB}[^#{IAC}]*#{IAC}#{SE}
        )/xno) do
      m = $1

      if m == IAC
        IAC
      elsif m == AYT
        fd.write("YES" + EOL)
        ''
      elsif m[0,1] == DO
        if(m[1,1] == OPT_BINARY)
          fd.write(IAC + WILL + OPT_BINARY)
        else
          fd.write(IAC + WONT + m[1,1])
        end
        ''
      elsif m[0,1] == DONT
        fd.write(IAC + WONT + m[1,1])
        ''
      elsif m[0,1] == WILL
        if m[1,1] == OPT_BINARY
          fd.write(IAC + DO + OPT_BINARY)
          # Disable Echo
        elsif m[1,1] == OPT_ECHO
          fd.write(IAC + DONT + OPT_ECHO)
        elsif m[1,1] == OPT_SGA
          fd.write(IAC + DO + OPT_SGA)
        else
          fd.write(IAC + DONT + m[1,1])
        end
        ''
      elsif m[0,1] == WONT
        fd.write(IAC + DONT + m[1,1])
        ''
      else
        ''
      end
    end

    @trace << data
    @recvd << data
    fd.flush

  rescue ::EOFError, ::Errno::EPIPE
  end

  data
end

#tel_timeoutObject

Returns the number of seconds to wait for a telnet reply


238
239
240
# File 'lib/msf/core/exploit/telnet.rb', line 238

def tel_timeout
  (datastore['TelnetTimeout'] || 10).to_i
end

#userObject


221
222
223
# File 'lib/msf/core/exploit/telnet.rb', line 221

def user
  datastore["USERNAME"]
end