mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
continued work to parse ranges.csv and then use it validate and enrich Accounts
This commit is contained in:
parent
a3508ad064
commit
349310aab8
1
.gitignore
vendored
1
.gitignore
vendored
@ -76,3 +76,4 @@ Core/src/org/sleuthkit/autopsy/casemodule/docs/screenshot.png
|
|||||||
/test/script/*/*.xml
|
/test/script/*/*.xml
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.*.swp
|
.*.swp
|
||||||
|
KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/.~lock.ranges.csv#
|
||||||
|
@ -1,93 +1,89 @@
|
|||||||
package org.sleuthkit.autopsy.keywordsearch;
|
package org.sleuthkit.autopsy.keywordsearch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Representation of a range of Issuer Identifiaction Numbers for the same bank.
|
* Representation of a range of Issuer/Bank Identifiaction Numbers (IIN/BIN) for
|
||||||
|
* the * same bank.
|
||||||
*/
|
*/
|
||||||
public class IINRange {
|
class IINRange {
|
||||||
|
|
||||||
private final int IIN_start;
|
private final int IINStart;
|
||||||
private final int IIN_end;
|
private final int IINEnd;
|
||||||
private final int number_length;
|
private final int numberLength;
|
||||||
private final CreditCardScheme scheme;
|
private final PaymentCardScheme scheme;
|
||||||
private final String brand;
|
private final String brand;
|
||||||
private final PaymentCardType type;
|
private final PaymentCardType type;
|
||||||
|
|
||||||
private final String country;
|
private final String country;
|
||||||
private final String bank_name;
|
private final String bankName;
|
||||||
private final String bank_logo;
|
private final String bankURL;
|
||||||
private final String bank_url;
|
private final String bankPhoneNumber;
|
||||||
private final String bank_phone;
|
private final String bankCity;
|
||||||
private final String bank_city;
|
|
||||||
|
|
||||||
enum PaymentCardType {
|
enum PaymentCardType {
|
||||||
DEBIT, DREDIT;
|
DEBIT, DREDIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CreditCardScheme {
|
enum PaymentCardScheme {
|
||||||
AMEX, VISA, MASTERCARD, DINERS, DISCOVER
|
AMEX, VISA, MASTERCARD, DINERS, DISCOVER
|
||||||
}
|
}
|
||||||
|
|
||||||
IINRange(int IIN_start, int IIN_end, int number_length, CreditCardScheme scheme, String brand, PaymentCardType type, String country, String bank_name, String bank_logo, String bank_url, String bank_phone, String bank_city) {
|
IINRange(int IIN_start, int IIN_end, int number_length, PaymentCardScheme scheme, String brand, PaymentCardType type, String country, String bank_name, String bank_url, String bank_phone, String bank_city) {
|
||||||
this.IIN_start = IIN_start;
|
this.IINStart = IIN_start;
|
||||||
this.IIN_end = IIN_end;
|
this.IINEnd = IIN_end;
|
||||||
this.number_length = number_length;
|
this.numberLength = number_length;
|
||||||
this.scheme = scheme;
|
this.scheme = scheme;
|
||||||
this.brand = brand;
|
this.brand = brand;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.country = country;
|
this.country = country;
|
||||||
this.bank_name = bank_name;
|
this.bankName = bank_name;
|
||||||
this.bank_logo = bank_logo;
|
|
||||||
this.bank_url = bank_url;
|
this.bankURL = bank_url;
|
||||||
this.bank_phone = bank_phone;
|
this.bankPhoneNumber = bank_phone;
|
||||||
this.bank_city = bank_city;
|
this.bankCity = bank_city;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIIN_start() {
|
int getIINstart() {
|
||||||
return IIN_start;
|
return IINStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIIN_end() {
|
int getIINend() {
|
||||||
return IIN_end;
|
return IINEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNumber_length() {
|
int getNumber_length() {
|
||||||
return number_length;
|
return numberLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreditCardScheme getScheme() {
|
PaymentCardScheme getPaymentCardScheme() {
|
||||||
return scheme;
|
return scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBrand() {
|
String getBrand() {
|
||||||
return brand;
|
return brand;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PaymentCardType getType() {
|
PaymentCardType getPaymentCardType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCountry() {
|
String getCountry() {
|
||||||
return country;
|
return country;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBank_name() {
|
String getBankName() {
|
||||||
return bank_name;
|
return bankName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBank_logo() {
|
String getBankURL() {
|
||||||
return bank_logo;
|
return bankURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBank_url() {
|
String getBankPhoneNumber() {
|
||||||
return bank_url;
|
return bankPhoneNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBank_phone() {
|
String getBankCity() {
|
||||||
return bank_phone;
|
return bankCity;
|
||||||
}
|
|
||||||
|
|
||||||
public String getBank_city() {
|
|
||||||
return bank_city;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,12 @@ import org.apache.commons.csv.CSVRecord;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public class IINValidator {
|
public class IINValidator {
|
||||||
|
|
||||||
RangeMap<Integer, IINRange> iinRanges = TreeRangeMap.create();
|
RangeMap<Integer, IINRange> iinRanges = TreeRangeMap.create();
|
||||||
private IINValidator() throws FileNotFoundException, IOException {
|
|
||||||
|
IINValidator() throws FileNotFoundException, IOException {
|
||||||
Reader in = new FileReader("ranges.csv");
|
Reader in = new FileReader("ranges.csv");
|
||||||
Iterable<CSVRecord> records = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(in);
|
Iterable<CSVRecord> records = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(in);
|
||||||
for (CSVRecord record : records) {
|
for (CSVRecord record : records) {
|
||||||
@ -30,18 +30,24 @@ public class IINValidator {
|
|||||||
IINRange iinRange = new IINRange(Integer.parseInt(record.get("iin_start")),
|
IINRange iinRange = new IINRange(Integer.parseInt(record.get("iin_start")),
|
||||||
Integer.parseInt(record.get("iin_end")),
|
Integer.parseInt(record.get("iin_end")),
|
||||||
Integer.parseInt(record.get("number_length")),
|
Integer.parseInt(record.get("number_length")),
|
||||||
IINRange.CreditCardScheme.valueOf(record.get("scheme")),
|
IINRange.PaymentCardScheme.valueOf(record.get("scheme")),
|
||||||
record.get("brand"),
|
record.get("brand"),
|
||||||
IINRange.PaymentCardType.valueOf(record.get("type")),
|
IINRange.PaymentCardType.valueOf(record.get("type")),
|
||||||
record.get("country"),
|
record.get("country"),
|
||||||
record.get("bank_name"),
|
record.get("bank_name"),
|
||||||
record.get("bank_logo"),
|
|
||||||
record.get("bank_url"),
|
record.get("bank_url"),
|
||||||
record.get("bank_phone"),
|
record.get("bank_phone"),
|
||||||
record.get("bank_city"));
|
record.get("bank_city"));
|
||||||
|
|
||||||
iinRanges.put(Range.closed(iinRange.getIIN_start(), iinRange.getIIN_end()), iinRange);
|
iinRanges.put(Range.closed(iinRange.getIINstart(), iinRange.getIINend()), iinRange);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean contains(int iin) {
|
||||||
|
return iinRanges.get(iin) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
IINRange getIINRange(int iin) {
|
||||||
|
return iinRanges.get(iin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
//
|
//
|
||||||
package org.sleuthkit.autopsy.keywordsearch;
|
package org.sleuthkit.autopsy.keywordsearch;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -31,6 +32,7 @@ import org.apache.commons.lang.StringUtils;
|
|||||||
import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit;
|
import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit;
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
import org.apache.solr.client.solrj.response.TermsResponse.Term;
|
import org.apache.solr.client.solrj.response.TermsResponse.Term;
|
||||||
|
import org.openide.util.Exceptions;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.Version;
|
import org.sleuthkit.autopsy.coreutils.Version;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
@ -51,6 +53,7 @@ final class TermComponentQuery implements KeywordSearchQuery {
|
|||||||
|
|
||||||
private static final String MODULE_NAME = KeywordSearchModuleFactory.getModuleName();
|
private static final String MODULE_NAME = KeywordSearchModuleFactory.getModuleName();
|
||||||
private static final BlackboardAttribute.Type SOLR_DOCUMENT_ID_TYPE = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SOLR_DOCUMENT_ID);
|
private static final BlackboardAttribute.Type SOLR_DOCUMENT_ID_TYPE = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SOLR_DOCUMENT_ID);
|
||||||
|
private static final BlackboardAttribute.Type ACCOUNT_NUMBER_TYPE = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_ACCOUNT_NUMBER);
|
||||||
|
|
||||||
//TODO: move these regex and the luhn check to a new class, something like: CreditCardNumberValidator
|
//TODO: move these regex and the luhn check to a new class, something like: CreditCardNumberValidator
|
||||||
/*
|
/*
|
||||||
@ -108,9 +111,19 @@ final class TermComponentQuery implements KeywordSearchQuery {
|
|||||||
private final Keyword keyword;
|
private final Keyword keyword;
|
||||||
private boolean isEscaped;
|
private boolean isEscaped;
|
||||||
private final List<KeywordQueryFilter> filters = new ArrayList<>();
|
private final List<KeywordQueryFilter> filters = new ArrayList<>();
|
||||||
|
private IINValidator iinValidator;
|
||||||
|
|
||||||
TermComponentQuery(KeywordList keywordList, Keyword keyword) {
|
TermComponentQuery(KeywordList keywordList, Keyword keyword) {
|
||||||
this.keyword = keyword;
|
this.keyword = keyword;
|
||||||
|
|
||||||
|
if (keyword.getType() == ATTRIBUTE_TYPE.TSK_ACCOUNT_NUMBER) {
|
||||||
|
try {
|
||||||
|
iinValidator = new IINValidator();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.keywordList = keywordList;
|
this.keywordList = keywordList;
|
||||||
this.escapedQuery = keyword.getQuery();
|
this.escapedQuery = keyword.getQuery();
|
||||||
}
|
}
|
||||||
@ -177,33 +190,59 @@ final class TermComponentQuery implements KeywordSearchQuery {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeywordCachedArtifact writeSingleFileHitsToBlackBoard(String termHit, KeywordHit hit, String snippet, String listName) {
|
public KeywordCachedArtifact writeSingleFileHitsToBlackBoard(String termHit, KeywordHit hit, String snippet, String listName) {
|
||||||
BlackboardArtifact bba;
|
BlackboardArtifact newArtifact;
|
||||||
Collection<BlackboardAttribute> attributes = new ArrayList<>();
|
Collection<BlackboardAttribute> attributes = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
//if the keyword hit matched the credit card number keyword/regex...
|
//if the keyword hit matched the credit card number keyword/regex...
|
||||||
if (keyword.getType() == ATTRIBUTE_TYPE.TSK_ACCOUNT_NUMBER) {
|
if (keyword.getType() == ATTRIBUTE_TYPE.TSK_ACCOUNT_NUMBER) {
|
||||||
bba = hit.getContent().newArtifact(ARTIFACT_TYPE.TSK_CREDIT_CARD_ACCOUNT);
|
newArtifact = hit.getContent().newArtifact(ARTIFACT_TYPE.TSK_CREDIT_CARD_ACCOUNT);
|
||||||
// make account artifact
|
// make account artifact
|
||||||
//try to match it against the track 1 regex
|
//try to match it against the track 1 regex
|
||||||
Matcher matcher = TRACK1_PATTERN.matcher(hit.getSnippet());
|
Matcher matcher = TRACK1_PATTERN.matcher(hit.getSnippet());
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
parseTrack1Data(bba, matcher);
|
parseTrack1Data(newArtifact, matcher);
|
||||||
}
|
}
|
||||||
//then try to match it against the track 2 regex
|
//then try to match it against the track 2 regex
|
||||||
matcher = TRACK2_PATTERN.matcher(hit.getSnippet());
|
matcher = TRACK2_PATTERN.matcher(hit.getSnippet());
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
parseTrack2Data(bba, matcher);
|
parseTrack2Data(newArtifact, matcher);
|
||||||
}
|
}
|
||||||
if (hit.getContent() instanceof AbstractFile) {
|
if (hit.getContent() instanceof AbstractFile) {
|
||||||
AbstractFile file = (AbstractFile) hit.getContent();
|
AbstractFile file = (AbstractFile) hit.getContent();
|
||||||
if (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS
|
if (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS
|
||||||
|| file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) {
|
|| file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) {
|
||||||
bba.addAttribute(new BlackboardAttribute(SOLR_DOCUMENT_ID_TYPE, MODULE_NAME, hit.getSolrDocumentId()));
|
newArtifact.addAttribute(new BlackboardAttribute(SOLR_DOCUMENT_ID_TYPE, MODULE_NAME, hit.getSolrDocumentId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String ccn = newArtifact.getAttribute(ACCOUNT_NUMBER_TYPE).getValueString();
|
||||||
|
final int iin = Integer.parseInt(ccn.substring(0, 7));
|
||||||
|
|
||||||
|
IINRange iinRange = iinValidator.getIINRange(iin);
|
||||||
|
newArtifact.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CREDIT_CARD_SCHEME, MODULE_NAME, iinRange.getPaymentCardScheme().name()));
|
||||||
|
newArtifact.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PAYMENT_CARD_TYPE, MODULE_NAME, iinRange.getPaymentCardType().name()));
|
||||||
|
if (StringUtils.isNotBlank(iinRange.getBrand())) {
|
||||||
|
newArtifact.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_BRAND, MODULE_NAME, iinRange.getBrand()));
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(iinRange.getBankName())) {
|
||||||
|
newArtifact.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_BANK_NAME, MODULE_NAME, iinRange.getBankName()));
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(iinRange.getBankPhoneNumber())) {
|
||||||
|
newArtifact.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, MODULE_NAME, iinRange.getBankPhoneNumber()));
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(iinRange.getBankURL())) {
|
||||||
|
newArtifact.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL, MODULE_NAME, iinRange.getBankURL()));
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(iinRange.getCountry())) {
|
||||||
|
newArtifact.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNTRY, MODULE_NAME, iinRange.getCountry()));
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(iinRange.getBankCity())) {
|
||||||
|
newArtifact.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CITY, MODULE_NAME, iinRange.getBankCity()));
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//make keyword hit artifact
|
//make keyword hit artifact
|
||||||
bba = hit.getContent().newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT);
|
newArtifact = hit.getContent().newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT);
|
||||||
|
|
||||||
//regex match
|
//regex match
|
||||||
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, termHit));
|
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, termHit));
|
||||||
@ -229,8 +268,8 @@ final class TermComponentQuery implements KeywordSearchQuery {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
//TODO: do we still/really need this KeywordCachedArtifact class?
|
//TODO: do we still/really need this KeywordCachedArtifact class?
|
||||||
bba.addAttributes(attributes);
|
newArtifact.addAttributes(attributes);
|
||||||
KeywordCachedArtifact writeResult = new KeywordCachedArtifact(bba);
|
KeywordCachedArtifact writeResult = new KeywordCachedArtifact(newArtifact);
|
||||||
writeResult.add(attributes);
|
writeResult.add(attributes);
|
||||||
return writeResult;
|
return writeResult;
|
||||||
} catch (TskCoreException e) {
|
} catch (TskCoreException e) {
|
||||||
@ -273,6 +312,7 @@ final class TermComponentQuery implements KeywordSearchQuery {
|
|||||||
*/
|
*/
|
||||||
QueryResults results = new QueryResults(this, keywordList);
|
QueryResults results = new QueryResults(this, keywordList);
|
||||||
int resultSize = 0;
|
int resultSize = 0;
|
||||||
|
|
||||||
for (Term term : terms) {
|
for (Term term : terms) {
|
||||||
final String termStr = KeywordSearchUtil.escapeLuceneQuery(term.getTerm());
|
final String termStr = KeywordSearchUtil.escapeLuceneQuery(term.getTerm());
|
||||||
|
|
||||||
@ -280,9 +320,15 @@ final class TermComponentQuery implements KeywordSearchQuery {
|
|||||||
//If the keyword is a credit card number, pass it through luhn validator
|
//If the keyword is a credit card number, pass it through luhn validator
|
||||||
Matcher matcher = CCN_PATTERN.matcher(term.getTerm());
|
Matcher matcher = CCN_PATTERN.matcher(term.getTerm());
|
||||||
matcher.find();
|
matcher.find();
|
||||||
if (false == LUHN_CHECK.isValid(matcher.group("ccn"))) {
|
final String ccn = matcher.group("ccn");
|
||||||
|
if (false == LUHN_CHECK.isValid(ccn)) {
|
||||||
continue; //if the hit does not pass the luhn check, skip it.
|
continue; //if the hit does not pass the luhn check, skip it.
|
||||||
}
|
}
|
||||||
|
final int iin = Integer.parseInt(ccn.substring(0, 7));
|
||||||
|
|
||||||
|
if (false == iinValidator.contains(iin)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user