Autopsy  4.17.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ExtractZoneIdentifier.java
Go to the documentation of this file.
1 /*
2  *
3  * Autopsy Forensic Browser
4  *
5  * Copyright 2019 Basis Technology Corp.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.recentactivity;
20 
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collection;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Properties;
29 import java.util.Set;
30 import java.util.logging.Level;
31 import org.openide.util.NbBundle.Messages;
36 import org.sleuthkit.datamodel.AbstractFile;
37 import org.sleuthkit.datamodel.BlackboardArtifact;
38 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
39 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD;
40 import org.sleuthkit.datamodel.BlackboardAttribute;
41 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
42 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID;
43 import org.sleuthkit.datamodel.Content;
44 import org.sleuthkit.datamodel.ReadContentInputStream;
45 import org.sleuthkit.datamodel.TskCoreException;
46 
52 final class ExtractZoneIdentifier extends Extract {
53 
54  private static final Logger LOG = Logger.getLogger(ExtractEdge.class.getName());
55 
56  private static final String ZONE_IDENTIFIER_FILE = "%:Zone.Identifier"; //NON-NLS
57  private static final String ZONE_IDENTIFIER = ":Zone.Identifier"; //NON-NLS
58 
59  @Messages({
60  "ExtractZone_process_errMsg_find=A failure occured while searching for :Zone.Indentifier files.",
61  "ExtractZone_process_errMsg=An error occured processing ':Zone.Indentifier' files.",
62  "ExtractZone_progress_Msg=Extracting :Zone.Identifer files"
63  })
64 
65  @Override
66  void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
67 
68  progressBar.progress(Bundle.ExtractZone_progress_Msg());
69 
70  List<AbstractFile> zoneFiles = null;
71  try {
72  zoneFiles = currentCase.getServices().getFileManager().findFiles(dataSource, ZONE_IDENTIFIER_FILE);
73  } catch (TskCoreException ex) {
74  addErrorMessage(Bundle.ExtractZone_process_errMsg_find());
75  LOG.log(Level.SEVERE, "Unable to find zone identifier files, exception thrown. ", ex); // NON-NLS
76  }
77 
78  if (zoneFiles == null || zoneFiles.isEmpty()) {
79  return;
80  }
81 
82  Set<Long> knownPathIDs = null;
83  try {
84  knownPathIDs = getPathIDsForType(TSK_WEB_DOWNLOAD);
85  } catch (TskCoreException ex) {
86  addErrorMessage(Bundle.ExtractZone_process_errMsg());
87  LOG.log(Level.SEVERE, "Failed to build PathIDs List for TSK_WEB_DOWNLOAD", ex); // NON-NLS
88  }
89 
90  if (knownPathIDs == null) {
91  return;
92  }
93 
94  Collection<BlackboardArtifact> associatedObjectArtifacts = new ArrayList<>();
95  Collection<BlackboardArtifact> downloadArtifacts = new ArrayList<>();
96 
97  for (AbstractFile zoneFile : zoneFiles) {
98 
99  if (context.dataSourceIngestIsCancelled()) {
100  return;
101  }
102 
103  try {
104  processZoneFile(context, dataSource, zoneFile, associatedObjectArtifacts, downloadArtifacts, knownPathIDs);
105  } catch (TskCoreException ex) {
106  addErrorMessage(Bundle.ExtractZone_process_errMsg());
107  String message = String.format("Failed to process zone identifier file %s", zoneFile.getName()); //NON-NLS
108  LOG.log(Level.WARNING, message, ex);
109  }
110  }
111 
112  postArtifacts(associatedObjectArtifacts);
113  postArtifacts(downloadArtifacts);
114  }
115 
127  private void processZoneFile(IngestJobContext context, Content dataSource,
128  AbstractFile zoneFile, Collection<BlackboardArtifact> associatedObjectArtifacts,
129  Collection<BlackboardArtifact> downloadArtifacts,
130  Set<Long> knownPathIDs) throws TskCoreException {
131 
132  ZoneIdentifierInfo zoneInfo = null;
133 
134  try {
135  zoneInfo = new ZoneIdentifierInfo(zoneFile);
136  } catch (IOException ex) {
137  String message = String.format("Unable to parse temporary File for %s", zoneFile.getName()); //NON-NLS
138  LOG.log(Level.WARNING, message, ex);
139  }
140 
141  if (zoneInfo == null) {
142  return;
143  }
144 
145  AbstractFile downloadFile = getDownloadFile(dataSource, zoneFile);
146 
147  if (downloadFile != null) {
148  // Only create a new TSK_WEB_DOWNLOAD artifact if one does not exist for downloadFile
149  if (!knownPathIDs.contains(downloadFile.getDataSourceObjectId())) {
150  // The zone identifier file is the parent of this artifact
151  // because it is the file we parsed to get the data
152  BlackboardArtifact downloadBba = createDownloadArtifact(zoneFile, zoneInfo, downloadFile);
153  if (downloadBba != null) {
154  downloadArtifacts.add(downloadBba);
155  // create a TSK_ASSOCIATED_OBJECT for the downloaded file, associating it with the TSK_WEB_DOWNLOAD artifact.
156  if (downloadFile.getArtifactsCount(TSK_ASSOCIATED_OBJECT) == 0) {
157  BlackboardArtifact associatedObjectBba = createAssociatedObjectArtifact(downloadFile, downloadBba);
158  if (associatedObjectBba != null) {
159  associatedObjectArtifacts.add(associatedObjectBba);
160  }
161  }
162  }
163  }
164 
165  }
166  }
167 
178  private AbstractFile getDownloadFile(Content dataSource, AbstractFile zoneFile) throws TskCoreException {
179  AbstractFile downloadFile = null;
180 
182  = currentCase.getServices().getFileManager();
183 
184  String downloadFileName = zoneFile.getName().replace(ZONE_IDENTIFIER, ""); //NON-NLS
185 
186  List<AbstractFile> fileList = fileManager.findFiles(dataSource, downloadFileName, zoneFile.getParentPath());
187 
188  if (fileList.size() == 1) {
189  downloadFile = fileList.get(0);
190 
191  // Check that the download file and the zone file came from the same dir
192  if (!downloadFile.getParentPath().equals(zoneFile.getParentPath())) {
193  downloadFile = null;
194  } else if (zoneFile.getMetaAddr() != downloadFile.getMetaAddr()) {
195  downloadFile = null;
196  }
197  }
198 
199  return downloadFile;
200  }
201 
212  private BlackboardArtifact createAssociatedObjectArtifact(AbstractFile downloadFile, BlackboardArtifact downloadBba) {
213 
214  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
215 
216  bbattributes.addAll(Arrays.asList(
217  new BlackboardAttribute(TSK_ASSOCIATED_ARTIFACT,
218  RecentActivityExtracterModuleFactory.getModuleName(),
219  downloadBba.getArtifactID())
220  ));
221 
222  return createArtifactWithAttributes(TSK_ASSOCIATED_OBJECT, downloadFile, bbattributes);
223  }
224 
234  private BlackboardArtifact createDownloadArtifact(AbstractFile zoneFile, ZoneIdentifierInfo zoneInfo, AbstractFile downloadFile) {
235 
236  String downloadFilePath = downloadFile.getParentPath() + downloadFile.getName();
237 
238  Collection<BlackboardAttribute> bbattributes = createDownloadAttributes(
239  downloadFilePath, null,
240  zoneInfo.getURL(), null,
241  (zoneInfo.getURL() != null ? NetworkUtils.extractDomain(zoneInfo.getURL()) : ""),
242  null);
243  if (zoneInfo.getZoneIdAsString() != null) {
244  bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT,
245  RecentActivityExtracterModuleFactory.getModuleName(),
246  zoneInfo.getZoneIdAsString()));
247  }
248  return createArtifactWithAttributes(TSK_WEB_DOWNLOAD, zoneFile, bbattributes);
249  }
250 
260  private Set<Long> getPathIDsForType(BlackboardArtifact.ARTIFACT_TYPE type) throws TskCoreException {
261  Set<Long> idList = new HashSet<>();
262  for (BlackboardArtifact artifact : currentCase.getSleuthkitCase().getBlackboardArtifacts(type)) {
263  BlackboardAttribute pathIDAttribute = artifact.getAttribute(new BlackboardAttribute.Type(TSK_PATH_ID));
264 
265  if (pathIDAttribute != null) {
266  long contentID = pathIDAttribute.getValueLong();
267  if (contentID != -1) {
268  idList.add(contentID);
269  }
270  }
271  }
272  return idList;
273  }
274 
275  @Messages({
276  "ExtractZone_Local_Machine=Local Machine Zone",
277  "ExtractZone_Local_Intranet=Local Intranet Zone",
278  "ExtractZone_Trusted=Trusted Sites Zone",
279  "ExtractZone_Internet=Internet Zone",
280  "ExtractZone_Restricted=Restricted Sites Zone"
281  })
282 
291  private final static class ZoneIdentifierInfo {
292 
293  private static final String ZONE_ID = "ZoneId"; //NON-NLS
294  private static final String REFERRER_URL = "ReferrerUrl"; //NON-NLS
295  private static final String HOST_URL = "HostUrl"; //NON-NLS
296  private static final String FAMILY_NAME = "LastWriterPackageFamilyName"; //NON-NLS
297  private static String fileName;
298 
299  private final Properties properties = new Properties(null);
300 
310  ZoneIdentifierInfo(AbstractFile zoneFile) throws IOException {
311  fileName = zoneFile.getName();
312  properties.load(new ReadContentInputStream(zoneFile));
313  }
314 
320  private int getZoneId() {
321  int zoneValue = -1;
322  String value = properties.getProperty(ZONE_ID);
323  try {
324  if (value != null) {
325  zoneValue = Integer.parseInt(value);
326  }
327  } catch (NumberFormatException ex) {
328  String message = String.format("Unable to parse Zone Id for File %s", fileName); //NON-NLS
329  LOG.log(Level.WARNING, message);
330  }
331 
332  return zoneValue;
333  }
334 
340  private String getZoneIdAsString() {
341  switch (getZoneId()) {
342  case 0:
343  return Bundle.ExtractZone_Local_Machine();
344  case 1:
345  return Bundle.ExtractZone_Local_Intranet();
346  case 2:
347  return Bundle.ExtractZone_Trusted();
348  case 3:
349  return Bundle.ExtractZone_Internet();
350  case 4:
351  return Bundle.ExtractZone_Restricted();
352  default:
353  return null;
354  }
355  }
356 
362  private String getURL() {
363  return properties.getProperty(HOST_URL);
364  }
365 
371  private String getReferrer() {
372  return properties.getProperty(REFERRER_URL);
373  }
374 
380  private String getFamilyName() {
381  return properties.getProperty(FAMILY_NAME);
382  }
383  }
384 
385 }
synchronized List< AbstractFile > findFiles(String fileName)

Copyright © 2012-2021 Basis Technology. Generated on: Tue Jan 19 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.