Module: Metasploit::Framework::Telnet::Client

Extended by:
ActiveSupport::Concern
Includes:
Metasploit::Framework::Tcp::Client, Msf::Auxiliary::Login
Included in:
LoginScanner::Telnet
Defined in:
lib/metasploit/framework/telnet/client.rb

Constant Summary collapse

IAC =

CONSTANTS

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 Msf::Auxiliary::Login

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

Instance Attribute Summary collapse

Attributes included from Metasploit::Framework::Tcp::Client

#max_send_size, #send_delay, #sock

Instance Method Summary collapse

Methods included from Msf::Auxiliary::Login

#busy_message?, #command_echo?, #create_login_ivars, #initialize, #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 Metasploit::Framework::Tcp::Client

#chost, #cport, #disconnect, #proxies, #rhost, #rport, #set_tcp_evasions, #ssl, #ssl_version

Instance Attribute Details

Returns the value of attribute banner


11
12
13
# File 'lib/metasploit/framework/telnet/client.rb', line 11

def banner
  @banner
end

Instance Method Details

Wrappers for getters

Raises:

  • (NotImplementedError)

209
210
211
# File 'lib/metasploit/framework/telnet/client.rb', line 209

def banner_timeout
  raise NotImplementedError
end

#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.


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/metasploit/framework/telnet/client.rb', line 87

def connect(global = true, verbose = true)
  @trace = ''
  @recvd = ''
  fd = super(global)

  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

#connect_reset_safeObject

Sometimes telnet servers start RSTing if you get them angry. This is a short term fix; the problem is that we don't know if it's going to reset forever, or just this time, or randomly. A better solution is to get the socket connect to try again with a little backoff.


121
122
123
124
125
126
127
128
# File 'lib/metasploit/framework/telnet/client.rb', line 121

def connect_reset_safe
  begin
    connect
  rescue Rex::ConnectionRefused
    return :refused
  end
  return :connected
end

#recv(fd = self.sock, timeout = telnet_timeout) ⇒ Object


130
131
132
# File 'lib/metasploit/framework/telnet/client.rb', line 130

def recv(fd=self.sock, timeout=telnet_timeout)
  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.


140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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
# File 'lib/metasploit/framework/telnet/client.rb', line 140

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

#telnet_timeoutObject

Raises:

  • (NotImplementedError)

213
214
215
# File 'lib/metasploit/framework/telnet/client.rb', line 213

def telnet_timeout
  raise NotImplementedError
end