diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java b/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java index 0f30930935..905b8c9f5a 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java @@ -22,6 +22,7 @@ */ package org.sleuthkit.autopsy.report; +import java.awt.Desktop; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; @@ -30,22 +31,28 @@ import java.io.IOException; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; +import java.sql.ResultSet; +import java.sql.SQLException; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.Comparator; import java.util.Date; import java.util.HashMap; -import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; +import java.util.TreeSet; import java.util.logging.Level; import org.openide.filesystems.FileUtil; +import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.EscapeUtil; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.datamodel.*; +import org.sleuthkit.autopsy.coreutils.EscapeUtil; /** * Generates an HTML report for all the Blackboard Artifacts found in the current case. @@ -57,7 +64,7 @@ public class ReportHTML implements ReportModule { + "\n"; private final String CSS = "\n"; private final String TABLE_FOOT = ""; - private final String HTML_FOOT = "\n"; + private final String HTML_FOOT = "\n\n"; private ReportConfiguration config; private int reportSize; @@ -65,23 +72,20 @@ public class ReportHTML implements ReportModule { private Case currentCase = Case.getCurrentCase(); private SleuthkitCase skCase = currentCase.getSleuthkitCase(); - //private Set>> general = new LinkedHashSet>>(); - private Set>> bookmarks = new LinkedHashSet>>(); - private Set>> cookies = new LinkedHashSet>>(); - private Set>> history = new LinkedHashSet>>(); - private Set>> downloads = new LinkedHashSet>>(); - private Set>> recent = new LinkedHashSet>>(); - private Set>> trackpoint = new LinkedHashSet>>(); - private Set>> installed = new LinkedHashSet>>(); - private Set>> keywords = new LinkedHashSet>>(); - //private Set>> hash = new LinkedHashSet>>(); - private Set>> devices = new LinkedHashSet>>(); - //private Set>> email = new LinkedHashSet>>(); - private Set>> search = new LinkedHashSet>>(); - private Set>> exif = new LinkedHashSet>>(); - private Set>> fileBookmarks = new LinkedHashSet>>(); + private Set>> bookmarks; + private Set>> cookies; + private Set>> history; + private Set>> downloads; + private Set>> recent; + private Set>> trackpoint; + private Set>> installed; + //private Set>> keywords; + //private Set>> hash; + private Set>> devices; + private Set>> search; + private Set>> exif; + private Set>> fileBookmarks; - //private int countGeneral; private int countBookmarks; private int countCookies; private int countHistory; @@ -92,7 +96,6 @@ public class ReportHTML implements ReportModule { private int countKeywords; //private int countHash; private int countDevices; - //private int countEmails; private int countSearch; private int countExif; private int countFileBookmarks; @@ -106,6 +109,57 @@ public class ReportHTML implements ReportModule { } return instance; } + + /** + * Iterates through two artifacts' attributes, and compares them in order until + * it finds one which is different from the other. If no differing attribute is + * found, the comparator compares file unique paths, and then lastly the + * artifact ID. + */ + private class ArtifactComparator implements Comparator>> { + + @Override + public int compare(Map.Entry> art1, Map.Entry> art2) { + // Get all the attributes for each artifact + int size = BlackboardAttribute.ATTRIBUTE_TYPE.values().length; + TreeMap att1 = getAttributes(art1.getValue()); + TreeMap att2 = getAttributes(art2.getValue()); + + // Compare the attributes one-by-one looking for differences + for(int i=0; i < size; i++) { + String a1 = att1.get(i); + String a2 = att2.get(i); + if((!a1.equals("") && !a2.equals("")) && a1.compareTo(a2) != 0) { + return a1.compareTo(a2); + } + } + + // If there are no differenct artifacts, compare the file path + Long objId = art1.getKey().getObjectID(); + AbstractFile file1 = getFile(objId); + objId = art2.getKey().getObjectID(); + AbstractFile file2 = getFile(objId); + + if(file1 != null && file2 !=null) { + try { + int result = file1.getUniquePath().compareTo(file2.getUniquePath()); + if(result != 0) { + return result; + } + } catch (TskCoreException ex) { // Not a big deal, we'll compare artifact IDs + } + } + + // If that's the same, use the artifact ID + if(art1.getKey().getArtifactID() < art2.getKey().getArtifactID()) { + return -1; + } else if(art1.getKey().getArtifactID() > art2.getKey().getArtifactID()) { + return 1; + } else { + return 0; + } + } + } /** * Generate all the data needed for the report. @@ -136,28 +190,25 @@ public class ReportHTML implements ReportModule { } // For every type of artifact, group that type into it's own set - //general = new LinkedHashSet>>(); - bookmarks = new LinkedHashSet>>(); - cookies = new LinkedHashSet>>(); - history = new LinkedHashSet>>(); - downloads = new LinkedHashSet>>(); - recent = new LinkedHashSet>>(); - trackpoint = new LinkedHashSet>>(); - installed = new LinkedHashSet>>(); - keywords = new LinkedHashSet>>(); - //hash = new LinkedHashSet>>(); - devices = new LinkedHashSet>>(); - //email = new LinkedHashSet>>(); - search = new LinkedHashSet>>(); - exif = new LinkedHashSet>>(); - fileBookmarks = new LinkedHashSet>>(); + ArtifactComparator c = new ArtifactComparator(); + bookmarks = new TreeSet>>(c); + cookies = new TreeSet>>(c); + history = new TreeSet>>(c); + downloads = new TreeSet>>(c); + recent = new TreeSet>>(c); + trackpoint = new TreeSet>>(c); + installed = new TreeSet>>(c); + //keywords = new TreeSet>>(c); + //hash = new TreeSet>>(c); + devices = new TreeSet>>(c); + search = new TreeSet>>(c); + exif = new TreeSet>>(c); + fileBookmarks = new TreeSet>>(c); for (Entry> entry : report.entrySet()) { if (ReportFilter.cancel == true) { break; } - //if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID()) { - // general.add(entry); if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()) { bookmarks.add(entry); } else if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()) { @@ -173,13 +224,11 @@ public class ReportHTML implements ReportModule { } else if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) { installed.add(entry); } else if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) { - keywords.add(entry); + countKeywords++; //} else if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) { // hash.add(entry); } else if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) { devices.add(entry); - //} else if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) { - // email.add(entry); } else if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) { search.add(entry); } else if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()){ @@ -189,8 +238,9 @@ public class ReportHTML implements ReportModule { } } + + // Get the sizes for each type - //countGeneral = general.size(); countBookmarks = bookmarks.size(); countCookies = cookies.size(); countHistory = history.size(); @@ -198,10 +248,9 @@ public class ReportHTML implements ReportModule { countRecent = recent.size(); countTrackpoint = trackpoint.size(); countInstalled = installed.size(); - countKeywords = keywords.size(); + //countKeywords = keywords.size(); //countHash = hash.size(); countDevices = devices.size(); - //countEmails = email.size(); countSearch = search.size(); countExif = exif.size(); countFileBookmarks = fileBookmarks.size(); @@ -218,21 +267,23 @@ public class ReportHTML implements ReportModule { Writer out = null; try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(folder + "index.css"), "UTF-8")); - String css = "body {padding: 30px; margin: 0; background: #FFFFFF; font: 13px/20px Arial, Helvetica, sans-serif; color: #535353;} \n" - + "h1 {font-size: 26px; color: #005577; margin: 0 0 20px 0;} \n" - + "h2 {font-size: 20px; font-weight: normal; color: #0077aa; margin: 40px 0 10px 0; padding: 0 0 10px 0; border-bottom: 1px solid #dddddd;} \n" - + "h3 {font-size: 16px; color: #0077aa; margin: 40px 0 10px 0;} \n" - + "ul.nav {list-style-type: none; line-height: 35px; padding: 0px;} \n" - + "ul.nav li a {font-size: 14px; color: #444; text-shadow: #e9f9fd 0 1px 0; text-decoration: none; padding-left: 25px;} \n" - + "ul.nav li a:hover {text-decoration: underline;} \n" - + "p {margin: 0 0 20px 0;} \n" - + "table {max-width: 100%; min-width: 700px; padding: 0; margin: 0; border-collapse: collapse; border-bottom: 1px solid #e5e5e5;} \n" - + "table thead th {display: table-cell; text-align: left; padding: 8px 16px; background: #e5e5e5; color: #777; font-size: 11px; text-shadow: #e9f9fd 0 1px 0; border-top: 1px solid #dedede; border-bottom: 2px solid #dedede;} \n" - + "/*table tr th:nth-child(1) {text-align: center; width: 60px;}*/ \n" - + "table td {display: table-cell; padding: 8px 16px; font: 13px/20px Arial, Helvetica, sans-serif; max-width: 500px; min-width: 125px; word-break: break-all; overflow: auto;} \n" - + "table tr:nth-child(even) td {background: #f3f3f3;} \n" - + "/*table tr td:nth-child(1) {text-align: left; width: 60px; background: #f3f3f3;}*/ \n" - + "/*table tr:nth-child(even) td:nth-child(1) {background: #eaeaea;}*/ \n"; + String css = "body {margin: 0px; padding: 0px; background: #FFFFFF; font: 13px/20px Arial, Helvetica, sans-serif; color: #535353;}\n" + + "#content {padding: 30px;}\n" + + "#header {width:100%; padding: 10px; line-height: 25px; background: #07A; color: #FFF; font-size: 20px;}\n" + + "h1 {font-size: 20px; font-weight: normal; color: #07A; padding: 0 0 7px 0; border-bottom: 1px solid #D6D6D6;}\n" + + "h2 {font-size: 20px; font-weight: bolder; color: #07A;}\n" + + "h3 {font-size: 16px; color: #07A;}\n" + + "ul.nav {list-style-type: none; line-height: 35px; padding: 0px;}\n" + + "ul li a {font-size: 14px; color: #444; text-decoration: none; padding-left: 25px;}\n" + + "ul li a:hover {text-decoration: underline;}\n" + + "p {margin: 0 0 20px 0;}\n" + + ".keyword_list td.keyword {background: #07A; color: #FFF; font-size: 16px; padding: 3px; padding-left: 15px;}\n" + + ".keyword_list td.blank {background: #FFF; padding: 20px; border-top: 1px solid #07A;}\n" + + "table {max-width: 100%; min-width: 700px; padding: 0; margin: 0; border-collapse: collapse; border-bottom: 1px solid #e5e5e5;}\n" + + ".keyword_list table {margin-left: 25px;}\n" + + "table th {display: table-cell; text-align: left; padding: 8px 16px; background: #e5e5e5; color: #777; font-size: 11px; text-shadow: #e9f9fd 0 1px 0; border-top: 1px solid #dedede; border-bottom: 2px solid #dedede;}\n" + + "table td {display: table-cell; padding: 8px 16px; font: 13px/20px Arial, Helvetica, sans-serif; max-width: 500px; min-width: 125px; word-break: break-all; overflow: auto;}\n" + + "table tr:nth-child(even) td {background: #f3f3f3;}"; out.write(css); } catch (FileNotFoundException ex) { logger.log(Level.SEVERE, "Could not find index.css file to write to."); @@ -273,7 +324,7 @@ public class ReportHTML implements ReportModule { Writer out = null; try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(folder + "index.html"), "UTF-8")); - out.write("\n" + CSS + "Report for " + currentCase.getName() + "\n" + "\n"); + out.write("\n" + CSS + "Autopsy Report for case " + currentCase.getName() + "\n" + "\n"); StringBuilder index = new StringBuilder(); index.append("\n"); @@ -314,12 +365,9 @@ public class ReportHTML implements ReportModule { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(folder + "nav.html"), "UTF-8")); out.write(generateHead("Report Navigation")); StringBuilder nav = new StringBuilder(); - nav.append("

Report Navigation

\n"); + nav.append("
\n

Report Navigation

\n"); nav.append("
    \n"); nav.append("
  • Case Summary
  • \n"); - //if(countGeneral > 0) { - // nav.append("General Information (").append(countGeneral).append(")
    \n"); - //} if(countBookmarks > 0) { nav.append("
  • Web Bookmarks (").append(countBookmarks).append(")
  • \n"); } @@ -332,6 +380,9 @@ public class ReportHTML implements ReportModule { if(countDownloads > 0) { nav.append("
  • Web Downloads (").append(countDownloads).append(")
  • \n"); } + if(countSearch > 0) { + nav.append("
  • Web Search Queries (").append(countSearch).append(")
  • \n"); + } if(countRecent > 0) { nav.append("
  • Recent Documents (").append(countRecent).append(")
  • \n"); } @@ -350,12 +401,6 @@ public class ReportHTML implements ReportModule { if(countDevices > 0) { nav.append("
  • Devices Attached (").append(countDevices).append(")
  • \n"); } - //if(countEmails > 0) { - // nav.append("
  • Emails (").append(countEmails).append(")
  • \n"); - //} - if(countSearch > 0) { - nav.append("
  • Web Search Queries (").append(countSearch).append(")
  • \n"); - } if(countExif > 0) { nav.append("
  • Exif Metadata (").append(countExif).append(")
  • \n"); } @@ -400,31 +445,33 @@ public class ReportHTML implements ReportModule { String examiner = currentCase.getExaminer(); String number = currentCase.getNumber(); Integer imagecount = currentCase.getImageIDs().length; - Integer filesystemcount = currentCase.getRootObjectsCount(); - Integer totalfiles = 0; - Integer totaldirs = 0; - try { - totaldirs = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR); - totalfiles = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG); - } catch (TskException ex) { - logger.log(Level.WARNING, "Could not get FsContentType counts from TSK ", ex); - } + StringBuilder summary = new StringBuilder(); if (IngestManager.getDefault().isIngestRunning() || IngestManager.getDefault().areModulesRunning()) { summary.append(INGEST_WARNING); } - summary.append("

    Report for Case: ").append(caseName).append("

    \n"); - summary.append("

    HTML Report Generated by Autopsy 3 on ").append(datetime).append("\n"); - summary.append("

      \n"); - summary.append("
    • Examiner: ").append(examiner).append("
    • \n"); - summary.append("
    • Number: ").append(number).append("
    • \n"); - summary.append("
    • # of Images: ").append(imagecount).append("
    • \n"); - summary.append("
    • FileSystems: ").append(filesystemcount).append("
    • \n"); - summary.append("
    • # of Files: ").append(totalfiles.toString()).append("
    • \n"); - summary.append("
    • # of Dirs: ").append(totaldirs.toString()).append("
    • \n"); - summary.append("
    • # of Artifacts: ").append(reportSize).append("
    • \n"); - summary.append("
    \n"); + summary.append("

    Report for Case: ").append(caseName).append("

    \n"); + summary.append("

    HTML Report Generated by Autopsy 3 on ").append(datetime).append("

    \n"); + summary.append("

    Examiner: ").append(examiner.isEmpty()? "No examiner" : examiner).append("

    \n"); + summary.append("

    Case Number: ").append(number.isEmpty() ? "No case number" : number).append("

    \n"); + summary.append("

    # of Images: ").append(imagecount).append("

    \n"); + try { + Image[] images = new Image[imagecount]; + for(int i=0; i
  • ").append(img.getName()).append(":\n"); + summary.append("
      \n
    • Timezone: ").append(img.getTimeZone()).append("
    • \n"); + for(String path : img.getPaths()) { + summary.append("
    • Image Path: ").append(path).append("
    • \n"); + } + summary.append("
    \n
\n\n"); + } + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Unable to get image information for the HTML report."); + } out.write(summary.toString()); out.write(HTML_FOOT); } catch (FileNotFoundException ex) { @@ -504,8 +551,8 @@ public class ReportHTML implements ReportModule { // Write the HTML title out.write(generateHead("Web Bookmark Artifacts (" + countBookmarks + ")")); // Write the title for the artifact and the top of the table - String title = "

Web Bookmarks (" + countBookmarks + ")

\n"; - String tableHeader = getTableHead("URL", "Title", "Program", "Path"); + String title = "
Web Bookmarks (" + countBookmarks + ")
\n
\n"; + String tableHeader = getTableHead("URL", "Title", "Date Accessed", "Program", "Source File"); out.write(title); out.write(tableHeader); @@ -523,6 +570,7 @@ public class ReportHTML implements ReportModule { row.append("\n"); row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID())).append("\n"); row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID())).append("\n"); + row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID())).append("\n"); row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())).append("\n"); row.append("").append(file !=null ? file.getUniquePath() : "").append("\n"); row.append("\n"); @@ -560,8 +608,8 @@ public class ReportHTML implements ReportModule { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(folder + "cookies.html"), "UTF-8")); out.write(generateHead("Web Cookie Artifacts (" + countCookies + ")")); - String title = "

Web Cookies (" + countCookies + ")

\n"; - String tableHeader = getTableHead("URL", "Date", "Name", "Value", "Program", "Path"); + String title = "
Web Cookies (" + countCookies + ")
\n
\n"; + String tableHeader = getTableHead("URL", "Date/Time", "Name", "Value", "Program", "Source File"); out.write(title); out.write(tableHeader); @@ -613,8 +661,8 @@ public class ReportHTML implements ReportModule { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(folder + "history.html"), "UTF-8")); out.write(generateHead("Web History Artifacts (" + countHistory + ")")); - String title = "

Web History (" + countHistory + ")

\n"; - String tableHeader = getTableHead("URL", "Date", "Referrer", "Name", "Program", "Path"); + String title = "
Web History (" + countHistory + ")
\n
\n"; + String tableHeader = getTableHead("URL", "Date Accessed", "Referrer", "Name", "Program", "Source File"); out.write(title); out.write(tableHeader); @@ -665,8 +713,8 @@ public class ReportHTML implements ReportModule { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(folder + "downloads.html"), "UTF-8")); out.write(generateHead("Web Download Artifacts (" + countDownloads + ")")); - String title = "

Web Downloads (" + countDownloads + ")

\n"; - String tableHeader = getTableHead("URL", "Source", "Time", "Program", "Path"); + String title = "
Web Downloads (" + countDownloads + ")
\n
\n"; + String tableHeader = getTableHead("URL", "Source URL", "Date Accessed", "Program", "Source File"); out.write(title); out.write(tableHeader); @@ -716,8 +764,8 @@ public class ReportHTML implements ReportModule { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(folder + "recent.html"), "UTF-8")); out.write(generateHead("Recent Document Artifacts (" + countRecent + ")")); - String title = "

Recent Documents (" + countRecent + ")

\n"; - String tableHeader = getTableHead("Name", "Related Shortcut", "Path"); + String title = "
Recent Documents (" + countRecent + ")
\n
\n"; + String tableHeader = getTableHead("Path", "Source File"); out.write(title); out.write(tableHeader); @@ -729,8 +777,7 @@ public class ReportHTML implements ReportModule { TreeMap attributes = getAttributes(entry.getValue()); StringBuilder row = new StringBuilder(); row.append("\n"); - row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID())).append("\n"); - row.append("").append(file !=null ? file.getName() : "").append("\n"); + row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID())).append("\n"); row.append("").append(file !=null ? file.getUniquePath() : "").append("\n"); row.append("\n"); out.write(row.toString()); @@ -765,8 +812,8 @@ public class ReportHTML implements ReportModule { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(folder + "trackpoint.html"), "UTF-8")); out.write(generateHead("Track Point Artifacts (" + countTrackpoint + ")")); - String title = "

Track Points (" + countTrackpoint + ")

\n"; - String tableHeader = getTableHead("Object ID", "Name", "Size", "Path"); + String title = "
Track Points (" + countTrackpoint + ")
\n
\n"; + String tableHeader = getTableHead("Object ID", "Name", "Size", "Source File"); out.write(title); out.write(tableHeader); @@ -779,7 +826,7 @@ public class ReportHTML implements ReportModule { StringBuilder row = new StringBuilder(); row.append("\n"); row.append("").append(objId.toString()).append("\n"); - row.append("").append(file != null ? file.getName().toString() : "").append("\n"); + row.append("").append(file != null ? file.getName().toString() : "").append("\n"); row.append("").append(fileSize.toString()).append("\n"); row.append("").append(file !=null ? file.getUniquePath() : "").append("\n"); row.append("\n"); @@ -815,8 +862,8 @@ public class ReportHTML implements ReportModule { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(folder + "installed.html"), "UTF-8")); out.write(generateHead("Installed Program Artifacts (" + countInstalled + ")")); - String title = "

Installed Programs (" + countInstalled + ")

\n"; - String tableHeader = getTableHead("Program Name", "Install Date/Time", "Path"); + String title = "
Installed Programs (" + countInstalled + ")
\n
\n"; + String tableHeader = getTableHead("Program Name", "Install Date/Time", "Source File"); out.write(title); out.write(tableHeader); @@ -828,7 +875,7 @@ public class ReportHTML implements ReportModule { TreeMap attributes = getAttributes(entry.getValue()); StringBuilder row = new StringBuilder(); row.append("\n"); - row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())).append("\n"); + row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())).append("\n"); row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID())).append("\n"); row.append("").append(file !=null ? file.getUniquePath() : "").append("\n"); row.append("\n"); @@ -898,8 +945,8 @@ public class ReportHTML implements ReportModule { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(folder + "devices.html"), "UTF-8")); out.write(generateHead("Attached Device Artifacts (" + countDevices + ")")); - String title = "

Attached Devices (" + countDevices + ")

\n"; - String tableHeader = getTableHead("Name", "Serial #", "Time", "Path"); + String title = "
Attached Devices (" + countDevices + ")
\n
\n"; + String tableHeader = getTableHead("Name", "Device ID", "Date/Time", "Source File"); out.write(title); out.write(tableHeader); @@ -911,7 +958,7 @@ public class ReportHTML implements ReportModule { TreeMap attributes = getAttributes(entry.getValue()); StringBuilder row = new StringBuilder(); row.append("\n"); - row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID())).append("\n"); + row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID())).append("\n"); row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID.getTypeID())).append("\n"); row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID())).append("\n"); row.append("").append(file !=null ? file.getUniquePath() : "").append("\n"); @@ -948,8 +995,8 @@ public class ReportHTML implements ReportModule { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(folder + "search.html"), "UTF-8")); out.write(generateHead("Web Search Query Artifacts (" + countSearch + ")")); - String title = "

Web Search Queries (" + countSearch + ")

\n"; - String tableHeader = getTableHead("Program Name", "Domain", "Text", "Last Modified", "Path"); + String title = "
Web Search Queries (" + countSearch + ")
\n
\n"; + String tableHeader = getTableHead("Text", "Domain", "Date Accessed", "Program Name", "Source File"); out.write(title); out.write(tableHeader); @@ -961,10 +1008,10 @@ public class ReportHTML implements ReportModule { TreeMap attributes = getAttributes(entry.getValue()); StringBuilder row = new StringBuilder(); row.append("\n"); - row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())).append("\n"); - row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID())).append("\n"); row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID())).append("\n"); + row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID())).append("\n"); row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID())).append("\n"); + row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())).append("\n"); row.append("").append(file !=null ? file.getUniquePath() : "").append("\n"); row.append("\n"); out.write(row.toString()); @@ -999,8 +1046,8 @@ public class ReportHTML implements ReportModule { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(folder + "exif.html"), "UTF-8")); out.write(generateHead("Exif Metadata Artifacts (" + countExif + ")")); - String title = "

Exif Metadata (" + countExif + ")

\n"; - String tableHeader = getTableHead("File Name", "Date Taken", "Device Manufacturer", "Device Model", "Latitude", "Longitude", "Altitude", "Path"); + String title = "
Exif Metadata (" + countExif + ")
\n
\n"; + String tableHeader = getTableHead("File Name", "Date Taken", "Device Manufacturer", "Device Model", "Latitude", "Longitude", "Source File"); out.write(title); out.write(tableHeader); @@ -1018,7 +1065,6 @@ public class ReportHTML implements ReportModule { row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID())).append("\n"); row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID())).append("\n"); row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID())).append("\n"); - row.append("").append(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE.getTypeID())).append("\n"); row.append("").append(file !=null ? file.getUniquePath() : "").append("\n"); row.append("\n"); out.write(row.toString()); @@ -1053,8 +1099,8 @@ public class ReportHTML implements ReportModule { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(folder + "filebookmarks.html"), "UTF-8")); out.write(generateHead("File Bookmarks (" + countFileBookmarks + ")")); - String title = "

File Bookmarks (" + countFileBookmarks + ")

\n"; - String tableHeader = getTableHead("Comment", "File Name", "Path"); + String title = "
File Bookmarks (" + countFileBookmarks + ")
\n
\n"; + String tableHeader = getTableHead("Comment", "File Name", "Source File"); out.write(title); out.write(tableHeader); @@ -1113,12 +1159,12 @@ public class ReportHTML implements ReportModule { writeCookie(path); writeHistory(path); writeDownload(path); + writeSearch(path); writeRecent(path); writeTrackpoint(path); writeInstalled(path); writeKeyword(path); writeDevice(path); - writeSearch(path); writeExif(path); writeFileBookmarks(path); } @@ -1148,6 +1194,10 @@ public class ReportHTML implements ReportModule { @Override public void getPreview(String path) { - BrowserControl.openUrl(path); + try { + Desktop.getDesktop().open(new File(path)); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } } } \ No newline at end of file