Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
DataSourceUsageAnalyzer.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019-2021 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
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.util.ArrayList;
22 import java.util.Collection;
23 import java.util.List;
24 import java.util.logging.Level;
25 import org.apache.commons.io.FilenameUtils;
26 import org.openide.util.NbBundle.Messages;
31 import org.sleuthkit.datamodel.AbstractFile;
32 import org.sleuthkit.datamodel.BlackboardArtifact;
33 import org.sleuthkit.datamodel.BlackboardAttribute;
34 import org.sleuthkit.datamodel.Content;
35 import org.sleuthkit.datamodel.FileSystem;
36 import org.sleuthkit.datamodel.Image;
37 import org.sleuthkit.datamodel.TskCoreException;
38 import org.sleuthkit.datamodel.TskData;
39 
45 @Messages({"DataSourceUsageAnalyzer.displayName=Data Source Usage Analyzer"})
46 class DataSourceUsageAnalyzer extends Extract {
47 
48  private static final Logger logger = Logger.getLogger(DataSourceUsageAnalyzer.class.getName());
49  private static final int FAT_EXFAT_FLAGS = TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT16.getValue()
50  | TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT32.getValue()
51  | TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_EXFAT.getValue();
52  private static final long HUNDRED_GB = 100 * 1024 * 1024 * 1024l;
53 
54  private static final String ANDROID_MEDIACARD_ROOT_FILENAMES[]
55  = // files expected in root folder of an Android media card
56  {".android_secure", "android", "audio",
57  "photos", "dcim", "music", "pictures", "videos"}; //NON-NLS
58  private Content dataSource;
59  private final IngestJobContext context;
60 
61  DataSourceUsageAnalyzer(IngestJobContext context) {
62  super(Bundle.DataSourceUsageAnalyzer_displayName(), context);
63  this.context = context;
64  }
65 
66  @Messages({
67  "# {0} - OS name",
68  "DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0})",
69  "Progress_Message_Analyze_Usage=Data Sources Usage Analysis",})
70  @Override
71  void process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
72  this.dataSource = dataSource;
73  try {
74  progressBar.progress(Bundle.Progress_Message_Analyze_Usage());
75  createDataSourceUsageArtifacts();
76  } catch (TskCoreException ex) {
77  logger.log(Level.WARNING, "Failed to check if datasource contained a volume with operating system specific files", ex);
78  }
79 
80  }
81 
82  private void createDataSourceUsageArtifacts() throws TskCoreException {
83  createOSInfoDataSourceUsageArtifacts();
84  if (context.dataSourceIngestIsCancelled()) {
85  return;
86  }
87  createAndroidMediaCardArtifacts();
88  if (context.dataSourceIngestIsCancelled()) {
89  return;
90  }
91  createDJIDroneDATArtitifacts();
92  }
93 
100  private void createOSInfoDataSourceUsageArtifacts() throws TskCoreException {
101  boolean windowsOsDetected = false;
102  List<BlackboardArtifact> osInfoArtifacts = tskCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO);
103  for (BlackboardArtifact osInfoArt : osInfoArtifacts) {
104  //if it is the current data source
105  if (osInfoArt.getDataSource().getId() == dataSource.getId()) {
106  BlackboardAttribute progNameAttr = osInfoArt.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME));
107  if (progNameAttr != null) {
108  if (progNameAttr.getValueString().isEmpty()) {
109  //skip empty Program Name text
110  } else if (progNameAttr.getDisplayString().toLowerCase().contains("windows")) { //non-nls
111  windowsOsDetected = true;
112  //use the program name when it appears to be windows
113  createDataSourceUsageArtifact(Bundle.DataSourceUsageAnalyzer_customVolume_label(progNameAttr.getDisplayString()));
114  } else {
115  ExtractOs.OS_TYPE osType = ExtractOs.OS_TYPE.fromOsInfoLabel(progNameAttr.getValueString());
116  if (osType != null) {
117  createDataSourceUsageArtifact(osType.getDsUsageLabel());
118  } else {
119  //unable to determine name for DATA_SOURCE_USAGE artifact using program name
120  createDataSourceUsageArtifact(Bundle.DataSourceUsageAnalyzer_customVolume_label(progNameAttr.getDisplayString()));
121  }
122  }
123  }
124  }
125  }
126  if (!windowsOsDetected) { //if we didn't find a windows OS_INFO artifact check if we still think it is a windows volume
127  checkIfOsSpecificVolume(ExtractOs.OS_TYPE.WINDOWS);
128  }
129  }
130 
140  private void createDataSourceUsageArtifact(String dataSourceUsageDescription) throws TskCoreException {
141  //if the data source usage description is not empty create a data source usage artifact if an Usage artifact does not already exist with the same description
142  List<BlackboardArtifact> artifacts = tskCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE, dataSource.getId());
143  for (BlackboardArtifact artifact : artifacts) {
144  if (artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION)).getValueString().equals(dataSourceUsageDescription)) {
145  return; //already exists don't create a duplicate
146  }
147  }
148  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
149  bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION,
150  getRAModuleName(),
151  dataSourceUsageDescription)); //NON-NLS
152  postArtifact(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_DATA_SOURCE_USAGE, dataSource, bbattributes));
153  }
154 
162  private void checkIfOsSpecificVolume(ExtractOs.OS_TYPE osType) throws TskCoreException {
163  for (String filePath : osType.getFilePaths()) {
164  for (AbstractFile file : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource,
165  FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath))) {
166  createDataSourceUsageArtifact(osType.getDsUsageLabel());
167  return;
168  }
169  }
170  }
171 
180  @Messages({
181  "DataSourceUsage_AndroidMedia=Android Media Card",
182  "DataSourceUsage_FlashDrive=Flash Drive"
183  })
184  private void createAndroidMediaCardArtifacts() {
185 
186  if (dataSource instanceof Image) {
187  Image image = (Image) dataSource;
188  try {
189  if (image.getSize() > HUNDRED_GB) {
190  return;
191  }
192 
193  List<FileSystem> fileSystems = image.getFileSystems();
194  if (fileSystems.isEmpty() || fileSystems.size() > 1) {
195  return;
196  }
197 
198  FileSystem fileSystem = fileSystems.get(0);
199  if (fileSystem == null || (fileSystem.getFsType().getValue() & FAT_EXFAT_FLAGS) == 0) {
200  return;
201  }
202 
203  if (hasAndroidMediaCardRootNames()) {
204  return;
205  }
206 
207  // If none of the Android paths is found but it meets other criteria, it might be just a flash drive
208  createDataSourceUsageArtifact(Bundle.DataSourceUsage_FlashDrive());
209 
210  } catch (TskCoreException ex) {
211  logger.log(Level.SEVERE, "Exception while checking image: {0} for Andriod media card", image.getName() + ex.getMessage()); //NON-NLS
212  }
213  }
214  }
215 
223  private boolean hasAndroidMediaCardRootNames() throws TskCoreException {
224  FileManager fileManager = currentCase.getServices().getFileManager();
225  for (String fileName : ANDROID_MEDIACARD_ROOT_FILENAMES) {
226  for (AbstractFile file : fileManager.findFiles(dataSource, fileName, "/")) { // NON-NLS
227  if (file.getParentPath().equals("/") && file.getName().equalsIgnoreCase(fileName)) { // NON-NLS
228  createDataSourceUsageArtifact(Bundle.DataSourceUsage_AndroidMedia());
229  return true;
230  }
231  }
232  }
233 
234  return false;
235  }
236 
245  @Messages({
246  "DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card"
247  })
248  private void createDJIDroneDATArtitifacts() throws TskCoreException {
249  FileManager fileManager = currentCase.getServices().getFileManager();
250  // The underscores are SQL wild cards.
251  List<AbstractFile> files = fileManager.findFiles(dataSource, "FLY___.DAT");
252  if (files != null && !files.isEmpty()) {
253  createDataSourceUsageArtifact(Bundle.DataSourceUsage_DJU_Drone_DAT());
254  }
255  }
256 }

Copyright © 2012-2022 Basis Technology. Generated on: Tue Aug 1 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.