lib/metasploit/aggregator/tlv/uuid.rb in metasploit-aggregator-0.1.2 vs lib/metasploit/aggregator/tlv/uuid.rb in metasploit-aggregator-0.1.3
- old
+ new
@@ -7,269 +7,269 @@
module Metasploit
module Aggregator
module Tlv
class UUID
- include Rex::Arch
- #
- # Constants
- #
+ include Rex::Arch
+ #
+ # Constants
+ #
- Architectures = {
- 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
- }
+ Architectures = {
+ 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'
- }
+ 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'
+ }
- # The raw length of the UUID structure
- RawLength = 16
+ # The raw length of the UUID structure
+ RawLength = 16
- # The base64url-encoded length of the UUID structure
- UriLength = 22
+ # The base64url-encoded length of the UUID structure
+ UriLength = 22
- # Validity constraints for UUID timestamps in UTC
- TimestampMaxFuture = Time.now.utc.to_i + (30*24*3600) # Up to 30 days in the future
- TimestampMaxPast = 1420070400 # Since 2015-01-01 00:00:00 UTC
+ # Validity constraints for UUID timestamps in UTC
+ TimestampMaxFuture = Time.now.utc.to_i + (30*24*3600) # Up to 30 days in the future
+ TimestampMaxPast = 1420070400 # Since 2015-01-01 00:00:00 UTC
- #
- # Class Methods
- #
+ #
+ # Class Methods
+ #
- #
- # 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
- #
- def self.parse_raw(raw)
- if raw.to_s.length < 16
- raise ArgumentError, "Raw UUID must be at least 16 bytes"
+ #
+ # 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
+ #
+ 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
- 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
+ #
+ # 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
+ #
+ 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
- #
- # 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
- #
- 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] }
+ #
+ # 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
+ #
+ 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
- uuid
- end
- #
- # 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
- #
- 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
+ #
+ # 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
+ #
+ 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
- #
- # 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
- #
- 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
+ def self.find_platform_name(num)
+ Platforms[num]
+ end
- def self.find_platform_name(num)
- Platforms[num]
- end
+ def self.find_architecture_name(num)
+ Architectures[num]
+ end
- def self.find_architecture_name(num)
- Architectures[num]
- end
+ #
+ # Instance methods
+ #
- #
- # Instance methods
- #
+ def initialize(opts=nil)
+ opts = load_new if opts.nil?
+ opts = load_raw(opts[:raw]) if opts[:raw]
- 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]
- 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
- # 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
+ #
+ # 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
+ #
+ def load_raw(raw)
+ self.class.filter_invalid(self.class.parse_raw(raw))
+ end
- #
- # 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
- #
- def load_raw(raw)
- self.class.filter_invalid(self.class.parse_raw(raw))
- end
+ def load_new
+ self.class.parse_raw(self.class.generate_raw())
+ end
- def load_new
- self.class.parse_raw(self.class.generate_raw())
- end
+ #
+ # Provides a string representation of a UUID
+ #
+ # @return [String] The human-readable version of the UUID data
+ #
+ 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
- #
- # Provides a string representation of a UUID
- #
- # @return [String] The human-readable version of the UUID data
- #
- 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
+ #
+ # Return a string that represents the Meterpreter arch/platform
+ #
+ 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
- #
- # Return a string that represents the Meterpreter arch/platform
- #
- 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
+ #
+ # Provides a hash representation of a UUID
+ #
+ # @return [Hash] The hash representation of the UUID suitable for creating a new one
+ #
+ def to_h
+ {
+ puid: self.puid,
+ arch: self.arch, platform: self.platform,
+ timestamp: self.timestamp,
+ xor1: self.xor1, xor2: self.xor2
+ }
end
- "#{arch}/#{self.platform}"
- end
- #
- # Provides a hash representation of a UUID
- #
- # @return [Hash] The hash representation of the UUID suitable for creating a new one
- #
- def to_h
- {
- puid: self.puid,
- arch: self.arch, platform: self.platform,
- timestamp: self.timestamp,
- xor1: self.xor1, xor2: self.xor2
- }
- end
+ #
+ # Provides a raw byte representation of a UUID
+ #
+ # @return [String] The 16-byte raw encoded version of the UUID
+ #
+ def to_raw
+ self.class.generate_raw(self.to_h)
+ end
- #
- # Provides a raw byte representation of a UUID
- #
- # @return [String] The 16-byte raw encoded version of the UUID
- #
- def to_raw
- self.class.generate_raw(self.to_h)
- end
+ #
+ # Provides a hex representation of the Payload UID of the UUID
+ #
+ # @return [String] The 16-byte hex string representing the Payload UID
+ #
+ def puid_hex
+ self.puid.unpack('H*').first
+ end
- #
- # Provides a hex representation of the Payload UID of the UUID
- #
- # @return [String] The 16-byte hex string representing the Payload UID
- #
- def puid_hex
- self.puid.unpack('H*').first
- end
+ #
+ # Clears the two random XOR keys used for obfuscation
+ #
+ def xor_reset
+ self.xor1 = self.xor2 = nil
+ self
+ end
- #
- # Clears the two random XOR keys used for obfuscation
- #
- def xor_reset
- self.xor1 = self.xor2 = nil
- self
+ attr_accessor :arch
+ attr_accessor :platform
+ attr_accessor :timestamp
+ attr_accessor :puid
+ attr_accessor :xor1
+ attr_accessor :xor2
end
-
- attr_accessor :arch
- attr_accessor :platform
- attr_accessor :timestamp
- attr_accessor :puid
- attr_accessor :xor1
- attr_accessor :xor2
- end
end
end
end