Class: Rex::Post::Meterpreter::PacketParser

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/post/meterpreter/packet_parser.rb

Overview

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

Constant Summary collapse

HEADER_SIZE =

4 byte xor 4 byte length 4 byte type

12

Instance Method Summary collapse

Constructor Details

#initialize(cipher = nil) ⇒ PacketParser

Initializes the packet parser context with an optional cipher.



23
24
25
26
27
# File 'lib/rex/post/meterpreter/packet_parser.rb', line 23

def initialize(cipher = nil)
  self.cipher = cipher

  reset
end

Instance Method Details

#recv(sock) ⇒ Object

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



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rex/post/meterpreter/packet_parser.rb', line 41

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

#resetObject

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



32
33
34
35
36
# File 'lib/rex/post/meterpreter/packet_parser.rb', line 32

def reset
  self.raw = ''
  self.hdr_length_left = HEADER_SIZE
  self.payload_length_left = 0
end