Mirror of metasploit
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ndmp.rb 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. # -*- coding: binary -*-
  2. require 'msf/core'
  3. module Msf
  4. ###
  5. #
  6. # This module exposes methods for accessing NDMP services
  7. #
  8. ###
  9. module Exploit::Remote::NDMP
  10. include Exploit::Remote::Tcp
  11. #
  12. # Creates an instance of a NDMP exploit module.
  13. #
  14. def initialize(info = {})
  15. super
  16. # Register the options that all NDMP exploits may make use of.
  17. register_options(
  18. [
  19. Opt::RHOST,
  20. Opt::RPORT(10000),
  21. ], Msf::Exploit::Remote::NDMP)
  22. self.recv_buff = ''
  23. end
  24. #
  25. # Flush the receive buffer on a new connection
  26. #
  27. def connect
  28. super
  29. self.recv_buff = ''
  30. end
  31. #
  32. # This method dumps ndmp version information
  33. #
  34. def ndmp_info
  35. connect
  36. req = [
  37. 1, # Sequence number
  38. Time.now.to_i, # Current time
  39. 0, # Message type (request)
  40. 0x108, # Message name (version)
  41. 0, # Reply sequence number
  42. 0, # Error status
  43. ].pack('NNNNNN')
  44. resp = ndmp_recv()
  45. ndmp_send(req)
  46. resp = ndmp_recv()
  47. disconnect
  48. if !(resp and resp.length > 28)
  49. return false
  50. end
  51. info = { }
  52. i = 32
  53. vend_len = resp[i, 4].unpack('N')[0]
  54. vend = resp[i + 4, vend_len]
  55. i += vend_len + 4 + 1
  56. prod_len = resp[i, 4].unpack('N')[0]
  57. prod = resp[i + 4, prod_len]
  58. i += prod_len + 4 + 1
  59. vers_len = resp[i, 4].unpack('N')[0]
  60. vers = resp[i + 4, vers_len]
  61. i += vers_len + 4 + 1
  62. info['Version'] = vers
  63. info['Product'] = prod
  64. info['Vendor'] = vend
  65. return info
  66. end
  67. #
  68. # This method reads from the socket and parses out a single
  69. # NDMP response, buffering the rest
  70. #
  71. def ndmp_recv(nsock = self.sock)
  72. # Attempt to read at least four bytes (the length value)
  73. if (self.recv_buff.length < 4)
  74. self.recv_buff << ( sock.get_once( 4 - self.recv_buff.length, 5) || '' )
  75. end
  76. # If we did not receive a full length value, return early
  77. if (self.recv_buff.length < 4)
  78. return false
  79. end
  80. # Read the length header out of the message
  81. dlen = self.recv_buff[0, 4].unpack('N')[0] & 0x7fffffff
  82. # Read any pending data and append it to the buffer
  83. self.recv_buff << ( sock.get_once || '' )
  84. # Do we have the entire response message?
  85. if (self.recv_buff.length >= dlen + 4)
  86. return self.recv_buff.slice!(0, dlen + 4)
  87. end
  88. return false
  89. end
  90. #
  91. # This method tacks a length header on a packet then sends
  92. # it out the socket
  93. #
  94. def ndmp_send(data, nsock = self.sock)
  95. nsock.put( [ data.length + 0x80000000 ].pack('N') + data )
  96. end
  97. attr_accessor :recv_buff
  98. end
  99. end