Class: Rex::Parser::AppleBackupManifestDB

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/parser/apple_backup_manifestdb.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mbdb_data, mbdx_data) ⇒ AppleBackupManifestDB

Returns a new instance of AppleBackupManifestDB.



17
18
19
20
21
22
23
24
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 17

def initialize(mbdb_data, mbdx_data)
	self.entries = {}
	self.entry_offsets = {}
	self.mbdb_data = mbdb_data
	self.mbdx_data = mbdx_data
	parse_mbdb
	parse_mbdx
end

Instance Attribute Details

#entriesObject

Returns the value of attribute entries.



12
13
14
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 12

def entries
  @entries
end

#entry_offsetsObject

Returns the value of attribute entry_offsets.



11
12
13
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 11

def entry_offsets
  @entry_offsets
end

#mbdbObject

Returns the value of attribute mbdb.



13
14
15
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 13

def mbdb
  @mbdb
end

#mbdb_dataObject

Returns the value of attribute mbdb_data.



14
15
16
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 14

def mbdb_data
  @mbdb_data
end

#mbdb_offsetObject

Returns the value of attribute mbdb_offset.



15
16
17
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 15

def mbdb_offset
  @mbdb_offset
end

#mbdxObject

Returns the value of attribute mbdx.



13
14
15
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 13

def mbdx
  @mbdx
end

#mbdx_dataObject

Returns the value of attribute mbdx_data.



14
15
16
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 14

def mbdx_data
  @mbdx_data
end

#mbdx_offsetObject

Returns the value of attribute mbdx_offset.



15
16
17
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 15

def mbdx_offset
  @mbdx_offset
end

Class Method Details

.from_files(mbdb_file, mbdx_file) ⇒ Object



26
27
28
29
30
31
32
33
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 26

def self.from_files(mbdb_file, mbdx_file)
	mbdb_data = ""
	::File.open(mbdb_file, "rb") {|fd| mbdb_data = fd.read(fd.stat.size) }
	mbdx_data = ""
	::File.open(mbdx_file, "rb") {|fd| mbdx_data = fd.read(fd.stat.size) }

	self.new(mbdb_data, mbdx_data)
end

Instance Method Details

#mbdb_read_int(size) ⇒ Object



101
102
103
104
105
106
107
108
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 101

def mbdb_read_int(size)
	val = 0
	size.downto(1) do |i|
		val = (val << 8) + self.mbdb_data[self.mbdb_offset, 1].unpack("C")[0]
		self.mbdb_offset += 1
	end
	val
end

#mbdb_read_stringObject

Raises:



91
92
93
94
95
96
97
98
99
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 91

def mbdb_read_string
	raise RuntimeError, "Corrupted MBDB file" if self.mbdb_offset > self.mbdb_data.length
	len = self.mbdb_data[self.mbdb_offset, 2].unpack("n")[0]
	self.mbdb_offset += 2
	return '' if len == 65535
	val = self.mbdb_data[self.mbdb_offset, len]
	self.mbdb_offset += len
	return val
end

#mbdx_read_int(size) ⇒ Object



120
121
122
123
124
125
126
127
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 120

def mbdx_read_int(size)
	val = 0
	size.downto(1) do |i|
		val = (val << 8) + self.mbdx_data[self.mbdx_offset, 1].unpack("C")[0]
		self.mbdx_offset += 1
	end
		val
end

#mbdx_read_stringObject

Raises:



110
111
112
113
114
115
116
117
118
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 110

def mbdx_read_string
	raise RuntimeError, "Corrupted MBDX file" if self.mbdx_offset > self.mbdx_data.length
	len = self.mbdx_data[self.mbdx_offset, 2].unpack("n")[0]
	self.mbdx_offset += 2
	return '' if len == 65535
	val = self.mbdx_data[self.mbdx_offset, len]
	self.mbdx_offset += len
	return val
end

#parse_mbdbObject

Raises:



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 35

def parse_mbdb
	raise ArgumentError, "Not valid MBDB data" if self.mbdb_data[0,4] != "mbdb"
	self.mbdb_offset = 4
	self.mbdb_offset = self.mbdb_offset + 2 # Maps to \x05 \x00 (unknown)

	while self.mbdb_offset < self.mbdb_data.length
		info = {}
		info[:start_offset] = self.mbdb_offset
		info[:domain]       = mbdb_read_string
		info[:filename]     = mbdb_read_string
		info[:linktarget]   = mbdb_read_string
		info[:datahash]     = mbdb_read_string
		info[:unknown1]     = mbdb_read_string
		info[:mode]         = mbdb_read_int(2)
		info[:unknown2]     = mbdb_read_int(4)
		info[:unknown3]     = mbdb_read_int(4)
		info[:uid]          = mbdb_read_int(4)
		info[:gid]          = mbdb_read_int(4)
		info[:mtime]        = Time.at(mbdb_read_int(4))
		info[:atime]        = Time.at(mbdb_read_int(4))
		info[:ctime]        = Time.at(mbdb_read_int(4))
		info[:length]       = mbdb_read_int(8)
		info[:flag]         = mbdb_read_int(1)
		property_count      = mbdb_read_int(1)
		info[:properties]   = {}
		1.upto(property_count) do |i|
			k = mbdb_read_string
			v = mbdb_read_string
			info[:properties][k] = v
		end
		self.entry_offsets[ info[:start_offset] ] = info
	end
	self.mbdb_data = ""
end

#parse_mbdxObject

Raises:



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/rex/parser/apple_backup_manifestdb.rb', line 70

def parse_mbdx
	raise ArgumentError, "Not a valid MBDX file" if self.mbdx_data[0,4] != "mbdx"

	self.mbdx_offset = 4
	self.mbdx_offset = self.mbdx_offset + 2 # Maps to \x02 \x00 (unknown)

	file_count = mbdx_read_int(4)

	while self.mbdx_offset < self.mbdx_data.length
		file_id = self.mbdx_data[self.mbdx_offset, 20].unpack("C*").map{|c| "%02x" % c}.join
		self.mbdx_offset += 20
		entry_offset = mbdx_read_int(4) + 6
		mode = mbdx_read_int(2)
		entry = entry_offsets[ entry_offset ]
		# May be corrupted if there is no matching entry, but what to do about it?
		next if not entry
		self.entries[file_id] = entry.merge({:mbdx_mode => mode, :file_id => file_id})
	end
	self.mbdx_data = ""
end