Parent

Class/Module Index [+]

Quicksearch

Rex::Post::Meterpreter::Tlv

Base TLV (Type-Length-Value) class

Attributes

compress[RW]
type[RW]
value[RW]

Public Class Methods

new(type, value = nil, compress=false) click to toggle source

Returns an instance of a TLV.

# File lib/rex/post/meterpreter/packet.rb, line 113
def initialize(type, value = nil, compress=false)
        @type     = type
        @compress = compress

        if (value != nil)
                if (type & TLV_META_TYPE_STRING == TLV_META_TYPE_STRING)
                        if (value.kind_of?(Fixnum))
                                @value = value.to_s
                        else
                                @value = value.dup
                        end
                else
                        @value = value
                end
        end
end

Public Instance Methods

from_r(raw) click to toggle source

Translates the raw format of the TLV into a sanitize version.

# File lib/rex/post/meterpreter/packet.rb, line 285
def from_r(raw)
        self.value  = nil

        length, self.type = raw.unpack("NN");

        # check if the tlv value has been compressed...
        if( self.type & TLV_META_TYPE_COMPRESSED == TLV_META_TYPE_COMPRESSED )
                # set this TLV as using compression
                @compress = true
                # remove the TLV_META_TYPE_COMPRESSED flag from the tlv type to restore the
                # tlv type to its origional, allowing for transparent data compression.
                self.type = self.type ^ TLV_META_TYPE_COMPRESSED
                # decompress the compressed data (skipping the length and type DWORD's)
                raw_decompressed = Rex::Text.zlib_inflate( raw[8..length-1] )
                # update the length to reflect the decompressed data length (+8 for the length and type DWORD's)
                length = raw_decompressed.length + 8
                # update the raw buffer with the new length, decompressed data and updated type.
                raw = [length, self.type].pack("NN") + raw_decompressed
        end

        if (self.type & TLV_META_TYPE_STRING == TLV_META_TYPE_STRING)
                if (raw.length > 0)
                        self.value = raw[8..length-2]
                else
                        self.value = nil
                end
        elsif (self.type & TLV_META_TYPE_UINT == TLV_META_TYPE_UINT)
                self.value = raw.unpack("NNN")[2]
        elsif (self.type & TLV_META_TYPE_QWORD == TLV_META_TYPE_QWORD)
                self.value = raw.unpack("NNQ")[2]
                self.value = self.ntohq( self.value )
        elsif (self.type & TLV_META_TYPE_BOOL == TLV_META_TYPE_BOOL)
                self.value = raw.unpack("NNc")[2]

                if (self.value == 1)
                        self.value = true
                else
                        self.value = false
                end
        else
                self.value = raw[8..length-1]
        end

        return length;
end
inspect() click to toggle source
# File lib/rex/post/meterpreter/packet.rb, line 130
def inspect
        utype = type ^ TLV_META_TYPE_COMPRESSED
        group = false
        meta = case (utype & TLV_META_MASK)
                when TLV_META_TYPE_STRING; "STRING"
                when TLV_META_TYPE_UINT; "INT"
                when TLV_META_TYPE_RAW; "RAW"
                when TLV_META_TYPE_BOOL; "BOOL"
                when TLV_META_TYPE_QWORD; "QWORD"
                when TLV_META_TYPE_GROUP; group=true; "GROUP"
                when TLV_META_TYPE_COMPLEX; "COMPLEX"
                else; 'unknown-meta-type'
                end
        stype = case type
                when PACKET_TYPE_REQUEST; "Request"
                when PACKET_TYPE_RESPONSE; "Response"
                when TLV_TYPE_REQUEST_ID; "REQUEST-ID"
                when TLV_TYPE_METHOD; "METHOD"
                when TLV_TYPE_RESULT; "RESULT"
                when TLV_TYPE_EXCEPTION; "EXCEPTION"
                when TLV_TYPE_STRING; "STRING"
                when TLV_TYPE_UINT; "UINT"
                when TLV_TYPE_BOOL; "BOOL"

                when TLV_TYPE_LENGTH; "LENGTH"
                when TLV_TYPE_DATA; "DATA"
                when TLV_TYPE_FLAGS; "FLAGS"

                when TLV_TYPE_CHANNEL_ID; "CHANNEL-ID"
                when TLV_TYPE_CHANNEL_TYPE; "CHANNEL-TYPE"
                when TLV_TYPE_CHANNEL_DATA; "CHANNEL-DATA"
                when TLV_TYPE_CHANNEL_DATA_GROUP; "CHANNEL-DATA-GROUP"
                when TLV_TYPE_CHANNEL_CLASS; "CHANNEL-CLASS"
                when TLV_TYPE_CHANNEL_PARENTID; "CHANNEL-PARENTID"

                when TLV_TYPE_SEEK_WHENCE; "SEEK-WHENCE"
                when TLV_TYPE_SEEK_OFFSET; "SEEK-OFFSET"
                when TLV_TYPE_SEEK_POS; "SEEK-POS"

                when TLV_TYPE_EXCEPTION_CODE; "EXCEPTION-CODE"
                when TLV_TYPE_EXCEPTION_STRING; "EXCEPTION-STRING"

                when TLV_TYPE_LIBRARY_PATH; "LIBRARY-PATH"
                when TLV_TYPE_TARGET_PATH; "TARGET-PATH"
                when TLV_TYPE_MIGRATE_PID; "MIGRATE-PID"
                when TLV_TYPE_MIGRATE_LEN; "MIGRATE-LEN"
                when TLV_TYPE_MIGRATE_PAYLOAD; "MIGRATE-PAYLOAD"
                when TLV_TYPE_MIGRATE_ARCH; "MIGRATE-ARCH"

                #when Extensions::Stdapi::TLV_TYPE_NETWORK_INTERFACE; 'network-interface'
                #when Extensions::Stdapi::TLV_TYPE_IP; 'ip-address'
                #when Extensions::Stdapi::TLV_TYPE_NETMASK; 'netmask'
                #when Extensions::Stdapi::TLV_TYPE_MAC_ADDRESS; 'mac-address'
                #when Extensions::Stdapi::TLV_TYPE_MAC_NAME; 'interface-name'
                #when Extensions::Stdapi::TLV_TYPE_IP6_SCOPE; 'address-scope'
                #when Extensions::Stdapi::TLV_TYPE_INTERFACE_MTU; 'interface-mtu'
                #when Extensions::Stdapi::TLV_TYPE_INTERFACE_FLAGS; 'interface-flags'
                #when Extensions::Stdapi::TLV_TYPE_INTERFACE_INDEX; 'interface-index'

                else; "unknown-#{type}"
                end
        val = value.inspect
        if val.length > 50
                val = val[0,50] + ' ..."'
        end
        group ||= (self.class.to_s =~ /Packet/)
        if group
                tlvs_inspect = "tlvs=[\n"
                @tlvs.each { |t|
                        tlvs_inspect << "  #{t.inspect}\n"
                }
                tlvs_inspect << "]"
        else
                tlvs_inspect = "meta=#{meta.ljust 10} value=#{val}"
        end
        "#<#{self.class} type=#{stype.ljust 15} #{tlvs_inspect}>"
