Autopsy  4.11.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ExtractEdge.java
Go to the documentation of this file.
1 /*
2  *
3  * Autopsy Forensic Browser
4  *
5  * Copyright 2019 Basis Technology Corp.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.recentactivity;
20 
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.IOException;
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
27 import java.text.ParseException;
28 import java.text.SimpleDateFormat;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collection;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Scanner;
35 import java.util.logging.Level;
36 import org.openide.modules.InstalledFileLocator;
37 import org.openide.util.NbBundle.Messages;
51 import org.sleuthkit.datamodel.AbstractFile;
52 import org.sleuthkit.datamodel.BlackboardArtifact;
53 import org.sleuthkit.datamodel.Content;
54 import org.sleuthkit.datamodel.TskCoreException;
55 
59 final class ExtractEdge extends Extract {
60 
61  private static final Logger LOG = Logger.getLogger(ExtractEdge.class.getName());
62  private final IngestServices services = IngestServices.getInstance();
63  private final Path moduleTempResultPath;
64  private Content dataSource;
65  private IngestJobContext context;
66  private HashMap<String, ArrayList<String>> containersTable;
67 
68  private static final String EDGE = "Edge"; //NON-NLS
69 
70  private static final String EDGE_KEYWORD_VISIT = "Visited:"; //NON-NLS
71  private static final String IGNORE_COMMA_IN_QUOTES_REGEX = ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"; //NON-NLS
72 
73  private static final String EDGE_TABLE_TYPE_DOWNLOAD = "iedownload"; //NON-NLS
74  private static final String EDGE_TABLE_TYPE_HISTORY = "History"; //NON-NLS
75  private static final String EDGE_TABLE_TYPE_COOKIE = "cookie"; //NON-NLS
76 
77  private static final String EDGE_HEAD_URL = "url"; //NON-NLS
78  private static final String EDGE_HEAD_ACCESSTIME = "accessedtime"; //NON-NLS
79  private static final String EDGE_HEAD_NAME = "name"; //NON-NLS
80  private static final String EDGE_HEAD_CONTAINER_ID = "containerid"; //NON-NLS
81  private static final String EDGE_HEAD_RESPONSEHEAD = "responseheaders"; //NON-NLS
82  private static final String EDGE_HEAD_TITLE = "title"; //NON-NLS
83  private static final String EDGE_HEAD_RDOMAIN = "rdomain"; //NON-NLS
84  private static final String EDGE_HEAD_VALUE = "value"; //NON-NLS
85  private static final String EDGE_HEAD_LASTMOD = "lastmodified"; //NON-NLS
86 
87  private static final String EDGE_WEBCACHE_PREFIX = "WebCacheV01"; //NON-NLS
88  private static final String EDGE_CONTAINER_FILE_PREFIX = "Container_"; //NON-NLS
89  private static final String EDGE_CONTAINER_FILE_EXT = ".csv"; //NON-NLS
90  private static final String EDGE_WEBCACHE_EXT = ".dat"; //NON-NLS
91 
92  private static final String ESE_TOOL_NAME = "ESEDatabaseView.exe"; //NON-NLS
93  private static final String EDGE_WEBCACHE_NAME = "WebCacheV01.dat"; //NON-NLS
94  private static final String EDGE_SPARTAN_NAME = "Spartan.edb"; //NON-NLS
95  private static final String EDGE_CONTAINTERS_FILE_NAME = "Containers.csv"; //NON-NLS
96  private static final String EDGE_FAVORITE_FILE_NAME = "Favorites.csv"; //NON-NLS
97  private static final String EDGE_OUTPUT_FILE_NAME = "Output.txt"; //NON-NLS
98  private static final String EDGE_ERROR_FILE_NAME = "File.txt"; //NON-NLS
99  private static final String EDGE_WEBCACHE_FOLDER_NAME = "WebCache"; //NON-NLS
100  private static final String EDGE_SPARTAN_FOLDER_NAME = "MicrosoftEdge"; //NON-NLS
101 
102  private static final String ESE_TOOL_FOLDER = "ESEDatabaseView"; //NON-NLS
103  private static final String EDGE_RESULT_FOLDER_NAME = "results"; //NON-NLS
104 
105  private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a"); //NON-NLS
106 
107  @Messages({
108  "ExtractEdge_process_errMsg_unableFindESEViewer=Unable to find ESEDatabaseViewer",
109  "ExtractEdge_process_errMsg_errGettingWebCacheFiles=Error trying to retrieving Edge WebCacheV01 file",
110  "ExtractEdge_process_errMsg_webcacheFail=Failure processing Microsoft Edge WebCacheV01.dat file",
111  "ExtractEdge_process_errMsg_spartanFail=Failure processing Microsoft Edge spartan.edb file",
112  "ExtractEdge_Module_Name=Microsoft Edge",
113  "ExtractEdge_getHistory_containerFileNotFound=Error while trying to analyze Edge history",
114  "Progress_Message_Edge_History=Microsoft Edge History",
115  "Progress_Message_Edge_Bookmarks=Microsoft Edge Bookmarks",
116  "Progress_Message_Edge_Cookies=Microsoft Edge Cookies",
117  })
118 
122  ExtractEdge() throws NoCurrentCaseException {
123  moduleTempResultPath = Paths.get(RAImageIngestModule.getRATempPath(Case.getCurrentCaseThrows(), EDGE), EDGE_RESULT_FOLDER_NAME);
124  }
125 
126  @Override
127  protected String getName() {
128  return Bundle.ExtractEdge_Module_Name();
129  }
130 
131  @Override
132  void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
133  this.dataSource = dataSource;
134  this.context = context;
135  this.setFoundData(false);
136 
137  List<AbstractFile> webCacheFiles = null;
138  List<AbstractFile> spartanFiles = null;
139 
140  try {
141  webCacheFiles = fetchWebCacheDBFiles();
142  } catch (TskCoreException ex) {
143  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_errGettingWebCacheFiles());
144  LOG.log(Level.SEVERE, "Error fetching 'WebCacheV01.dat' files for Microsoft Edge", ex); //NON-NLS
145  }
146 
147  try {
148  spartanFiles = fetchSpartanDBFiles(); // For later use with bookmarks
149  } catch (TskCoreException ex) {
150  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_spartanFail());
151  LOG.log(Level.SEVERE, "Error fetching 'spartan.edb' files for Microsoft Edge", ex); //NON-NLS
152  }
153 
154  // No edge files found
155  if (webCacheFiles == null && spartanFiles == null) {
156  return;
157  }
158 
159  this.setFoundData(true);
160 
161  if (!PlatformUtil.isWindowsOS()) {
162  LOG.log(Level.WARNING, "Microsoft Edge files found, unable to parse on Non-Windows system"); //NON-NLS
163  return;
164  }
165 
166  final String esedumper = getPathForESEDumper();
167  if (esedumper == null) {
168  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_unableFindESEViewer());
169  LOG.log(Level.SEVERE, "Error finding ESEDatabaseViewer program"); //NON-NLS
170  return; //If we cannot find the ESEDatabaseView we cannot proceed
171  }
172 
173  try {
174  this.processWebCacheDbFile(esedumper, webCacheFiles, progressBar);
175  } catch (IOException | TskCoreException ex) {
176  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_webcacheFail());
177  LOG.log(Level.SEVERE, "Error returned from processWebCacheDbFile", ex); // NON-NLS
178  }
179 
180  progressBar.progress(Bundle.Progress_Message_Edge_Bookmarks());
181  try {
182  this.processSpartanDbFile(esedumper, spartanFiles);
183  } catch (IOException | TskCoreException ex) {
184  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_spartanFail());
185  LOG.log(Level.SEVERE, "Error returned from processSpartanDbFile", ex); // NON-NLS
186  }
187  }
188 
198  void processWebCacheDbFile(String eseDumperPath, List<AbstractFile> webCacheFiles, DataSourceIngestModuleProgress progressBar) throws IOException, TskCoreException {
199 
200  for (AbstractFile webCacheFile : webCacheFiles) {
201 
202  if (context.dataSourceIngestIsCancelled()) {
203  return;
204  }
205 
206  clearContainerTable();
207 
208  //Run the dumper
209  String tempWebCacheFileName = EDGE_WEBCACHE_PREFIX
210  + Integer.toString((int) webCacheFile.getId()) + EDGE_WEBCACHE_EXT; //NON-NLS
211  File tempWebCacheFile = new File(RAImageIngestModule.getRATempPath(currentCase, EDGE), tempWebCacheFileName);
212 
213  try {
214  ContentUtils.writeToFile(webCacheFile, tempWebCacheFile,
215  context::dataSourceIngestIsCancelled);
216  } catch (IOException ex) {
217  throw new IOException("Error writingToFile: " + webCacheFile, ex); //NON-NLS
218  }
219 
220  File resultsDir = new File(moduleTempResultPath.toAbsolutePath() + Integer.toString((int) webCacheFile.getId()));
221  resultsDir.mkdirs();
222  try {
223  executeDumper(eseDumperPath, tempWebCacheFile.getAbsolutePath(),
224  resultsDir.getAbsolutePath());
225 
226  if (context.dataSourceIngestIsCancelled()) {
227  return;
228  }
229 
230  progressBar.progress(Bundle.Progress_Message_Edge_History());
231 
232  this.getHistory(webCacheFile, resultsDir);
233 
234  if (context.dataSourceIngestIsCancelled()) {
235  return;
236  }
237 
238  progressBar.progress(Bundle.Progress_Message_Edge_Cookies());
239 
240  this.getCookies(webCacheFile, resultsDir);
241 
242  } finally {
243  tempWebCacheFile.delete();
244  FileUtil.deleteFileDir(resultsDir);
245  }
246  }
247  }
248 
258  void processSpartanDbFile(String eseDumperPath, List<AbstractFile> spartanFiles) throws IOException, TskCoreException {
259 
260  for (AbstractFile spartanFile : spartanFiles) {
261 
262  if (context.dataSourceIngestIsCancelled()) {
263  return;
264  }
265 
266  //Run the dumper
267  String tempSpartanFileName = EDGE_WEBCACHE_PREFIX
268  + Integer.toString((int) spartanFile.getId()) + EDGE_WEBCACHE_EXT;
269  File tempSpartanFile = new File(RAImageIngestModule.getRATempPath(currentCase, EDGE), tempSpartanFileName);
270 
271  try {
272  ContentUtils.writeToFile(spartanFile, tempSpartanFile,
273  context::dataSourceIngestIsCancelled);
274  } catch (IOException ex) {
275  throw new IOException("Error writingToFile: " + spartanFile, ex); //NON-NLS
276  }
277 
278  File resultsDir = new File(moduleTempResultPath.toAbsolutePath() + Integer.toString((int) spartanFile.getId()));
279  resultsDir.mkdirs();
280  try {
281  executeDumper(eseDumperPath, tempSpartanFile.getAbsolutePath(),
282  resultsDir.getAbsolutePath());
283 
284  if (context.dataSourceIngestIsCancelled()) {
285  return;
286  }
287 
288  this.getBookmarks(spartanFile, resultsDir);
289 
290  } finally {
291  tempSpartanFile.delete();
292  FileUtil.deleteFileDir(resultsDir);
293  }
294  }
295  }
296 
306  private void getHistory(AbstractFile origFile, File resultDir) throws TskCoreException, FileNotFoundException {
307  ArrayList<File> historyFiles = getHistoryFiles(resultDir);
308 
309  if (historyFiles == null) {
310  return;
311  }
312 
313  for (File file : historyFiles) {
314  if (context.dataSourceIngestIsCancelled()) {
315  return;
316  }
317 
318  Scanner fileScanner;
319  try {
320  fileScanner = new Scanner(new FileInputStream(file.toString()));
321  } catch (FileNotFoundException ex) {
322  LOG.log(Level.WARNING, "Unable to find the ESEDatabaseView file at " + file.getPath(), ex); //NON-NLS
323  continue; // If we couldn't open this file, continue to the next file
324  }
325 
326  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
327 
328  try {
329  List<String> headers = null;
330  while (fileScanner.hasNext()) {
331  if (context.dataSourceIngestIsCancelled()) {
332  return;
333  }
334 
335  String line = fileScanner.nextLine();
336  if (headers == null) {
337  headers = Arrays.asList(line.toLowerCase().split(","));
338  continue;
339  }
340 
341  if (line.contains(EDGE_KEYWORD_VISIT)) {
342  BlackboardArtifact ba = getHistoryArtifact(origFile, headers, line);
343  if (ba != null) {
344  bbartifacts.add(ba);
345  this.indexArtifact(ba);
346  }
347  }
348  }
349  } finally {
350  fileScanner.close();
351  }
352 
353  if (!bbartifacts.isEmpty()) {
354  services.fireModuleDataEvent(new ModuleDataEvent(
355  RecentActivityExtracterModuleFactory.getModuleName(),
356  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, bbartifacts));
357  }
358  }
359  }
360 
369  private void getBookmarks(AbstractFile origFile, File resultDir) throws TskCoreException {
370  Scanner fileScanner;
371  File favoriteFile = new File(resultDir, EDGE_FAVORITE_FILE_NAME);
372 
373  try {
374  fileScanner = new Scanner(new FileInputStream(favoriteFile));
375  } catch (FileNotFoundException ex) {
376  // This is a non-fatal error, if the favorites file is not found
377  // there might have not been any favorites\bookmarks
378  return;
379  }
380 
381  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
382 
383  try {
384  List<String> headers = null;
385  while (fileScanner.hasNext()) {
386  String line = fileScanner.nextLine();
387  if (headers == null) {
388  headers = Arrays.asList(line.toLowerCase().split(","));
389  continue;
390  }
391 
392  BlackboardArtifact ba = getBookmarkArtifact(origFile, headers, line);
393  if (ba != null) {
394  bbartifacts.add(ba);
395  this.indexArtifact(ba);
396  }
397  }
398  } finally {
399  fileScanner.close();
400  }
401 
402  if (!bbartifacts.isEmpty()) {
403  services.fireModuleDataEvent(new ModuleDataEvent(
404  RecentActivityExtracterModuleFactory.getModuleName(),
405  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, bbartifacts));
406  }
407  }
408 
416  private void getCookies(AbstractFile origFile, File resultDir) throws TskCoreException {
417  File containerFiles[] = resultDir.listFiles((dir, name) -> name.toLowerCase().contains(EDGE_TABLE_TYPE_COOKIE));
418 
419  if (containerFiles == null) {
420  return;
421  }
422 
423  for (File file : containerFiles) {
424  if (context.dataSourceIngestIsCancelled()) {
425  return;
426  }
427 
428  Scanner fileScanner;
429  try {
430  fileScanner = new Scanner(new FileInputStream(file.toString()));
431  } catch (FileNotFoundException ex) {
432  LOG.log(Level.WARNING, "Unable to find the ESEDatabaseView file at " + file.getPath(), ex); //NON-NLS
433  continue; // If we couldn't open this file, continue to the next file
434  }
435 
436  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
437 
438  try {
439  List<String> headers = null;
440  while (fileScanner.hasNext()) {
441  if (context.dataSourceIngestIsCancelled()) {
442  return;
443  }
444 
445  String line = fileScanner.nextLine();
446  if (headers == null) {
447  headers = Arrays.asList(line.toLowerCase().split(","));
448  continue;
449  }
450 
451  BlackboardArtifact ba = getCookieArtifact(origFile, headers, line);
452  if (ba != null) {
453  bbartifacts.add(ba);
454  this.indexArtifact(ba);
455  }
456  }
457  } finally {
458  fileScanner.close();
459  }
460 
461  if (!bbartifacts.isEmpty()) {
462  services.fireModuleDataEvent(new ModuleDataEvent(
463  RecentActivityExtracterModuleFactory.getModuleName(),
464  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, bbartifacts));
465  }
466  }
467  }
468 
479  private void getDownloads(AbstractFile origFile, File resultDir) throws TskCoreException, FileNotFoundException {
480  ArrayList<File> downloadFiles = getDownloadFiles(resultDir);
481 
482  if (downloadFiles == null) {
483  return;
484  }
485 
486  for (File file : downloadFiles) {
487  if (context.dataSourceIngestIsCancelled()) {
488  return;
489  }
490 
491  Scanner fileScanner;
492  try {
493  fileScanner = new Scanner(new FileInputStream(file.toString()));
494  } catch (FileNotFoundException ex) {
495  LOG.log(Level.WARNING, "Unable to find the ESEDatabaseView file at " + file.getPath(), ex); //NON-NLS
496  continue; // If we couldn't open this file, continue to the next file
497  }
498  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
499 
500  try {
501  List<String> headers = null;
502  while (fileScanner.hasNext()) {
503  if (context.dataSourceIngestIsCancelled()) {
504  return;
505  }
506 
507  String line = fileScanner.nextLine();
508  if (headers == null) {
509  headers = Arrays.asList(line.toLowerCase().split(","));
510  continue;
511  }
512 
513  if (line.contains(EDGE_TABLE_TYPE_DOWNLOAD)) {
514 
515  BlackboardArtifact ba = getDownloadArtifact(origFile, headers, line);
516  if (ba != null) {
517  bbartifacts.add(ba);
518  this.indexArtifact(ba);
519  }
520  }
521  }
522  } finally {
523  fileScanner.close();
524  }
525 
526  if (!bbartifacts.isEmpty()) {
527  services.fireModuleDataEvent(new ModuleDataEvent(
528  RecentActivityExtracterModuleFactory.getModuleName(),
529  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, bbartifacts));
530  }
531  }
532  }
533 
539  private String getPathForESEDumper() {
540  Path path = Paths.get(ESE_TOOL_FOLDER, ESE_TOOL_NAME);
541  File eseToolFile = InstalledFileLocator.getDefault().locate(path.toString(),
542  ExtractEdge.class.getPackage().getName(), false);
543  if (eseToolFile != null) {
544  return eseToolFile.getAbsolutePath();
545  }
546 
547  return null;
548  }
549 
556  private List<AbstractFile> fetchWebCacheDBFiles() throws TskCoreException {
558  = currentCase.getServices().getFileManager();
559  return fileManager.findFiles(dataSource, EDGE_WEBCACHE_NAME, EDGE_WEBCACHE_FOLDER_NAME);
560  }
561 
568  private List<AbstractFile> fetchSpartanDBFiles() throws TskCoreException {
570  = currentCase.getServices().getFileManager();
571  return fileManager.findFiles(dataSource, EDGE_SPARTAN_NAME, EDGE_SPARTAN_FOLDER_NAME);
572  }
573 
585  private void executeDumper(String dumperPath, String inputFilePath,
586  String outputDir) throws IOException {
587 
588  final Path outputFilePath = Paths.get(outputDir, EDGE_OUTPUT_FILE_NAME);
589  final Path errFilePath = Paths.get(outputDir, EDGE_ERROR_FILE_NAME);
590  LOG.log(Level.INFO, "Writing ESEDatabaseViewer results to: {0}", outputDir); //NON-NLS
591 
592  List<String> commandLine = new ArrayList<>();
593  commandLine.add(dumperPath);
594  commandLine.add("/table"); //NON-NLS
595  commandLine.add(inputFilePath);
596  commandLine.add("*"); //NON-NLS
597  commandLine.add("/scomma"); //NON-NLS
598  commandLine.add(outputDir + "\\" + "*.csv"); //NON-NLS
599 
600  ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
601  processBuilder.redirectOutput(outputFilePath.toFile());
602  processBuilder.redirectError(errFilePath.toFile());
603 
604  ExecUtil.execute(processBuilder, new DataSourceIngestModuleProcessTerminator(context));
605  }
606 
617  private BlackboardArtifact getHistoryArtifact(AbstractFile origFile, List<String> headers, String line) throws TskCoreException {
618  String[] rowSplit = line.split(",");
619 
620  int index = headers.indexOf(EDGE_HEAD_URL);
621  String urlUserStr = rowSplit[index];
622 
623  String[] str = urlUserStr.split("@");
624  String user = (str[0].replace(EDGE_KEYWORD_VISIT, "")).trim();
625  String url = str[1];
626 
627  index = headers.indexOf(EDGE_HEAD_ACCESSTIME);
628  String accessTime = rowSplit[index].trim();
629  Long ftime = null;
630  try {
631  Long epochtime = DATE_FORMATTER.parse(accessTime).getTime();
632  ftime = epochtime / 1000;
633  } catch (ParseException ex) {
634  LOG.log(Level.WARNING, "The Accessed Time format in history file seems invalid " + accessTime, ex); //NON-NLS
635  }
636 
637  BlackboardArtifact bbart = origFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY);
638 
639  bbart.addAttributes(createHistoryAttribute(url, ftime,
640  null, null,
641  this.getName(),
642  NetworkUtils.extractDomain(url), user));
643 
644  return bbart;
645  }
646 
656  private BlackboardArtifact getCookieArtifact(AbstractFile origFile, List<String> headers, String line) throws TskCoreException {
657  String[] lineSplit = line.split(","); // NON-NLS
658 
659  String accessTime = lineSplit[headers.indexOf(EDGE_HEAD_LASTMOD)].trim();
660  Long ftime = null;
661  try {
662  Long epochtime = DATE_FORMATTER.parse(accessTime).getTime();
663  ftime = epochtime / 1000;
664  } catch (ParseException ex) {
665  LOG.log(Level.WARNING, "The Accessed Time format in history file seems invalid " + accessTime, ex); //NON-NLS
666  }
667 
668  String domain = lineSplit[headers.indexOf(EDGE_HEAD_RDOMAIN)].trim();
669  String name = hexToChar(lineSplit[headers.indexOf(EDGE_HEAD_NAME)].trim());
670  String value = hexToChar(lineSplit[headers.indexOf(EDGE_HEAD_VALUE)].trim());
671  String url = flipDomain(domain);
672 
673  BlackboardArtifact bbart = origFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE);
674  bbart.addAttributes(createCookieAttributes(url, ftime, name, value, this.getName(), NetworkUtils.extractDomain(url)));
675  return bbart;
676  }
677 
691  private BlackboardArtifact getDownloadArtifact(AbstractFile origFile, List<String> headers, String line) throws TskCoreException {
692  BlackboardArtifact bbart = null;
693 
694  String[] lineSplit = line.split(","); // NON-NLS
695  String rheader = lineSplit[headers.indexOf(EDGE_HEAD_RESPONSEHEAD)];
696 
697  return bbart;
698  }
699 
712  private BlackboardArtifact getBookmarkArtifact(AbstractFile origFile, List<String> headers, String line) throws TskCoreException {
713  // split on all commas as long as they are not inbetween quotes
714  String[] lineSplit = line.split(IGNORE_COMMA_IN_QUOTES_REGEX, -1);
715 
716  String url = lineSplit[headers.indexOf(EDGE_HEAD_URL)];
717  String title = lineSplit[headers.indexOf(EDGE_HEAD_TITLE)].replace("\"", ""); // NON-NLS
718 
719  if (url.isEmpty()) {
720  return null;
721  }
722 
723  BlackboardArtifact bbart = origFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK);
724  bbart.addAttributes(createBookmarkAttributes(url, title, null,
725  this.getName(), NetworkUtils.extractDomain(url)));
726  return bbart;
727  }
728 
735  private String hexToChar(String hexString) {
736  String[] hexValues = hexString.split(" "); // NON-NLS
737  StringBuilder output = new StringBuilder();
738 
739  for (String str : hexValues) {
740  try {
741  int value = Integer.parseInt(str, 16);
742  if (value > 31) { // Ignore non-print characters
743  output.append((char) value);
744  }
745  } catch (NumberFormatException ex) {
746  return null;
747  }
748  }
749 
750  return output.toString();
751  }
752 
764  private String flipDomain(String domain) {
765  if (domain == null || domain.isEmpty()) {
766  return null;
767  }
768 
769  String[] tokens = domain.split("\\."); // NON-NLS
770 
771  if (tokens.length < 2 || tokens.length > 3) {
772  return domain; // don't know what to do, just send it back as is
773  }
774 
775  StringBuilder buf = new StringBuilder();
776  if (tokens.length > 2) {
777  buf.append(tokens[2]);
778  buf.append(".");
779  }
780  buf.append(tokens[1]);
781  buf.append(".");
782  buf.append(tokens[0]);
783 
784  return buf.toString();
785  }
786 
794  private ArrayList<File> getDownloadFiles(File resultDir) throws FileNotFoundException {
795  return getContainerFiles(resultDir, EDGE_TABLE_TYPE_DOWNLOAD);
796  }
797 
805  private ArrayList<File> getHistoryFiles(File resultDir) throws FileNotFoundException {
806  return getContainerFiles(resultDir, EDGE_TABLE_TYPE_HISTORY);
807  }
808 
817  private ArrayList<File> getContainerFiles(File resultDir, String type) throws FileNotFoundException {
818  HashMap<String, ArrayList<String>> idTable = getContainerIDTable(resultDir);
819 
820  ArrayList<String> idList = idTable.get(type);
821  if (idList == null) {
822  return null;
823  }
824 
825  ArrayList<File> fileList = new ArrayList<>();
826  for (String str : idList) {
827  String fileName = EDGE_CONTAINER_FILE_PREFIX + str + EDGE_CONTAINER_FILE_EXT;
828  fileList.add(new File(resultDir, fileName));
829  }
830 
831  return fileList;
832  }
833 
844  private HashMap<String, ArrayList<String>> getContainerIDTable(File resultDir) throws FileNotFoundException {
845 
846  if (containersTable == null) {
847  File containerFile = new File(resultDir, EDGE_CONTAINTERS_FILE_NAME);
848 
849  try (Scanner fileScanner = new Scanner(new FileInputStream(containerFile))) {
850  List<String> headers = null;
851  containersTable = new HashMap<>();
852  int nameIdx = 0;
853  int idIdx = 0;
854  while (fileScanner.hasNext()) {
855  String line = fileScanner.nextLine();
856  if (headers == null) {
857  headers = Arrays.asList(line.toLowerCase().split(","));
858  nameIdx = headers.indexOf(EDGE_HEAD_NAME);
859  idIdx = headers.indexOf(EDGE_HEAD_CONTAINER_ID);
860  } else {
861  String[] row = line.split(","); // NON-NLS
862  String name = row[nameIdx];
863  String id = row[idIdx];
864 
865  ArrayList<String> idList = containersTable.get(name);
866  if (idList == null) {
867  idList = new ArrayList<>();
868  containersTable.put(name, idList);
869  }
870 
871  idList.add(id);
872  }
873  }
874  }
875  }
876 
877  return containersTable;
878  }
879 
883  private void clearContainerTable(){
884  containersTable = null;
885  }
886 }
synchronized List< AbstractFile > findFiles(String fileName)

Copyright © 2012-2018 Basis Technology. Generated on: Fri Jun 21 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.