CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/tools/exploit/reg.rb
Views: 11768
1
#!/usr/bin/env ruby
2
3
##
4
# This module requires Metasploit: https://metasploit.com/download
5
# Current source: https://github.com/rapid7/metasploit-framework
6
##
7
8
#
9
# This script acts as a small registry reader.
10
# You may easily automate a lot of registry forensics with a proper method.
11
#
12
begin
13
msfbase = __FILE__
14
while File.symlink?(msfbase)
15
msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
16
end
17
18
$:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', '..', 'lib')))
19
require 'msfenv'
20
21
$:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']
22
23
require 'rex'
24
require 'rex/registry/hive'
25
26
def print_all(nodekey)
27
print_all_keys(nodekey)
28
print_all_values(nodekey)
29
end
30
31
def print_all_keys(nodekey)
32
33
return if !nodekey
34
return if !nodekey.lf_record
35
return if !nodekey.lf_record.children
36
return if nodekey.lf_record.children.length == 0
37
38
table = Rex::Text::Table.new(
39
'Header' => "Child Keys for #{nodekey.full_path}",
40
'Indent' => ' '.length,
41
'Columns' => [ 'Name', 'Last Edited', 'Subkey Count', 'Value Count' ]
42
)
43
44
if nodekey.lf_record && nodekey.lf_record.children && nodekey.lf_record.children.length > 0
45
nodekey.lf_record.children.each do |key|
46
table << [key.name, key.readable_timestamp, key.subkeys_count, key.value_count]
47
end
48
end
49
50
puts table.to_s
51
end
52
53
def print_all_values(nodekey)
54
55
return if !nodekey
56
return if !nodekey.lf_record
57
return if !nodekey.lf_record.children
58
return if nodekey.lf_record.children.length == 0
59
60
table = Rex::Text::Table.new(
61
'Header' => "Values in key #{nodekey.full_path}",
62
'Indent' => ' '.length,
63
'Columns' => ['Name','Value Type', 'Value']
64
)
65
if nodekey.value_list && nodekey.value_list.values.length > 0
66
nodekey.value_list.values.each do |value|
67
table << [value.name, value.readable_value_type, value.value.data]
68
end
69
end
70
71
puts table.to_s
72
end
73
74
def get_system_information
75
if @hive.hive_name =~ /SYSTEM/
76
mounted_devices_info_key = @hive.relative_query("\\MountedDevices")
77
78
current_control_set_key = @hive.value_query('\Select\Default')
79
current_control_set = "ControlSet00" + current_control_set_key.value.data.unpack('c').first.to_s if current_control_set_key
80
81
computer_name_key = @hive.value_query("\\" + current_control_set + "\\Control\\ComputerName\\ComputerName") if current_control_set
82
computer_name = computer_name_key.value.data.to_s if computer_name_key
83
84
event_log_info_key = @hive.relative_query("\\" + current_control_set + "\\Services\\EventLog") if current_control_set
85
86
puts "Computer Name: " + computer_name if computer_name
87
88
print_all_values(event_log_info_key) if event_log_info_key
89
puts "-----------------------------------------" if event_log_info_key
90
91
print_all_values(mounted_devices_info_key) if mounted_devices_info_key
92
puts "-----------------------------------------" if mounted_devices_info_key
93
94
elsif @hive.hive_name =~ /SOFTWARE/
95
current_version_info_key = @hive.relative_query("\\Microsoft\\Windows NT\\CurrentVersion")
96
login_info_key = @hive.relative_query("\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon")
97
98
print_all_values(current_version_info_key)
99
puts "-----------------------------------------" if current_version_info_key
100
101
print_all_values(login_info_key)
102
puts "-----------------------------------------" if login_info_key
103
end
104
end
105
106
def get_user_information
107
108
109
local_groups_info_key = @hive.relative_query("\\SAM\\Domains\\Builtin\\Aliases\\Names")
110
local_users_info_key = @hive.relative_query("\\SAM\\Domains\\Account\\Users\\Names")
111
112
print_all(local_groups_info_key)
113
puts "------------------------------------------------" if local_groups_info_key && local_groups_info_key.lf_record.children
114
115
print_all(local_users_info_key)
116
puts "------------------------------------------------" if local_users_info_key && local_groups_info_key.lf_record.children
117
end
118
119
def dump_creds
120
end
121
122
def get_boot_key
123
124
return if !@hive.root_key
125
return if !@hive.root_key.name
126
127
puts "Getting boot key"
128
puts "Root key: " + @hive.root_key.name
129
130
default_control_set = @hive.value_query('\Select\Default').value.data.unpack("c").first
131
132
puts "Default ControlSet: ControlSet00#{default_control_set}"
133
134
bootkey = ""
135
basekey = "\\ControlSet00#{default_control_set}\\Control\\Lsa"
136
137
%W{JD Skew1 GBG Data}.each do |k|
138
ok = @hive.relative_query(basekey + "\\" + k)
139
return nil if not ok
140
141
tmp = ""
142
0.upto(ok.class_name_length - 1) do |i|
143
next if i%2 == 1
144
145
tmp << ok.class_name_data[i,1]
146
end
147
148
bootkey << [tmp.to_i(16)].pack('V')
149
end
150
151
152
keybytes = bootkey.unpack("C*")
153
154
descrambled = ""
155
# descrambler = [ 0x08, 0x05, 0x04, 0x02, 0x0b, 0x09, 0x0d, 0x03, 0x00, 0x06, 0x01, 0x0c, 0x0e, 0x0a, 0x0f, 0x07 ]
156
descrambler = [ 0x0b, 0x06, 0x07, 0x01, 0x08, 0x0a, 0x0e, 0x00, 0x03, 0x05, 0x02, 0x0f, 0x0d, 0x09, 0x0c, 0x04 ]
157
158
0.upto(keybytes.length-1) do |x|
159
descrambled << [ keybytes[ descrambler[x] ] ].pack("C")
160
end
161
162
puts descrambled.unpack("H*")
163
end
164
165
def list_applications
166
end
167
168
def list_drivers
169
end
170
171
def get_aol_instant_messenger_information
172
173
if @hive.hive_name != /NTUSER\.dat/i
174
users_list_key = @hive.relative_query('\Software\America Online\AOL Instant Messenger(TM)\CurrentVersion\Users')
175
last_logged_in_user_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Login - Screen Name")
176
177
print_all_keys(users_list_key)
178
179
users_list_key.lf_record.children.each do |screenname|
180
away_messages_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Users\\#{screenname.name}\\IAmGoneList")
181
file_xfer_settings_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Users\\#{screenname.name}\\Xfer")
182
profile_info_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Users\\#{screenname.name}\\DirEntry")
183
recent_contacts_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Users\\#{screenname.name}\\Recent IM ScreenNames")
184
185
print_all(away_messages_key)
186
print_all(file_xfer_settings_key)
187
print_all(profile_info_key)
188
print_all(recent_contacts_key)
189
end
190
191
end
192
end
193
194
def get_msn_messenger_information
195
196
if @hive.hive_name =~ /NTUSER\.dat/i
197
general_information_key = @hive.relative_query("\\Software\\Microsoft\\MessengerService\\ListCache\\.NETMessengerService\\")
198
file_sharing_information_key = @hive.relative_query("\\Software\\Microsoft\\MSNMessenger\\FileSharing - Autoshare")
199
file_transfers_information_key = @hive.relative_query("\\Software\\Microsoft\\MSNMessenger\\ - FTReceiveFolder")
200
201
print_all(general_information_key)
202
print_all(file_sharing_information_key)
203
print_all(file_transfers_information_key)
204
end
205
end
206
207
def get_windows_messenger_information
208
if @hive.hive_name =~ /NTUSER\.dat/i
209
contact_list_information_key = @hive.relative_query("\\Software\\Microsoft\\MessengerService\\ListCache\\.NET Messenger Service")
210
file_transfers_information_key = @hive.relative_query("\\Software\\Microsoft\\Messenger Service - FtReceiveFolder")
211
last_user_information_key = @hive.relative_query("\\Software\\Microsoft\\MessengerService\\ListCache\\.NET Messenger Service - IdentityName")
212
213
print_all(contact_list_information_key)
214
print_all(file_transfers_information_key)
215
print_all(last_user_information_key)
216
end
217
end
218
219
def get_icq_information
220
if @hive.hive_name =~ /NTUSER\.dat/i
221
general_information_key = @hive.relative_query("\\Software\\Mirabalis\\ICQ")
222
223
print_all(general_information_key)
224
elsif @hive.hive_name =~ /SOFTWARE/
225
owner_number_key = @hive.relative_query("\\Software\\Mirabalis\\ICQ\\Owner")
226
print_all(owner_number_key)
227
end
228
end
229
230
def get_ie_information
231
if @hive.hive_name =~ /NTUSER\.dat/i
232
stored_logon_information_key = @hive.relative_query("\\Software\\Microsoft\\Protected Storage System Provider\\SID\\Internet Explorer\\Internet Explorer - URL:StringData")
233
stored_search_terms_information_key = @hive.relative_query("\\Software\\Microsoft\\Protected Storage SystemProvider\\SID\\Internet Explorer\\Internet Explorer - q:SearchIndex")
234
ie_setting_information_key = @hive.relative_query("\\Software\\Microsoft\\Internet Explorer\\Main")
235
history_length_value_key = @hive.value_query("\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\URL History - DaysToKeep")
236
typed_urls_information_key = @hive.relative_query("\\Software\\Microsoft\\Internet Explorer\\Typed URLs")
237
intelliforms_information_key = @hive.relative_query("\\Software\\Microsoft\\Internet Explorer\\Intelliforms")
238
autocomplete_web_addresses_key = @hive.relative_query("\\Software\\Microsoft\\Protected Storage System Provider")
239
default_download_dir = @hive.relative_query("\\Software\\Microsoft\\Internet Explorer")
240
241
print_all(stored_logon_information_key)
242
print_all(stored_search_terms_information_key)
243
print_all(ie_setting_information_key)
244
print_all(typed_urls_information_key)
245
print_all(intelliforms_information_key)
246
print_all(autocomplete_web_addresses_key)
247
print_all(default_download_dir)
248
249
puts "Days saved in history: " + history_length_value_key.value.data.to_s if !history_length_value_key.kind_of? Array
250
end
251
end
252
253
def get_outlook_information
254
if @hive.hive_name =~ /NTUSER\.dat/i
255
account_information_key = @hive.relative_query("\\Software\\Microsoft\\Protected Storage System Provider\\SID\\Identification\\INETCOMM Server Passwords")
256
257
print_all(account_information_key)
258
end
259
end
260
261
def get_yahoo_messenger_information
262
if @hive.hive_name =~ /NTUSER\.dat/i
263
profiles_key = @hive.relative_query("\\Software\\Yahoo\\Pager\\profiles")
264
265
print_all(profiles_key)
266
267
profiles_key.lf_record.children.each do |child|
268
file_transfers_information_key = @hive.relative_query("\\Software\\Yahoo\\Pager\\profiles\\#{child.name}\\FileTransfer")
269
message_archiving_information_key = @hive.relative_query("\\Software\\Yahoo\\Pager\\profiles\\#{child.name}\\Archive")
270
271
print_all(file_transfers_information_key)
272
print_all(message_archiving_information_key)
273
end
274
end
275
end
276
277
def get_networking_information
278
279
end
280
281
def get_user_application_information
282
end
283
284
if ARGV.length == 0 || ARGV[0] == "help"
285
no_args = %Q{
286
Usage: reg.rb <command> <opts> <hivepath>
287
288
Available commands:
289
query_key Query for more information about a specific node key
290
query_value Query for the value of a specific value key
291
get_boot_key Extract the boot key from the SYSTEM hive
292
dump_creds Dump the usernames and password hashes of the users from the SAM hive
293
list_applications List all the applications installed via the SOFTWARE hive
294
list_drivers List all the devices and their respective drivers and driver versions from SYSTEM hive
295
get_everything When pointed to a directory with hives, it will run all commands on all available hives
296
get_aol_instant_messenger_information Get credentials and general information on AOL Instant Messenger users from NTUSER.dat
297
get_msn_messenger_information Get credentials and general information on MSN Messenger users from NTUSER.dat
298
get_windows_messenger_information Get credentials and general information on Windows Messenger users from NTUSER.dat
299
get_icq_information Get credentials and general information on ICQ users from NTUSER.dat
300
get_ie_information Get stored credentials, typed history, search terms, and general settings from NTUSER.dat
301
get_outlook_information Gets outlook and outlook express stored credentials and general information from NTUSER.dat
302
get_yahoo_messenger_information Gets credentials and general information on Yahoo! Messenger users from NTUSER.dat
303
get_system_information Gets general system administration from both SOFTWARE and SYSTEM hives
304
get_networking_information Gets networing information from the SAM, SYSTEM, and NTUSER.dat hives
305
get_user_information Gets general user information from the SYSTEM, SECURITY, SAM, and NTUSER.dat hives
306
get_user_application_information Gets user-specific application information from the NTUSER.DAT and SOFTWARE hives
307
}
308
309
puts no_args
310
exit
311
end
312
313
314
case ARGV[0]
315
316
when "query_key"
317
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
318
puts "Hive name: #{@hive.hive_name}"
319
320
1.upto(ARGV.length - 2) do |arg|
321
selected = @hive.relative_query(ARGV[arg])
322
print_all(selected)
323
end
324
325
when "query_value"
326
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
327
puts "Hive name: #{@hive.hive_name}"
328
329
1.upto(ARGV.length - 2) do |i|
330
selected = @hive.value_query(ARGV[i])
331
332
if !selected
333
puts "Value not found."
334
return
335
end
336
337
puts "Value Name: #{selected.name}"
338
puts "Value Data: #{selected.value.data.inspect}"
339
end
340
341
when "get_boot_key"
342
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
343
344
if @hive.hive_name !~ /SYSTEM/
345
puts "I need a SYSTEM hive to grab the boot key, not a #{@hive.hive_name}."
346
else
347
get_boot_key
348
end
349
350
when "dump_creds"
351
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
352
353
if @hive.hive_name !~ /SAM/
354
puts "I need a SAM hive, not a #{@hive.hive_name}"
355
else
356
dump_creds
357
end
358
359
when "list_applications"
360
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
361
362
if @hive.hive_name !~ /SOFTWARE/
363
puts "I need a SOFTWARE hive, not a #{@hive.hive_name}."
364
else
365
list_applications
366
end
367
368
when "list_drivers"
369
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
370
371
if @hive.hive_name !~ /SYSTEM/
372
puts "I need a SYSTEM hive, not a #{@hive.hive_name}."
373
else
374
list_drivers
375
end
376
377
when "get_everything"
378
Dir.foreach(ARGV[1]) do |file|
379
next if file =~ /^\./
380
next if ::File.directory?(ARGV[1] + "/" + file)
381
382
@hive = Rex::Registry::Hive.new(ARGV[1] + "/" + file)
383
384
next if !@hive.hive_regf
385
next if !@hive.hive_name
386
387
case @hive.hive_name
388
389
when /SYSTEM/
390
391
puts "Found a SYSTEM hive..."
392
393
list_drivers
394
get_boot_key
395
get_system_information
396
get_networking_information
397
get_user_information
398
399
when /SOFTWARE/
400
401
puts "Found a SOFTWARE hive..."
402
403
list_applications
404
get_icq_information
405
get_system_information
406
get_networking_information
407
get_user_information
408
get_user_application_information
409
410
when /SAM/
411
412
puts "Found a SAM hive..."
413
414
get_networking_information
415
get_user_information
416
417
when /SECURITY/
418
419
puts "Found a SECURITY hive..."
420
421
get_user_information
422
423
when /NTUSER\.dat/i
424
425
puts "Found a NTUSER.dat hive..."
426
427
get_aol_instant_messenger_information
428
get_icq_information
429
get_ie_information
430
get_msn_messenger_information
431
get_outlook_information
432
get_windows_messenger_information
433
get_yahoo_messenger_information
434
get_networking_information
435
get_user_information
436
get_user_application_information
437
438
end
439
end
440
441
when "get_aol_instant_messenger_information"
442
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
443
444
if @hive.hive_name !~ /NTUSER\.DAT/i
445
puts "I need the NTUSER.dat hive, not #{@hive.hive_name}."
446
else
447
get_aol_instant_messenger_information
448
end
449
450
when "get_icq_information"
451
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
452
453
if @hive.hive_name !~ /NTUSER\.dat/i && @hive.hive_name !~ /SOFTWARE/
454
puts "I need either a SOFTWARE or NTUSER.dat hive, not #{@hive.hive_name}."
455
else
456
get_icq_information
457
end
458
459
when "get_ie_information"
460
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
461
462
if @hive.hive_name !~ /NTUSER\.dat/i
463
puts "I need an NTUSER.dat hive, not #{@hive.hive_name}."
464
else
465
get_ie_information
466
end
467
468
when "get_msn_messenger_information"
469
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
470
471
if @hive.hive_name !~ /NTUSER\.dat/i
472
puts "I need an NTUSER.dat hive, not #{@hive.hive_name}."
473
else
474
get_msn_messenger_information
475
end
476
477
when "get_outlook_information"
478
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
479
480
if @hive.hive_name !~ /NTUSER\.dat/i
481
puts "I need an NTUSER.dat hive, not #{@hive.hive_name}."
482
else
483
get_outlook_information
484
end
485
486
when "get_windows_messenger_information"
487
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
488
489
if @hive.hive_name !~ /NTUSER\.dat/i
490
puts "I need an NTUSER.dat hive, not a #{@hive.hive_name}."
491
else
492
get_windows_messenger_information
493
end
494
495
when "get_yahoo_messenger_information"
496
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
497
498
if @hive.hive_name !~ /NTUSER\.dat/i
499
puts "I need an NTUSER.dat hive, not a #{@hive.hive_name}."
500
else
501
get_yahoo_messenger_information
502
end
503
504
when "get_system_information"
505
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
506
507
if @hive.hive_name !~ /SYSTEM/ && @hive.hive_name !~ /SOFTWARE/
508
puts "I need the SYSTEM or SOFTWARE hive, not #{@hive.hive_name}."
509
else
510
get_system_information
511
end
512
513
when "get_networking_information"
514
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
515
516
if @hive.hive_name !~ /SAM/ && @hive.hive_name !~ /SYSTEM/ && @hive.hive_name !~ /NTUSER\.dat/i
517
puts "I need either a SAM, SYSTEM, or NTUSER.dat hive, not a #{@hive.hive_name}."
518
else
519
get_networking_information
520
end
521
522
when "get_user_information"
523
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
524
525
if @hive.hive_name !~ /SAM/
526
puts "I need a SAM hive. Not a #{@hive.hive_name}."
527
else
528
get_user_information
529
end
530
531
when "get_user_application_information"
532
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
533
534
if @hive.hive_name !~ /NTUSER\.dat/i && @hive.hive_name !~ /SOFTWARE/
535
puts "I need either an NTUSER.dat or SOFTWARE hive, not a #{@hive.hive_name}."
536
else
537
get_user_application_information
538
end
539
540
else
541
puts "Sorry invalid command, try with \"help\""
542
end
543
rescue SignalException => e
544
puts("Aborted! #{e}")
545
end
546
547