mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 09:17:42 +00:00
cleanup IEExtractor.java
This commit is contained in:
parent
14806c9083
commit
e41ddc86da
@ -22,41 +22,55 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.recentactivity;
|
package org.sleuthkit.autopsy.recentactivity;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
|
||||||
import org.openide.util.NbBundle;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.Arrays;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.modules.InstalledFileLocator;
|
import org.openide.modules.InstalledFileLocator;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
import org.sleuthkit.autopsy.casemodule.services.FileManager;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
||||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
|
||||||
import org.sleuthkit.datamodel.Content;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator;
|
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||||
|
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||||
import org.sleuthkit.datamodel.*;
|
import org.sleuthkit.datamodel.*;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_ACCOUNT;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts activity from Internet Explorer browser, as well as recent documents
|
* Extracts activity from Internet Explorer browser, as well as recent documents
|
||||||
@ -65,17 +79,19 @@ import org.sleuthkit.datamodel.*;
|
|||||||
class IEExtractor extends Extractor {
|
class IEExtractor extends Extractor {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(IEExtractor.class.getName());
|
private static final Logger logger = Logger.getLogger(IEExtractor.class.getName());
|
||||||
|
private static final String PARENT_MODULE_NAME_NO_SPACE
|
||||||
|
= NbBundle.getMessage(IEExtractor.class, "ExtractIE.parentModuleName.noSpace");
|
||||||
|
private static final String PASCO_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
|
||||||
|
|
||||||
private final IngestServices services = IngestServices.getInstance();
|
private final IngestServices services = IngestServices.getInstance();
|
||||||
private final String moduleTempResultsDir;
|
private final String moduleTempResultsDir;
|
||||||
private String PASCO_LIB_PATH;
|
private final String JAVA_PATH = PlatformUtil.getJavaPath();
|
||||||
private final String JAVA_PATH;
|
|
||||||
private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
|
|
||||||
private Content dataSource;
|
private Content dataSource;
|
||||||
private IngestJobContext context;
|
private IngestJobContext context;
|
||||||
|
|
||||||
IEExtractor() throws NoCurrentCaseException {
|
IEExtractor() throws NoCurrentCaseException {
|
||||||
moduleTempResultsDir = RAImageIngestModule.getRATempPath(Case.getCurrentCaseThrows(), "IE") + File.separator + "results"; //NON-NLS
|
moduleTempResultsDir = RAImageIngestModule.getRATempPath(Case.getCurrentCaseThrows(), "IE") + File.separator + "results"; //NON-NLS
|
||||||
JAVA_PATH = PlatformUtil.getJavaPath();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -96,8 +112,8 @@ class IEExtractor extends Extractor {
|
|||||||
/**
|
/**
|
||||||
* Finds the files storing bookmarks and creates artifacts
|
* Finds the files storing bookmarks and creates artifacts
|
||||||
*/
|
*/
|
||||||
private void getBookmark() {
|
private void getBookmark() throws TskCoreException {
|
||||||
org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager();
|
FileManager fileManager = currentCase.getServices().getFileManager();
|
||||||
List<AbstractFile> favoritesFiles;
|
List<AbstractFile> favoritesFiles;
|
||||||
try {
|
try {
|
||||||
favoritesFiles = fileManager.findFiles(dataSource, "%.url", "Favorites"); //NON-NLS
|
favoritesFiles = fileManager.findFiles(dataSource, "%.url", "Favorites"); //NON-NLS
|
||||||
@ -125,36 +141,21 @@ class IEExtractor extends Extractor {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
String url = getURLFromIEBookmarkFile(fav);
|
Collection<BlackboardAttribute> bbattributes = Arrays.asList(
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_URL, PARENT_MODULE_NAME_NO_SPACE, getURLFromIEBookmarkFile(fav)),
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_TITLE, PARENT_MODULE_NAME_NO_SPACE, fav.getName()),
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_DATETIME_CREATED, PARENT_MODULE_NAME_NO_SPACE, fav.getCrtime()),
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_PROG_NAME, PARENT_MODULE_NAME_NO_SPACE,
|
||||||
|
NbBundle.getMessage(this.getClass(), "ExtractIE.moduleName.text")),
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_DOMAIN, PARENT_MODULE_NAME_NO_SPACE, Util.extractDomain(getURLFromIEBookmarkFile(fav))));
|
||||||
|
|
||||||
String name = fav.getName();
|
bbartifacts.add(this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, fav, bbattributes));
|
||||||
Long datetime = fav.getCrtime();
|
|
||||||
String Tempdate = datetime.toString();
|
|
||||||
datetime = Long.valueOf(Tempdate);
|
|
||||||
String domain = Util.extractDomain(url);
|
|
||||||
|
|
||||||
Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
|
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractIE.parentModuleName.noSpace"), url));
|
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractIE.parentModuleName.noSpace"), name));
|
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractIE.parentModuleName.noSpace"), datetime));
|
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractIE.parentModuleName.noSpace"),
|
|
||||||
NbBundle.getMessage(this.getClass(), "ExtractIE.moduleName.text")));
|
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractIE.parentModuleName.noSpace"), domain));
|
|
||||||
|
|
||||||
BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, fav, bbattributes);
|
|
||||||
if (bbart != null) {
|
|
||||||
bbartifacts.add(bbart);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
services.fireModuleDataEvent(new ModuleDataEvent(
|
services.fireModuleDataEvent(new ModuleDataEvent(
|
||||||
NbBundle.getMessage(this.getClass(), "ExtractIE.parentModuleName"),
|
NbBundle.getMessage(this.getClass(), "ExtractIE.parentModuleName"),
|
||||||
@ -162,18 +163,14 @@ class IEExtractor extends Extractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getURLFromIEBookmarkFile(AbstractFile fav) {
|
private String getURLFromIEBookmarkFile(AbstractFile fav) {
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(new ReadContentInputStream(fav)));
|
String line;
|
||||||
String line, url = "";
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new ReadContentInputStream(fav)));) {
|
||||||
try {
|
while (null != (line = reader.readLine())) {
|
||||||
line = reader.readLine();
|
|
||||||
while (null != line) {
|
|
||||||
// The actual shortcut line we are interested in is of the
|
// The actual shortcut line we are interested in is of the
|
||||||
// form URL=http://path/to/website
|
// form URL=http://path/to/website
|
||||||
if (line.startsWith("URL")) { //NON-NLS
|
if (line.startsWith("URL")) { //NON-NLS
|
||||||
url = line.substring(line.indexOf("=") + 1);
|
return StringUtils.substringAfter(line, "="); //NON-NLS
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
line = reader.readLine();
|
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.log(Level.WARNING, "Failed to read from content: " + fav.getName(), ex); //NON-NLS
|
logger.log(Level.WARNING, "Failed to read from content: " + fav.getName(), ex); //NON-NLS
|
||||||
@ -185,22 +182,16 @@ class IEExtractor extends Extractor {
|
|||||||
this.addErrorMessage(
|
this.addErrorMessage(
|
||||||
NbBundle.getMessage(this.getClass(), "ExtractIE.getURLFromIEBmkFile.errMsg2", this.getModuleName(),
|
NbBundle.getMessage(this.getClass(), "ExtractIE.getURLFromIEBmkFile.errMsg2", this.getModuleName(),
|
||||||
fav.getName()));
|
fav.getName()));
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
reader.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
logger.log(Level.WARNING, "Failed to close reader.", ex); //NON-NLS
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds files that store cookies and adds artifacts for them.
|
* Finds files that store cookies and adds artifacts for them.
|
||||||
*/
|
*/
|
||||||
private void getCookie() {
|
private void getCookie() throws TskCoreException {
|
||||||
org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager();
|
FileManager fileManager = currentCase.getServices().getFileManager();
|
||||||
List<AbstractFile> cookiesFiles;
|
List<AbstractFile> cookiesFiles;
|
||||||
try {
|
try {
|
||||||
cookiesFiles = fileManager.findFiles(dataSource, "%.txt", "Cookies"); //NON-NLS
|
cookiesFiles = fileManager.findFiles(dataSource, "%.txt", "Cookies"); //NON-NLS
|
||||||
@ -226,9 +217,9 @@ class IEExtractor extends Extractor {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] t = new byte[(int) cookiesFile.getSize()];
|
byte[] cookiesBuffer = new byte[(int) cookiesFile.getSize()];
|
||||||
try {
|
try {
|
||||||
final int bytesRead = cookiesFile.read(t, 0, cookiesFile.getSize());
|
cookiesFile.read(cookiesBuffer, 0, cookiesFile.getSize());
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.WARNING, "Error reading bytes of Internet Explorer cookie.", ex); //NON-NLS
|
logger.log(Level.WARNING, "Error reading bytes of Internet Explorer cookie.", ex); //NON-NLS
|
||||||
this.addErrorMessage(
|
this.addErrorMessage(
|
||||||
@ -236,44 +227,33 @@ class IEExtractor extends Extractor {
|
|||||||
this.getModuleName(), cookiesFile.getName()));
|
this.getModuleName(), cookiesFile.getName()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String cookieString = new String(t);
|
|
||||||
String[] values = cookieString.split("\n");
|
|
||||||
String url = values.length > 2 ? values[2] : "";
|
|
||||||
String value = values.length > 1 ? values[1] : "";
|
|
||||||
String name = values.length > 0 ? values[0] : "";
|
|
||||||
Long datetime = cookiesFile.getCrtime();
|
|
||||||
String tempDate = datetime.toString();
|
|
||||||
datetime = Long.valueOf(tempDate);
|
|
||||||
String domain = Util.extractDomain(url);
|
|
||||||
|
|
||||||
Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
|
String[] values = new String(cookiesBuffer).split("\n");
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
|
String URL = values.length > 2 ? values[2] : "";
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractIE.parentModuleName.noSpace"), url));
|
Collection<BlackboardAttribute> bbattributes = Arrays.asList(new BlackboardAttribute(
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME,
|
TSK_DATETIME, PARENT_MODULE_NAME_NO_SPACE,
|
||||||
NbBundle.getMessage(this.getClass(),
|
cookiesFile.getCrtime()),
|
||||||
"ExtractIE.parentModuleName.noSpace"), datetime));
|
new BlackboardAttribute(
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
|
TSK_NAME, PARENT_MODULE_NAME_NO_SPACE,
|
||||||
NbBundle.getMessage(this.getClass(),
|
values.length > 0 ? values[0] : ""),
|
||||||
"ExtractIE.parentModuleName.noSpace"), (name != null) ? name : ""));
|
new BlackboardAttribute(
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
|
TSK_VALUE, PARENT_MODULE_NAME_NO_SPACE,
|
||||||
NbBundle.getMessage(this.getClass(),
|
values.length > 1 ? values[1] : ""),
|
||||||
"ExtractIE.parentModuleName.noSpace"), value));
|
new BlackboardAttribute(
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
|
TSK_URL, PARENT_MODULE_NAME_NO_SPACE,
|
||||||
NbBundle.getMessage(this.getClass(),
|
URL),
|
||||||
"ExtractIE.parentModuleName.noSpace"),
|
new BlackboardAttribute(
|
||||||
NbBundle.getMessage(this.getClass(), "ExtractIE.moduleName.text")));
|
TSK_PROG_NAME, PARENT_MODULE_NAME_NO_SPACE,
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
|
getModuleName()),
|
||||||
NbBundle.getMessage(this.getClass(),
|
new BlackboardAttribute(
|
||||||
"ExtractIE.parentModuleName.noSpace"), domain));
|
TSK_DOMAIN, PARENT_MODULE_NAME_NO_SPACE,
|
||||||
BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes);
|
Util.extractDomain(URL)));
|
||||||
if (bbart != null) {
|
|
||||||
bbartifacts.add(bbart);
|
bbartifacts.add(this.addArtifact(TSK_WEB_COOKIE, cookiesFile, bbattributes));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
services.fireModuleDataEvent(new ModuleDataEvent(
|
services.fireModuleDataEvent(new ModuleDataEvent(
|
||||||
NbBundle.getMessage(this.getClass(), "ExtractIE.parentModuleName"),
|
NbBundle.getMessage(this.getClass(), "ExtractIE.parentModuleName"), TSK_WEB_COOKIE, bbartifacts));
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE, bbartifacts));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -281,8 +261,8 @@ class IEExtractor extends Extractor {
|
|||||||
*/
|
*/
|
||||||
private void getHistory() {
|
private void getHistory() {
|
||||||
logger.log(Level.INFO, "Pasco results path: {0}", moduleTempResultsDir); //NON-NLS
|
logger.log(Level.INFO, "Pasco results path: {0}", moduleTempResultsDir); //NON-NLS
|
||||||
boolean foundHistory = false;
|
|
||||||
|
|
||||||
|
//TODO: Why are we getting the pasoc library path for datasource we process?
|
||||||
final File pascoRoot = InstalledFileLocator.getDefault().locate("pasco2", IEExtractor.class.getPackage().getName(), false); //NON-NLS
|
final File pascoRoot = InstalledFileLocator.getDefault().locate("pasco2", IEExtractor.class.getPackage().getName(), false); //NON-NLS
|
||||||
if (pascoRoot == null) {
|
if (pascoRoot == null) {
|
||||||
this.addErrorMessage(
|
this.addErrorMessage(
|
||||||
@ -294,14 +274,14 @@ class IEExtractor extends Extractor {
|
|||||||
final String pascoHome = pascoRoot.getAbsolutePath();
|
final String pascoHome = pascoRoot.getAbsolutePath();
|
||||||
logger.log(Level.INFO, "Pasco2 home: {0}", pascoHome); //NON-NLS
|
logger.log(Level.INFO, "Pasco2 home: {0}", pascoHome); //NON-NLS
|
||||||
|
|
||||||
PASCO_LIB_PATH = pascoHome + File.separator + "pasco2.jar" + File.pathSeparator //NON-NLS
|
String pascoLibPath = pascoHome + File.separator + "pasco2.jar" + File.pathSeparator //NON-NLS
|
||||||
+ pascoHome + File.separator + "*";
|
+ pascoHome + File.separator + "*";
|
||||||
|
|
||||||
File resultsDir = new File(moduleTempResultsDir);
|
File resultsDir = new File(moduleTempResultsDir);
|
||||||
resultsDir.mkdirs();
|
resultsDir.mkdirs();
|
||||||
|
|
||||||
// get index.dat files
|
// get index.dat files
|
||||||
org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager();
|
FileManager fileManager = currentCase.getServices().getFileManager();
|
||||||
List<AbstractFile> indexFiles;
|
List<AbstractFile> indexFiles;
|
||||||
try {
|
try {
|
||||||
indexFiles = fileManager.findFiles(dataSource, "index.dat"); //NON-NLS
|
indexFiles = fileManager.findFiles(dataSource, "index.dat"); //NON-NLS
|
||||||
@ -319,18 +299,20 @@ class IEExtractor extends Extractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dataFound = true;
|
dataFound = true;
|
||||||
|
boolean foundHistory = false;
|
||||||
Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
|
Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
|
||||||
String temps;
|
|
||||||
String indexFileName;
|
|
||||||
for (AbstractFile indexFile : indexFiles) {
|
for (AbstractFile indexFile : indexFiles) {
|
||||||
// Since each result represent an index.dat file,
|
/* Since each result represent an index.dat file, just create these
|
||||||
// just create these files with the following notation:
|
* files with the following notation: index<Number>.dat (i.e.
|
||||||
// index<Number>.dat (i.e. index0.dat, index1.dat,..., indexN.dat)
|
* index0.dat, index1.dat,..., indexN.dat) Write each index.dat file
|
||||||
// Write each index.dat file to a temp directory.
|
* to a temp directory.
|
||||||
//BlackboardArtifact bbart = fsc.newArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY);
|
*
|
||||||
indexFileName = "index" + Integer.toString((int) indexFile.getId()) + ".dat"; //NON-NLS
|
* TODO: this comment is not accurate. It implies we use an
|
||||||
//indexFileName = "index" + Long.toString(bbart.getArtifactID()) + ".dat";
|
* sequential id number but actualy we use the file id from the db.
|
||||||
temps = RAImageIngestModule.getRATempPath(currentCase, "IE") + File.separator + indexFileName; //NON-NLS
|
*/
|
||||||
|
String indexFileName = "index" + indexFile.getId() + ".dat"; //NON-NLS
|
||||||
|
String temps = RAImageIngestModule.getRATempPath(currentCase, "IE") + File.separator + indexFileName; //NON-NLS
|
||||||
File datFile = new File(temps);
|
File datFile = new File(temps);
|
||||||
if (context.dataSourceIngestIsCancelled()) {
|
if (context.dataSourceIngestIsCancelled()) {
|
||||||
break;
|
break;
|
||||||
@ -346,13 +328,13 @@ class IEExtractor extends Extractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String filename = "pasco2Result." + indexFile.getId() + ".txt"; //NON-NLS
|
String filename = "pasco2Result." + indexFile.getId() + ".txt"; //NON-NLS
|
||||||
boolean bPascProcSuccess = executePasco(temps, filename);
|
boolean bPascProcSuccess = executePasco(pascoLibPath, temps, filename);
|
||||||
if (context.dataSourceIngestIsCancelled()) {
|
if (context.dataSourceIngestIsCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//At this point pasco2 proccessed the index files.
|
//At this point pasco2 proccessed the index file.
|
||||||
//Now fetch the results, parse them and the delete the files.
|
//Now fetch the results, parse them and the delete the file.
|
||||||
if (bPascProcSuccess) {
|
if (bPascProcSuccess) {
|
||||||
// Don't add TSK_OS_ACCOUNT artifacts to the ModuleDataEvent
|
// Don't add TSK_OS_ACCOUNT artifacts to the ModuleDataEvent
|
||||||
bbartifacts.addAll(parsePascoOutput(indexFile, filename).stream()
|
bbartifacts.addAll(parsePascoOutput(indexFile, filename).stream()
|
||||||
@ -360,7 +342,7 @@ class IEExtractor extends Extractor {
|
|||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
foundHistory = true;
|
foundHistory = true;
|
||||||
|
|
||||||
//Delete index<n>.dat file since it was succcessfully by Pasco
|
//Delete index<n>.dat file since it was succcessfully parsed by Pasco
|
||||||
datFile.delete();
|
datFile.delete();
|
||||||
} else {
|
} else {
|
||||||
logger.log(Level.WARNING, "pasco execution failed on: {0}", this.getModuleName()); //NON-NLS
|
logger.log(Level.WARNING, "pasco execution failed on: {0}", this.getModuleName()); //NON-NLS
|
||||||
@ -382,22 +364,22 @@ class IEExtractor extends Extractor {
|
|||||||
* @param indexFilePath Path to local index.dat file to analyze
|
* @param indexFilePath Path to local index.dat file to analyze
|
||||||
* @param outputFileName Name of file to save output to
|
* @param outputFileName Name of file to save output to
|
||||||
*
|
*
|
||||||
* @return false on error
|
* @return the boolean
|
||||||
*/
|
*/
|
||||||
private boolean executePasco(String indexFilePath, String outputFileName) {
|
private boolean executePasco(String pascoLibraryPath, String indexFilePath, String outputFileName) {
|
||||||
boolean success = true;
|
boolean success = true;
|
||||||
try {
|
try {
|
||||||
final String outputFileFullPath = moduleTempResultsDir + File.separator + outputFileName;
|
final String outputFileFullPath = moduleTempResultsDir + File.separator + outputFileName;
|
||||||
final String errFileFullPath = moduleTempResultsDir + File.separator + outputFileName + ".err"; //NON-NLS
|
final String errFileFullPath = moduleTempResultsDir + File.separator + outputFileName + ".err"; //NON-NLS
|
||||||
logger.log(Level.INFO, "Writing pasco results to: {0}", outputFileFullPath); //NON-NLS
|
logger.log(Level.INFO, "Writing pasco results to: {0}", outputFileFullPath); //NON-NLS
|
||||||
List<String> commandLine = new ArrayList<>();
|
List<String> commandLine = Arrays.asList(
|
||||||
commandLine.add(JAVA_PATH);
|
JAVA_PATH,
|
||||||
commandLine.add("-cp"); //NON-NLS
|
"-cp",//NON-NLS
|
||||||
commandLine.add(PASCO_LIB_PATH);
|
pascoLibraryPath,
|
||||||
commandLine.add("isi.pasco2.Main"); //NON-NLS
|
"isi.pasco2.Main", //NON-NLS
|
||||||
commandLine.add("-T"); //NON-NLS
|
"-T", //NON-NLS
|
||||||
commandLine.add("history"); //NON-NLS
|
"history", //NON-NLS
|
||||||
commandLine.add(indexFilePath);
|
indexFilePath);
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
|
ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
|
||||||
processBuilder.redirectOutput(new File(outputFileFullPath));
|
processBuilder.redirectOutput(new File(outputFileFullPath));
|
||||||
processBuilder.redirectError(new File(errFileFullPath));
|
processBuilder.redirectError(new File(errFileFullPath));
|
||||||
@ -430,7 +412,6 @@ class IEExtractor extends Extractor {
|
|||||||
*/
|
*/
|
||||||
private Collection<BlackboardArtifact> parsePascoOutput(AbstractFile origFile, String pascoOutputFileName) {
|
private Collection<BlackboardArtifact> parsePascoOutput(AbstractFile origFile, String pascoOutputFileName) {
|
||||||
|
|
||||||
Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
|
|
||||||
String fnAbs = moduleTempResultsDir + File.separator + pascoOutputFileName;
|
String fnAbs = moduleTempResultsDir + File.separator + pascoOutputFileName;
|
||||||
|
|
||||||
File file = new File(fnAbs);
|
File file = new File(fnAbs);
|
||||||
@ -439,131 +420,124 @@ class IEExtractor extends Extractor {
|
|||||||
NbBundle.getMessage(this.getClass(), "ExtractIE.parsePascoOutput.errMsg.notFound", this.getModuleName(),
|
NbBundle.getMessage(this.getClass(), "ExtractIE.parsePascoOutput.errMsg.notFound", this.getModuleName(),
|
||||||
file.getName()));
|
file.getName()));
|
||||||
logger.log(Level.WARNING, "Pasco Output not found: {0}", file.getPath()); //NON-NLS
|
logger.log(Level.WARNING, "Pasco Output not found: {0}", file.getPath()); //NON-NLS
|
||||||
return bbartifacts;
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the file the is not empty or the Scanner will
|
// Make sure the file the is not empty or the Scanner will
|
||||||
// throw a "No Line found" Exception
|
// throw a "No Line found" Exception
|
||||||
if (file.length() == 0) {
|
if (file.length() == 0) {
|
||||||
return bbartifacts;
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
try (Scanner fileScanner = new Scanner(new FileInputStream(file.toString()));) {
|
||||||
|
|
||||||
Scanner fileScanner;
|
// Keep a list of reported user accounts to avoid repeats.
|
||||||
try {
|
// Initialize it with the empty string to represent an unknown user.
|
||||||
fileScanner = new Scanner(new FileInputStream(file.toString()));
|
Set<String> reportedUserAccounts = Sets.newHashSet("");
|
||||||
|
Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
|
||||||
|
while (fileScanner.hasNext()) {
|
||||||
|
String line = fileScanner.nextLine();
|
||||||
|
if (!line.startsWith("URL")) { //NON-NLS
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] lineBuff = line.split("\\t"); //NON-NLS
|
||||||
|
|
||||||
|
if (lineBuff.length < 4) {
|
||||||
|
logger.log(Level.INFO, "Found unrecognized IE history format."); //NON-NLS
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String actime = lineBuff[3];
|
||||||
|
Long ftime = (long) 0;
|
||||||
|
String user;
|
||||||
|
String realurl;
|
||||||
|
String domain;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We've seen two types of lines: URL http://XYZ.com .... URL
|
||||||
|
* Visited: Joe@http://XYZ.com ....
|
||||||
|
*/
|
||||||
|
if (lineBuff[1].contains("@")) {
|
||||||
|
String url[] = lineBuff[1].split("@", 2);
|
||||||
|
user = url[0];
|
||||||
|
user = user.replace("Visited:", ""); //NON-NLS
|
||||||
|
user = user.replace(":Host:", ""); //NON-NLS
|
||||||
|
user = user.replaceAll(":(.*?):", "");
|
||||||
|
user = user.trim();
|
||||||
|
realurl = url[1];
|
||||||
|
realurl = realurl.replace("Visited:", ""); //NON-NLS
|
||||||
|
realurl = realurl.replaceAll(":(.*?):", "");
|
||||||
|
realurl = realurl.replace(":Host:", ""); //NON-NLS
|
||||||
|
realurl = realurl.trim();
|
||||||
|
} else {
|
||||||
|
user = "";
|
||||||
|
realurl = lineBuff[1].trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
domain = Util.extractDomain(realurl);
|
||||||
|
|
||||||
|
if (!actime.isEmpty()) {
|
||||||
|
try {
|
||||||
|
Long epochtime = new SimpleDateFormat(PASCO_DATE_FORMAT).parse(actime).getTime();
|
||||||
|
ftime = epochtime / 1000;
|
||||||
|
} catch (ParseException e) {
|
||||||
|
this.addErrorMessage(
|
||||||
|
NbBundle.getMessage(this.getClass(), "ExtractIE.parsePascoOutput.errMsg.errParsingEntry",
|
||||||
|
this.getModuleName()));
|
||||||
|
logger.log(Level.WARNING, String.format("Error parsing Pasco results, may have partial processing of corrupt file (id=%d)", origFile.getId()), e); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
BlackboardArtifact bbart = origFile.newArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY);
|
||||||
|
Collection<BlackboardAttribute> bbattributes = Arrays.asList(
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_URL, PARENT_MODULE_NAME_NO_SPACE,
|
||||||
|
realurl),
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_DATETIME_ACCESSED, PARENT_MODULE_NAME_NO_SPACE,
|
||||||
|
ftime),
|
||||||
|
//TODO: why are we adding an attribute that is always blank?
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_REFERRER, PARENT_MODULE_NAME_NO_SPACE,
|
||||||
|
""),
|
||||||
|
// @@@ NOte that other browser modules are adding TITLE in here for the title
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_PROG_NAME, PARENT_MODULE_NAME_NO_SPACE,
|
||||||
|
getModuleName()),
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_DOMAIN, PARENT_MODULE_NAME_NO_SPACE,
|
||||||
|
domain),
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_USER_NAME, PARENT_MODULE_NAME_NO_SPACE,
|
||||||
|
user));
|
||||||
|
bbart.addAttributes(bbattributes);
|
||||||
|
|
||||||
|
// index the artifact for keyword search
|
||||||
|
this.indexArtifact(bbart);
|
||||||
|
bbartifacts.add(bbart);
|
||||||
|
|
||||||
|
if (reportedUserAccounts.contains(user) == false) {
|
||||||
|
BlackboardArtifact osAttr = origFile.newArtifact(TSK_OS_ACCOUNT);
|
||||||
|
osAttr.addAttribute(new BlackboardAttribute(TSK_USER_NAME, PARENT_MODULE_NAME_NO_SPACE, user));
|
||||||
|
|
||||||
|
// index the artifact for keyword search
|
||||||
|
this.indexArtifact(osAttr);
|
||||||
|
bbartifacts.add(osAttr);
|
||||||
|
|
||||||
|
reportedUserAccounts.add(user);
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error writing Internet Explorer web history artifact to the blackboard.", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bbartifacts;
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (FileNotFoundException ex) {
|
||||||
this.addErrorMessage(
|
this.addErrorMessage(
|
||||||
NbBundle.getMessage(this.getClass(), "ExtractIE.parsePascoOutput.errMsg.errParsing", this.getModuleName(),
|
NbBundle.getMessage(this.getClass(), "ExtractIE.parsePascoOutput.errMsg.errParsing", this.getModuleName(),
|
||||||
file.getName()));
|
file.getName()));
|
||||||
logger.log(Level.WARNING, "Unable to find the Pasco file at " + file.getPath(), ex); //NON-NLS
|
logger.log(Level.WARNING, "Unable to find the Pasco file at " + file.getPath(), ex); //NON-NLS
|
||||||
return bbartifacts;
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep a list of reported user accounts to avoid repeats
|
|
||||||
Set<String> reportedUserAccounts = new HashSet<>();
|
|
||||||
|
|
||||||
while (fileScanner.hasNext()) {
|
|
||||||
String line = fileScanner.nextLine();
|
|
||||||
if (!line.startsWith("URL")) { //NON-NLS
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] lineBuff = line.split("\\t"); //NON-NLS
|
|
||||||
|
|
||||||
if (lineBuff.length < 4) {
|
|
||||||
logger.log(Level.INFO, "Found unrecognized IE history format."); //NON-NLS
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String actime = lineBuff[3];
|
|
||||||
Long ftime = (long) 0;
|
|
||||||
String user;
|
|
||||||
String realurl;
|
|
||||||
String domain;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We've seen two types of lines: URL http://XYZ.com .... URL
|
|
||||||
* Visited: Joe@http://XYZ.com ....
|
|
||||||
*/
|
|
||||||
if (lineBuff[1].contains("@")) {
|
|
||||||
String url[] = lineBuff[1].split("@", 2);
|
|
||||||
user = url[0];
|
|
||||||
user = user.replace("Visited:", ""); //NON-NLS
|
|
||||||
user = user.replace(":Host:", ""); //NON-NLS
|
|
||||||
user = user.replaceAll("(:)(.*?)(:)", "");
|
|
||||||
user = user.trim();
|
|
||||||
realurl = url[1];
|
|
||||||
realurl = realurl.replace("Visited:", ""); //NON-NLS
|
|
||||||
realurl = realurl.replaceAll(":(.*?):", "");
|
|
||||||
realurl = realurl.replace(":Host:", ""); //NON-NLS
|
|
||||||
realurl = realurl.trim();
|
|
||||||
} else {
|
|
||||||
user = "";
|
|
||||||
realurl = lineBuff[1].trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
domain = Util.extractDomain(realurl);
|
|
||||||
|
|
||||||
if (!actime.isEmpty()) {
|
|
||||||
try {
|
|
||||||
Long epochtime = dateFormatter.parse(actime).getTime();
|
|
||||||
ftime = epochtime / 1000;
|
|
||||||
} catch (ParseException e) {
|
|
||||||
this.addErrorMessage(
|
|
||||||
NbBundle.getMessage(this.getClass(), "ExtractIE.parsePascoOutput.errMsg.errParsingEntry",
|
|
||||||
this.getModuleName()));
|
|
||||||
logger.log(Level.WARNING, String.format("Error parsing Pasco results, may have partial processing of corrupt file (id=%d)", origFile.getId()), e); //NON-NLS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
BlackboardArtifact bbart = origFile.newArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY);
|
|
||||||
Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
|
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractIE.parentModuleName.noSpace"), realurl));
|
|
||||||
//bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", EscapeUtil.decodeURL(realurl)));
|
|
||||||
|
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractIE.parentModuleName.noSpace"), ftime));
|
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractIE.parentModuleName.noSpace"), ""));
|
|
||||||
// @@@ NOte that other browser modules are adding TITLE in hre for the title
|
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractIE.parentModuleName.noSpace"),
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractIE.moduleName.text")));
|
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractIE.parentModuleName.noSpace"), domain));
|
|
||||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractIE.parentModuleName.noSpace"), user));
|
|
||||||
bbart.addAttributes(bbattributes);
|
|
||||||
|
|
||||||
// index the artifact for keyword search
|
|
||||||
this.indexArtifact(bbart);
|
|
||||||
bbartifacts.add(bbart);
|
|
||||||
|
|
||||||
if ((!user.isEmpty()) && (!reportedUserAccounts.contains(user))) {
|
|
||||||
BlackboardArtifact osAttr = origFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
|
|
||||||
osAttr.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
|
|
||||||
NbBundle.getMessage(this.getClass(), "ExtractIE.parentModuleName.noSpace"), user));
|
|
||||||
|
|
||||||
// index the artifact for keyword search
|
|
||||||
this.indexArtifact(osAttr);
|
|
||||||
bbartifacts.add(osAttr);
|
|
||||||
|
|
||||||
reportedUserAccounts.add(user);
|
|
||||||
}
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.SEVERE, "Error writing Internet Explorer web history artifact to the blackboard.", ex); //NON-NLS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fileScanner.close();
|
|
||||||
return bbartifacts;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user