diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml index 202fd21824..ff33bd0a36 100644 --- a/Core/nbproject/project.xml +++ b/Core/nbproject/project.xml @@ -183,6 +183,7 @@ org.sleuthkit.autopsy.casemodule + org.sleuthkit.autopsy.casemodule.services org.sleuthkit.autopsy.core org.sleuthkit.autopsy.corecomponentinterfaces org.sleuthkit.autopsy.corecomponents diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index 02b31d6a6e..a599372982 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -19,10 +19,6 @@ package org.sleuthkit.autopsy.casemodule; import java.awt.Frame; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.io.BufferedInputStream; @@ -31,7 +27,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.Arrays; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; @@ -40,19 +35,14 @@ import java.util.Map; import java.util.Set; import java.util.TimeZone; import java.util.logging.Level; -import javax.swing.JDialog; -import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; -import javax.swing.filechooser.FileFilter; -import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.actions.CallableSystemAction; import org.openide.util.actions.SystemAction; import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.casemodule.services.Services; import org.sleuthkit.autopsy.corecomponentinterfaces.CoreComponentControl; -import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationCleanDialog; -import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationDialog; import org.sleuthkit.autopsy.coreutils.FileUtil; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Version; @@ -124,6 +114,7 @@ public class Case { private SleuthkitCase db; // Track the current case (only set with changeCase() method) private static Case currentCase = null; + private Services services; private static final Logger logger = Logger.getLogger(Case.class.getName()); @@ -137,6 +128,7 @@ public class Case { this.configFilePath = configFilePath; this.xmlcm = xmlcm; this.db = db; + this.services = new Services(db); } /** @@ -333,6 +325,13 @@ public class Case { throw new CaseActionException("Error adding image to the case", ex); } } + + /** + * @return The Services object for this case. + */ + public Services getServices() { + return services; + } /** * Get the underlying SleuthkitCase instance from the Sleuth Kit bindings @@ -350,6 +349,7 @@ public class Case { changeCase(null); try { + services.close(); this.xmlcm.close(); // close the xmlcm this.db.close(); } catch (Exception e) { diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/FileManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/FileManager.java new file mode 100644 index 0000000000..4a34625bb4 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/FileManager.java @@ -0,0 +1,99 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2012 Basis Technology Corp. + * + * Copyright 2012 42six Solutions. + * Contact: aebadirad 42six com + * Project Contact/Architect: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.casemodule.services; + +import java.io.Closeable; +import java.io.IOException; +import java.util.List; +import org.sleuthkit.datamodel.FsContent; +import org.sleuthkit.datamodel.Image; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Abstraction to facilitate access to files and directories. + */ +public class FileManager implements Closeable { + + private SleuthkitCase tskCase; + + public FileManager(SleuthkitCase tskCase) { + this.tskCase = tskCase; + } + + /** + * @param fileName the name of the file or directory to match + * @return a list of FsContent for files/directories whose name matches the + * given fileName + */ + public synchronized List findFiles(Image image, String fileName) throws TskCoreException { + if (tskCase == null) { + throw new TskCoreException("Attemtped to use FileManager after it was closed."); + } + return tskCase.findFiles(image, fileName); + } + + /** + * @param fileName the name of the file or directory to match + * @param dirName the name of a parent directory of fileName + * @return a list of FsContent for files/directories whose name matches + * fileName and whose parent directory contains dirName. + */ + public synchronized List findFiles(Image image, String fileName, String dirName) throws TskCoreException { + if (tskCase == null) { + throw new TskCoreException("Attemtped to use FileManager after it was closed."); + } + return tskCase.findFiles(image, fileName, dirName); + } + + /** + * @param fileName the name of the file or directory to match + * @param parentFsContent + * @return a list of FsContent for files/directories whose name matches + * fileName and that were inside a directory described by parentFsContent. + */ + public synchronized List findFiles(Image image, String fileName, FsContent parentFsContent) throws TskCoreException { + if (tskCase == null) { + throw new TskCoreException("Attemtped to use FileManager after it was closed."); + } + return findFiles(image, fileName, parentFsContent.getName()); + } + + /** + * @param filePath The full path to the file(s) of interest. This can + * optionally include the image and volume names. + * @return a list of FsContent that have the given file path. + */ + public synchronized List openFiles(Image image, String filePath) throws TskCoreException { + if (tskCase == null) { + throw new TskCoreException("Attemtped to use FileManager after it was closed."); + } + return tskCase.openFiles(image, filePath); + } + + @Override + public synchronized void close() throws IOException { + tskCase = null; + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Services.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/Services.java new file mode 100644 index 0000000000..9371d6d6ea --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Services.java @@ -0,0 +1,64 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2012 Basis Technology Corp. + * + * Copyright 2012 42six Solutions. + * Contact: aebadirad 42six com + * Project Contact/Architect: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.casemodule.services; + +import java.io.Closeable; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import org.sleuthkit.datamodel.SleuthkitCase; + +/** + * A class to manage various services. + */ +public class Services implements Closeable { + + private SleuthkitCase tskCase; + + // NOTE: all new services added to Services class must be added to this list + // of services. + private List services = new ArrayList(); + + // services + private FileManager fileManager; + + public Services(SleuthkitCase tskCase) { + this.tskCase = tskCase; + } + + public synchronized FileManager getFileManager() { + if (fileManager == null) { + fileManager = new FileManager(tskCase); + services.add(fileManager); + } + return fileManager; + } + + @Override + public void close() throws IOException { + // close all services + for (Closeable service : services) { + service.close(); + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index 637729198f..d37fe5406e 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -404,7 +404,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { * @param table the object table * @return max the maximum width of the column */ - private int getMaxColumnWidth(int index, FontMetrics metrics, int margin, int padding, String header, Object[][] table) { + private synchronized int getMaxColumnWidth(int index, FontMetrics metrics, int margin, int padding, String header, Object[][] table) { // set the tree (the node / names column) width String headerName = header; int headerWidth = metrics.stringWidth(headerName); // length of the header @@ -412,7 +412,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { // Get maximum width of column data for (int i = 0; i < table.length; i++) { - if (index >= table[i].length) { + if (table[i] == null || index >= table[i].length) { continue; } String test = table[i][index].toString(); diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestScheduler.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestScheduler.java index c03e37d8ac..5ad1970843 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestScheduler.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestScheduler.java @@ -394,6 +394,11 @@ class IngestScheduler { * @param task */ synchronized void add(ScheduledTask task) { + //skip if task contains no modules + if (task.modules.isEmpty()) { + return; + } + if (getImages().contains(task.image)) { //reset counters if the same image enqueued twice //Note, not very accurate, because we may have processed some files from @@ -927,6 +932,11 @@ class IngestScheduler { } synchronized void add(Task task) { + //skip if task contains no modules + if (task.modules.isEmpty()) { + return; + } + Task existTask = null; for (Task curTask : tasks) { if (curTask.image.equals(task.image)) { diff --git a/KeywordSearch/nbproject/genfiles.properties b/KeywordSearch/nbproject/genfiles.properties index b2d8509e82..97886535c8 100644 --- a/KeywordSearch/nbproject/genfiles.properties +++ b/KeywordSearch/nbproject/genfiles.properties @@ -3,6 +3,6 @@ build.xml.script.CRC32=87b97b04 build.xml.stylesheet.CRC32=a56c6a5b@1.46.2 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=1cff292d +nbproject/build-impl.xml.data.CRC32=8f39548f nbproject/build-impl.xml.script.CRC32=fe1f48d2 nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.50.1 diff --git a/NEWS.txt b/NEWS.txt index faafb83b3e..7b5223753b 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -3,11 +3,16 @@ New features: Improvements: -- Add Image Wizard - better work-flow, better device size reporting -- File Ingest: reduced file queuing time and memory usage +- File Ingest: minimized file queuing time and memory usage +- Add Image Wizard - better work-flow, better device size reporting, info on currently processed directory +- Added extraction of all unallocated blocks (from volume, image) as a single file +- Reporting improvements: reorganized columns, sorted by 1st column, added logo to html report Bugfixes: - fixed periodic keyword search during ingest, when it'd run max. 2 times only +- fixed Downloads "target" in Recent Activity +- fixed missing hash and keyword search hits in reports + ---------------- VERSION 3.0.1 -------------- diff --git a/RecentActivity/nbproject/genfiles.properties b/RecentActivity/nbproject/genfiles.properties index 90aa712a1d..fe69d96298 100644 --- a/RecentActivity/nbproject/genfiles.properties +++ b/RecentActivity/nbproject/genfiles.properties @@ -1,8 +1,8 @@ -build.xml.data.CRC32=320aa38b +build.xml.data.CRC32=bcfe7e87 build.xml.script.CRC32=d323407a build.xml.stylesheet.CRC32=a56c6a5b@2.50.1 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=320aa38b +nbproject/build-impl.xml.data.CRC32=bcfe7e87 nbproject/build-impl.xml.script.CRC32=aef16a21 nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.50.1 diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java index af2068f2eb..153d2989b0 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java @@ -37,6 +37,8 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.sql.SQLException; +import org.sleuthkit.autopsy.casemodule.services.FileManager; import org.sleuthkit.autopsy.coreutils.EscapeUtil; import org.sleuthkit.autopsy.ingest.IngestImageWorkerController; import org.sleuthkit.autopsy.ingest.IngestModuleImage; @@ -96,20 +98,25 @@ public class Chrome extends Extract implements IngestModuleImage { } private void getHistory(Image image, IngestImageWorkerController controller) { - //Make these seperate, this is for history - List FFSqlitedb = this.extractFiles(image, "select * from tsk_files where name LIKE 'History' and name NOT LIKE '%journal%' AND parent_path LIKE '%Chrome%'"); + FileManager fileManager = currentCase.getServices().getFileManager(); + List historyFiles = null; + try { + historyFiles = fileManager.findFiles(image, "History", "Chrome"); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error when trying to get Chrome history files.", ex); + } int j = 0; - if (FFSqlitedb != null && !FFSqlitedb.isEmpty()) { - while (j < FFSqlitedb.size()) { - String temps = currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db"; + if (historyFiles != null && !historyFiles.isEmpty()) { + while (j < historyFiles.size()) { + String temps = currentCase.getTempDirectory() + File.separator + historyFiles.get(j).getName().toString() + j + ".db"; int errors = 0; try { - ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db")); + ContentUtils.writeToFile(historyFiles.get(j), new File(currentCase.getTempDirectory() + File.separator + historyFiles.get(j).getName().toString() + j + ".db")); } catch (IOException ex) { logger.log(Level.SEVERE, "Error writing temp sqlite db for Chrome web history artifacts.{0}", ex); - this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + FFSqlitedb.get(j).getName()); + this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + historyFiles.get(j).getName()); } File dbFile = new File(temps); if (controller.isCancelled()) { @@ -130,7 +137,7 @@ public class Chrome extends Extract implements IngestModuleImage { bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "Recent Activity", ((result.get("title").toString() != null) ? result.get("title").toString() : ""))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), "Recent Activity", "Chrome")); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "Recent Activity", (Util.extractDomain((result.get("url").toString() != null) ? result.get("url").toString() : "")))); - this.addArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY, FFSqlitedb.get(j), bbattributes); + this.addArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY, historyFiles.get(j), bbattributes); } if (errors > 0) { @@ -145,20 +152,25 @@ public class Chrome extends Extract implements IngestModuleImage { } private void getBookmark(Image image, IngestImageWorkerController controller) { - - //this is for bookmarks - List FFSqlitedb = this.extractFiles(image, "select * from tsk_files where name LIKE 'Bookmarks' and name NOT LIKE '%journal%' and parent_path LIKE '%Chrome%'"); + + FileManager fileManager = currentCase.getServices().getFileManager(); + List bookmarkFiles = null; + try { + bookmarkFiles = fileManager.findFiles(image, "Bookmarks", "Chrome"); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error when trying to get Chrome history files.", ex); + } int j = 0; - if (FFSqlitedb != null && !FFSqlitedb.isEmpty()) { - while (j < FFSqlitedb.size()) { - String temps = currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db"; + if (bookmarkFiles != null && !bookmarkFiles.isEmpty()) { + while (j < bookmarkFiles.size()) { + String temps = currentCase.getTempDirectory() + File.separator + bookmarkFiles.get(j).getName().toString() + j + ".db"; int errors = 0; try { - ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db")); + ContentUtils.writeToFile(bookmarkFiles.get(j), new File(currentCase.getTempDirectory() + File.separator + bookmarkFiles.get(j).getName().toString() + j + ".db")); } catch (IOException ex) { logger.log(Level.SEVERE, "Error writing temp sqlite db for Chrome bookmark artifacts.{0}", ex); - this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + FFSqlitedb.get(j).getName()); + this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + bookmarkFiles.get(j).getName()); } logger.log(Level.INFO, moduleName + "- Now getting Bookmarks from " + temps); File dbFile = new File(temps); @@ -180,7 +192,7 @@ public class Chrome extends Extract implements IngestModuleImage { String name = address.get("name").getAsString(); Long date = address.get("date_added").getAsLong(); String domain = Util.extractDomain(url); - BlackboardArtifact bbart = FFSqlitedb.get(j).newArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK); + BlackboardArtifact bbart = bookmarkFiles.get(j).newArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK); Collection bbattributes = new ArrayList(); //TODO Revisit usage of deprecated constructor as per TSK-583 //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "Recent Activity", "Last Visited", (date / 10000000))); @@ -213,19 +225,25 @@ public class Chrome extends Extract implements IngestModuleImage { //COOKIES section // This gets the cookie info private void getCookie(Image image, IngestImageWorkerController controller) { - - List FFSqlitedb = this.extractFiles(image, "select * from tsk_files where name LIKE '%Cookies%' and name NOT LIKE '%journal%' and parent_path LIKE '%Chrome%'"); + + FileManager fileManager = currentCase.getServices().getFileManager(); + List cookiesFiles = null; + try { + cookiesFiles = fileManager.findFiles(image, "Cookies", "Chrome"); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error when trying to get Chrome history files.", ex); + } int j = 0; - if (FFSqlitedb != null && !FFSqlitedb.isEmpty()) { - while (j < FFSqlitedb.size()) { - String temps = currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db"; + if (cookiesFiles != null && !cookiesFiles.isEmpty()) { + while (j < cookiesFiles.size()) { + String temps = currentCase.getTempDirectory() + File.separator + cookiesFiles.get(j).getName().toString() + j + ".db"; int errors = 0; try { - ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db")); + ContentUtils.writeToFile(cookiesFiles.get(j), new File(currentCase.getTempDirectory() + File.separator + cookiesFiles.get(j).getName().toString() + j + ".db")); } catch (IOException ex) { logger.log(Level.SEVERE, "Error writing temp sqlite db for Chrome cookie artifacts.{0}", ex); - this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + FFSqlitedb.get(j).getName()); + this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + cookiesFiles.get(j).getName()); } File dbFile = new File(temps); if (controller.isCancelled()) { @@ -249,7 +267,7 @@ public class Chrome extends Extract implements IngestModuleImage { String domain = result.get("host_key").toString(); domain = domain.replaceFirst("^\\.+(?!$)", ""); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "Recent Activity", domain)); - this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, FFSqlitedb.get(j), bbattributes); + this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFiles.get(j), bbattributes); } if (errors > 0) { @@ -266,19 +284,25 @@ public class Chrome extends Extract implements IngestModuleImage { //Downloads section // This gets the downloads info private void getDownload(Image image, IngestImageWorkerController controller) { - - List FFSqlitedb = this.extractFiles(image, "select * from tsk_files where name LIKE 'History' and name NOT LIKE '%journal%' and parent_path LIKE '%Chrome%'"); + + FileManager fileManager = currentCase.getServices().getFileManager(); + List historyFiles = null; + try { + historyFiles = fileManager.findFiles(image, "History", "Chrome"); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error when trying to get Chrome history files.", ex); + } int j = 0; - if (FFSqlitedb != null && !FFSqlitedb.isEmpty()) { - while (j < FFSqlitedb.size()) { - String temps = currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db"; + if (historyFiles != null && !historyFiles.isEmpty()) { + while (j < historyFiles.size()) { + String temps = currentCase.getTempDirectory() + File.separator + historyFiles.get(j).getName().toString() + j + ".db"; int errors = 0; try { - ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db")); + ContentUtils.writeToFile(historyFiles.get(j), new File(currentCase.getTempDirectory() + File.separator + historyFiles.get(j).getName().toString() + j + ".db")); } catch (IOException ex) { logger.log(Level.SEVERE, "Error writing temp sqlite db for Chrome download artifacts.{0}", ex); - this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + FFSqlitedb.get(j).getName()); + this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + historyFiles.get(j).getName()); } File dbFile = new File(temps); if (controller.isCancelled()) { @@ -291,7 +315,7 @@ public class Chrome extends Extract implements IngestModuleImage { for (HashMap result : tempList) { Collection bbattributes = new ArrayList(); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), "Recent Activity", (result.get("full_path").toString()))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID(), "Recent Activity", Util.findID((result.get("full_path").toString())))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID(), "Recent Activity", Util.findID(image, (result.get("full_path").toString())))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "Recent Activity", ((result.get("url").toString() != null) ? result.get("url").toString() : ""))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "Recent Activity", ((result.get("url").toString() != null) ? EscapeUtil.decodeURL(result.get("url").toString()) : ""))); Long time = (Long.valueOf(result.get("start_time").toString())); @@ -303,7 +327,7 @@ public class Chrome extends Extract implements IngestModuleImage { String domain = Util.extractDomain((result.get("url").toString() != null) ? result.get("url").toString() : ""); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "Recent Activity", domain)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), "Recent Activity", "Chrome")); - this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, FFSqlitedb.get(j), bbattributes); + this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, historyFiles.get(j), bbattributes); } if (errors > 0) { @@ -320,19 +344,25 @@ public class Chrome extends Extract implements IngestModuleImage { //Login/Password section // This gets the user info private void getLogin(Image image, IngestImageWorkerController controller) { - - List FFSqlitedb = this.extractFiles(image, "select * from tsk_files where name LIKE 'signons.sqlite' and name NOT LIKE '%journal%' and parent_path LIKE '%Chrome%'"); + + FileManager fileManager = currentCase.getServices().getFileManager(); + List signonFiles = null; + try { + signonFiles = fileManager.findFiles(image, "signons.sqlite", "Chrome"); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error when trying to get Chrome history files.", ex); + } int j = 0; - if (FFSqlitedb != null && !FFSqlitedb.isEmpty()) { - while (j < FFSqlitedb.size()) { - String temps = currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db"; + if (signonFiles != null && !signonFiles.isEmpty()) { + while (j < signonFiles.size()) { + String temps = currentCase.getTempDirectory() + File.separator + signonFiles.get(j).getName().toString() + j + ".db"; int errors = 0; try { - ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db")); + ContentUtils.writeToFile(signonFiles.get(j), new File(currentCase.getTempDirectory() + File.separator + signonFiles.get(j).getName().toString() + j + ".db")); } catch (IOException ex) { logger.log(Level.SEVERE, "Error writing temp sqlite db for Chrome login artifacts.{0}", ex); - this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + FFSqlitedb.get(j).getName()); + this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + signonFiles.get(j).getName()); } File dbFile = new File(temps); if (controller.isCancelled()) { @@ -354,7 +384,7 @@ public class Chrome extends Extract implements IngestModuleImage { bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "Recent Activity", (Util.extractDomain((result.get("origin_url").toString() != null) ? result.get("url").toString() : "")))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USERNAME.getTypeID(), "Recent Activity", ((result.get("username_value").toString() != null) ? result.get("username_value").toString().replaceAll("'", "''") : ""))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "Recent Activity", result.get("signon_realm").toString())); - this.addArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY, FFSqlitedb.get(j), bbattributes); + this.addArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY, signonFiles.get(j), bbattributes); } if (errors > 0) { diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java index 6d557a49e7..202b1b7c30 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java @@ -75,9 +75,6 @@ public class ExtractIE extends Extract implements IngestModuleImage { private static final Logger logger = Logger.getLogger(ExtractIE.class.getName()); private IngestServices services; - private String indexDatQueryStr = "select * from tsk_files where name LIKE '%index.dat%'"; - private String favoriteQuery = "select * from `tsk_files` where parent_path LIKE '%/Favorites%' and name LIKE '%.url'"; - private String cookiesQuery = "select * from `tsk_files` where parent_path LIKE '%/Cookies%' and name LIKE '%.txt'"; private String recentQuery = "select * from `tsk_files` where parent_path LIKE '%/Recent%' and name LIKE '%.lnk'"; //sleauthkit db handle SleuthkitCase tempDb; @@ -131,14 +128,21 @@ public class ExtractIE extends Extract implements IngestModuleImage { // This gets the favorite info private void getBookmark(Image image, IngestImageWorkerController controller) { - List FavoriteList = this.extractFiles(image, favoriteQuery); int errors = 0; + + org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager(); + List favoritesFiles = null; + try { + favoritesFiles = fileManager.findFiles(image, "%.url", "Favorites"); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error fetching 'index.data' files for Internet Explorer history."); + } - for (FsContent Favorite : FavoriteList) { + for (FsContent favoritesFile : favoritesFiles) { if (controller.isCancelled()) { break; } - Content fav = Favorite; + Content fav = favoritesFile; byte[] t = new byte[(int) fav.getSize()]; try { final int bytesRead = fav.read(t, 0, fav.getSize()); @@ -154,8 +158,8 @@ public class ExtractIE extends Extract implements IngestModuleImage { if (m.find()) { url = m.group(1); } - String name = Favorite.getName(); - Long datetime = Favorite.getCrtime(); + String name = favoritesFile.getName(); + Long datetime = favoritesFile.getCrtime(); String Tempdate = datetime.toString(); datetime = Long.valueOf(Tempdate); String domain = Util.extractDomain(url); @@ -169,7 +173,7 @@ public class ExtractIE extends Extract implements IngestModuleImage { bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", name)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), "RecentActivity", "Internet Explorer")); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "RecentActivity", domain)); - this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, Favorite, bbattributes); + this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, favoritesFile, bbattributes); services.fireModuleDataEvent(new ModuleDataEvent("Recent Activity", BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK)); } @@ -181,14 +185,21 @@ public class ExtractIE extends Extract implements IngestModuleImage { //Cookies section // This gets the cookies info private void getCookie(Image image, IngestImageWorkerController controller) { + + org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager(); + List cookiesFiles = null; + try { + cookiesFiles = fileManager.findFiles(image, "%.txt", "Cookies"); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error fetching 'index.data' files for Internet Explorer history."); + } - List CookiesList = this.extractFiles(image, cookiesQuery); int errors = 0; - for (FsContent Cookie : CookiesList) { + for (FsContent cookiesFile : cookiesFiles) { if (controller.isCancelled()) { break; } - Content fav = Cookie; + Content fav = cookiesFile; byte[] t = new byte[(int) fav.getSize()]; try { final int bytesRead = fav.read(t, 0, fav.getSize()); @@ -200,7 +211,7 @@ public class ExtractIE extends Extract implements IngestModuleImage { String url = values.length > 2 ? values[2] : ""; String value = values.length > 1 ? values[1] : ""; String name = values.length > 0 ? values[0] : ""; - Long datetime = Cookie.getCrtime(); + Long datetime = cookiesFile.getCrtime(); String Tempdate = datetime.toString(); datetime = Long.valueOf(Tempdate); String domain = Util.extractDomain(url); @@ -217,7 +228,7 @@ public class ExtractIE extends Extract implements IngestModuleImage { bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", (name != null) ? name : "")); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), "RecentActivity", "Internet Explorer")); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "RecentActivity", domain)); - this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, Cookie, bbattributes); + this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes); } if (errors > 0) { this.addErrorMessage(this.getName() + ": Error parsing " + errors + " Internet Explorer cookies."); @@ -229,26 +240,33 @@ public class ExtractIE extends Extract implements IngestModuleImage { //Recent Documents section // This gets the recent object info private void getRecentDocuments(Image image, IngestImageWorkerController controller) { + + org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager(); + List recentFiles = null; + try { + recentFiles = fileManager.findFiles(image, "%.lnk", "Recent"); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error fetching 'index.data' files for Internet Explorer history."); + } - List RecentList = this.extractFiles(image, recentQuery); - - for (FsContent Recent : RecentList) { + for (FsContent recentFile : recentFiles) { if (controller.isCancelled()) { break; } - Content fav = Recent; + Content fav = recentFile; JLNK lnk = new JLnkParser(new ReadContentInputStream(fav), (int) fav.getSize()).parse(); String path = lnk.getBestPath(); - Long datetime = Recent.getCrtime(); + Long datetime = recentFile.getCrtime(); Collection bbattributes = new ArrayList(); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), "RecentActivity", path)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", Util.getFileName(path))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID(), "RecentActivity", Util.findID(path))); + long id = Util.findID(image, path); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID(), "RecentActivity", id)); //TODO Revisit usage of deprecated constructor as per TSK-583 //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), "RecentActivity", "Date Created", datetime)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), "RecentActivity", datetime)); - this.addArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT, Recent, bbattributes); + this.addArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT, recentFile, bbattributes); } services.fireModuleDataEvent(new ModuleDataEvent("Recent Activity", BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT)); @@ -286,7 +304,6 @@ public class ExtractIE extends Extract implements IngestModuleImage { File resultsDir = new File(PASCO_RESULTS_PATH); resultsDir.mkdirs(); - Collection FsContentCollection = null; tempDb = currentCase.getSleuthkitCase(); Collection imageFS = tempDb.getFileSystems(image); List fsIds = new LinkedList(); @@ -305,24 +322,25 @@ public class ExtractIE extends Extract implements IngestModuleImage { allFS += ")"; } } + + // get index.dat files + org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager(); + List indexFiles = null; try { - ResultSet rs = tempDb.runQuery(indexDatQueryStr + allFS); - FsContentCollection = tempDb.resultSetToFsContents(rs); - rs.close(); - rs.getStatement().close(); - } catch (SQLException ex) { - logger.log(Level.SEVERE, "Error reading database for Internet Explorer history artifacts: {0}", ex); + indexFiles = fileManager.findFiles(image, "index.dat"); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error fetching 'index.data' files for Internet Explorer history."); } + String temps; String indexFileName; - - for (FsContent fsc : FsContentCollection) { + for (FsContent indexFile : indexFiles) { // Since each result represent an index.dat file, // just create these files with the following notation: // index.dat (i.e. index0.dat, index1.dat,..., indexN.dat) // Write each index.dat file to a temp directory. //BlackboardArtifact bbart = fsc.newArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY); - indexFileName = "index" + Integer.toString((int) fsc.getId()) + ".dat"; + indexFileName = "index" + Integer.toString((int) indexFile.getId()) + ".dat"; //indexFileName = "index" + Long.toString(bbart.getArtifactID()) + ".dat"; temps = currentCase.getTempDirectory() + File.separator + indexFileName; File datFile = new File(temps); @@ -331,12 +349,12 @@ public class ExtractIE extends Extract implements IngestModuleImage { break; } try { - ContentUtils.writeToFile(fsc, datFile); + ContentUtils.writeToFile(indexFile, datFile); } catch (IOException e) { logger.log(Level.SEVERE, "Error while trying to write index.dat file " + datFile.getAbsolutePath(), e); } - String filename = "pasco2Result." + fsc.getId() + ".txt"; + String filename = "pasco2Result." + indexFile.getId() + ".txt"; boolean bPascProcSuccess = executePasco(temps, filename); pascoResults.add(filename); diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 3e11cde6a5..3432d17ea8 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -105,62 +105,49 @@ public class ExtractRegistry extends Extract implements IngestModuleImage { public void setArguments(String args) { this.args = args; } - - private void getregistryfiles(Image image, IngestImageWorkerController controller) { - Case currentCase = Case.getCurrentCase(); // get the most updated case - SleuthkitCase tempDb = currentCase.getSleuthkitCase(); - Collection imageFS = tempDb.getFileSystems(image); - List fsIds = new LinkedList(); - for (FileSystem img : imageFS) { - Long tempID = img.getId(); - fsIds.add(tempID.toString()); - } - - String allFS = new String(); - for (int i = 0; i < fsIds.size(); i++) { - if (i == 0) { - allFS += " AND (0"; - } - allFS += " OR fs_obj_id = '" + fsIds.get(i) + "'"; - if (i == fsIds.size() - 1) { - allFS += ")"; - } - } - List Regfiles = new ArrayList(); + + private void getRegistryFiles(Image image, IngestImageWorkerController controller) { + + org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager(); + List allRegistryFiles = new ArrayList(); try { - ResultSet rs = tempDb.runQuery("select * from tsk_files where lower(name) = 'ntuser.dat' OR lower(parent_path) LIKE '%/system32/config%' and (name LIKE 'system' OR name LIKE 'software' OR name = 'SECURITY' OR name = 'SAM' OR name = 'default')" + allFS); - Regfiles = tempDb.resultSetToFsContents(rs); - } catch (SQLException ex) { - logger.log(Level.SEVERE, "Error querying the database for registry files: {0}", ex); + allRegistryFiles.addAll(fileManager.findFiles(image, "ntuser.dat")); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error fetching 'ntuser.dat' file."); } - - int j = 0; - - while (j < Regfiles.size()) { - boolean Success; - Content orgFS = Regfiles.get(j); - long orgId = orgFS.getId(); - String temps = currentCase.getTempDirectory() + "\\" + Regfiles.get(j).getName().toString(); + + // try to find each of the listed registry files whose parent directory + // is like '%/system32/config%' + String[] regFileNames = new String[] {"system", "software", "security", "sam", "default"}; + for (String regFileName : regFileNames) { try { - ContentUtils.writeToFile(Regfiles.get(j), new File(currentCase.getTempDirectory() + "\\" + Regfiles.get(j).getName())); + allRegistryFiles.addAll(fileManager.findFiles(image, regFileName, "%/system32/config%")); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error fetching registry file: " + regFileName); + } + } + + int j = 0; + for (FsContent regFile : allRegistryFiles) { + String regFileName = regFile.getName(); + String temps = currentCase.getTempDirectory() + "\\" + regFileName; + try { + ContentUtils.writeToFile(regFile, new File(currentCase.getTempDirectory() + "\\" + regFileName)); } catch (IOException ex) { logger.log(Level.SEVERE, "Error writing the temp registry file. {0}", ex); } - File regFile = new File(temps); + File aRegFile = new File(temps); logger.log(Level.INFO, moduleName + "- Now getting registry information from " + temps); - String txtPath = executeRegRip(temps, j); + String txtPath = executeRegRip(temps, j++); if (txtPath.length() > 0) { - Success = parseReg(txtPath, orgId); - } else { - Success = false; + if (parseReg(txtPath, regFile.getId()) == false) { + continue; + } } + //At this point pasco2 proccessed the index files. //Now fetch the results, parse them and the delete the files. - if (Success) { - //Delete dat file since it was succcessful - regFile.delete(); - } - j++; + aRegFile.delete(); } } @@ -396,7 +383,7 @@ public class ExtractRegistry extends Extract implements IngestModuleImage { @Override public void process(Image image, IngestImageWorkerController controller) { - this.getregistryfiles(image, controller); + this.getRegistryFiles(image, controller); } @Override diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java index c6995577a8..51e679b826 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java @@ -31,6 +31,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.logging.Level; +import org.sleuthkit.autopsy.casemodule.services.FileManager; import org.sleuthkit.autopsy.coreutils.EscapeUtil; import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.ingest.IngestImageWorkerController; @@ -44,6 +45,7 @@ import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.FsContent; import org.sleuthkit.datamodel.Image; +import org.sleuthkit.datamodel.TskCoreException; /** * Firefox recent activity extraction @@ -91,216 +93,254 @@ public class Firefox extends Extract implements IngestModuleImage { private void getHistory(Image image, IngestImageWorkerController controller) { //Make these seperate, this is for history - List FFSqlitedb = this.extractFiles(image, "select * from tsk_files where name LIKE '%places.sqlite%' and name NOT LIKE '%journal%' and parent_path LIKE '%Firefox%'"); + //List FFSqlitedb = this.extractFiles(image, "select * from tsk_files where name LIKE '%places.sqlite%' and name NOT LIKE '%journal%' and parent_path LIKE '%Firefox%'"); + + FileManager fileManager = currentCase.getServices().getFileManager(); + List historyFiles = null; + try { + historyFiles = fileManager.findFiles(image, "%places.sqlite%", "Firefox"); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error fetching internet history files for Firefox."); + } + + if (historyFiles == null) { + return; + } int j = 0; - if (FFSqlitedb != null && !FFSqlitedb.isEmpty()) { - while (j < FFSqlitedb.size()) { - String temps = currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db"; - int errors = 0; - try { - ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db")); - } catch (IOException ex) { - logger.log(Level.SEVERE, "Error writing the sqlite db for firefox web history artifacts.{0}", ex); - this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + FFSqlitedb.get(j).getName()); - } - File dbFile = new File(temps); - if (controller.isCancelled()) { - dbFile.delete(); - break; - } - List> tempList = this.dbConnect(temps, ffquery); - logger.log(Level.INFO, moduleName + "- Now getting history from " + temps + " with " + tempList.size() + "artifacts identified."); - for (HashMap result : tempList) { - Collection bbattributes = new ArrayList(); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity", ((result.get("url").toString() != null) ? result.get("url").toString() : ""))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("url").toString() != null) ? EscapeUtil.decodeURL(result.get("url").toString()) : ""))); - //TODO Revisit usage of deprecated constructor as per TSK-583 - //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", "Last Visited", (Long.valueOf(result.get("visit_date").toString())))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(), "RecentActivity", (Long.valueOf(result.get("visit_date").toString())))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID(), "RecentActivity", ((result.get("ref").toString() != null) ? result.get("ref").toString() : ""))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", ((result.get("title").toString() != null) ? result.get("title").toString() : ""))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), "RecentActivity", "FireFox")); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "RecentActivity", (Util.extractDomain((result.get("url").toString() != null) ? result.get("url").toString() : "")))); - this.addArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY, FFSqlitedb.get(j), bbattributes); - - } - if (errors > 0) { - this.addErrorMessage(this.getName() + ": Error parsing " + errors + " Firefox web history artifacts."); - } - j++; - dbFile.delete(); + for (FsContent historyFile : historyFiles) { + String fileName = historyFile.getName(); + String temps = currentCase.getTempDirectory() + File.separator + fileName + j + ".db"; + int errors = 0; + try { + ContentUtils.writeToFile(historyFile, new File(currentCase.getTempDirectory() + File.separator + fileName + j + ".db")); + } catch (IOException ex) { + logger.log(Level.SEVERE, "Error writing the sqlite db for firefox web history artifacts.{0}", ex); + this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + fileName); } + File dbFile = new File(temps); + if (controller.isCancelled()) { + dbFile.delete(); + break; + } + List> tempList = this.dbConnect(temps, ffquery); + logger.log(Level.INFO, moduleName + "- Now getting history from " + temps + " with " + tempList.size() + "artifacts identified."); + for (HashMap result : tempList) { + Collection bbattributes = new ArrayList(); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity", ((result.get("url").toString() != null) ? result.get("url").toString() : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("url").toString() != null) ? EscapeUtil.decodeURL(result.get("url").toString()) : ""))); + //TODO Revisit usage of deprecated constructor as per TSK-583 + //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", "Last Visited", (Long.valueOf(result.get("visit_date").toString())))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(), "RecentActivity", (Long.valueOf(result.get("visit_date").toString())))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID(), "RecentActivity", ((result.get("ref").toString() != null) ? result.get("ref").toString() : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", ((result.get("title").toString() != null) ? result.get("title").toString() : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), "RecentActivity", "FireFox")); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "RecentActivity", (Util.extractDomain((result.get("url").toString() != null) ? result.get("url").toString() : "")))); + this.addArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY, historyFile, bbattributes); - services.fireModuleDataEvent(new ModuleDataEvent("Recent Activity", BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY)); + } + if (errors > 0) { + this.addErrorMessage(this.getName() + ": Error parsing " + errors + " Firefox web history artifacts."); + } + ++j; + dbFile.delete(); } + + services.fireModuleDataEvent(new ModuleDataEvent("Recent Activity", BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY)); } private void getBookmark(Image image, IngestImageWorkerController controller) { - //this is for bookmarks - List FFSqlitedb = this.extractFiles(image, "select * from tsk_files where name LIKE '%places.sqlite%' and name NOT LIKE '%journal%' and parent_path LIKE '%Firefox%'"); + FileManager fileManager = currentCase.getServices().getFileManager(); + List bookmarkFiles = null; + try { + bookmarkFiles = fileManager.findFiles(image, "places.sqlite", "Firefox"); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error fetching bookmark files for Firefox."); + } + + if (bookmarkFiles == null) { + return; + } int j = 0; - if (FFSqlitedb != null && !FFSqlitedb.isEmpty()) { - while (j < FFSqlitedb.size()) { - String temps = currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db"; - int errors = 0; - try { - ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db")); - } catch (IOException ex) { - logger.log(Level.SEVERE, "Error writing the sqlite db for firefox bookmark artifacts.{0}", ex); - this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + FFSqlitedb.get(j).getName()); - } - File dbFile = new File(temps); - if (controller.isCancelled()) { - dbFile.delete(); - break; - } - List> tempList = this.dbConnect(temps, ffbookmarkquery); - logger.log(Level.INFO, moduleName + "- Now getting bookmarks from " + temps + " with " + tempList.size() + "artifacts identified."); - for (HashMap result : tempList) { - - Collection bbattributes = new ArrayList(); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity", ((result.get("url").toString() != null) ? result.get("url").toString() : ""))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("url").toString() != null) ? EscapeUtil.decodeURL(result.get("url").toString()) : ""))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", ((result.get("title").toString() != null) ? result.get("title").toString() : ""))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), "RecentActivity", "FireFox")); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "RecentActivity", (Util.extractDomain((result.get("url").toString() != null) ? result.get("url").toString() : "")))); - this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, FFSqlitedb.get(j), bbattributes); - - } - if (errors > 0) { - this.addErrorMessage(this.getName() + ": Error parsing " + errors + " Firefox web history artifacts."); - } - j++; - dbFile.delete(); + for (FsContent bookmarkFile : bookmarkFiles) { + String fileName = bookmarkFile.getName(); + String temps = currentCase.getTempDirectory() + File.separator + fileName + j + ".db"; + int errors = 0; + try { + ContentUtils.writeToFile(bookmarkFile, new File(currentCase.getTempDirectory() + File.separator + fileName + j + ".db")); + } catch (IOException ex) { + logger.log(Level.SEVERE, "Error writing the sqlite db for firefox bookmark artifacts.{0}", ex); + this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + fileName); } + File dbFile = new File(temps); + if (controller.isCancelled()) { + dbFile.delete(); + break; + } + List> tempList = this.dbConnect(temps, ffbookmarkquery); + logger.log(Level.INFO, moduleName + "- Now getting bookmarks from " + temps + " with " + tempList.size() + "artifacts identified."); + for (HashMap result : tempList) { - services.fireModuleDataEvent(new ModuleDataEvent("Recent Activity", BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK)); + Collection bbattributes = new ArrayList(); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity", ((result.get("url").toString() != null) ? result.get("url").toString() : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("url").toString() != null) ? EscapeUtil.decodeURL(result.get("url").toString()) : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", ((result.get("title").toString() != null) ? result.get("title").toString() : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), "RecentActivity", "FireFox")); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "RecentActivity", (Util.extractDomain((result.get("url").toString() != null) ? result.get("url").toString() : "")))); + this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, bookmarkFile, bbattributes); + + } + if (errors > 0) { + this.addErrorMessage(this.getName() + ": Error parsing " + errors + " Firefox web history artifacts."); + } + ++j; + dbFile.delete(); } + + services.fireModuleDataEvent(new ModuleDataEvent("Recent Activity", BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK)); } //COOKIES section // This gets the cookie info private void getCookie(Image image, IngestImageWorkerController controller) { - List FFSqlitedb = this.extractFiles(image, "select * from tsk_files where name LIKE '%cookies.sqlite%' and name NOT LIKE '%journal%' and parent_path LIKE '%Firefox%'"); + FileManager fileManager = currentCase.getServices().getFileManager(); + List cookiesFiles = null; + try { + cookiesFiles = fileManager.findFiles(image, "cookies.sqlite", "Firefox"); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error fetching cookies files for Firefox."); + } + + if (cookiesFiles == null) { + return; + } int j = 0; - if (FFSqlitedb != null && !FFSqlitedb.isEmpty()) { - while (j < FFSqlitedb.size()) { - String temps = currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db"; - int errors = 0; - try { - ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db")); - } catch (IOException ex) { - logger.log(Level.SEVERE, "Error writing the sqlite db for firefox cookie artifacts.{0}", ex); - this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + FFSqlitedb.get(j).getName()); - } - File dbFile = new File(temps); - if (controller.isCancelled()) { - dbFile.delete(); - break; - } - boolean checkColumn = Util.checkColumn("creationTime", "moz_cookies", temps); - String query = null; - if (checkColumn) { - query = ffcookiequery; - } else { - query = ff3cookiequery; - } - - List> tempList = this.dbConnect(temps, query); - logger.log(Level.INFO, moduleName + "- Now getting cookies from " + temps + " with " + tempList.size() + "artifacts identified."); - for (HashMap result : tempList) { - - Collection bbattributes = new ArrayList(); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity", ((result.get("host").toString() != null) ? result.get("host").toString() : ""))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("host").toString() != null) ? EscapeUtil.decodeURL(result.get("host").toString()) : ""))); - //TODO Revisit usage of deprecated constructor as per TSK-583 - //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", "Title", ((result.get("name").toString() != null) ? result.get("name").toString() : ""))); - //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), "RecentActivity", "Last Visited", (Long.valueOf(result.get("lastAccessed").toString())))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", ((result.get("name").toString() != null) ? result.get("name").toString() : ""))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), "RecentActivity", (Long.valueOf(result.get("lastAccessed").toString())))); - if (checkColumn == true) { - //TODO Revisit usage of deprecated constructor as per TSK-583 - //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), "RecentActivity", "Created", (Long.valueOf(result.get("creationTime").toString())))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), "RecentActivity", (Long.valueOf(result.get("creationTime").toString())))); - } - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), "RecentActivity", "FireFox")); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "RecentActivity", ((result.get("host").toString() != null) ? result.get("host").toString() : ""))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(), "RecentActivity", ((result.get("value").toString() != null) ? result.get("value").toString() : ""))); - String domain = Util.extractDomain(result.get("host").toString()); - domain = domain.replaceFirst("^\\.+(?!$)", ""); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "RecentActivity", domain)); - this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, FFSqlitedb.get(j), bbattributes); - - } - if (errors > 0) { - this.addErrorMessage(this.getName() + ": Error parsing " + errors + " Firefox web history artifacts."); - } - j++; + for (FsContent cookiesFile : cookiesFiles) { + String fileName = cookiesFile.getName(); + String temps = currentCase.getTempDirectory() + File.separator + fileName + j + ".db"; + int errors = 0; + try { + ContentUtils.writeToFile(cookiesFile, new File(currentCase.getTempDirectory() + File.separator + fileName + j + ".db")); + } catch (IOException ex) { + logger.log(Level.SEVERE, "Error writing the sqlite db for firefox cookie artifacts.{0}", ex); + this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + fileName); + } + File dbFile = new File(temps); + if (controller.isCancelled()) { dbFile.delete(); + break; + } + boolean checkColumn = Util.checkColumn("creationTime", "moz_cookies", temps); + String query = null; + if (checkColumn) { + query = ffcookiequery; + } else { + query = ff3cookiequery; } - services.fireModuleDataEvent(new ModuleDataEvent("Recent Activity", BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE)); + List> tempList = this.dbConnect(temps, query); + logger.log(Level.INFO, moduleName + "- Now getting cookies from " + temps + " with " + tempList.size() + "artifacts identified."); + for (HashMap result : tempList) { + + Collection bbattributes = new ArrayList(); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity", ((result.get("host").toString() != null) ? result.get("host").toString() : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("host").toString() != null) ? EscapeUtil.decodeURL(result.get("host").toString()) : ""))); + //TODO Revisit usage of deprecated constructor as per TSK-583 + //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", "Title", ((result.get("name").toString() != null) ? result.get("name").toString() : ""))); + //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), "RecentActivity", "Last Visited", (Long.valueOf(result.get("lastAccessed").toString())))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", ((result.get("name").toString() != null) ? result.get("name").toString() : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), "RecentActivity", (Long.valueOf(result.get("lastAccessed").toString())))); + if (checkColumn == true) { + //TODO Revisit usage of deprecated constructor as per TSK-583 + //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), "RecentActivity", "Created", (Long.valueOf(result.get("creationTime").toString())))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), "RecentActivity", (Long.valueOf(result.get("creationTime").toString())))); + } + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), "RecentActivity", "FireFox")); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "RecentActivity", ((result.get("host").toString() != null) ? result.get("host").toString() : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(), "RecentActivity", ((result.get("value").toString() != null) ? result.get("value").toString() : ""))); + String domain = Util.extractDomain(result.get("host").toString()); + domain = domain.replaceFirst("^\\.+(?!$)", ""); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "RecentActivity", domain)); + this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes); + + } + if (errors > 0) { + this.addErrorMessage(this.getName() + ": Error parsing " + errors + " Firefox web history artifacts."); + } + ++j; + dbFile.delete(); } + + services.fireModuleDataEvent(new ModuleDataEvent("Recent Activity", BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE)); } //Downloads section // This gets the downloads info private void getDownload(Image image, IngestImageWorkerController controller) { - List FFSqlitedb = this.extractFiles(image, "select * from tsk_files where name LIKE 'downloads.sqlite' and name NOT LIKE '%journal%' and parent_path LIKE '%Firefox%'"); + FileManager fileManager = currentCase.getServices().getFileManager(); + List downloadsFiles = null; + try { + downloadsFiles = fileManager.findFiles(image, "downloads.sqlite", "Firefox"); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error fetching 'downloads' files for Firefox."); + } + + if (downloadsFiles == null) { + return; + } int j = 0; - if (FFSqlitedb != null && !FFSqlitedb.isEmpty()) { - while (j < FFSqlitedb.size()) { - String temps = currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db"; - int errors = 0; - try { - ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + File.separator + FFSqlitedb.get(j).getName().toString() + j + ".db")); - } catch (IOException ex) { - logger.log(Level.SEVERE, "Error writing the sqlite db for firefox download artifacts.{0}", ex); - this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + FFSqlitedb.get(j).getName()); - } - File dbFile = new File(temps); - if (controller.isCancelled()) { - dbFile.delete(); - break; - } - - List> tempList = this.dbConnect(temps, ffdownloadquery); - logger.log(Level.INFO, moduleName + "- Now getting downloads from " + temps + " with " + tempList.size() + "artifacts identified."); - for (HashMap result : tempList) { - try { - Collection bbattributes = new ArrayList(); - String urldecodedtarget = URLDecoder.decode(result.get("source").toString().replaceAll("file:///", ""), "UTF-8"); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity", ((result.get("source").toString() != null) ? result.get("source").toString() : ""))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("source").toString() != null) ? EscapeUtil.decodeURL(result.get("source").toString()) : ""))); - //TODO Revisit usage of deprecated constructor as per TSK-583 - //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", "Last Visited", (Long.valueOf(result.get("startTime").toString())))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(), "RecentActivity", (Long.valueOf(result.get("startTime").toString())))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID(), "RecentActivity", Util.findID(urldecodedtarget))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), "RecentActivity", ((result.get("target").toString() != null) ? result.get("target").toString() : ""))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), "RecentActivity", "FireFox")); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "RecentActivity", (Util.extractDomain((result.get("source").toString() != null) ? result.get("source").toString() : "")))); - this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, FFSqlitedb.get(j), bbattributes); - } catch (UnsupportedEncodingException ex) { - logger.log(Level.SEVERE, "Error decoding Firefox download URL in " + temps, ex); - errors++; - } - } - if (errors > 0) { - this.addErrorMessage(this.getName() + ": Error parsing " + errors + " Firefox web history artifacts."); - } - j++; + for (FsContent downloadsFile : downloadsFiles) { + String fileName = downloadsFile.getName(); + String temps = currentCase.getTempDirectory() + File.separator + fileName + j + ".db"; + int errors = 0; + try { + ContentUtils.writeToFile(downloadsFile, new File(currentCase.getTempDirectory() + File.separator + fileName + j + ".db")); + } catch (IOException ex) { + logger.log(Level.SEVERE, "Error writing the sqlite db for firefox download artifacts.{0}", ex); + this.addErrorMessage(this.getName() + ": Error while trying to analyze file:" + fileName); + } + File dbFile = new File(temps); + if (controller.isCancelled()) { dbFile.delete(); + break; } - services.fireModuleDataEvent(new ModuleDataEvent("Recent Activity", BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD)); + List> tempList = this.dbConnect(temps, ffdownloadquery); + logger.log(Level.INFO, moduleName + "- Now getting downloads from " + temps + " with " + tempList.size() + "artifacts identified."); + for (HashMap result : tempList) { + try { + Collection bbattributes = new ArrayList(); + String urldecodedtarget = URLDecoder.decode(result.get("source").toString().replaceAll("file:///", ""), "UTF-8"); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity", ((result.get("source").toString() != null) ? result.get("source").toString() : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("source").toString() != null) ? EscapeUtil.decodeURL(result.get("source").toString()) : ""))); + //TODO Revisit usage of deprecated constructor as per TSK-583 + //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", "Last Visited", (Long.valueOf(result.get("startTime").toString())))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(), "RecentActivity", (Long.valueOf(result.get("startTime").toString())))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID(), "RecentActivity", Util.findID(image, urldecodedtarget))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), "RecentActivity", ((result.get("target").toString() != null) ? result.get("target").toString() : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), "RecentActivity", "FireFox")); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "RecentActivity", (Util.extractDomain((result.get("source").toString() != null) ? result.get("source").toString() : "")))); + this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes); + } catch (UnsupportedEncodingException ex) { + logger.log(Level.SEVERE, "Error decoding Firefox download URL in " + temps, ex); + errors++; + } + } + if (errors > 0) { + this.addErrorMessage(this.getName() + ": Error parsing " + errors + " Firefox web history artifacts."); + } + j++; + dbFile.delete(); + break; } + + services.fireModuleDataEvent(new ModuleDataEvent("Recent Activity", BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD)); } @Override diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Util.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Util.java index 15f001b848..f14ac6bb72 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Util.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Util.java @@ -31,21 +31,20 @@ import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.StringTokenizer; import java.util.logging.Level; import org.sleuthkit.autopsy.coreutils.Logger; -//import org.apache.commons.lang.NullArgumentException; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.services.FileManager; import org.sleuthkit.datamodel.FsContent; -import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.autopsy.report.SQLiteDBConnect; +import org.sleuthkit.datamodel.Image; +import org.sleuthkit.datamodel.TskCoreException; /** * @@ -84,32 +83,6 @@ public class Util { } } - public static boolean imgpathexists(String path) { - Case currentCase = Case.getCurrentCase(); // get the most updated case - SleuthkitCase tempDb = currentCase.getSleuthkitCase(); - Boolean rt = false; - int count = 0; - try { - List FFSqlitedb; - ResultSet rs = tempDb.runQuery("select * from tsk_files where parent_path LIKE '%" + path + "%'"); - FFSqlitedb = tempDb.resultSetToFsContents(rs); - count = FFSqlitedb.size(); - final Statement s = rs.getStatement(); - rs.close(); - if (s != null) { - s.close(); - } - if (count > 0) { - rt = true; - } else { - rt = false; - } - } catch (SQLException ex) { - logger.log(Level.WARNING, "Error checking if image exists, unable to contact sqlite database.", ex); - } - return rt; - } - public static String getBaseDomain(String url) { String host = null; //strip protocol @@ -213,8 +186,8 @@ public class Util { } return path; } - - public static long findID(String path) { + + public static long findID(Image image, String path) { String parent_path = path.replace('\\', '/'); // fix Chrome paths if (parent_path.length() > 2 && parent_path.charAt(1) == ':') { parent_path = parent_path.substring(2); // remove drive letter (e.g., 'C:') @@ -222,24 +195,20 @@ public class Util { int index = parent_path.lastIndexOf('/'); String name = parent_path.substring(++index); parent_path = parent_path.substring(0, index); - String query = "select * from tsk_files where parent_path like \"" + parent_path + "\" AND name like \"" + name + "\""; - Case currentCase = Case.getCurrentCase(); - SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + //String query = "select * from tsk_files where parent_path like \"" + parent_path + "\" AND name like \"" + name + "\""; + + FileManager fileManager = Case.getCurrentCase().getServices().getFileManager(); + List files = null; try { - ResultSet rs = tempDb.runQuery(query); - List results = tempDb.resultSetToFsContents(rs); - Statement s = rs.getStatement(); - rs.close(); - if (s != null) { - s.close(); - } - if (results.size() > 0) { - return results.get(0).getId(); - } - } catch (SQLException ex) { - logger.log(Level.WARNING, "Error finding ID, unable to contact sqlite database", ex); + files = fileManager.findFiles(image, name, parent_path); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error fetching 'index.data' files for Internet Explorer history."); } - return -1; + + if (files == null || files.isEmpty()) { + return -1; + } + return files.get(0).getId(); } public static boolean checkColumn(String column, String tablename, String connection) {