Autopsy 4.22.1
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 */
19package org.sleuthkit.autopsy.recentactivity;
20
21import java.util.ArrayList;
22import java.util.Collection;
23import java.util.List;
24import java.util.logging.Level;
25import org.apache.commons.io.FilenameUtils;
26import org.openide.util.NbBundle.Messages;
27import org.sleuthkit.autopsy.casemodule.services.FileManager;
28import org.sleuthkit.autopsy.coreutils.Logger;
29import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
30import org.sleuthkit.autopsy.ingest.IngestJobContext;
31import org.sleuthkit.datamodel.AbstractFile;
32import org.sleuthkit.datamodel.BlackboardArtifact;
33import org.sleuthkit.datamodel.BlackboardAttribute;
34import org.sleuthkit.datamodel.Content;
35import org.sleuthkit.datamodel.FileSystem;
36import org.sleuthkit.datamodel.Image;
37import org.sleuthkit.datamodel.TskCoreException;
38import org.sleuthkit.datamodel.TskData;
39
45@Messages({"DataSourceUsageAnalyzer.displayName=Data Source Usage Analyzer"})
46class 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}
List< AbstractFile > findFiles(String fileName)
synchronized static Logger getLogger(String name)
Definition Logger.java:124
OS_TYPE(String osInfoText, String dsUsageText, List< String > filePathList)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.