| Trees | Indices | Help | 
 | 
|---|
|  | 
  1  # Rekall Memory Forensics 
  2  # Copyright (C) 2008-2011 Volatile Systems 
  3  # Copyright (C) 2011 Jamie Levy (Gleeda) <jamie.levy@gmail.com> 
  4  # Copyright 2013 Google Inc. All Rights Reserved. 
  5  # 
  6  # Additional Authors: 
  7  # Michael Cohen <scudette@gmail.com> 
  8  # 
  9  # This program is free software; you can redistribute it and/or modify 
 10  # it under the terms of the GNU General Public License as published by 
 11  # the Free Software Foundation; either version 2 of the License, or (at 
 12  # your option) any later version. 
 13  # 
 14  # This program is distributed in the hope that it will be useful, but 
 15  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 16  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 17  # General Public License for more details. 
 18  # 
 19  # You should have received a copy of the GNU General Public License 
 20  # along with this program; if not, write to the Free Software 
 21  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 22  # 
 23   
 24  """ 
 25  @author:       Jamie Levy (gleeda) 
 26  @license:      GNU General Public License 2.0 or later 
 27  @contact:      jamie.levy@gmail.com 
 28  @organization: Volatile Systems 
 29  """ 
 30  import ntpath 
 31   
 32  from rekall import obj 
 33  from rekall import scan 
 34  from rekall.plugins.windows.registry import registry 
 35  from rekall.plugins.windows.registry import getsids 
 36  from rekall_lib import utils 
 37   
 38  # for more information on Event Log structures see WFA 2E pg 260-263 by Harlan 
 39  # Carvey 
 40  evt_log_types = { 
 41      'EVTLogHeader' : [0x30, { 
 42          'HeaderSize' : [0x0, ['unsigned int']], 
 43          'Magic' : [0x4, ['String', dict(length=4)]],  # LfLe 
 44   
 45          # Offset of oldest record. 
 46          'OffsetOldest' : [0x10, ['int']], 
 47   
 48          # Offset of next record to be written. 
 49          'OffsetNextToWrite' : [0x14, ['int']], 
 50          'NextID' : [0x18, ['int']],  # Next event record ID. 
 51          'OldestID' : [0x1c, ['int']], # Oldest event record ID. 
 52   
 53          # Maximum size of event record (from registry). 
 54          'MaxSize' : [0x20, ['int']], 
 55   
 56          # Retention time of records (from registry). 
 57          'RetentionTime' : [0x28, ['int']], 
 58   
 59          # Size of the record (repeat of DWORD at offset 0). 
 60          'RecordSize' : [0x2c, ['int']], 
 61          }], 
 62   
 63      'EVTRecordStruct' : [0x38, { 
 64          'RecordLength' : [0x0, ['int']], 
 65          'Magic' : [0x4, ['String', dict(length=4)]],  # LfLe 
 66          'RecordNumber' : [0x8, ['int']], 
 67   
 68          'TimeGenerated' : [0xc, ['UnixTimeStamp']], 
 69          'TimeWritten' : [0x10, ['UnixTimeStamp']], 
 70   
 71          # Specific to event source and uniquely identifies the event. 
 72          'EventID' : [0x14, ['unsigned short']], 
 73          'EventType' : [0x18, ['Enumeration', dict( 
 74              target='unsigned short', 
 75              choices={0x01: "Error", 
 76                       0x02: "Warning", 
 77                       0x04: "Info", 
 78                       0x08: "Success", 
 79                       0x10: "Failure"})]], 
 80   
 81          # Number of description strings in event message. 
 82          'NumStrings' : [0x1a, ['unsigned short']], 
 83          'EventCategory' : [0x1c, ['unsigned short']], 
 84          'ReservedFlags' : [0x1e, ['unsigned short']], 
 85          'ClosingRecordNum' : [0x20, ['int']], 
 86   
 87          # Offset w/in record of description strings. 
 88          'StringOffset' : [0x24, ['int']], 
 89   
 90          # Length of SID: if 0 no SID is present. 
 91          'SidLength' : [0x28, ['int']], 
 92   
 93          # Offset w/in record to start of SID (if present). 
 94          'SidOffset' : [0x2c, ['int']], 
 95   
 96          # Length of binary data of record. 
 97          'DataLength' : [0x30, ['int']], 
 98   
 99          # Offset of data w/in record. 
100          'DataOffset' : [0x34, ['int']], 
101   
102          'Source': [0x38, ['UnicodeString', dict( 
103              length=lambda x: x.RecordLength)]], 
104   
105          # The computer name is right after the Source. 
106          'Computer': [lambda x: x.Source.obj_offset + x.Source.obj_size, 
107                       ['UnicodeString', dict( 
108                           length=lambda x: x.RecordLength)]], 
109   
110          'Sid': [lambda x: x.obj_offset + x.SidOffset.v(), ['_SID']], 
111   
112          'Data':[lambda x: x.obj_offset + x.StringOffset.v(), [ 
113              "ListArray", dict( 
114                  target="UnicodeString", 
115                  target_args=dict(encoding="utf16"), 
116                  maximum_size=lambda x: x.RecordLength, 
117                  count=lambda x: x.NumStrings)]], 
118          }], 
119   
120      "_SID": [None, { 
121          "IdentifierAuthority": [None, ["Enumeration", dict( 
122              choices={ 
123                  "\x00\x00\x00\x00\x00\x00": "Null Authority", 
124                  "\x00\x00\x00\x00\x00\x01": "World Authority", 
125                  "\x00\x00\x00\x00\x00\x02": "Local Authority", 
126                  "\x00\x00\x00\x00\x00\x03": "Creator Authority", 
127                  "\x00\x00\x00\x00\x00\x04": "NonUnique Authority", 
128                  "\x00\x00\x00\x00\x00\x05": "NT Authority", 
129                  }, 
130              target="String", 
131              target_args=dict(length=6, term=None) 
132              )]], 
133          "NumericIdentifier": [0x4, ["unsigned be int"]], 
134          "SubAuthority": [None, ["Array", dict( 
135              target="unsigned long", 
136              count=lambda x: x.SubAuthorityCount)]], 
137          }], 
138      } 
143      """A Pretty printing implementation of sids. 
144   
145      Reference: 
146      http://www.sekchek.com/downloads/white-papers/windows-about-sids.pdf 
147      """ 
149          """Format the Sid using SDDL Notation.""" 
150          components = [self.Revision, self.NumericIdentifier] 
151          components.extend(self.SubAuthority) 
152   
153          result = u"S-" + u"-".join([str(x) for x in components]) 
154   
155          # Try to resolve a friendly name from the cache in the context. 
156          friendly_name = self.obj_context.get("sid_cache", {}).get(result) 
157          if friendly_name: 
158              result = u"%s (%s)" % (result, friendly_name) 
159   
160          return result 
161   
170   
173      checks = [('StringCheck', dict(needle="LfLe"))] 
174   
176          for hit in super(EVTScanner, self).scan(offset, maxlen=maxlen): 
177              event_offset = hit - self.profile.get_obj_offset( 
178                  "EVTRecordStruct", "Magic") 
179   
180              event = self.profile.EVTRecordStruct( 
181                  offset=event_offset, vm=self.address_space, context=context) 
182   
183              # Eliminate crazy events (between 2001 and 2017): 
184              if (1500000000 > event.TimeGenerated > 1000000000 and 
185                      1500000000 > event.TimeWritten > 1000000000): 
186                  yield event 
187   
190      """Extract Windows Event Logs (XP/2003 only)""" 
191   
192      name = "evtlogs" 
193      mode = "mode_xp" 
194   
196          super(EvtLogs, self).__init__(**kwargs) 
197          self.profile = EVTObjectTypes(self.profile) 
198          self.context = dict(sid_cache={}) 
199   
201          """Search for event log files in memory. 
202   
203          We search for processes called 'services.exe' with a vad to and open 
204          file ending with '.evt'. 
205          """ 
206          ps_plugin = self.get_plugin("pslist", proc_regex="services.exe") 
207   
208          for task in ps_plugin.filter_processes(): 
209              for vad in task.RealVadRoot.traverse(): 
210                  try: 
211                      filename = vad.ControlArea.FilePointer.FileName 
212                      if utils.SmartUnicode(filename).lower().endswith(".evt"): 
213                          yield task, vad 
214                  except AttributeError: 
215                      pass 
216   
218          scanner = EVTScanner(profile=self.profile, address_space=address_space, 
219                               session=self.session) 
220          for event in scanner.scan(offset=vad.Start, maxlen=vad.Length, 
221                                    context=self.context): 
222              yield event 
223   
225          """Search for known sids that we can cache.""" 
226          sid_cache = self.context["sid_cache"] 
227          sid_cache.update(getsids.well_known_sids) 
228   
229          # Search for all known user sids. 
230          for hive_offset in self.hive_offsets: 
231              hive_address_space = registry.HiveAddressSpace( 
232                  base=self.kernel_address_space, 
233                  hive_addr=hive_offset, profile=self.profile) 
234   
235              reg = registry.Registry( 
236                  profile=self.profile, address_space=hive_address_space) 
237   
238              # We get the user names according to the name of the diretory where 
239              # their profile is. This is not very accurate - should we check the 
240              # SAM instead? 
241              profiles = reg.open_key( 
242                  'Microsoft\\Windows NT\\CurrentVersion\\ProfileList') 
243   
244              for profile in profiles.subkeys(): 
245                  path = profile.open_value("ProfileImagePath").DecodedData 
246                  if path: 
247                      sid_cache[utils.SmartUnicode(profile.Name)] = ( 
248                          utils.SmartUnicode(ntpath.basename(path))) 
249   
250          # Search for all service sids. 
251          getservicesids = self.get_plugin("getservicesids") 
252          for sid, service_name in getservicesids.get_service_sids(): 
253              sid_cache[sid] = "(Service: %s)" % service_name 
254   
256          if self.plugin_args.verbosity > 5: 
257              self.PrecacheSids() 
258   
259          renderer.table_header([("TimeWritten", "timestamp", ""), 
260                                 ("Filename", "filename", ""), 
261                                 ("Computer", "computer", ""), 
262                                 ("Sid", "sid", ""), 
263                                 ("Source", "source", ""), 
264                                 ("Event Id", "event_id", ""), 
265                                 ("Event Type", "event_type", ""), 
266                                 ("Message", "message", "")]) 
267   
268          for task, vad in self.FindEVTFiles(): 
269              filename = ntpath.basename( 
270                  utils.SmartUnicode(vad.ControlArea.FilePointer.FileName)) 
271   
272              for event in self.ScanEvents(vad, task.get_process_address_space()): 
273                  args = ";".join( 
274                      repr(utils.SmartStr(x)) for x in event.Data) 
275   
276                  renderer.table_row( 
277                      event.TimeWritten, 
278                      filename, 
279                      event.Computer, 
280                      event.Sid, 
281                      event.Source, 
282                      event.EventID, 
283                      event.EventType, 
284                      args) 
285   
| Trees | Indices | Help | 
 | 
|---|
| Generated by Epydoc 3.0.1 on Mon Oct 9 03:29:44 2017 | http://epydoc.sourceforge.net |