class Metasploit::Aggregator::Tlv::UUID

Constants

Architectures

Constants

Platforms
RawLength

The raw length of the UUID structure

TimestampMaxFuture

Validity constraints for UUID timestamps in UTC

TimestampMaxPast
UriLength

The base64url-encoded length of the UUID structure

Attributes

arch[RW]
platform[RW]
puid[RW]
timestamp[RW]
xor1[RW]
xor2[RW]

Public Class Methods

filter_invalid(uuid) click to toggle source

Filter out UUIDs with obviously invalid fields and return either a validated UUID or a UUID with the arch, platform, and timestamp fields strippped out.

@param uuid [Hash] The UUID in hash format @return [Hash] The filtered UUID in hash format

# File lib/metasploit/aggregator/tlv/uuid.rb, line 114
def self.filter_invalid(uuid)
  # Verify the UUID fields and return just the Payload ID unless the
  # timestamp is within our constraints and the UUID has either a
  # valid architecture or platform
  if uuid[:timestamp] > TimestampMaxFuture ||
      uuid[:timestamp] < TimestampMaxPast   ||
      (uuid[:arch].nil? && uuid[:platform].nil?)
    return { puid: uuid[:puid] }
  end
  uuid
end
find_architecture_id(name) click to toggle source

Look up the numeric architecture ID given a string as input

@param name [String] The name of the architecture to lookup @return [Fixnum] The integer value of this architecture

# File lib/metasploit/aggregator/tlv/uuid.rb, line 145
def self.find_architecture_id(name)
  name = name.first if name.kind_of? ::Array
  ( Architectures.keys.select{ |k|
    Architectures[k] == name
  }.first || Architectures[0] ).to_i
end
find_architecture_name(num) click to toggle source
# File lib/metasploit/aggregator/tlv/uuid.rb, line 156
def self.find_architecture_name(num)
  Architectures[num]
end
find_platform_id(platform) click to toggle source

Look up the numeric platform ID given a string or PlatformList as input

@param platform [String] The name of the platform to lookup @return [Fixnum] The integer value of this platform

# File lib/metasploit/aggregator/tlv/uuid.rb, line 132
def self.find_platform_id(platform)
  name = name.first if name.kind_of? ::Array
  ( Platforms.keys.select{ |k|
    Platforms[k] == name
  }.first || Platforms[0] ).to_i
end
find_platform_name(num) click to toggle source
# File lib/metasploit/aggregator/tlv/uuid.rb, line 152
def self.find_platform_name(num)
  Platforms[num]
end
new(opts=nil) click to toggle source

Instance methods

# File lib/metasploit/aggregator/tlv/uuid.rb, line 164
def initialize(opts=nil)
  opts = load_new if opts.nil?
  opts = load_raw(opts[:raw]) if opts[:raw]

  self.puid      = opts[:puid]
  self.timestamp = opts[:timestamp]
  self.arch      = opts[:arch]
  self.platform  = opts[:platform]
  self.xor1      = opts[:xor1]
  self.xor2      = opts[:xor2]

  # Generate some sensible defaults
  self.puid ||= SecureRandom.random_bytes(8)
  self.xor1 ||= rand(256)
  self.xor2 ||= rand(256)
  self.timestamp ||= Time.now.utc.to_i
end
parse_raw(raw) click to toggle source

Parse a raw 16-byte payload UUID and return the payload ID, platform, architecture, and timestamp

@param raw [String] The raw 16-byte payload UUID to parse @return [Hash] A hash containing the Payload ID, platform, architecture, and timestamp

# File lib/metasploit/aggregator/tlv/uuid.rb, line 93
def self.parse_raw(raw)
  if raw.to_s.length < 16
    raise ArgumentError, "Raw UUID must be at least 16 bytes"
  end

  puid, plat_xor, arch_xor, plat_id, arch_id, tstamp = raw.unpack('a8C4N')
  plat     = find_platform_name(plat_xor ^ plat_id)
  arch     = find_architecture_name(arch_xor ^ arch_id)
  time_xor = [plat_xor, arch_xor, plat_xor, arch_xor].pack('C4').unpack('N').first
  time     = time_xor ^ tstamp
  { puid: puid, platform: plat, arch: arch, timestamp: time, xor1: plat_xor, xor2: arch_xor }
end

Public Instance Methods

load_new() click to toggle source
# File lib/metasploit/aggregator/tlv/uuid.rb, line 192
def load_new
  self.class.parse_raw(self.class.generate_raw())
end
load_raw(raw) click to toggle source

Initializes a UUID object given a raw 16+ byte blob

@param raw [String] The string containing at least 16 bytes of encoded data @return [Hash] The attributes encoded into this UUID

# File lib/metasploit/aggregator/tlv/uuid.rb, line 188
def load_raw(raw)
  self.class.filter_invalid(self.class.parse_raw(raw))
end
puid_hex() click to toggle source

Provides a hex representation of the Payload UID of the UUID

@return [String] The 16-byte hex string representing the Payload UID

# File lib/metasploit/aggregator/tlv/uuid.rb, line 253
def puid_hex
  self.puid.unpack('H*').first
end
session_type() click to toggle source

Return a string that represents the Meterpreter arch/platform

# File lib/metasploit/aggregator/tlv/uuid.rb, line 215
def session_type
  # mini-patch for x86 so that it renders x64 instead. This is
  # mostly to keep various external modules happy.
  arch = self.arch
  if arch == ARCH_X86_64
    arch = ARCH_X64
  end
  "#{arch}/#{self.platform}"
end
to_h() click to toggle source

Provides a hash representation of a UUID

@return [Hash] The hash representation of the UUID suitable for creating a new one

# File lib/metasploit/aggregator/tlv/uuid.rb, line 230
def to_h
  {
      puid: self.puid,
      arch: self.arch, platform: self.platform,
      timestamp: self.timestamp,
      xor1: self.xor1, xor2: self.xor2
  }
end
to_raw() click to toggle source

Provides a raw byte representation of a UUID

@return [String] The 16-byte raw encoded version of the UUID

# File lib/metasploit/aggregator/tlv/uuid.rb, line 244
def to_raw
  self.class.generate_raw(self.to_h)
end
to_s() click to toggle source

Provides a string representation of a UUID

@return [String] The human-readable version of the UUID data

# File lib/metasploit/aggregator/tlv/uuid.rb, line 201
def to_s
  arch_id   = self.class.find_architecture_id(self.arch).to_s
  plat_id   = self.class.find_platform_id(self.platform).to_s
  [
      self.puid_hex,
      [ self.arch     || "noarch",     arch_id ].join("="),
      [ self.platform || "noplatform", plat_id ].join("="),
      Time.at(self.timestamp.to_i).utc.strftime("%Y-%m-%dT%H:%M:%SZ")
  ].join("/")
end
xor_reset() click to toggle source

Clears the two random XOR keys used for obfuscation

# File lib/metasploit/aggregator/tlv/uuid.rb, line 260
def xor_reset
  self.xor1 = self.xor2 = nil
  self
end