Skip to content

Commit f676dc0

Browse files
author
HD Moore
committed
Lands rapid7#4849, prevents the target from running out of memory during NTFS reads
2 parents 24440b8 + 7252ba2 commit f676dc0

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

lib/rex/parser/fs/ntfs.rb

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ def cluster_from_attribute_non_resident(attribute, cluster_num = 0, size_max = (
181181

182182
data = ''
183183
while data.length < size_wanted
184-
data << @file_handler.read(size_wanted - data.length)
184+
# Use a 4Mb block size to avoid target memory consumption
185+
data << @file_handler.read([size_wanted - data.length, 2**22].min)
185186
end
186187
attribut << data
187188
end
@@ -196,8 +197,11 @@ def cluster_from_attribute_non_resident(attribute, cluster_num = 0, size_max = (
196197
#
197198
# return the attribute list from the MFT record
198199
# deal with resident and non resident attributes (but not $DATA due to performance issue)
200+
# if lazy = True, this function only gather essential non resident attributes
201+
# (INDEX_ALLOCATION). Non resident attributes can still be gathered later with
202+
# cluster_from_attribute_non_resident function.
199203
#
200-
def mft_record_attribute(mft_record)
204+
def mft_record_attribute(mft_record, lazy=true)
201205
attribute_list_offset = mft_record[20, 2].unpack('C')[0]
202206
curs = attribute_list_offset
203207
attribute_identifier = mft_record[curs, 4].unpack('V')[0]
@@ -213,10 +217,11 @@ def mft_record_attribute(mft_record)
213217
res[attribute_identifier] = mft_record[curs + content_offset, content_size]
214218
else
215219
# non resident
216-
if attribute_identifier == DATA_ATTRIBUTE_ID
217-
res[attribute_identifier] = mft_record[curs, attribute_size]
218-
else
220+
if attribute_identifier == INDEX_ALLOCATION_ID or
221+
(!lazy and attribute_identifier != DATA_ATTRIBUTE_ID)
219222
res[attribute_identifier] = cluster_from_attribute_non_resident(mft_record[curs, attribute_size])
223+
else
224+
res[attribute_identifier] = mft_record[curs, attribute_size]
220225
end
221226
end
222227
if attribute_identifier == DATA_ATTRIBUTE_ID

modules/post/windows/gather/file_from_raw_ntfs.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,12 @@ def run
9494
end
9595

9696
def read(size)
97+
vprint_debug("Reading #{size} bytes")
9798
client.railgun.kernel32.ReadFile(@handle, size, size, 4, nil)['lpBuffer']
9899
end
99100

100101
def seek(offset)
102+
vprint_debug("Seeking to offset #{offset}")
101103
high_offset = offset >> 32
102104
low_offset = offset & (2**33 - 1)
103105
client.railgun.kernel32.SetFilePointer(@handle, low_offset, high_offset, 0)

0 commit comments

Comments
 (0)