@Override public void startUp(IngestJobContext context) throws IngestModuleException { this.context = context; refCounter.incrementAndGet(context.getJobId()); synchronized (SampleFileIngestModule.class) { if (attrId == -1) { // For this sample, make a new attribute type to use to post // results to the blackboard. There are many standard blackboard // artifact and attribute types and you should use them instead // creating new ones to facilitate use of your results by other // modules. Case autopsyCase = Case.getCurrentCase(); SleuthkitCase sleuthkitCase = autopsyCase.getSleuthkitCase(); try { // See if the attribute type has already been defined. attrId = sleuthkitCase.getAttrTypeID("ATTR_SAMPLE"); if (attrId == -1) { attrId = sleuthkitCase.addAttrType("ATTR_SAMPLE", "Sample Attribute"); } } catch (TskCoreException ex) { IngestServices ingestServices = IngestServices.getInstance(); Logger logger = ingestServices.getLogger(SampleIngestModuleFactory.getModuleName()); logger.log(Level.SEVERE, "Failed to create blackboard attribute", ex); attrId = -1; throw new IngestModuleException(ex.getLocalizedMessage()); } } } }
/** * Create a tag for an artifact with TSK_TAG_NAME as tagName. * * @param artifact to create tag for * @param tagName TSK_TAG_NAME * @param comment the tag comment or null if not present */ public static void createTag(BlackboardArtifact artifact, String tagName, String comment) { try { Case currentCase = Case.getCurrentCase(); SleuthkitCase skCase = currentCase.getSleuthkitCase(); AbstractFile file = skCase.getAbstractFileById(artifact.getObjectID()); final BlackboardArtifact bookArt = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT); List<BlackboardAttribute> attrs = new ArrayList<BlackboardAttribute>(); BlackboardAttribute attr1 = new BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID(), "", tagName); if (comment != null && !comment.isEmpty()) { BlackboardAttribute attr2 = new BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID(), "", comment); attrs.add(attr2); } BlackboardAttribute attr3 = new BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID(), "", artifact.getArtifactID()); attrs.add(attr1); attrs.add(attr3); bookArt.addAttributes(attrs); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Failed to create tag for artifact " + artifact.getArtifactID()); } }
/** * Get a list of all the bookmarks. * * @return a list of all bookmark artifacts */ static List<BlackboardArtifact> getBookmarks() { try { Case currentCase = Case.getCurrentCase(); SleuthkitCase skCase = currentCase.getSleuthkitCase(); return skCase.getBlackboardArtifacts( BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAG_NAME, Tags.BOOKMARK_TAG_NAME); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Failed to get list of artifacts from the case."); } return new ArrayList<BlackboardArtifact>(); }
/** * Get the data model Content objects in the root of this case's hierarchy. * * @return a list of the root objects */ public List<Content> getRootObjects() { try { return db.getRootObjects(); } catch (TskException ex) { throw new RuntimeException("Error getting root objects.", ex); } }
/** * Creates a new case (create the XML config file and database) * * @param caseDir The directory to store case data in. Will be created if it doesn't already * exist. If it exists, it should have all of the needed sub dirs that createCaseDirectory() * will create. * @param caseName the name of case * @param caseNumber the case number * @param examiner the examiner for this case */ public static void create(String caseDir, String caseName, String caseNumber, String examiner) throws CaseActionException { logger.log( Level.INFO, "Creating new case.\ncaseDir: {0}\ncaseName: {1}", new Object[] {caseDir, caseName}); // create case directory if it doesn't already exist. if (new File(caseDir).exists() == false) { Case.createCaseDirectory(caseDir); } String configFilePath = caseDir + File.separator + caseName + CASE_DOT_EXTENSION; XMLCaseManagement xmlcm = new XMLCaseManagement(); xmlcm.create(caseDir, caseName, examiner, caseNumber); // create a new XML config file xmlcm.writeFile(); String dbPath = caseDir + File.separator + "autopsy.db"; SleuthkitCase db = null; try { db = SleuthkitCase.newCase(dbPath); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error creating a case: " + caseName + " in dir " + caseDir, ex); throw new CaseActionException( "Error creating a case: " + caseName + " in dir " + caseDir, ex); } Case newCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db); changeCase(newCase); }
/** * Get children count without actually loading all nodes * * @return */ static long calculateItems(SleuthkitCase sleuthkitCase, FileSizeFilter filter) { try { return sleuthkitCase.countFilesWhere(makeQuery(filter)); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error getting files by size search view count", ex); // NON-NLS return 0; } }
/** * Returns a List of FsContent objects from TSK based on sql query. * * @param image is a Image object that denotes which image to get the files from * @param query is a sql string query that is to be run * @return FFSqlitedb is a List of FsContent objects */ @SuppressWarnings("deprecation") public List<FsContent> extractFiles(Image image, String query) { Collection<FileSystem> imageFS = tskCase.getFileSystems(image); List<String> fsIds = new LinkedList<String>(); 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<FsContent> FFSqlitedb = null; ResultSet rs = null; try { rs = tskCase.runQuery(query + allFS); FFSqlitedb = tskCase.resultSetToFsContents(rs); } catch (SQLException ex) { logger.log( Level.SEVERE, "Error while trying to extract files for:" + this.getClass().getName(), ex); this.addErrorMessage(this.getName() + ": Error while trying to extract files to analyze."); } finally { if (rs != null) { try { tskCase.closeRunQuery(rs); } catch (SQLException ex) { logger.log( Level.SEVERE, "Error while trying to close result set after extract files for:" + this.getClass().getName(), ex); } } } return FFSqlitedb; }
/** * Get a list of all the tag names. Uses a custom query for speed when dealing with thousands of * Tags. * * @return a list of all tag names. */ @SuppressWarnings("deprecation") public static List<String> getTagNames() { Case currentCase = Case.getCurrentCase(); SleuthkitCase skCase = currentCase.getSleuthkitCase(); List<String> names = new ArrayList<>(); ResultSet rs = null; try { rs = skCase.runQuery( "SELECT value_text" + " FROM blackboard_attributes" + " WHERE attribute_type_id = " + ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID() + " GROUP BY value_text" + " ORDER BY value_text"); while (rs.next()) { names.add(rs.getString("value_text")); } } catch (SQLException ex) { logger.log(Level.SEVERE, "Failed to query the blackboard for tag names."); } finally { if (rs != null) { try { skCase.closeRunQuery(rs); } catch (SQLException ex) { logger.log(Level.SEVERE, "Failed to close the query for blackboard for tag names."); } } } // add the 'Bookmark' tag, if it's not already in the list if (!names.contains(BOOKMARK_TAG_NAME)) { names.add(BOOKMARK_TAG_NAME); } return names; }
/** * Get the artifact for a result tag. * * @param tagArtifactId artifact id of the tag * @return the tag's artifact */ static BlackboardArtifact getArtifactFromTag(long tagArtifactId) { try { Case currentCase = Case.getCurrentCase(); SleuthkitCase skCase = currentCase.getSleuthkitCase(); BlackboardArtifact artifact = skCase.getBlackboardArtifact(tagArtifactId); if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID() || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID()) { List<BlackboardAttribute> attributes = artifact.getAttributes(); for (BlackboardAttribute att : attributes) { if (att.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID()) { return skCase.getBlackboardArtifact(att.getValueLong()); } } } } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Failed to get artifact " + tagArtifactId + " from case."); } return null; }
static Map<Long, String> getImagePaths(SleuthkitCase db) { // TODO: clean this up Map<Long, String> imgPaths = new HashMap<Long, String>(); try { Map<Long, List<String>> imgPathsList = db.getImagePaths(); for (Map.Entry<Long, List<String>> entry : imgPathsList.entrySet()) { if (entry.getValue().size() > 0) { imgPaths.put(entry.getKey(), entry.getValue().get(0)); } } } catch (TskException ex) { logger.log(Level.WARNING, "Error getting image paths", ex); } return imgPaths; }
private List<AbstractFile> runFsQuery() { List<AbstractFile> ret = new ArrayList<>(); try { String query = makeQuery(filter); ret = skCase.findAllFilesWhere(query); } catch (Exception e) { logger.log( Level.SEVERE, "Error getting files for the file size view: " + e.getMessage()); // NON-NLS } return ret; }
/** * Adds the image to the current case after it has been added to the DB Sends out event and * reopens windows if needed. * * @param imgPaths the paths of the image that being added * @param imgId the ID of the image that being added * @param timeZone the timeZone of the image where it's added */ Image addImage(String imgPath, long imgId, String timeZone) throws CaseActionException { logger.log( Level.INFO, "Adding image to Case. imgPath: {0} ID: {1} TimeZone: {2}", new Object[] {imgPath, imgId, timeZone}); try { Image newImage = db.getImageById(imgId); pcs.firePropertyChange( CASE_ADD_DATA_SOURCE, null, newImage); // the new value is the instance of the image CoreComponentControl.openCoreWindows(); return newImage; } catch (Exception ex) { throw new CaseActionException("Error adding image to the case", ex); } }
/** * Opens the existing case (open the XML config file) * * @param configFilePath the path of the configuration file that's opened * @throws CaseActionException */ static void open(String configFilePath) throws CaseActionException { logger.log(Level.INFO, "Opening case.\nconfigFilePath: {0}", configFilePath); try { XMLCaseManagement xmlcm = new XMLCaseManagement(); xmlcm.open( configFilePath); // open and load the config file to the document handler in the XML class xmlcm.writeFile(); // write any changes to the config file String caseName = xmlcm.getCaseName(); String caseNumber = xmlcm.getCaseNumber(); String examiner = xmlcm.getCaseExaminer(); // if the caseName is "", case / config file can't be opened if (caseName.equals("")) { throw new CaseActionException("Case name is blank."); } String caseDir = xmlcm.getCaseDirectory(); String dbPath = caseDir + File.separator + "autopsy.db"; SleuthkitCase db = SleuthkitCase.openCase(dbPath); checkImagesExist(db); Case openedCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db); changeCase(openedCase); } catch (Exception ex) { logger.log(Level.SEVERE, "Error opening the case: ", ex); // close the previous case if there's any CaseCloseAction closeCase = SystemAction.get(CaseCloseAction.class); closeCase.actionPerformed(null); if (!configFilePath.endsWith(CASE_DOT_EXTENSION)) { throw new CaseActionException( "Check that you selected the correct case file (usually with " + CASE_DOT_EXTENSION + " extension)", ex); } else { throw new CaseActionException("Error opening the case", ex); } } }
@Override public synchronized ObservableResult evaluate() { setWarnings(""); if (obj.getAddressValue() == null) { return new ObservableResult( id, "AddressObject: No address value field found", // NON-NLS spacing, ObservableResult.ObservableState.INDETERMINATE, null); } String origAddressStr = obj.getAddressValue().getValue().toString(); // For now, we don't support "NONE" because it honestly doesn't seem like it // would ever appear in practice. if (((obj.getAddressValue().getApplyCondition() != null) && (obj.getAddressValue().getApplyCondition() == ConditionApplicationEnum.NONE))) { return new ObservableResult( id, "AddressObject: Can not process apply condition " + obj.getAddressValue().getApplyCondition().toString() // NON-NLS + " on Address object", spacing, ObservableResult.ObservableState.INDETERMINATE, null); // NON-NLS } // Set warnings for any unsupported fields setUnsupportedFieldWarnings(); Case case1 = Case.getCurrentCase(); SleuthkitCase sleuthkitCase = case1.getSleuthkitCase(); try { // Need to check that every part of the string had at least one match // in the AND case boolean everyPartMatched = true; List<BlackboardArtifact> combinedArts = new ArrayList<BlackboardArtifact>(); String searchString = ""; String[] parts = origAddressStr.split("##comma##"); // NON-NLS for (String addressStr : parts) { // Update the string to show in the results if (!searchString.isEmpty()) { if ((obj.getAddressValue().getApplyCondition() != null) && (obj.getAddressValue().getApplyCondition() == ConditionApplicationEnum.ALL)) { searchString += " AND "; // NON-NLS } else { searchString += " OR "; // NON-NLS } } searchString += addressStr; if ((obj.getAddressValue().getCondition() == null) || (obj.getAddressValue().getCondition() == ConditionTypeEnum.EQUALS)) { List<BlackboardArtifact> arts = sleuthkitCase.getBlackboardArtifacts( BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, addressStr); if (arts.isEmpty()) { everyPartMatched = false; } else { combinedArts.addAll(arts); } } else { // This is inefficient, but the easiest way to do it. List<BlackboardArtifact> finalHits = new ArrayList<BlackboardArtifact>(); // Get all the URL artifacts List<BlackboardArtifact> artList = sleuthkitCase.getBlackboardArtifacts( BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT); for (BlackboardArtifact art : artList) { for (BlackboardAttribute attr : art.getAttributes()) { if (attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) { if (compareStringObject( addressStr, obj.getAddressValue().getCondition(), obj.getAddressValue().getApplyCondition(), attr.getValueString())) { finalHits.add(art); } } } } if (finalHits.isEmpty()) { everyPartMatched = false; } else { combinedArts.addAll(finalHits); } } } // If we're in the ALL case, make sure every piece matched if ((obj.getAddressValue().getApplyCondition() != null) && (obj.getAddressValue().getApplyCondition() == ConditionApplicationEnum.ALL) && (!everyPartMatched)) { return new ObservableResult( id, "AddressObject: No matches for " + searchString, // NON-NLS spacing, ObservableResult.ObservableState.FALSE, null); } if (!combinedArts.isEmpty()) { List<StixArtifactData> artData = new ArrayList<StixArtifactData>(); for (BlackboardArtifact a : combinedArts) { artData.add(new StixArtifactData(a.getObjectID(), id, "AddressObject")); // NON-NLS } return new ObservableResult( id, "AddressObject: Found a match for " + searchString, // NON-NLS spacing, ObservableResult.ObservableState.TRUE, artData); } return new ObservableResult( id, "AddressObject: Found no matches for " + searchString, // NON-NLS spacing, ObservableResult.ObservableState.FALSE, null); } catch (TskCoreException ex) { return new ObservableResult( id, "AddressObject: Exception during evaluation: " + ex.getLocalizedMessage(), // NON-NLS spacing, ObservableResult.ObservableState.INDETERMINATE, null); } }
public List<Image> getImages() throws TskCoreException { return db.getImages(); }