Class: Msf::Exploit::Remote::NDMPSocket::NDMP::Socket

Inherits:
Object
  • Object
show all
Defined in:
lib/msf/core/exploit/remote/ndmp_socket.rb

Overview

This class wraps a normal socket with NDMP functionality, such as NDMP message reading and writing.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sock) ⇒ Socket

Returns a new instance of Socket.



60
61
62
63
# File 'lib/msf/core/exploit/remote/ndmp_socket.rb', line 60

def initialize(sock)
  @sock = sock
  @next_sequence_num = 1
end

Class Method Details

.raw_recv(n, *_args) ⇒ Object



144
145
146
# File 'lib/msf/core/exploit/remote/ndmp_socket.rb', line 144

def self.raw_recv(n, *_args)
  @sock.sysread(n)
end

.raw_send(b, *_args) ⇒ Object



148
149
150
# File 'lib/msf/core/exploit/remote/ndmp_socket.rb', line 148

def self.raw_send(b, *_args)
  @sock.syswrite(b)
end

Instance Method Details

#closeObject



94
95
96
# File 'lib/msf/core/exploit/remote/ndmp_socket.rb', line 94

def close
  @sock.close
end

#do_request_response(msg, *args) ⇒ Object

Send and receive a pair of NDMP messages.



131
132
133
134
# File 'lib/msf/core/exploit/remote/ndmp_socket.rb', line 131

def do_request_response(msg, *args)
  return nil unless prepare_and_write_ndmp_msg(msg, *args)
  read_ndmp_msg(msg.header.type)
end

#prepare_and_write_ndmp_msg(msg, all_but_last_char = false, times = 1, flags = 0) ⇒ Object

Prepare a NDMP message for sending and send it. Can send messages multiple times.

If all_but_all_char is true, then the last character will be held back and will be returned so that it can be sent at a later point elsewhere. This is sometimes necessary for exploiting e.g. race conditions.



119
120
121
122
123
124
125
126
# File 'lib/msf/core/exploit/remote/ndmp_socket.rb', line 119

def prepare_and_write_ndmp_msg(msg, all_but_last_char=false, times=1, flags=0)
  msg.header.sequence_num = @next_sequence_num
  @next_sequence_num += 1
  msg.header.timestamp = Time.now.to_i

  frag = msg.header.to_xdr + msg.body
  write_ndmp_frag(frag, all_but_last_char, times, flags)
end

#raw_recv(*args) ⇒ Object



65
66
67
# File 'lib/msf/core/exploit/remote/ndmp_socket.rb', line 65

def raw_recv(*args)
  @sock.recv(*args)
end

#raw_recvall(n, *args) ⇒ Object



69
70
71
72
73
74
75
76
77
# File 'lib/msf/core/exploit/remote/ndmp_socket.rb', line 69

def raw_recvall(n, *args)
  r = ''
  while r.length < n
    s = raw_recv(n - r.length, *args)
    return nil if s.to_s.empty?
    r << s
  end
  r
end

#raw_send(*args) ⇒ Object



79
80
81
# File 'lib/msf/core/exploit/remote/ndmp_socket.rb', line 79

def raw_send(*args)
  @sock.send(*args)
end

#raw_sendall(s, *args) ⇒ Object



83
84
85
86
87
88
89
90
91
92
# File 'lib/msf/core/exploit/remote/ndmp_socket.rb', line 83

def raw_sendall(s, *args)
  n = 0
  while n < s.length
    i = raw_send(s[n..s.length], *args)
    return false if i <= 0
    n += i
  end

  true
end

#read_ndmp_msg(require_ok_type = nil) ⇒ Object

Read a single NDMP message. If require_ok_type is given, the message must be of the given type and have no error indicated.



102
103
104
105
106
107
108
109
110
# File 'lib/msf/core/exploit/remote/ndmp_socket.rb', line 102

def read_ndmp_msg(require_ok_type=nil)
  frags = read_ndmp_frags
  return nil if frags.nil?
  header = Message::Header.from_xdr(frags.slice!(0...(4 * 6)))

  return nil if require_ok_type && (require_ok_type != header.type || header.error != 0)

  Message.new(header, frags)
end

#wrap_with_ssl(ssl_context) ⇒ Object

Establish a SSL session on the socket. Raw socket reading/writing functions are replaced with their SSL equivalents.



140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/msf/core/exploit/remote/ndmp_socket.rb', line 140

def wrap_with_ssl(ssl_context)
  @sock = OpenSSL::SSL::SSLSocket.new(@sock, ssl_context)
  @sock.connect

  def self.raw_recv(n, *_args)
    @sock.sysread(n)
  end

  def self.raw_send(b, *_args)
    @sock.syswrite(b)
  end
end