23 package org.sleuthkit.autopsy.recentactivity;
 
   25 import com.google.gson.JsonArray;
 
   26 import com.google.gson.JsonElement;
 
   27 import com.google.gson.JsonIOException;
 
   28 import com.google.gson.JsonObject;
 
   29 import com.google.gson.JsonParser;
 
   30 import com.google.gson.JsonSyntaxException;
 
   31 import org.openide.util.NbBundle;
 
   34 import java.util.logging.Level;
 
   37 import java.io.FileNotFoundException;
 
   38 import java.io.FileReader;
 
   39 import java.io.IOException;
 
   56 class Chrome 
extends Extract {
 
   58     private static final String historyQuery = 
"SELECT urls.url, urls.title, urls.visit_count, urls.typed_count, "  
   59             + 
"last_visit_time, urls.hidden, visits.visit_time, (SELECT urls.url FROM urls WHERE urls.id=visits.url) AS from_visit, visits.transition FROM urls, visits WHERE urls.id = visits.url"; 
 
   60     private static final String cookieQuery = 
"SELECT name, value, host_key, expires_utc,last_access_utc, creation_utc FROM cookies"; 
 
   61     private static final String downloadQuery = 
"SELECT full_path, url, start_time, received_bytes FROM downloads"; 
 
   62     private static final String downloadQueryVersion30 = 
"SELECT current_path AS full_path, url, start_time, received_bytes FROM downloads, downloads_url_chains WHERE downloads.id=downloads_url_chains.id"; 
 
   63     private static final String loginQuery = 
"SELECT origin_url, username_value, signon_realm from logins"; 
 
   69         moduleName = NbBundle.getMessage(Chrome.class, 
"Chrome.moduleName");
 
   74         this.dataSource = dataSource;
 
   75         this.context = context;
 
   87     private void getHistory() {
 
   88         FileManager fileManager = currentCase.getServices().getFileManager();
 
   89         List<AbstractFile> historyFiles;
 
   91             historyFiles = fileManager.
findFiles(dataSource, 
"History", 
"Chrome"); 
 
   93             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getHistory.errMsg.errGettingFiles");
 
   94             logger.log(Level.SEVERE, msg, ex);
 
   95             this.addErrorMessage(this.getName() + 
": " + msg);
 
  100         List<AbstractFile> allocatedHistoryFiles = 
new ArrayList<>();
 
  103                 allocatedHistoryFiles.add(historyFile);
 
  108         if (allocatedHistoryFiles.isEmpty()) {
 
  109             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getHistory.errMsg.couldntFindAnyFiles");
 
  110             logger.log(Level.INFO, msg);
 
  115         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  117         while (j < historyFiles.size()) {
 
  120             if (historyFile.
getSize() == 0) {
 
  125             } 
catch (IOException ex) {
 
  126                 logger.log(Level.SEVERE, 
"Error writing temp sqlite db for Chrome web history artifacts.{0}", ex); 
 
  127                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getHistory.errMsg.errAnalyzingFile",
 
  128                         this.getName(), historyFile.
getName()));
 
  131             File dbFile = 
new File(temps);
 
  136             List<HashMap<String, Object>> tempList;
 
  137             tempList = this.dbConnect(temps, historyQuery);
 
  138             logger.log(Level.INFO, 
"{0}- Now getting history from {1} with {2}artifacts identified.", 
new Object[]{moduleName, temps, tempList.size()}); 
 
  139             for (HashMap<String, Object> result : tempList) {
 
  140                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<BlackboardAttribute>();
 
  142                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  143                         ((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
""))); 
 
  145                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  146                         (Long.valueOf(result.get(
"last_visit_time").toString()) / 1000000) - Long.valueOf(
"11644473600"))); 
 
  148                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  149                         ((result.get(
"from_visit").toString() != null) ? result.get(
"from_visit").toString() : 
""))); 
 
  151                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  152                         ((result.get(
"title").toString() != null) ? result.get(
"title").toString() : 
""))); 
 
  154                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  155                         NbBundle.getMessage(
this.getClass(), 
"Chrome.moduleName")));
 
  157                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  158                         (Util.extractDomain((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
"")))); 
 
  162                     bbartifacts.add(bbart);
 
  169                 NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  176     private void getBookmark() {
 
  177         FileManager fileManager = currentCase.getServices().getFileManager();
 
  178         List<AbstractFile> bookmarkFiles = null;
 
  180             bookmarkFiles = fileManager.
findFiles(dataSource, 
"Bookmarks", 
"Chrome"); 
 
  182             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getBookmark.errMsg.errGettingFiles");
 
  183             logger.log(Level.SEVERE, msg, ex);
 
  184             this.addErrorMessage(this.getName() + 
": " + msg);
 
  188         if (bookmarkFiles.isEmpty()) {
 
  189             logger.log(Level.INFO, 
"Didn't find any Chrome bookmark files."); 
 
  194         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  197         while (j < bookmarkFiles.size()) {
 
  199             if (bookmarkFile.
getSize() == 0) {
 
  205             } 
catch (IOException ex) {
 
  206                 logger.log(Level.SEVERE, 
"Error writing temp sqlite db for Chrome bookmark artifacts.{0}", ex); 
 
  207                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getBookmark.errMsg.errAnalyzingFile",
 
  208                         this.getName(), bookmarkFile.
getName()));
 
  212             logger.log(Level.INFO, 
"{0}- Now getting Bookmarks from {1}", 
new Object[]{moduleName, temps}); 
 
  213             File dbFile = 
new File(temps);
 
  219             FileReader tempReader;
 
  221                 tempReader = 
new FileReader(temps);
 
  222             } 
catch (FileNotFoundException ex) {
 
  223                 logger.log(Level.SEVERE, 
"Error while trying to read into the Bookmarks for Chrome.", ex); 
 
  224                 this.addErrorMessage(
 
  225                         NbBundle.getMessage(
this.getClass(), 
"Chrome.getBookmark.errMsg.errAnalyzeFile", this.getName(),
 
  230             final JsonParser parser = 
new JsonParser();
 
  231             JsonElement jsonElement;
 
  232             JsonObject jElement, jRoot, jBookmark;
 
  233             JsonArray jBookmarkArray;
 
  236                 jsonElement = parser.parse(tempReader);
 
  237                 jElement = jsonElement.getAsJsonObject();
 
  238                 jRoot = jElement.get(
"roots").getAsJsonObject(); 
 
  239                 jBookmark = jRoot.get(
"bookmark_bar").getAsJsonObject(); 
 
  240                 jBookmarkArray = jBookmark.getAsJsonArray(
"children"); 
 
  241             } 
catch (JsonIOException | JsonSyntaxException | IllegalStateException ex) {
 
  242                 logger.log(Level.WARNING, 
"Error parsing Json from Chrome Bookmark.", ex); 
 
  243                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getBookmark.errMsg.errAnalyzingFile3",
 
  244                         this.getName(), bookmarkFile.
getName()));
 
  248             for (JsonElement result : jBookmarkArray) {
 
  249                 JsonObject address = result.getAsJsonObject();
 
  250                 if (address == null) {
 
  253                 JsonElement urlEl = address.get(
"url"); 
 
  256                     url = urlEl.getAsString();
 
  261                 JsonElement nameEl = address.get(
"name"); 
 
  262                 if (nameEl != null) {
 
  263                     name = nameEl.getAsString();
 
  268                 JsonElement dateEl = address.get(
"date_added"); 
 
  269                 if (dateEl != null) {
 
  270                     date = dateEl.getAsLong();
 
  272                     date = Long.valueOf(0);
 
  274                 String domain = Util.extractDomain(url);
 
  277                     Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  280                             NbBundle.getMessage(
this.getClass(),
 
  281                                     "Chrome.parentModuleName"), url));
 
  283                             NbBundle.getMessage(
this.getClass(),
 
  284                                     "Chrome.parentModuleName"), name));
 
  286                             NbBundle.getMessage(
this.getClass(),
 
  287                                     "Chrome.parentModuleName"), (date / 1000000) - Long.valueOf(
"11644473600")));
 
  289                             NbBundle.getMessage(
this.getClass(),
 
  290                                     "Chrome.parentModuleName"),
 
  291                             NbBundle.getMessage(
this.getClass(), 
"Chrome.moduleName")));
 
  293                             NbBundle.getMessage(
this.getClass(),
 
  294                                     "Chrome.parentModuleName"), domain));
 
  298                     this.indexArtifact(bbart);
 
  299                     bbartifacts.add(bbart);
 
  301                     logger.log(Level.SEVERE, 
"Error while trying to insert Chrome bookmark artifact{0}", ex); 
 
  302                     this.addErrorMessage(
 
  303                             NbBundle.getMessage(
this.getClass(), 
"Chrome.getBookmark.errMsg.errAnalyzingFile4",
 
  304                                     this.getName(), bookmarkFile.
getName()));
 
  311                 NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  318     private void getCookie() {
 
  320         FileManager fileManager = currentCase.getServices().getFileManager();
 
  321         List<AbstractFile> cookiesFiles;
 
  323             cookiesFiles = fileManager.
findFiles(dataSource, 
"Cookies", 
"Chrome"); 
 
  325             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getCookie.errMsg.errGettingFiles");
 
  326             logger.log(Level.SEVERE, msg, ex);
 
  327             this.addErrorMessage(this.getName() + 
": " + msg);
 
  331         if (cookiesFiles.isEmpty()) {
 
  332             logger.log(Level.INFO, 
"Didn't find any Chrome cookies files."); 
 
  337         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  339         while (j < cookiesFiles.size()) {
 
  341             if (cookiesFile.
getSize() == 0) {
 
  347             } 
catch (IOException ex) {
 
  348                 logger.log(Level.SEVERE, 
"Error writing temp sqlite db for Chrome cookie artifacts.{0}", ex); 
 
  349                 this.addErrorMessage(
 
  350                         NbBundle.getMessage(
this.getClass(), 
"Chrome.getCookie.errMsg.errAnalyzeFile", this.getName(),
 
  354             File dbFile = 
new File(temps);
 
  360             List<HashMap<String, Object>> tempList = this.dbConnect(temps, cookieQuery);
 
  361             logger.log(Level.INFO, 
"{0}- Now getting cookies from {1} with {2}artifacts identified.", 
new Object[]{moduleName, temps, tempList.size()}); 
 
  362             for (HashMap<String, Object> result : tempList) {
 
  363                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<BlackboardAttribute>();
 
  365                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  366                         ((result.get(
"host_key").toString() != null) ? result.get(
"host_key").toString() : 
""))); 
 
  368                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  369                         (Long.valueOf(result.get(
"last_access_utc").toString()) / 1000000) - Long.valueOf(
"11644473600"))); 
 
  372                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  373                         ((result.get(
"name").toString() != null) ? result.get(
"name").toString() : 
""))); 
 
  375                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  376                         ((result.get(
"value").toString() != null) ? result.get(
"value").toString() : 
""))); 
 
  378                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  379                         NbBundle.getMessage(
this.getClass(), 
"Chrome.moduleName")));
 
  380                 String domain = result.get(
"host_key").toString(); 
 
  381                 domain = domain.replaceFirst(
"^\\.+(?!$)", 
"");
 
  383                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"), domain));
 
  387                     bbartifacts.add(bbart);
 
  395                 NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  402     private void getDownload() {
 
  403         FileManager fileManager = currentCase.getServices().getFileManager();
 
  404         List<AbstractFile> downloadFiles = null;
 
  406             downloadFiles = fileManager.
findFiles(dataSource, 
"History", 
"Chrome"); 
 
  408             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getDownload.errMsg.errGettingFiles");
 
  409             logger.log(Level.SEVERE, msg, ex);
 
  410             this.addErrorMessage(this.getName() + 
": " + msg);
 
  414         if (downloadFiles.isEmpty()) {
 
  415             logger.log(Level.INFO, 
"Didn't find any Chrome download files."); 
 
  420         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  422         while (j < downloadFiles.size()) {
 
  424             if (downloadFile.
getSize() == 0) {
 
  430             } 
catch (IOException ex) {
 
  431                 logger.log(Level.SEVERE, 
"Error writing temp sqlite db for Chrome download artifacts.{0}", ex); 
 
  432                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getDownload.errMsg.errAnalyzeFiles1",
 
  433                         this.getName(), downloadFile.
getName()));
 
  436             File dbFile = 
new File(temps);
 
  442             List<HashMap<String, Object>> tempList;
 
  444             if (isChromePreVersion30(temps)) {
 
  445                 tempList = this.dbConnect(temps, downloadQuery);
 
  447                 tempList = this.dbConnect(temps, downloadQueryVersion30);
 
  450             logger.log(Level.INFO, 
"{0}- Now getting downloads from {1} with {2}artifacts identified.", 
new Object[]{moduleName, temps, tempList.size()}); 
 
  451             for (HashMap<String, Object> result : tempList) {
 
  452                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<BlackboardAttribute>();
 
  454                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"), (result.get(
"full_path").toString()))); 
 
  455                 long pathID = Util.findID(dataSource, (result.get(
"full_path").toString())); 
 
  458                             NbBundle.getMessage(
this.getClass(),
 
  459                                     "Chrome.parentModuleName"), pathID));
 
  462                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  463                         ((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
""))); 
 
  465                 Long time = (Long.valueOf(result.get(
"start_time").toString()) / 1000000) - Long.valueOf(
"11644473600"); 
 
  470                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"), time));
 
  471                 String domain = Util.extractDomain((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
""); 
 
  473                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"), domain));
 
  475                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  476                         NbBundle.getMessage(
this.getClass(), 
"Chrome.moduleName")));
 
  480                     bbartifacts.add(bbart);
 
  488                 NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  495     private void getLogin() {
 
  496         FileManager fileManager = currentCase.getServices().getFileManager();
 
  497         List<AbstractFile> signonFiles;
 
  499             signonFiles = fileManager.
findFiles(dataSource, 
"signons.sqlite", 
"Chrome"); 
 
  501             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getLogin.errMsg.errGettingFiles");
 
  502             logger.log(Level.SEVERE, msg, ex);
 
  503             this.addErrorMessage(this.getName() + 
": " + msg);
 
  507         if (signonFiles.isEmpty()) {
 
  508             logger.log(Level.INFO, 
"Didn't find any Chrome signon files."); 
 
  513         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  515         while (j < signonFiles.size()) {
 
  517             if (signonFile.
getSize() == 0) {
 
  523             } 
catch (IOException ex) {
 
  524                 logger.log(Level.SEVERE, 
"Error writing temp sqlite db for Chrome login artifacts.{0}", ex); 
 
  525                 this.addErrorMessage(
 
  526                         NbBundle.getMessage(
this.getClass(), 
"Chrome.getLogin.errMsg.errAnalyzingFiles", this.getName(),
 
  530             File dbFile = 
new File(temps);
 
  535             List<HashMap<String, Object>> tempList = this.dbConnect(temps, loginQuery);
 
  536             logger.log(Level.INFO, 
"{0}- Now getting login information from {1} with {2}artifacts identified.", 
new Object[]{moduleName, temps, tempList.size()}); 
 
  537             for (HashMap<String, Object> result : tempList) {
 
  538                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  540                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  541                         ((result.get(
"origin_url").toString() != null) ? result.get(
"origin_url").toString() : 
""))); 
 
  546                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  547                         (Long.valueOf(result.get(
"last_visit_time").toString()) / 1000000) - Long.valueOf(
"11644473600"))); 
 
  549                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  550                         ((result.get(
"from_visit").toString() != null) ? result.get(
"from_visit").toString() : 
""))); 
 
  552                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  553                         ((result.get(
"title").toString() != null) ? result.get(
"title").toString() : 
""))); 
 
  555                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  556                         NbBundle.getMessage(
this.getClass(), 
"Chrome.moduleName")));
 
  558                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  559                         (Util.extractDomain((result.get(
"origin_url").toString() != null) ? result.get(
"url").toString() : 
"")))); 
 
  561                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  562                         ((result.get(
"username_value").toString() != null) ? result.get(
"username_value").toString().replaceAll(
"'", 
"''") : 
""))); 
 
  564                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  565                         result.get(
"signon_realm").toString())); 
 
  569                     bbartifacts.add(bbart);
 
  573                 Collection<BlackboardAttribute> osAcctAttributes = 
new ArrayList<>();
 
  575                         NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  576                         ((result.get(
"username_value").toString() != null) ? result.get(
"username_value").toString().replaceAll(
"'", 
"''") : 
""))); 
 
  584                 NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  588     private boolean isChromePreVersion30(String temps) {
 
  589         String query = 
"PRAGMA table_info(downloads)"; 
 
  590         List<HashMap<String, Object>> columns = this.dbConnect(temps, query);
 
  591         for (HashMap<String, Object> col : columns) {
 
  592             if (col.get(
"name").equals(
"url")) { 
 
void addAttributes(Collection< BlackboardAttribute > attributes)
 
static String getRATempPath(Case a_case, String mod)
 
static< T > long writeToFile(Content content, java.io.File outputFile, ProgressHandle progress, Future< T > worker, boolean source)
 
void fireModuleDataEvent(ModuleDataEvent moduleDataEvent)
 
boolean dataSourceIngestIsCancelled()
 
BlackboardArtifact newArtifact(int artifactTypeID)
 
synchronized List< AbstractFile > findFiles(String fileName)
 
synchronized static Logger getLogger(String name)
 
static synchronized IngestServices getInstance()