19 package org.sleuthkit.autopsy.recentactivity;
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Properties;
29 import java.util.logging.Level;
30 import org.openide.util.NbBundle.Messages;
37 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
38 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD;
40 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID;
50 final class ExtractZoneIdentifier
extends Extract {
52 private static final Logger LOG = Logger.getLogger(ExtractEdge.class.getName());
54 private static final String ZONE_IDENTIFIER_FILE =
"%:Zone.Identifier";
55 private static final String ZONE_IDENTIFIER =
":Zone.Identifier";
56 private Content dataSource;
57 private final IngestJobContext context;
60 "ExtractZone_displayName= Zone Identifier Analyzer",
61 "ExtractZone_process_errMsg_find=A failure occured while searching for :Zone.Indentifier files.",
62 "ExtractZone_process_errMsg=An error occured processing ':Zone.Indentifier' files.",
63 "ExtractZone_progress_Msg=Extracting :Zone.Identifer files"
66 ExtractZoneIdentifier(IngestJobContext context) {
67 super(Bundle.ExtractZone_displayName(), context);
68 this.context = context;
72 void process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
73 this.dataSource = dataSource;
74 progressBar.progress(Bundle.ExtractZone_progress_Msg());
76 List<AbstractFile> zoneFiles = null;
78 zoneFiles = currentCase.getServices().getFileManager().findFiles(dataSource, ZONE_IDENTIFIER_FILE);
79 }
catch (TskCoreException ex) {
80 addErrorMessage(Bundle.ExtractZone_process_errMsg_find());
81 LOG.log(Level.SEVERE,
"Unable to find zone identifier files, exception thrown. ", ex);
84 if (zoneFiles == null || zoneFiles.isEmpty()) {
88 Set<Long> knownPathIDs = null;
90 knownPathIDs = getPathIDsForType(TSK_WEB_DOWNLOAD);
91 }
catch (TskCoreException ex) {
92 addErrorMessage(Bundle.ExtractZone_process_errMsg());
93 LOG.log(Level.SEVERE,
"Failed to build PathIDs List for TSK_WEB_DOWNLOAD", ex);
96 if (knownPathIDs == null) {
100 Collection<BlackboardArtifact> associatedObjectArtifacts =
new ArrayList<>();
101 Collection<BlackboardArtifact> downloadArtifacts =
new ArrayList<>();
103 for (AbstractFile zoneFile : zoneFiles) {
105 if (context.dataSourceIngestIsCancelled()) {
110 processZoneFile(zoneFile, associatedObjectArtifacts, downloadArtifacts, knownPathIDs);
111 }
catch (TskCoreException ex) {
112 addErrorMessage(Bundle.ExtractZone_process_errMsg());
113 String message = String.format(
"Failed to process zone identifier file %s", zoneFile.getName());
114 LOG.log(Level.WARNING, message, ex);
118 if (!context.dataSourceIngestIsCancelled()) {
119 postArtifacts(associatedObjectArtifacts);
120 postArtifacts(downloadArtifacts);
133 private void processZoneFile(
134 AbstractFile zoneFile, Collection<BlackboardArtifact> associatedObjectArtifacts,
135 Collection<BlackboardArtifact> downloadArtifacts,
136 Set<Long> knownPathIDs)
throws TskCoreException {
138 ZoneIdentifierInfo zoneInfo = null;
141 zoneInfo =
new ZoneIdentifierInfo(zoneFile);
142 }
catch (IOException ex) {
143 String message = String.format(
"Unable to parse temporary File for %s", zoneFile.getName());
144 LOG.log(Level.WARNING, message, ex);
147 if (zoneInfo == null) {
151 AbstractFile downloadFile = getDownloadFile(zoneFile);
153 if (downloadFile != null) {
155 if (!knownPathIDs.contains(downloadFile.getId())) {
158 BlackboardArtifact downloadBba = createDownloadArtifact(zoneFile, zoneInfo, downloadFile);
159 downloadArtifacts.add(downloadBba);
161 if (downloadFile.getArtifactsCount(TSK_ASSOCIATED_OBJECT) == 0) {
162 associatedObjectArtifacts.add(createAssociatedArtifact(downloadFile, downloadBba));
178 private AbstractFile getDownloadFile(AbstractFile zoneFile)
throws TskCoreException {
180 String downloadFileName = zoneFile.getName().replace(ZONE_IDENTIFIER,
"");
186 AbstractFile potentialDownloadFile = currentCase.getSleuthkitCase().getAbstractFileById(zoneFile.getId() - 1);
187 if (isZoneFileMatch(zoneFile, downloadFileName, potentialDownloadFile)) {
188 return potentialDownloadFile;
190 potentialDownloadFile = currentCase.getSleuthkitCase().getAbstractFileById(zoneFile.getId() - 2);
191 if (isZoneFileMatch(zoneFile, downloadFileName, potentialDownloadFile)) {
192 return potentialDownloadFile;
196 List<AbstractFile> fileList = fileManager.
findFilesExactName(zoneFile.getParent().getId(), downloadFileName);
198 for (AbstractFile file : fileList) {
199 if (isZoneFileMatch(zoneFile, downloadFileName, file)) {
219 private boolean isZoneFileMatch(AbstractFile zoneFile, String expectedDownloadFileName, AbstractFile possibleDownloadFile) {
221 if (zoneFile == null || possibleDownloadFile == null || expectedDownloadFileName == null) {
225 if (zoneFile.getMetaAddr() != possibleDownloadFile.getMetaAddr()) {
229 if (!expectedDownloadFileName.equals(possibleDownloadFile.getName())) {
233 if (!possibleDownloadFile.getParentPath().equals(zoneFile.getParentPath())) {
249 private BlackboardArtifact createDownloadArtifact(AbstractFile zoneFile, ZoneIdentifierInfo zoneInfo, AbstractFile downloadFile)
throws TskCoreException {
251 String downloadFilePath = downloadFile.getParentPath() + downloadFile.getName();
252 long pathID = Util.findID(dataSource, downloadFilePath);
253 Collection<BlackboardAttribute> bbattributes = createDownloadAttributes(
254 downloadFilePath, pathID,
255 zoneInfo.getURL(), null,
256 (zoneInfo.getURL() != null ? NetworkUtils.extractDomain(zoneInfo.getURL()) :
""),
258 if (zoneInfo.getZoneIdAsString() != null) {
259 bbattributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT,
260 RecentActivityExtracterModuleFactory.getModuleName(),
261 zoneInfo.getZoneIdAsString()));
263 return createArtifactWithAttributes(BlackboardArtifact.Type.TSK_WEB_DOWNLOAD, zoneFile, bbattributes);
275 private Set<Long> getPathIDsForType(BlackboardArtifact.ARTIFACT_TYPE type) throws TskCoreException {
276 Set<Long> idList =
new HashSet<>();
277 for (BlackboardArtifact artifact : currentCase.getSleuthkitCase().getBlackboardArtifacts(type)) {
278 BlackboardAttribute pathIDAttribute = artifact.getAttribute(
new BlackboardAttribute.Type(TSK_PATH_ID));
280 if (pathIDAttribute != null) {
281 long contentID = pathIDAttribute.getValueLong();
282 if (contentID != -1) {
283 idList.add(contentID);
291 "ExtractZone_Local_Machine=Local Machine Zone",
292 "ExtractZone_Local_Intranet=Local Intranet Zone",
293 "ExtractZone_Trusted=Trusted Sites Zone",
294 "ExtractZone_Internet=Internet Zone",
295 "ExtractZone_Restricted=Restricted Sites Zone"
308 private static final String ZONE_ID =
"ZoneId";
309 private static final String REFERRER_URL =
"ReferrerUrl";
310 private static final String HOST_URL =
"HostUrl";
311 private static final String FAMILY_NAME =
"LastWriterPackageFamilyName";
314 private final Properties properties =
new Properties(null);
326 fileName = zoneFile.getName();
329 properties.load(
new ReadContentInputStream(zoneFile));
330 }
catch (IllegalArgumentException ex) {
331 String message = String.format(
"Unable to parse Zone Id for File %s", fileName);
332 LOG.log(Level.WARNING, message);
343 String value = properties.getProperty(ZONE_ID);
346 zoneValue = Integer.parseInt(value);
348 }
catch (NumberFormatException ex) {
349 String message = String.format(
"Unable to parse Zone Id for File %s", fileName);
350 LOG.log(Level.WARNING, message);
362 switch (getZoneId()) {
364 return Bundle.ExtractZone_Local_Machine();
366 return Bundle.ExtractZone_Local_Intranet();
368 return Bundle.ExtractZone_Trusted();
370 return Bundle.ExtractZone_Internet();
372 return Bundle.ExtractZone_Restricted();
384 return properties.getProperty(HOST_URL);
393 return properties.getProperty(REFERRER_URL);
402 return properties.getProperty(FAMILY_NAME);
List< AbstractFile > findFilesExactName(long parentId, String name)