Merge a2adf40bf8fdef36ba696478df70b7adeae59b17 into 4290ea753912378913b1f3f54e0fc5720afeda5d
This commit is contained in:
commit
dccb475f65
@ -300,7 +300,10 @@
|
||||
"Decode NetBIOS Name",
|
||||
"Defang URL",
|
||||
"Fang URL",
|
||||
"Defang IP Addresses"
|
||||
"Defang IP Addresses",
|
||||
"Fang IP Addresses",
|
||||
"Defang email addresses",
|
||||
"Fang email addresses"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
85
src/core/operations/DefangEmailAddresses.mjs
Normal file
85
src/core/operations/DefangEmailAddresses.mjs
Normal file
@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @author Collin Laney [collin.laney@coldogstudios.com]
|
||||
* @copyright Crown Copyright 2026
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import {EMAIL_REGEX} from "../lib/Extract.mjs";
|
||||
|
||||
/**
|
||||
* Defang email addresses operation
|
||||
*/
|
||||
class DefangEmailAddresses extends Operation {
|
||||
|
||||
/**
|
||||
* DefangEmailAddresses constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Defang email addresses";
|
||||
this.module = "Default";
|
||||
this.description = "Takes email addresses and 'Defangs' them, meaning the addresses become invalid, removing the risk of accidentally using them as email links or indicators.";
|
||||
this.infoURL = "https://isc.sans.edu/forums/diary/Defang+all+the+things/22744/";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Escape @",
|
||||
type: "boolean",
|
||||
value: true
|
||||
},
|
||||
{
|
||||
name: "Escape dots",
|
||||
type: "boolean",
|
||||
value: true
|
||||
},
|
||||
{
|
||||
name: "Process",
|
||||
type: "option",
|
||||
value: ["Valid email addresses", "Everything"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [at, dots, process] = args;
|
||||
|
||||
switch (process) {
|
||||
case "Valid email addresses":
|
||||
input = input.replace(EMAIL_REGEX, x => {
|
||||
return defangEmailAddress(x, at, dots);
|
||||
});
|
||||
break;
|
||||
case "Everything":
|
||||
input = defangEmailAddress(input, at, dots);
|
||||
break;
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Defangs a given email address
|
||||
*
|
||||
* @param {string} email
|
||||
* @param {boolean} at
|
||||
* @param {boolean} dots
|
||||
* @returns {string}
|
||||
*/
|
||||
function defangEmailAddress(email, at, dots) {
|
||||
if (at) email = email.replace(/@/g, "[@]");
|
||||
if (dots) email = email.replace(/\./g, "[.]");
|
||||
|
||||
return email;
|
||||
}
|
||||
|
||||
export default DefangEmailAddresses;
|
||||
68
src/core/operations/FangEmailAddresses.mjs
Normal file
68
src/core/operations/FangEmailAddresses.mjs
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @author Collin Laney [collin.laney@coldogstudios.com]
|
||||
* @copyright Crown Copyright 2026
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
|
||||
/**
|
||||
* Fang email addresses operation
|
||||
*/
|
||||
class FangEmailAddresses extends Operation {
|
||||
|
||||
/**
|
||||
* FangEmailAddresses constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Fang email addresses";
|
||||
this.module = "Default";
|
||||
this.description = "Takes 'Defanged' email addresses and 'Fangs' them, restoring the alterations that made them invalid.";
|
||||
this.infoURL = "https://isc.sans.edu/forums/diary/Defang+all+the+things/22744/";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Restore [@] and [at]",
|
||||
type: "boolean",
|
||||
value: true
|
||||
},
|
||||
{
|
||||
name: "Restore [.]",
|
||||
type: "boolean",
|
||||
value: true
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [at, dots] = args;
|
||||
|
||||
return fangEmailAddress(input, at, dots);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fangs a given email address
|
||||
*
|
||||
* @param {string} email
|
||||
* @param {boolean} at
|
||||
* @param {boolean} dots
|
||||
* @returns {string}
|
||||
*/
|
||||
function fangEmailAddress(email, at, dots) {
|
||||
if (at) email = email.replace(/\[@\]|\[at\]/gi, "@");
|
||||
if (dots) email = email.replace(/\[\.\]/g, ".");
|
||||
|
||||
return email;
|
||||
}
|
||||
|
||||
export default FangEmailAddresses;
|
||||
72
src/core/operations/FangIPAddresses.mjs
Normal file
72
src/core/operations/FangIPAddresses.mjs
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @author Collin Laney [collin.laney@coldogstudios.com]
|
||||
* @copyright Crown Copyright 2026
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
|
||||
/**
|
||||
* Fang IP Addresses operation
|
||||
*/
|
||||
class FangIPAddresses extends Operation {
|
||||
|
||||
/**
|
||||
* FangIPAddresses constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Fang IP Addresses";
|
||||
this.module = "Default";
|
||||
this.description = "Takes 'Defanged' IPv4 or IPv6 addresses and 'Fangs' them, restoring the alterations that made them invalid.";
|
||||
this.infoURL = "https://isc.sans.edu/forums/diary/Defang+all+the+things/22744/";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Restore [.]",
|
||||
type: "boolean",
|
||||
value: true
|
||||
},
|
||||
{
|
||||
name: "Restore [:]",
|
||||
type: "boolean",
|
||||
value: true
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [dots, colons] = args;
|
||||
|
||||
input = input.replace(DEFANGED_IPV4_REGEX, x => {
|
||||
return dots ? x.replace(/\[\.\]/g, ".") : x;
|
||||
});
|
||||
|
||||
input = input.replace(DEFANGED_IPV6_REGEX, x => {
|
||||
return colons ? x.replace(/\[:\]/g, ":") : x;
|
||||
});
|
||||
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
export default FangIPAddresses;
|
||||
|
||||
|
||||
/**
|
||||
* Defanged IPv4 regular expression
|
||||
*/
|
||||
const DEFANGED_IPV4_REGEX = new RegExp("(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\[\\.\\]){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?", "g");
|
||||
|
||||
|
||||
/**
|
||||
* Defanged IPv6 regular expression
|
||||
*/
|
||||
const DEFANGED_IPV6_REGEX = new RegExp("(?:[\\dA-Fa-f]{0,4}\\[:\\]){2,7}[\\dA-Fa-f]{0,4}(?:\\/\\d{1,3})?", "g");
|
||||
43
tests/operations/tests/DefangEmail.mjs
Normal file
43
tests/operations/tests/DefangEmail.mjs
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Defang email address tests.
|
||||
*
|
||||
* @copyright Crown Copyright 2026
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Defang email addresses: valid email address",
|
||||
input: "Contact security@example.com for details.",
|
||||
expectedOutput: "Contact security[@]example[.]com for details.",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Defang email addresses",
|
||||
args: [true, true, "Valid email addresses"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Defang email addresses: multiple addresses",
|
||||
input: "one@example.com firstname.lastname@example.co.uk",
|
||||
expectedOutput: "one[@]example[.]com firstname[.]lastname[@]example[.]co[.]uk",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Defang email addresses",
|
||||
args: [true, true, "Valid email addresses"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Defang email addresses: everything",
|
||||
input: "Use @ and . anywhere",
|
||||
expectedOutput: "Use [@] and [.] anywhere",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Defang email addresses",
|
||||
args: [true, true, "Everything"],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
43
tests/operations/tests/FangEmail.mjs
Normal file
43
tests/operations/tests/FangEmail.mjs
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Fang email address tests.
|
||||
*
|
||||
* @copyright Crown Copyright 2026
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Fang email addresses: defanged email address",
|
||||
input: "Contact security[@]example[.]com for details.",
|
||||
expectedOutput: "Contact security@example.com for details.",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fang email addresses",
|
||||
args: [true, true],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Fang email addresses: defanged with [at]",
|
||||
input: "Contact security[at]example[.]com for details.",
|
||||
expectedOutput: "Contact security@example.com for details.",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fang email addresses",
|
||||
args: [true, true],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Fang email addresses: restore at only",
|
||||
input: "firstname[.]lastname[@]example[.]com",
|
||||
expectedOutput: "firstname[.]lastname@example[.]com",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fang email addresses",
|
||||
args: [true, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
61
tests/operations/tests/FangIP.mjs
Normal file
61
tests/operations/tests/FangIP.mjs
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Fang IP address tests.
|
||||
*
|
||||
* @copyright Crown Copyright 2026
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Fang IP: Valid IPV4",
|
||||
input: "192[.]168[.]1[.]1",
|
||||
expectedOutput: "192.168.1.1",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fang IP Addresses",
|
||||
args: [true, true],
|
||||
},
|
||||
],
|
||||
}, {
|
||||
name: "Fang IP: Valid IPV4 CIDR",
|
||||
input: "10[.]0[.]0[.]0/24",
|
||||
expectedOutput: "10.0.0.0/24",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fang IP Addresses",
|
||||
args: [true, true],
|
||||
},
|
||||
],
|
||||
}, {
|
||||
name: "Fang IP: Valid IPV6",
|
||||
input: "2001[:]0db8[:]85a3[:]0000[:]0000[:]8a2e[:]0370[:]7343",
|
||||
expectedOutput: "2001:0db8:85a3:0000:0000:8a2e:0370:7343",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fang IP Addresses",
|
||||
args: [true, true],
|
||||
},
|
||||
],
|
||||
}, {
|
||||
name: "Fang IP: Valid IPV6 Shorthand",
|
||||
input: "2001[:]db8[:]3c4d[:]15[:][:]1a2f[:]1a2b",
|
||||
expectedOutput: "2001:db8:3c4d:15::1a2f:1a2b",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fang IP Addresses",
|
||||
args: [true, true],
|
||||
},
|
||||
],
|
||||
}, {
|
||||
name: "Fang IP: Does not fang defanged domain",
|
||||
input: "example[.]com",
|
||||
expectedOutput: "example[.]com",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fang IP Addresses",
|
||||
args: [true, true],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
Loading…
x
Reference in New Issue
Block a user