Class: Msf::Payload::UUID
- Inherits:
-
Object
- Object
- Msf::Payload::UUID
- Defined in:
- lib/msf/core/payload/uuid.rb
Overview
unique ID values used by payloads.
Defined Under Namespace
Modules: Options
Constant Summary collapse
- Architectures =
Constants
{ 0 => nil, 1 => Rex::Arch::ARCH_X86, 2 => Rex::Arch::ARCH_X64, # removed Rex::Arch::ARCH_X86_64, now consistent across the board 3 => Rex::Arch::ARCH_X64, 4 => Rex::Arch::ARCH_MIPS, 5 => Rex::Arch::ARCH_MIPSLE, 6 => Rex::Arch::ARCH_MIPSBE, 7 => Rex::Arch::ARCH_PPC, 8 => Rex::Arch::ARCH_PPC64, 9 => Rex::Arch::ARCH_CBEA, 10 => Rex::Arch::ARCH_CBEA64, 11 => Rex::Arch::ARCH_SPARC, 12 => Rex::Arch::ARCH_ARMLE, 13 => Rex::Arch::ARCH_ARMBE, 14 => Rex::Arch::ARCH_CMD, 15 => Rex::Arch::ARCH_PHP, 16 => Rex::Arch::ARCH_TTY, 17 => Rex::Arch::ARCH_JAVA, 18 => Rex::Arch::ARCH_RUBY, 19 => Rex::Arch::ARCH_DALVIK, 20 => Rex::Arch::ARCH_PYTHON, 21 => Rex::Arch::ARCH_NODEJS, 22 => Rex::Arch::ARCH_FIREFOX, 23 => Rex::Arch::ARCH_ZARCH, 24 => Rex::Arch::ARCH_AARCH64, 25 => Rex::Arch::ARCH_MIPS64, 26 => Rex::Arch::ARCH_PPC64LE, 27 => Rex::Arch::ARCH_R, 28 => Rex::Arch::ARCH_PPCE500V2 }
- 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', 24 => 'r', 25 => 'apple_ios', 26 => 'juniper', 27 => 'unifi', 28 => 'brocade', 29 => 'mikrotik', 30 => 'arista' }
- 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
-
#arch ⇒ Object
Returns the value of attribute arch.
-
#name ⇒ Object
Returns the value of attribute name.
-
#platform ⇒ Object
Returns the value of attribute platform.
-
#puid ⇒ Object
Returns the value of attribute puid.
-
#registered ⇒ Object
Returns the value of attribute registered.
-
#timestamp ⇒ Object
Returns the value of attribute timestamp.
-
#xor1 ⇒ Object
Returns the value of attribute xor1.
-
#xor2 ⇒ Object
Returns the value of attribute xor2.
Class Method Summary collapse
-
.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.
-
.find_architecture_id(name) ⇒ Integer
Look up the numeric architecture ID given a string as input.
- .find_architecture_name(num) ⇒ Object
-
.find_platform_id(platform) ⇒ Integer
Look up the numeric platform ID given a string or PlatformList as input.
- .find_platform_name(num) ⇒ Object
-
.generate_raw(opts = {}) ⇒ String
Generate a raw 16-byte payload UUID given a seed, platform, architecture, and timestamp.
-
.parse_raw(raw) ⇒ Hash
Parse a raw 16-byte payload UUID and return the payload ID, platform, architecture, and timestamp.
-
.parse_uri(uri) ⇒ Hash
Parse a 22-byte base64url-encoded payload UUID and return the hash.
-
.seed_to_puid(seed) ⇒ String
Generate a 8-byte payload ID given a seed string.
Instance Method Summary collapse
-
#initialize(opts = nil) ⇒ UUID
constructor
Instance methods.
- #load_new ⇒ Object
-
#load_raw(raw) ⇒ Hash
Initializes a UUID object given a raw 16+ byte blob.
-
#load_uri(uri) ⇒ Hash
Initializes a UUID object given a 22+ byte URI.
-
#puid_hex ⇒ String
Provides a hex representation of the Payload UID of the UUID.
-
#session_type ⇒ Object
Return a string that represents the Meterpreter arch/platform.
-
#to_h ⇒ Hash
Provides a hash representation of a UUID.
-
#to_raw ⇒ String
Provides a raw byte representation of a UUID.
-
#to_s ⇒ String
Provides a string representation of a UUID.
-
#to_uri ⇒ String
Provides a URI-encoded representation of a UUID.
-
#xor_reset ⇒ Object
Clears the two random XOR keys used for obfuscation.
Constructor Details
#initialize(opts = nil) ⇒ UUID
Instance methods
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/msf/core/payload/uuid.rb', line 249 def initialize(opts=nil) opts = load_new if opts.nil? opts = load_uri(opts[:uri]) if opts[:uri] opts = load_raw(opts[:raw]) if opts[:raw] self.puid = opts[:puid] self. = opts[:timestamp] self.arch = opts[:arch] self.platform = opts[:platform] self.xor1 = opts[:xor1] self.xor2 = opts[:xor2] self. = nil self.name = nil self.registered = false if opts[:seed] self.puid = self.class.seed_to_puid(opts[:seed]) end # Generate some sensible defaults self.puid ||= SecureRandom.random_bytes(8) self.xor1 ||= rand(256) self.xor2 ||= rand(256) self. ||= Time.now.utc.to_i end |
Instance Attribute Details
#arch ⇒ Object
Returns the value of attribute arch.
382 383 384 |
# File 'lib/msf/core/payload/uuid.rb', line 382 def arch @arch end |
#name ⇒ Object
Returns the value of attribute name.
380 381 382 |
# File 'lib/msf/core/payload/uuid.rb', line 380 def name @name end |
#platform ⇒ Object
Returns the value of attribute platform.
383 384 385 |
# File 'lib/msf/core/payload/uuid.rb', line 383 def platform @platform end |
#puid ⇒ Object
Returns the value of attribute puid.
416 417 418 |
# File 'lib/msf/core/payload/uuid.rb', line 416 def puid @puid end |
#registered ⇒ Object
Returns the value of attribute registered.
378 379 380 |
# File 'lib/msf/core/payload/uuid.rb', line 378 def registered @registered end |
#timestamp ⇒ Object
Returns the value of attribute timestamp.
379 380 381 |
# File 'lib/msf/core/payload/uuid.rb', line 379 def @timestamp end |
#xor1 ⇒ Object
Returns the value of attribute xor1.
417 418 419 |
# File 'lib/msf/core/payload/uuid.rb', line 417 def xor1 @xor1 end |
#xor2 ⇒ Object
Returns the value of attribute xor2.
418 419 420 |
# File 'lib/msf/core/payload/uuid.rb', line 418 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.
178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/msf/core/payload/uuid.rb', line 178 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) ⇒ Integer
Look up the numeric architecture ID given a string as input
230 231 232 233 234 235 |
# File 'lib/msf/core/payload/uuid.rb', line 230 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
241 242 243 |
# File 'lib/msf/core/payload/uuid.rb', line 241 def self.find_architecture_name(num) Architectures[num] end |
.find_platform_id(platform) ⇒ Integer
Look up the numeric platform ID given a string or PlatformList as input
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/msf/core/payload/uuid.rb', line 207 def self.find_platform_id(platform) # Handle a PlatformList input by grabbing the first entry if platform.respond_to?(:platforms) platform = platform.platforms.first.realname.downcase end # Map a platform abbreviation to the real name name = platform ? Msf::Platform.find_platform(platform) : nil if name && name.respond_to?(:realname) name = name.realname.downcase end ( Platforms.keys.select{ |k| Platforms[k] == name }.first || Platforms[0] ).to_i end |
.find_platform_name(num) ⇒ Object
237 238 239 |
# File 'lib/msf/core/payload/uuid.rb', line 237 def self.find_platform_name(num) Platforms[num] end |
.generate_raw(opts = {}) ⇒ String
Generate a raw 16-byte payload UUID given a seed, platform, architecture, and timestamp
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/msf/core/payload/uuid.rb', line 108 def self.generate_raw(opts={}) plat_id = find_platform_id(opts[:platform]) || 0 arch_id = find_architecture_id(opts[:arch]) || 0 tstamp = opts[:timestamp] || Time.now.utc.to_i puid = opts[:puid] if opts[:seed] puid = seed_to_puid(opts[:seed]) end puid ||= SecureRandom.random_bytes(8) if puid.length != 8 raise ArgumentError, "The :puid parameter must be exactly 8 bytes" end plat_xor = opts[:xor1] || rand(256) arch_xor = opts[:xor2] || rand(256) # Recycle the previous two XOR bytes to keep our output small time_xor = [plat_xor, arch_xor, plat_xor, arch_xor].pack('C4').unpack('N').first # Combine the payload UID with the arch/platform and use xor to # obscure the platform, architecture, and timestamp puid + [ plat_xor, arch_xor, plat_xor ^ plat_id, arch_xor ^ arch_id, time_xor ^ tstamp ].pack('C4N') end |
.parse_raw(raw) ⇒ Hash
Parse a raw 16-byte payload UUID and return the payload ID, platform, architecture, and timestamp
147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/msf/core/payload/uuid.rb', line 147 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 |
.parse_uri(uri) ⇒ Hash
Parse a 22-byte base64url-encoded payload UUID and return the hash
196 197 198 |
# File 'lib/msf/core/payload/uuid.rb', line 196 def self.parse_uri(uri) parse_raw(Rex::Text.decode_base64url(uri)) end |
.seed_to_puid(seed) ⇒ String
Generate a 8-byte payload ID given a seed string
166 167 168 |
# File 'lib/msf/core/payload/uuid.rb', line 166 def self.seed_to_puid(seed) Rex::Text.sha1_raw(seed)[12,8] end |
Instance Method Details
#load_new ⇒ Object
296 297 298 |
# File 'lib/msf/core/payload/uuid.rb', line 296 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
282 283 284 |
# File 'lib/msf/core/payload/uuid.rb', line 282 def load_raw(raw) self.class.filter_invalid(self.class.parse_raw(raw)) end |
#load_uri(uri) ⇒ Hash
Initializes a UUID object given a 22+ byte URI
292 293 294 |
# File 'lib/msf/core/payload/uuid.rb', line 292 def load_uri(uri) self.class.filter_invalid(self.class.parse_uri(uri)) end |
#puid_hex ⇒ String
Provides a hex representation of the Payload UID of the UUID
366 367 368 |
# File 'lib/msf/core/payload/uuid.rb', line 366 def puid_hex self.puid.unpack('H*').first end |
#session_type ⇒ Object
Return a string that represents the Meterpreter arch/platform
319 320 321 322 323 324 325 326 327 |
# File 'lib/msf/core/payload/uuid.rb', line 319 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 ⇒ Hash
Provides a hash representation of a UUID
334 335 336 337 338 339 340 341 |
# File 'lib/msf/core/payload/uuid.rb', line 334 def to_h { puid: self.puid, arch: self.arch, platform: self.platform, timestamp: self., xor1: self.xor1, xor2: self.xor2 } end |
#to_raw ⇒ String
Provides a raw byte representation of a UUID
348 349 350 |
# File 'lib/msf/core/payload/uuid.rb', line 348 def to_raw self.class.generate_raw(self.to_h) end |
#to_s ⇒ String
Provides a string representation of a UUID
305 306 307 308 309 310 311 312 313 314 |
# File 'lib/msf/core/payload/uuid.rb', line 305 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..to_i).utc.strftime("%Y-%m-%dT%H:%M:%SZ") ].join("/") end |
#to_uri ⇒ String
Provides a URI-encoded representation of a UUID
357 358 359 |
# File 'lib/msf/core/payload/uuid.rb', line 357 def to_uri Rex::Text.encode_base64url(self.to_raw) end |
#xor_reset ⇒ Object
Clears the two random XOR keys used for obfuscation
373 374 375 376 |
# File 'lib/msf/core/payload/uuid.rb', line 373 def xor_reset self.xor1 = self.xor2 = nil self end |