/** * Adds a new hash database to the set of hash databases used to classify files as known or known * bad and saves the configuration. * * @param hashSetName Hash set name used to represent the hash database in user interface * components. * @param path Full path to the database file to be created. * @param searchDuringIngest A flag indicating whether or not the hash database should be searched * during ingest. * @param sendIngestMessages A flag indicating whether hash set hit messages should be sent as * ingest messages. * @param knownFilesType The classification to apply to files whose hashes are found in the hash * database. * @return A HashDb representing the hash database. * @throws HashDbManagerException */ public HashDb addNewHashDatabase( String hashSetName, String path, boolean searchDuringIngest, boolean sendIngestMessages, HashDb.KnownFilesType knownFilesType) throws HashDbManagerException { HashDb hashDb = null; try { hashDb = addNewHashDatabaseInternal( hashSetName, path, searchDuringIngest, sendIngestMessages, knownFilesType); } catch (TskCoreException ex) { throw new HashDbManagerException(ex.getMessage()); } // Save the configuration if (!save()) { throw new HashDbManagerException( NbBundle.getMessage(this.getClass(), "HashDbManager.saveErrorExceptionMsg")); } return hashDb; }
@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()); } } } }
@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); } }
/** * Test the Registry object against one registry file. * * @param a_regInfo The registry file * @return Result of the test */ private ObservableResult testRegistryFile(RegistryFileInfo a_regInfo) { try { RegistryKey root = openRegistry(a_regInfo.tempFileName); RegistryKey result = findKey(root, obj.getKey().getValue().toString()); if (result == null) { // Take another shot looking for the key minus the first part of the path (sometimes the // hive file name is here). This should only happen if the hive name started // with "HKEY" if ((obj.getHive() != null) && obj.getHive().getValue().toString().startsWith("HKEY")) { // NON-NLS String[] parts = obj.getKey().getValue().toString().split("\\\\"); String newKey = ""; for (int i = 1; i < parts.length; i++) { if (newKey.length() > 0) { newKey += "\\"; } newKey += parts[i]; } result = findKey(root, newKey); } if (result == null) { return new ObservableResult( id, "RegistryObject: Could not find key " + obj.getKey().getValue(), // NON-NLS spacing, ObservableResult.ObservableState.FALSE, null); } } if ((obj.getValues() == null) || (obj.getValues().getValues().isEmpty())) { // No values to test List<StixArtifactData> artData = new ArrayList<StixArtifactData>(); artData.add( new StixArtifactData(a_regInfo.abstractFile.getId(), id, "Registry")); // NON-NLS return new ObservableResult( id, "RegistryObject: Found key " + obj.getKey().getValue(), // NON-NLS spacing, ObservableResult.ObservableState.TRUE, artData); } // Test all the values for (org.mitre.cybox.objects.RegistryValueType stixRegValue : obj.getValues().getValues()) { try { for (RegistryValue valFromFile : result.getValueList()) { // Test if the name field matches (if present) boolean nameSuccess = true; // True if the name matches or isn't present if (stixRegValue.getName() != null) { try { nameSuccess = compareStringObject(stixRegValue.getName(), valFromFile.getName()); } catch (UnsupportedEncodingException ex) { nameSuccess = false; } } boolean valueSuccess = true; if (nameSuccess && (stixRegValue.getData() != null)) { switch (valFromFile.getValueType()) { case REG_SZ: case REG_EXPAND_SZ: try { valueSuccess = compareStringObject( stixRegValue.getData(), valFromFile.getValue().getAsString()); } catch (UnsupportedEncodingException ex) { valueSuccess = false; } break; case REG_DWORD: case REG_BIG_ENDIAN: case REG_QWORD: // Only support "equals" for now. if ((stixRegValue.getData().getCondition() == null) || (stixRegValue.getData().getCondition() == ConditionTypeEnum.EQUALS)) { // Try to convert the STIX string to a long try { long stixValue = Long.decode(stixRegValue.getData().getValue().toString()); try { valueSuccess = (stixValue == valFromFile.getValue().getAsNumber()); } catch (UnsupportedEncodingException ex) { valueSuccess = false; } } catch (NumberFormatException ex) { // We probably weren't looking at a numeric field to begin with, // so getting this exception isn't really an error. valueSuccess = false; } } else { valueSuccess = false; } break; default: // Nothing to do here. These are the types we don't handle: // REG_BIN, REG_FULL_RESOURCE_DESCRIPTOR, REG_LINK, REG_MULTI_SZ, REG_NONE, // REG_RESOURCE_LIST, REG_RESOURCE_REQUIREMENTS_LIST } } if (nameSuccess && valueSuccess) { // Found a match for all values List<StixArtifactData> artData = new ArrayList<StixArtifactData>(); artData.add( new StixArtifactData(a_regInfo.abstractFile.getId(), id, "Registry")); // NON-NLS return new ObservableResult( id, "RegistryObject: Found key " + obj.getKey().getValue() // NON-NLS + " and value " + stixRegValue.getName().getValue().toString() // NON-NLS + " = " + stixRegValue.getData().getValue().toString(), spacing, ObservableResult.ObservableState.TRUE, artData); } } } catch (Exception ex) { // Broad catch here becase the registry parser can create all kinds of exceptions beyond // what it reports. return new ObservableResult( id, "RegistryObject: Exception during evaluation: " + ex.getLocalizedMessage(), // NON-NLS spacing, ObservableResult.ObservableState.INDETERMINATE, null); } } } catch (TskCoreException ex) { return new ObservableResult( id, "RegistryObject: Exception during evaluation: " + ex.getLocalizedMessage(), // NON-NLS spacing, ObservableResult.ObservableState.INDETERMINATE, null); } return new ObservableResult( id, "RegistryObject: Not done", // NON-NLS spacing, ObservableResult.ObservableState.INDETERMINATE, null); }