Class: Metasploit::Aggregator::Tlv::UUID

Inherits:
Object
  • Object
show all
Includes:
Rex::Arch
Defined in:
lib/metasploit/aggregator/tlv/uuid.rb

Constant Summary collapse

Architectures =

Constants

{
    0 => nil,
    1 => ARCH_X86,
    2 => ARCH_X64, # removed ARCH_X86_64, now consistent across the board
    3 => ARCH_X64,
    4 => ARCH_MIPS,
    5 => ARCH_MIPSLE,
    6 => ARCH_MIPSBE,
    7 => ARCH_PPC,
    8 => ARCH_PPC64,
    9 => ARCH_CBEA,
    10 => ARCH_CBEA64,
    11 => ARCH_SPARC,
    12 => ARCH_ARMLE,
    13 => ARCH_ARMBE,
    14 => ARCH_CMD,
    15 => ARCH_PHP,
    16 => ARCH_TTY,
    17 => ARCH_JAVA,
    18 => ARCH_RUBY,
    19 => ARCH_DALVIK,
    20 => ARCH_PYTHON,
    21 => ARCH_NODEJS,
    22 => ARCH_FIREFOX,
    23 => ARCH_ZARCH,
    24 => ARCH_AARCH64,
    25 => ARCH_MIPS64,
    26 => ARCH_PPC64LE
}
Platforms =
{
    0 => nil,
    1 => 'windows',
    2 => 'netware',
    3 => 'android',
    4 => 'java',
    5 => 'ruby',
    6 => 'linux',
    7 => 'cisco',
    8 => 'solaris',
    9 => 'osx',
    10 => 'bsd',
    11 => 'openbsd',
    12 => 'bsdi',
    13 => 'netbsd',
    14 => 'freebsd',
    15 => 'aix',
    16 => 'hpux',
    17 => 'irix',
    18 => 'unix',
    19 => 'php',
    20 => 'js',
    21 => 'python',
    22 => 'nodejs',
    23 => 'firefox'
}
RawLength =

The raw length of the UUID structure

16
UriLength =

The base64url-encoded length of the UUID structure

22
TimestampMaxFuture =

Validity constraints for UUID timestamps in UTC

Time.now.utc.to_i + (30*24*3600)
TimestampMaxPast =

Since 2015-01-01 00:00:00 UTC

1420070400

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = nil) ⇒ UUID

Instance methods



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 165

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

Instance Attribute Details

#archObject

Returns the value of attribute arch.



266
267
268
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 266

def arch
  @arch
end

#platformObject

Returns the value of attribute platform.



267
268
269
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 267

def platform
  @platform
end

#puidObject

Returns the value of attribute puid.



269
270
271
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 269

def puid
  @puid
end

#timestampObject

Returns the value of attribute timestamp.



268
269
270
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 268

def timestamp
  @timestamp
end

#xor1Object

Returns the value of attribute xor1.



270
271
272
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 270

def xor1
  @xor1
end

#xor2Object

Returns the value of attribute xor2.



271
272
273
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 271

def xor2
  @xor2
end

Class Method Details

.filter_invalid(uuid) ⇒ Hash

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.

Parameters:

  • uuid (Hash)

    The UUID in hash format

Returns:

  • (Hash)

    The filtered UUID in hash format



115
116
117
118
119
120
121
122
123
124
125
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 115

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) ⇒ Fixnum

Look up the numeric architecture ID given a string as input

Parameters:

  • name (String)

    The name of the architecture to lookup

Returns:

  • (Fixnum)

    The integer value of this architecture



146
147
148
149
150
151
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 146

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) ⇒ Object



157
158
159
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 157

def self.find_architecture_name(num)
  Architectures[num]
end

.find_platform_id(platform) ⇒ Fixnum

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

Parameters:

  • platform (String)

    The name of the platform to lookup

Returns:

  • (Fixnum)

    The integer value of this platform



133
134
135
136
137
138
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 133

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) ⇒ Object



153
154
155
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 153

def self.find_platform_name(num)
  Platforms[num]
end

.parse_raw(raw) ⇒ Hash

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

Parameters:

  • raw (String)

    The raw 16-byte payload UUID to parse

Returns:

  • (Hash)

    A hash containing the Payload ID, platform, architecture, and timestamp



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 94

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

Instance Method Details

#load_newObject



193
194
195
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 193

def load_new
  self.class.parse_raw(self.class.generate_raw())
end

#load_raw(raw) ⇒ Hash

Initializes a UUID object given a raw 16+ byte blob

Parameters:

  • raw (String)

    The string containing at least 16 bytes of encoded data

Returns:

  • (Hash)

    The attributes encoded into this UUID



189
190
191
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 189

def load_raw(raw)
  self.class.filter_invalid(self.class.parse_raw(raw))
end

#puid_hexString

Provides a hex representation of the Payload UID of the UUID

Returns:

  • (String)

    The 16-byte hex string representing the Payload UID



254
255
256
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 254

def puid_hex
  self.puid.unpack('H*').first
end

#session_typeObject

Return a string that represents the Meterpreter arch/platform



216
217
218
219
220
221
222
223
224
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 216

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_hHash

Provides a hash representation of a UUID

Returns:

  • (Hash)

    The hash representation of the UUID suitable for creating a new one



231
232
233
234
235
236
237
238
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 231

def to_h
  {
      puid: self.puid,
      arch: self.arch, platform: self.platform,
      timestamp: self.timestamp,
      xor1: self.xor1, xor2: self.xor2
  }
end

#to_rawString

Provides a raw byte representation of a UUID

Returns:

  • (String)

    The 16-byte raw encoded version of the UUID



245
246
247
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 245

def to_raw
  self.class.generate_raw(self.to_h)
end

#to_sString

Provides a string representation of a UUID

Returns:

  • (String)

    The human-readable version of the UUID data



202
203
204
205
206
207
208
209
210
211
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 202

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_resetObject

Clears the two random XOR keys used for obfuscation



261
262
263
264
# File 'lib/metasploit/aggregator/tlv/uuid.rb', line 261

def xor_reset
  self.xor1 = self.xor2 = nil
  self
end