# Psnuffle password sniffer add-on class for HTTP URLs # part of psnuffle sniffer auxiliary module # # Sniffer class for GET/POST URLs. # Also extracts HTTP Basic authentication credentials. # class SnifferURL < BaseProtocolParser def register_sigs self.sigs = { :get => /^GET\s+([^\n]+)\s+HTTP\/\d\.\d/i, :post => /^POST\s+([^\n]+)\s+HTTP\/\d\.\d/i, :webhost => /^HOST:\s+([^\n\r]+)/i, :basic_auth => /^Authorization:\s+Basic\s+([^\n\r]+)/i, } end def parse(pkt) # We want to return immediately if we do not have a packet which is handled by us return unless pkt.is_tcp? return if (pkt.tcp_sport != 80 && pkt.tcp_dport != 80) s = find_session((pkt.tcp_sport == 80) ? get_session_src(pkt) : get_session_dst(pkt)) self.sigs.each_key do |k| # There is only one pattern per run to test matched = nil matches = nil if(pkt.payload =~ self.sigs[k]) matched = k matches = $1 sessions[s[:session]].merge!({k => matches}) end case matched when :webhost sessions[s[:session]].merge!({k => matches}) if s[:get] print_status("HTTP GET: #{s[:session]} http://#{s[:webhost]}#{s[:get]}") end if s[:post] print_status("HTTP POST: #{s[:session]} http://#{s[:webhost]}#{s[:post]}") end if s[:basic_auth] s[:user], s[:pass] = Rex::Text.decode_base64(s[:basic_auth]).split(':', 2) report_auth_info s print_status "HTTP Basic Authentication: #{s[:session]} >> #{s[:user]} / #{s[:pass]}" end when nil # No matches, no saved state end # end case matched end # end of each_key end # end of parse end # end of URL sniffer