Skip to content

Commit 1d4c810

Browse files
authored
Merge pull request #512 from MShwed/feature/extract-hashes
2 parents ccd3839 + d2bd397 commit 1d4c810

File tree

4 files changed

+163
-0
lines changed

4 files changed

+163
-0
lines changed

src/core/config/Categories.json

+1
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@
338338
"Extract domains",
339339
"Extract file paths",
340340
"Extract dates",
341+
"Extract hashes",
341342
"Regular expression",
342343
"XPath expression",
343344
"JPath expression",

src/core/operations/ExtractHashes.mjs

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* @author mshwed [[email protected]]
3+
* @copyright Crown Copyright 2019
4+
* @license Apache-2.0
5+
*/
6+
7+
import Operation from "../Operation.mjs";
8+
import { search } from "../lib/Extract.mjs";
9+
10+
/**
11+
* Extract Hash Values operation
12+
*/
13+
class ExtractHashes extends Operation {
14+
15+
/**
16+
* ExtractHashValues constructor
17+
*/
18+
constructor() {
19+
super();
20+
21+
this.name = "Extract hashes";
22+
this.module = "Regex";
23+
this.description = "Extracts potential hashes based on hash character length";
24+
this.infoURL = "https://en.wikipedia.org/wiki/Comparison_of_cryptographic_hash_functions";
25+
this.inputType = "string";
26+
this.outputType = "string";
27+
this.args = [
28+
{
29+
name: "Hash character length",
30+
type: "number",
31+
value: 40
32+
},
33+
{
34+
name: "All hashes",
35+
type: "boolean",
36+
value: false
37+
},
38+
{
39+
name: "Display Total",
40+
type: "boolean",
41+
value: false
42+
}
43+
];
44+
}
45+
46+
/**
47+
* @param {string} input
48+
* @param {Object[]} args
49+
* @returns {string}
50+
*/
51+
run(input, args) {
52+
const results = [];
53+
let hashCount = 0;
54+
55+
const [hashLength, searchAllHashes, showDisplayTotal] = args;
56+
57+
// Convert character length to bit length
58+
let hashBitLengths = [(hashLength / 2) * 8];
59+
60+
if (searchAllHashes) hashBitLengths = [4, 8, 16, 32, 64, 128, 160, 192, 224, 256, 320, 384, 512, 1024];
61+
62+
for (const hashBitLength of hashBitLengths) {
63+
// Convert bit length to character length
64+
const hashCharacterLength = (hashBitLength / 8) * 2;
65+
66+
const regex = new RegExp(`(\\b|^)[a-f0-9]{${hashCharacterLength}}(\\b|$)`, "g");
67+
const searchResults = search(input, regex, null, false);
68+
69+
hashCount += searchResults.length;
70+
results.push(...searchResults);
71+
}
72+
73+
let output = "";
74+
if (showDisplayTotal) {
75+
output = `Total Results: ${hashCount}\n\n`;
76+
}
77+
78+
output = output + results.join("\n");
79+
return output;
80+
}
81+
82+
}
83+
84+
export default ExtractHashes;

tests/operations/index.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import "./tests/DefangIP.mjs";
6262
import "./tests/ELFInfo.mjs";
6363
import "./tests/Enigma.mjs";
6464
import "./tests/ExtractEmailAddresses.mjs";
65+
import "./tests/ExtractHashes.mjs";
6566
import "./tests/Float.mjs";
6667
import "./tests/FileTree.mjs";
6768
import "./tests/FletcherChecksum.mjs";
+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* ExtractHashes tests.
3+
*
4+
* @author mshwed [[email protected]]
5+
* @copyright Crown Copyright 2024
6+
* @license Apache-2.0
7+
*/
8+
import TestRegister from "../../lib/TestRegister.mjs";
9+
10+
TestRegister.addTests([
11+
{
12+
name: "Extract MD5 hash",
13+
input: "The quick brown fox jumps over the lazy dog\n\nMD5: 9e107d9d372bb6826bd81d3542a419d6",
14+
expectedOutput: "9e107d9d372bb6826bd81d3542a419d6",
15+
recipeConfig: [
16+
{
17+
"op": "Extract hashes",
18+
"args": [32, false, false]
19+
},
20+
],
21+
},
22+
{
23+
name: "Extract SHA1 hash",
24+
input: "The quick brown fox jumps over the lazy dog\n\nSHA1: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
25+
expectedOutput: "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
26+
recipeConfig: [
27+
{
28+
"op": "Extract hashes",
29+
"args": [40, false, false]
30+
},
31+
],
32+
},
33+
{
34+
name: "Extract SHA256 hash",
35+
input: "The quick brown fox jumps over the lazy dog\n\nSHA256: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
36+
expectedOutput: "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
37+
recipeConfig: [
38+
{
39+
"op": "Extract hashes",
40+
"args": [64, false, false]
41+
},
42+
],
43+
},
44+
{
45+
name: "Extract SHA512 hash",
46+
input: "The quick brown fox jumps over the lazy dog\n\nSHA512: 07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6",
47+
expectedOutput: "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6",
48+
recipeConfig: [
49+
{
50+
"op": "Extract hashes",
51+
"args": [128, false, false]
52+
},
53+
],
54+
},
55+
{
56+
name: "Extract all hashes",
57+
input: "The quick brown fox jumps over the lazy dog\n\nMD5: 9e107d9d372bb6826bd81d3542a419d6\nSHA1: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\nSHA256: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
58+
expectedOutput: "9e107d9d372bb6826bd81d3542a419d6\n2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\nd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
59+
recipeConfig: [
60+
{
61+
"op": "Extract hashes",
62+
"args": [0, true, false]
63+
},
64+
],
65+
},
66+
{
67+
name: "Extract hashes with total count",
68+
input: "The quick brown fox jumps over the lazy dog\n\nMD5: 9e107d9d372bb6826bd81d3542a419d6\nSHA1: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\nSHA256: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
69+
expectedOutput: "Total Results: 3\n\n9e107d9d372bb6826bd81d3542a419d6\n2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\nd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
70+
recipeConfig: [
71+
{
72+
"op": "Extract hashes",
73+
"args": [0, true, true]
74+
},
75+
],
76+
}
77+
]);

0 commit comments

Comments
 (0)