mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-13 16:36:15 +00:00
1184: Chrome cache
- Extract and save data segments from data_x files.
This commit is contained in:
parent
9796ccfffb
commit
b36b5d7d63
@ -21,6 +21,7 @@
|
|||||||
package org.sleuthkit.autopsy.recentactivity;
|
package org.sleuthkit.autopsy.recentactivity;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -43,16 +44,21 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException;
|
import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||||
|
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
|
||||||
|
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||||
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.DerivedFile;
|
||||||
import org.sleuthkit.datamodel.ReadContentInputStream;
|
import org.sleuthkit.datamodel.ReadContentInputStream;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
import org.sleuthkit.datamodel.TimeUtilities;
|
import org.sleuthkit.datamodel.TimeUtilities;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import org.sleuthkit.datamodel.TskData;
|
||||||
import org.sleuthkit.datamodel.TskException;
|
import org.sleuthkit.datamodel.TskException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,12 +71,17 @@ final class ChromeCacheExtractor {
|
|||||||
private final int INDEXFILE_HDR_SIZE = 92*4;
|
private final int INDEXFILE_HDR_SIZE = 92*4;
|
||||||
private final int DATAFILE_HDR_SIZE = 8192;
|
private final int DATAFILE_HDR_SIZE = 8192;
|
||||||
|
|
||||||
private final String moduleName;
|
|
||||||
private final Logger logger = Logger.getLogger(this.getClass().getName());
|
private final Logger logger = Logger.getLogger(this.getClass().getName());
|
||||||
private String outputFolderName;
|
|
||||||
|
private static final String VERSION_NUMBER = "1.0.0";
|
||||||
|
private final String moduleName;
|
||||||
|
|
||||||
|
private String absOutputFolderName;
|
||||||
|
private String relOutputFolderName;
|
||||||
|
|
||||||
private final Content dataSource;
|
private final Content dataSource;
|
||||||
private final IngestJobContext context;
|
private final IngestJobContext context;
|
||||||
|
private IngestServices services = IngestServices.getInstance();
|
||||||
private Case currentCase;
|
private Case currentCase;
|
||||||
private FileManager fileManager;
|
private FileManager fileManager;
|
||||||
private FileTypeDetector fileTypeDetector;
|
private FileTypeDetector fileTypeDetector;
|
||||||
@ -125,8 +136,9 @@ final class ChromeCacheExtractor {
|
|||||||
fileTypeDetector = new FileTypeDetector();
|
fileTypeDetector = new FileTypeDetector();
|
||||||
|
|
||||||
// Create an output folder to save any derived files
|
// Create an output folder to save any derived files
|
||||||
outputFolderName = RAImageIngestModule.getRAOutputPath(currentCase, moduleName);
|
absOutputFolderName = RAImageIngestModule.getRAOutputPath(currentCase, moduleName);
|
||||||
File dir = new File(outputFolderName);
|
relOutputFolderName = RAImageIngestModule.getRelModuleOutputPath() + File.separator + moduleName;
|
||||||
|
File dir = new File(absOutputFolderName);
|
||||||
if (dir.exists() == false) {
|
if (dir.exists() == false) {
|
||||||
dir.mkdirs();
|
dir.mkdirs();
|
||||||
}
|
}
|
||||||
@ -166,8 +178,17 @@ final class ChromeCacheExtractor {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String getOutputFolderName() {
|
private String getAbsOutputFolderName() {
|
||||||
return outputFolderName;
|
return absOutputFolderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the relative location of output folder for this module
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getRelOutputFolderName() {
|
||||||
|
return relOutputFolderName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,7 +206,6 @@ final class ChromeCacheExtractor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Optional<CacheFileCopy> indexFile;
|
Optional<CacheFileCopy> indexFile;
|
||||||
try {
|
try {
|
||||||
// find the index file
|
// find the index file
|
||||||
@ -209,6 +229,8 @@ final class ChromeCacheExtractor {
|
|||||||
|
|
||||||
logger.log(Level.INFO, "{0}- Now reading Cache index file", new Object[]{moduleName}); //NON-NLS
|
logger.log(Level.INFO, "{0}- Now reading Cache index file", new Object[]{moduleName}); //NON-NLS
|
||||||
|
|
||||||
|
List<AbstractFile> derivedFiles = new ArrayList<>();
|
||||||
|
|
||||||
ByteBuffer indexFileROBuffer = indexFile.get().getByteBuffer();
|
ByteBuffer indexFileROBuffer = indexFile.get().getByteBuffer();
|
||||||
IndexFileHeader indexHdr = new IndexFileHeader(indexFileROBuffer);
|
IndexFileHeader indexHdr = new IndexFileHeader(indexFileROBuffer);
|
||||||
|
|
||||||
@ -238,19 +260,46 @@ final class ChromeCacheExtractor {
|
|||||||
// Todo: extract the data if we are going to do something with it in the future
|
// Todo: extract the data if we are going to do something with it in the future
|
||||||
|
|
||||||
//data.extract();
|
//data.extract();
|
||||||
|
String dataFilename = data.getAddress().getFilename();
|
||||||
|
Optional<AbstractFile> dataFile = this.findCacheFile(dataFilename);
|
||||||
|
|
||||||
if (data.isInExternalFile() ) {
|
|
||||||
String externalFilename = data.getAddress().getFilename();
|
|
||||||
Optional<AbstractFile> externalFile = this.findCacheFile(externalFilename);
|
|
||||||
|
|
||||||
if (externalFile.isPresent()) {
|
|
||||||
try {
|
|
||||||
Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
|
Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
|
||||||
bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL,
|
bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL,
|
||||||
moduleName,
|
moduleName,
|
||||||
((cacheEntry.getKey() != null) ? cacheEntry.getKey() : ""))); //NON-NLS
|
((cacheEntry.getKey() != null) ? cacheEntry.getKey() : ""))); //NON-NLS
|
||||||
|
|
||||||
BlackboardArtifact bbart = externalFile.get().newArtifact(ARTIFACT_TYPE.TSK_SOURCE_ARTIFACT);
|
if (dataFile.isPresent()) {
|
||||||
|
if (data.isInExternalFile() ) {
|
||||||
|
try {
|
||||||
|
BlackboardArtifact bbart = dataFile.get().newArtifact(ARTIFACT_TYPE.TSK_SOURCE_ARTIFACT);
|
||||||
|
if (bbart != null) {
|
||||||
|
bbart.addAttributes(bbattributes);
|
||||||
|
}
|
||||||
|
} catch (TskException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error while trying to add an artifact", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// extract data segment and save it as derived file
|
||||||
|
data.extract();
|
||||||
|
String filename = data.save();
|
||||||
|
String relPathname = getRelOutputFolderName() + File.separator + filename;
|
||||||
|
|
||||||
|
// TBD: check if data segment is compressed? With Brotli?
|
||||||
|
DerivedFile derivedFile = fileManager.addDerivedFile(filename, relPathname,
|
||||||
|
data.getDataLength(),
|
||||||
|
cacheEntry.getCreationTime(), cacheEntry.getCreationTime(), cacheEntry.getCreationTime(), cacheEntry.getCreationTime(), // TBD
|
||||||
|
true,
|
||||||
|
dataFile.get(),
|
||||||
|
"",
|
||||||
|
moduleName,
|
||||||
|
VERSION_NUMBER,
|
||||||
|
"",
|
||||||
|
TskData.EncodingType.NONE);
|
||||||
|
|
||||||
|
derivedFiles.add(derivedFile);
|
||||||
|
try {
|
||||||
|
BlackboardArtifact bbart = derivedFile.newArtifact(ARTIFACT_TYPE.TSK_SOURCE_ARTIFACT);
|
||||||
if (bbart != null) {
|
if (bbart != null) {
|
||||||
bbart.addAttributes(bbattributes);
|
bbart.addAttributes(bbattributes);
|
||||||
}
|
}
|
||||||
@ -267,6 +316,15 @@ final class ChromeCacheExtractor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (derivedFiles.isEmpty() == false) {
|
||||||
|
for (AbstractFile derived : derivedFiles) {
|
||||||
|
services.fireModuleContentEvent(new ModuleContentEvent(derived));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context.addFilesToJob(derivedFiles);
|
||||||
|
services.fireModuleDataEvent(new ModuleDataEvent(moduleName, BlackboardArtifact.ARTIFACT_TYPE.TSK_SOURCE_ARTIFACT));
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -715,35 +773,40 @@ final class ChromeCacheExtractor {
|
|||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RAMAN TBD: save needs to return something that can be used to add a derived file
|
|
||||||
// void save() throws TskCoreException, IngestModuleException {
|
|
||||||
// String fileName;
|
|
||||||
//
|
|
||||||
// if (address.isInExternalFile()) {
|
|
||||||
// fileName = address.getFilename();
|
|
||||||
// } else {
|
|
||||||
// fileName = String.format("%s__%08x", address.getFilename(), address.getUint32CacheAddr());
|
|
||||||
// }
|
|
||||||
// save(getOutputFolderName() + File.separator + fileName);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// TBD: save needs to return something that can be used to add a derived file
|
String save() throws TskCoreException, IngestModuleException {
|
||||||
// void save(String filePathName) throws TskCoreException, IngestModuleException {
|
String fileName;
|
||||||
//
|
|
||||||
// // Save the data to specified file
|
if (address.isInExternalFile()) {
|
||||||
// if (data == null) {
|
fileName = address.getFilename();
|
||||||
// extract();
|
} else {
|
||||||
// }
|
fileName = String.format("%s__%08x", address.getFilename(), address.getUint32CacheAddr());
|
||||||
//
|
}
|
||||||
// if (!this.isInExternalFile() ||
|
|
||||||
// !this.isCompressedFile()) {
|
String filePathName = getAbsOutputFolderName() + File.separator + fileName;
|
||||||
// // write the
|
save(filePathName);
|
||||||
// try (FileOutputStream stream = new FileOutputStream(filePathName)) {
|
|
||||||
// stream.write(data);
|
return fileName;
|
||||||
// } catch (IOException ex) {
|
}
|
||||||
// throw new TskCoreException(String.format("Failed to write output file %s", filePathName), ex);
|
|
||||||
// }
|
|
||||||
// }
|
void save(String filePathName) throws TskCoreException, IngestModuleException {
|
||||||
|
|
||||||
|
// Save the data to specified file
|
||||||
|
if (data == null) {
|
||||||
|
extract();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isInExternalFile() ||
|
||||||
|
!this.isCompressedFile()) {
|
||||||
|
|
||||||
|
// write the
|
||||||
|
try (FileOutputStream stream = new FileOutputStream(filePathName)) {
|
||||||
|
stream.write(data);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new TskCoreException(String.format("Failed to write output file %s", filePathName), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
// else {
|
// else {
|
||||||
// if (mimeType.toLowerCase().contains("gzip")) {
|
// if (mimeType.toLowerCase().contains("gzip")) {
|
||||||
// //if (mimeType.equalsIgnoreCase("application/gzip")) {
|
// //if (mimeType.equalsIgnoreCase("application/gzip")) {
|
||||||
@ -767,7 +830,7 @@ final class ChromeCacheExtractor {
|
|||||||
// System.out.println("TBD Dont know how to uncompress Brotli yet" );
|
// System.out.println("TBD Dont know how to uncompress Brotli yet" );
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -225,4 +225,15 @@ public final class RAImageIngestModule implements DataSourceIngestModule {
|
|||||||
}
|
}
|
||||||
return tmpDir;
|
return tmpDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get relative path for module output folder.
|
||||||
|
*
|
||||||
|
* @throws NoCurrentCaseException if there is no open case.
|
||||||
|
* @return the relative path of the module output folder
|
||||||
|
*/
|
||||||
|
static String getRelModuleOutputPath() throws NoCurrentCaseException {
|
||||||
|
return Case.getCurrentCaseThrows().getModuleOutputDirectoryRelativePath() + File.separator
|
||||||
|
+ "RecentActivity";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user