class Rex::Post::Meterpreter::PacketParser

This class is responsible for reading in and decrypting meterpreter packets that arrive on a socket

Constants

HEADER_SIZE

4 byte xor 4 byte length 4 byte type

Public Class Methods

new(cipher = nil) click to toggle source

Initializes the packet parser context with an optional cipher.

# File lib/rex/post/meterpreter/packet_parser.rb, line 22
def initialize(cipher = nil)
  self.cipher = cipher

  reset
end

Public Instance Methods

recv(sock) click to toggle source

Reads data from the wire and parse as much of the packet as possible.

# File lib/rex/post/meterpreter/packet_parser.rb, line 40
def recv(sock)
  # Create a typeless packet
  packet = Packet.new(0)

  if (self.hdr_length_left > 0)
    buf = sock.read(self.hdr_length_left)

    if (buf)
      self.raw << buf

      self.hdr_length_left -= buf.length
    else
      raise EOFError
    end

    # If we've finished reading the header, set the
    # payload length left to the number of bytes
    # specified in the length
    if (self.hdr_length_left == 0)
      xor_key = raw[0, 4].unpack('N')[0]
      length_bytes = packet.xor_bytes(xor_key, raw[4, 4])
      # header size doesn't include the xor key, which is always tacked on the front
      self.payload_length_left = length_bytes.unpack("N")[0] - (HEADER_SIZE - 4)
    end
  elsif (self.payload_length_left > 0)
    buf = sock.read(self.payload_length_left)

    if (buf)
      self.raw << buf

      self.payload_length_left -= buf.length
    else
      raise EOFError
    end
  end

  # If we've finished reading the entire packet
  if ((self.hdr_length_left == 0) &&
      (self.payload_length_left == 0))

    # TODO: cipher decryption
    if (cipher)
    end

    # Deserialize the packet from the raw buffer
    packet.from_r(self.raw)

    # Reset our state
    reset

    return packet
  end
end
reset() click to toggle source

Resets the parser state so that a new packet can begin being parsed.

# File lib/rex/post/meterpreter/packet_parser.rb, line 31
def reset
  self.raw = ''
  self.hdr_length_left = HEADER_SIZE
  self.payload_length_left = 0
end