end
meta_type?(meta) click to toggle source

Checks to see if a TLVs meta type is equivalent to the meta type passed.

# File lib/rex/post/meterpreter/packet.rb, line 217
def meta_type?(meta)
        return (self.type & meta == meta)
end
to_r() click to toggle source

Converts the TLV to raw.

# File lib/rex/post/meterpreter/packet.rb, line 244
def to_r
        # Forcibly convert to ASCII-8BIT encoding
        raw = value.to_s.unpack("C*").pack("C*")

        if (self.type & TLV_META_TYPE_STRING == TLV_META_TYPE_STRING)
                raw += "\x00"
        elsif (self.type & TLV_META_TYPE_UINT == TLV_META_TYPE_UINT)
                raw = [value].pack("N")
        elsif (self.type & TLV_META_TYPE_QWORD == TLV_META_TYPE_QWORD)
                raw = [ self.htonq( value.to_i ) ].pack("Q")
        elsif (self.type & TLV_META_TYPE_BOOL == TLV_META_TYPE_BOOL)
                if (value == true)
                        raw = [1].pack("c")
                else
                        raw = [0].pack("c")
                end
        end

        # check if the tlv is to be compressed...
        if( @compress )
                raw_uncompressed = raw
                # compress the raw data
                raw_compressed = Rex::Text.zlib_deflate( raw_uncompressed )
                # check we have actually made the raw data smaller...
                # (small blobs often compress slightly larger then the origional)
                # if the compressed data is not smaller, we dont use the compressed data
                if( raw_compressed.length < raw_uncompressed.length )
                        # if so, set the TLV's type to indicate compression is used
                        self.type = self.type | TLV_META_TYPE_COMPRESSED
                        # update the raw data with the uncompressed data length + compressed data
                        # (we include the uncompressed data length as the C side will need to know this for decompression)
                        raw = [ raw_uncompressed.length ].pack("N") + raw_compressed
                end
        end

        return [raw.length + 8, self.type].pack("NN") + raw
end
type?(type) click to toggle source

Checks to see if the TLVs type is equivalent to the type passed.

# File lib/rex/post/meterpreter/packet.rb, line 224
def type?(type)
        return self.type == type
end
value?(value) click to toggle source

Checks to see if the TLVs value is equivalent to the value passed.

# File lib/rex/post/meterpreter/packet.rb, line 231
def value?(value)
        return self.value == value
end

Protected Instance Methods

htonq( value ) click to toggle source
# File lib/rex/post/meterpreter/packet.rb, line 333
def htonq( value )
        if( [1].pack( 's' ) == [1].pack( 'n' ) )
                return value
        end
        return [ value ].pack( 'Q' ).reverse.unpack( 'Q' ).first
end
ntohq( value ) click to toggle source
# File lib/rex/post/meterpreter/packet.rb, line 340
def ntohq( value )
        return htonq( value )
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.