updates to packet class and added packet parser

git-svn-id: file:///home/svn/incoming/trunk@2345 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
Matt Miller 2005-04-10 00:39:39 +00:00
parent 50d92bcafa
commit 1407b65ff5
2 changed files with 106 additions and 10 deletions

View File

@ -65,9 +65,11 @@ module Rex
module Post
module Meterpreter
###
#
# Base TLV class
#
###
class Tlv
attr_accessor :type, :value
@ -115,7 +117,7 @@ class Tlv
def from_r(raw)
self.value = nil
length, type = raw.unpack("NN");
length, self.type = raw.unpack("NN");
if (self.type & TLV_META_TYPE_STRING == TLV_META_TYPE_STRING)
if (raw.length > 0)
@ -133,9 +135,11 @@ class Tlv
end
end
###
#
# Group TLVs contain zero or more TLVs
#
###
class GroupTlv < Tlv
attr_accessor :tlvs
@ -181,9 +185,18 @@ class GroupTlv < Tlv
#
# Adds a TLV of a given type and value
def add_tlv(type, value = nil)
def add_tlv(type, value = nil, replace = false)
tlv = nil
# If we should replace any TLVs with the same type...remove them first
if (replace)
each(type) { |tlv|
if (tlv.type == type)
self.tlvs.delete(tlv)
end
}
end
if (type & TLV_META_TYPE_GROUP == TLV_META_TYPE_GROUP)
tlv = GroupTlv.new(type)
else
@ -222,7 +235,7 @@ class GroupTlv < Tlv
raw << tlv.to_r
}
return [raw.length, self.type].pack("NN") + raw
return [raw.length + 8, self.type].pack("NN") + raw
end
# From raw
@ -253,9 +266,11 @@ class GroupTlv < Tlv
end
###
#
# The logical meterpreter packet class
#
###
class Packet < GroupTlv
#
@ -293,14 +308,10 @@ class Packet < GroupTlv
if (method)
self.method = method
end
end
def type=(type)
@type = type
# If it's a request, generate a random request identifier
if ((type == PACKET_TYPE_REQUEST) ||
(type == PACKET_TYPE_RESPONSE))
(type == PACKET_TYPE_PLAINTEXT_REQUEST))
rid = ''
1.upto(32) { |val| rid << rand(10).to_s }
@ -314,7 +325,7 @@ class Packet < GroupTlv
end
def method=(method)
add_tlv(TLV_TYPE_METHOD, method)
add_tlv(TLV_TYPE_METHOD, method, true)
end
def method
@ -326,7 +337,7 @@ class Packet < GroupTlv
end
def result=(result)
add_tlv(TLV_TYPE_RESULT, result)
add_tlv(TLV_TYPE_RESULT, result, true)
end
def result

View File

@ -0,0 +1,85 @@
#!/usr/bin/ruby
module Rex
module Post
module Meterpreter
###
#
# PacketParser
# ------------
#
# This class is responsible for reading in and decrypting meterpreter
# packets that arrive on a socket
#
###
class PacketParser
def initialize(cipher = nil)
self.cipher = cipher
reset
end
def reset
self.raw = ''
self.hdr_length_left = 8
self.payload_length_left = 0
end
# Reads data from the wire
def recv(sock)
if (self.hdr_length_left > 0)
buf = sock.read(self.hdr_length_left)
if (buf)
self.raw << buf
self.hdr_length_left -= buf.length
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)
self.payload_length_left = raw.unpack("N")[0] - 8
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
end
end
# If we've finished reading the entire packet
if ((self.hdr_length_left == 0) &&
(self.payload_length_left == 0))
# Create a typeless packet
packet = Packet.new(0)
# TODO: cipher decryption
if (cipher)
puts "TODO: decryption\n"
end
# Serialize the packet from the raw buffer
packet.from_r(self.raw)
# Reset our state
reset
return packet
end
end
protected
attr_accessor :cipher, :raw, :hdr_length_left, :payload_length_left
end
end; end; end