Merge branch 'master' of github.com:gchq/CyberChef into expose-operationerror

This commit is contained in:
d98762625 2019-10-07 17:59:00 +01:00
commit bd6673afed
12 changed files with 1069 additions and 60 deletions

8
package-lock.json generated
View file

@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "9.7.1",
"version": "9.7.7",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -9461,9 +9461,9 @@
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
},
"node-forge": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.5.tgz",
"integrity": "sha512-vFMQIWt+J/7FLNyKouZ9TazT74PRV3wgv9UT4cRjC8BffxFbKXkgIWR42URCPSnHm/QDz6BOlb2Q0U4+VQT67Q=="
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz",
"integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ=="
},
"node-gyp": {
"version": "3.8.0",

View file

@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "9.7.1",
"version": "9.7.7",
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
"author": "n1474335 <n1474335@gmail.com>",
"homepage": "https://gchq.github.io/CyberChef",
@ -131,7 +131,7 @@
"moment": "^2.24.0",
"moment-timezone": "^0.5.26",
"ngeohash": "^0.6.3",
"node-forge": "^0.8.5",
"node-forge": "^0.9.1",
"node-md6": "^0.1.0",
"nodom": "^2.2.0",
"notepack.io": "^2.2.0",

File diff suppressed because it is too large Load diff

View file

@ -97,6 +97,7 @@ class Magic {
if (!fileType.length) return null;
return {
name: fileType[0].name,
ext: fileType[0].extension,
mime: fileType[0].mime,
desc: fileType[0].description

View file

@ -54,7 +54,7 @@ class ConvertDataUnits extends Operation {
const DATA_UNITS = [
"Bits (b)", "Nibbles", "Octets", "Bytes (B)",
"[Binary bits (2^n)]", "Kibibits (Kib)", "Mebibits (Mib)", "Gibibits (Gib)", "Tebibits (Tib)", "Pebibits (Pib)", "Exbibits (Eib)", "Zebibits (Zib)", "Yobibits (Yib)", "[/Binary bits (2^n)]",
"[Decimal bits (10^n)]", "Decabits", "Hectobits", "Kilobits (kb)", "Megabits (Mb)", "Gigabits (Gb)", "Terabits (Tb)", "Petabits (Pb)", "Exabits (Eb)", "Zettabits (Zb)", "Yottabits (Yb)", "[/Decimal bits (10^n)]",
"[Decimal bits (10^n)]", "Decabits", "Hectobits", "Kilobits (Kb)", "Megabits (Mb)", "Gigabits (Gb)", "Terabits (Tb)", "Petabits (Pb)", "Exabits (Eb)", "Zettabits (Zb)", "Yottabits (Yb)", "[/Decimal bits (10^n)]",
"[Binary bytes (8 x 2^n)]", "Kibibytes (KiB)", "Mebibytes (MiB)", "Gibibytes (GiB)", "Tebibytes (TiB)", "Pebibytes (PiB)", "Exbibytes (EiB)", "Zebibytes (ZiB)", "Yobibytes (YiB)", "[/Binary bytes (8 x 2^n)]",
"[Decimal bytes (8 x 10^n)]", "Kilobytes (KB)", "Megabytes (MB)", "Gigabytes (GB)", "Terabytes (TB)", "Petabytes (PB)", "Exabytes (EB)", "Zettabytes (ZB)", "Yottabytes (YB)", "[/Decimal bytes (8 x 10^n)]"
];

View file

@ -8,6 +8,13 @@ import Operation from "../Operation.mjs";
import {detectFileType} from "../lib/FileType.mjs";
import {FILE_SIGNATURES} from "../lib/FileSignatures.mjs";
// Concat all supported extensions into a single flat list
const exts = [].concat.apply([], Object.keys(FILE_SIGNATURES).map(cat =>
[].concat.apply([], FILE_SIGNATURES[cat].map(sig =>
sig.extension.split(",")
))
)).unique().sort().join(", ");
/**
* Detect File Type operation
*/
@ -22,11 +29,7 @@ class DetectFileType extends Operation {
this.name = "Detect File Type";
this.module = "Default";
this.description = "Attempts to guess the MIME (Multipurpose Internet Mail Extensions) type of the data based on 'magic bytes'.<br><br>Currently supports the following file types: " +
Object.keys(FILE_SIGNATURES).map(cat =>
FILE_SIGNATURES[cat].map(sig =>
sig.extension.split(",")[0]
).join(", ")
).join(", ") + ".";
exts + ".";
this.infoURL = "https://wikipedia.org/wiki/List_of_file_signatures";
this.inputType = "ArrayBuffer";
this.outputType = "string";

View file

@ -62,9 +62,9 @@ class OpticalCharacterRecognition extends Operation {
try {
const image = `data:${type};base64,${toBase64(input)}`;
const worker = new TesseractWorker({
workerPath: `${assetDir}/tesseract/worker.min.js`,
langPath: `${assetDir}/tesseract/lang-data/`,
corePath: `${assetDir}/tesseract/tesseract-core.wasm.js`,
workerPath: `${assetDir}tesseract/worker.min.js`,
langPath: `${assetDir}tesseract/lang-data`,
corePath: `${assetDir}tesseract/tesseract-core.wasm.js`,
});
const result = await worker.recognize(image)
.progress(progress => {

View file

@ -43,11 +43,13 @@ class NodeRecipe {
} else {
throw new TypeError("Inputted function not a Chef operation.");
}
// CASE: op with configuration
} else if (ing.op && ing.args) {
// Return op and args pair for opList item.
// CASE: op, maybe with configuration
} else if (ing.op) {
const sanitisedOp = this._validateIngredient(ing.op);
return {op: sanitisedOp, args: ing.args};
if (ing.args) {
return {op: sanitisedOp, args: ing.args};
}
return sanitisedOp;
} else {
throw new TypeError("Recipe can only contain function names or functions");
}

View file

@ -1046,15 +1046,25 @@ class OutputWaiter {
* @param {Object[]} options
*/
backgroundMagicResult(options) {
if (!options.length ||
!options[0].recipe.length)
return;
if (!options.length) return;
const currentRecipeConfig = this.app.getRecipeConfig();
const newRecipeConfig = currentRecipeConfig.concat(options[0].recipe);
const opSequence = options[0].recipe.map(o => o.op).join(", ");
let msg = "",
newRecipeConfig;
this.showMagicButton(opSequence, options[0].data, newRecipeConfig);
if (options[0].recipe.length) {
const opSequence = options[0].recipe.map(o => o.op).join(", ");
newRecipeConfig = currentRecipeConfig.concat(options[0].recipe);
msg = `<i>${opSequence}</i> will produce <span class="data-text">"${Utils.escapeHtml(Utils.truncate(options[0].data), 30)}"</span>`;
} else if (options[0].fileType && options[0].fileType.name) {
const ft = options[0].fileType;
newRecipeConfig = currentRecipeConfig.concat([{op: "Detect File Type", args: []}]);
msg = `<i>${ft.name}</i> file detected`;
} else {
return;
}
this.showMagicButton(msg, newRecipeConfig);
}
/**
@ -1072,15 +1082,14 @@ class OutputWaiter {
}
/**
* Displays the Magic button with a title and adds a link to a complete recipe.
* Displays the Magic button with a title and adds a link to a recipe.
*
* @param {string} opSequence
* @param {string} result
* @param {string} msg
* @param {Object[]} recipeConfig
*/
showMagicButton(opSequence, result, recipeConfig) {
showMagicButton(msg, recipeConfig) {
const magicButton = document.getElementById("magic");
magicButton.setAttribute("data-original-title", `<i>${opSequence}</i> will produce <span class="data-text">"${Utils.escapeHtml(Utils.truncate(result), 30)}"</span>`);
magicButton.setAttribute("data-original-title", msg);
magicButton.setAttribute("data-recipe", JSON.stringify(recipeConfig), null, "");
magicButton.classList.remove("hidden");
magicButton.classList.add("pulse");

View file

@ -259,6 +259,13 @@ TestRegister.addApiTests([
assert.strictEqual(result.toString(), "73:6f:6d:65:20:69:6e:70:75:74");
}),
it("chef.bake: should take single JSON object desribing op with optional args", () => {
const result = chef.bake("some input", {
op: chef.toHex,
});
assert.strictEqual(result.toString(), "73 6f 6d 65 20 69 6e 70 75 74");
}),
it("chef.bake: should take single JSON object describing op and args ARRAY", () => {
const result = chef.bake("some input", {
op: chef.toHex,
@ -295,6 +302,21 @@ TestRegister.addApiTests([
assert.strictEqual(result.toString(), "67;63;72;66;146;72;66;144;72;66;65;72;62;60;72;66;71;72;66;145;72;67;60;72;67;65;72;67;64");
}),
it("chef.bake: should take multiple ops in JSON object form, some without args", () => {
const result = chef.bake("some input", [
{
op: chef.toHex,
},
{
op: "to octal",
args: {
delimiter: "Semi-colon",
}
}
]);
assert.strictEqual(result.toString(), "67;63;40;66;146;40;66;144;40;66;65;40;62;60;40;66;71;40;66;145;40;67;60;40;67;65;40;67;64");
}),
it("chef.bake: should handle op with multiple args", () => {
const result = chef.bake("some input", {
op: "to morse code",
@ -324,6 +346,17 @@ TestRegister.addApiTests([
assert.strictEqual(result.toString(), "begin_something_anananaaaaak_da_aaak_da_aaaaananaaaaaaan_da_aaaaaaanan_da_aaak_end_something");
}),
it("chef.bake: should accept Clean JSON format from Chef website - args optional", () => {
const result = chef.bake("some input", [
{ "op": "To Morse Code" },
{ "op": "Hex to PEM",
"args": ["SOMETHING"] },
{ "op": "To Snake case",
"args": [false] }
]);
assert.strictEqual(result.toString(), "begin_something_aaaaaaaaaaaaaa_end_something");
}),
it("Excluded operations: throw a sensible error when you try and call one", () => {
try {
chef.fork();

View file

@ -70,13 +70,13 @@ TestRegister.addApiTests([
}),
it("AES decrypt: toggleString and option", () => {
const result = AESDecrypt("812c34ae6af353244a63c6ce23b7c34286b60be28ea4645523d4494700e7", {
const result = AESDecrypt("4a123af235a507bbc9d5871721d61b98504d569a9a5a7847e2d78315fec7", {
key: {
string: "some longer key1",
option: "utf8",
},
iv: {
string: "some iv",
string: "some iv some iv1",
option: "utf8",
},
mode: "OFB",
@ -916,8 +916,13 @@ smothering ampersand abreast
it("Triple DES encrypt / decrypt", () => {
assert.strictEqual(
chef.tripleDESDecrypt(
chef.tripleDESEncrypt("Destroy Money", {key: {string: "30 31 2f 30 34 2f 31 39 39 39 20 32 32 3a 33 33 3a 30 3130 31 2f 30 34", option: "Hex"}}),
{key: {string: "30 31 2f 30 34 2f 31 39 39 39 20 32 32 3a 33 33 3a 30 3130 31 2f 30 34", option: "Hex"}}).toString(),
chef.tripleDESEncrypt("Destroy Money", {
key: {string: "30 31 2f 30 34 2f 31 39 39 39 20 32 32 3a 33 33 3a 30 3130 31 2f 30 34", option: "Hex"},
iv: {string: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00", option: "Hex"}}),
{
key: {string: "30 31 2f 30 34 2f 31 39 39 39 20 32 32 3a 33 33 3a 30 3130 31 2f 30 34", option: "Hex"},
iv: {string: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00", option: "Hex"}
}).toString(),
"Destroy Money");
}),

View file

@ -76,7 +76,7 @@ The following algorithms will be used based on the size of the key:
],
},
{
name: "AES Encrypt: AES-128-CBC, no IV, ASCII",
name: "AES Encrypt: AES-128-CBC with IV0, ASCII",
input: "The quick brown fox jumps over the lazy dog.",
expectedOutput: "2ef6c3fdb1314b5c2c326a2087fe1a82d5e73bf605ec8431d73e847187fc1c8fbbe969c177df1ecdf8c13f2f505f9498",
recipeConfig: [
@ -84,14 +84,14 @@ The following algorithms will be used based on the size of the key:
"op": "AES Encrypt",
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": ""},
{"option": "Hex", "string": "00000000000000000000000000000000"},
"CBC", "Raw", "Hex"
]
}
],
},
{
name: "AES Encrypt: AES-128-CTR, no IV, ASCII",
name: "AES Encrypt: AES-128-CTR with IV0, ASCII",
input: "The quick brown fox jumps over the lazy dog.",
expectedOutput: "a98c9e8e3b7c894384d740e4f0f4ed0be2bbb1e0e13a255812c3c6b0a629e4ad759c075b2469c6f4fb2c0cf9",
recipeConfig: [
@ -99,14 +99,14 @@ The following algorithms will be used based on the size of the key:
"op": "AES Encrypt",
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": ""},
{"option": "Hex", "string": "00000000000000000000000000000000"},
"CTR", "Raw", "Hex"
]
}
],
},
{
name: "AES Encrypt: AES-128-CBC with IV, ASCII",
name: "AES Encrypt: AES-128-CBC with IV1, ASCII",
input: "The quick brown fox jumps over the lazy dog.",
expectedOutput: "4fa077d50cc71a57393e7b542c4e3aea0fb75383b97083f2f568ffc13c0e7a47502ec6d9f25744a061a3a5e55fe95e8d",
recipeConfig: [
@ -537,9 +537,10 @@ Triple DES uses a key length of 24 bytes (192 bits).`,
],
},
{
// play.golang.org/p/4Qm2hfLGsqc
name: "DES Encrypt: DES-CTR, Binary",
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
expectedOutput: "09015087e15b0937ab0ae5a84d66e520893690a6ea066382bf1330e8876cb3aa82ccc634f8f0d458bbe0257df6f4637cdac89f311168ba91208a21ba4bdd13c4b1a92cb93b33364b5b94a5d3d7fba68f6eed5807d9f5afeb7fbffcd94792131d264004ae",
expectedOutput: "09015087e15b0937c462fd5974af0c4b5880de136a5680453c99f4500628cbeca769623515d836985110b93eacfea7fa4a7b2b3cb4f67acbb5f7e8ddb5a5d445da74bf6572b0a874befa3888c81110776388e400afd8dc908dcc0c018c7753355f8a1c9f",
recipeConfig: [
{
"op": "DES Encrypt",
@ -630,9 +631,10 @@ DES uses a key length of 8 bytes (64 bits).`,
],
},
{
// play.golang.org/p/RElT6pVeNz2
name: "Triple DES Encrypt: DES-EDE3-CTR, Binary",
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
expectedOutput: "874d32cd7bdae52c254687e2d7e7093b077af2ec70878f99315f52a21ded5fb10c80a47e6271384335ac47376c758f675484fd7b8be9568aaec643f0d15cffdf3fe54ef3a1b2da50d5d8c7994d7a4a94e0a13a4d437443f0f1f39e93dd13ff06a80c66e4",
expectedOutput: "874d32cd7bdae52cd8630d3ab2bf373e7110e13713caa6a8bfed9d9dd802d0ebe93128ac0d0f05abcc56237b75fb69207dba11e68ddc4b0118a4c75e7248bbd80aaba4dd4436642546ec6ca7fa7526f3b0018ed5194c409dc2c1484530b968af554984f3",
recipeConfig: [
{
"op": "Triple DES Encrypt",
@ -681,7 +683,7 @@ The following algorithms will be used based on the size of the key:
],
},
{
name: "AES Decrypt: AES-128-CBC, no IV, ASCII",
name: "AES Decrypt: AES-128-CBC with IV0, ASCII",
input: "2ef6c3fdb1314b5c2c326a2087fe1a82d5e73bf605ec8431d73e847187fc1c8fbbe969c177df1ecdf8c13f2f505f9498",
expectedOutput: "The quick brown fox jumps over the lazy dog.",
recipeConfig: [
@ -689,7 +691,7 @@ The following algorithms will be used based on the size of the key:
"op": "AES Decrypt",
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": ""},
{"option": "Hex", "string": "00000000000000000000000000000000"},
"CBC", "Hex", "Raw",
{"option": "Hex", "string": ""}
]
@ -697,7 +699,7 @@ The following algorithms will be used based on the size of the key:
],
},
{
name: "AES Decrypt: AES-128-CTR, no IV, ASCII",
name: "AES Decrypt: AES-128-CTR with IV0, ASCII",
input: "a98c9e8e3b7c894384d740e4f0f4ed0be2bbb1e0e13a255812c3c6b0a629e4ad759c075b2469c6f4fb2c0cf9",
expectedOutput: "The quick brown fox jumps over the lazy dog.",
recipeConfig: [
@ -705,7 +707,7 @@ The following algorithms will be used based on the size of the key:
"op": "AES Decrypt",
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": ""},
{"option": "Hex", "string": "00000000000000000000000000000000"},
"CTR", "Hex", "Raw",
{"option": "Hex", "string": ""}
]
@ -1160,9 +1162,10 @@ Triple DES uses a key length of 24 bytes (192 bits).`,
],
},
{
// play.golang.org/p/FpvqncmPk7R
name: "DES Decrypt: DES-CTR, Binary",
input: "09015087e15b0937ab0ae5a84d66e520893690a6ea066382bf1330e8876cb3aa82ccc634f8f0d458bbe0257df6f4637cdac89f311168ba91208a21ba4bdd13c4b1a92cb93b33364b5b94a5d3d7fba68f6eed5807d9f5afeb7fbffcd94792131d264004ae",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
expectedOutput: "7a0e643132750e96b76dc9efa7810bea2b8feaa5b97887e44f96c0e6d506cc4dd4665683c6f63139221f8d887fd0a05b39741f8a67d87d6ac6f8dc6b668bd3e4a97b8bd3a19eafd5cdf50c3e1b3f17d61087d0b67cf6db31fec338b75f5954942c852829",
recipeConfig: [
{
"op": "DES Decrypt",
@ -1253,9 +1256,10 @@ DES uses a key length of 8 bytes (64 bits).`,
],
},
{
// play.golang.org/p/iBacN9kX_RO
name: "Triple DES Decrypt: DES-EDE3-CTR, Binary",
input: "874d32cd7bdae52c254687e2d7e7093b077af2ec70878f99315f52a21ded5fb10c80a47e6271384335ac47376c758f675484fd7b8be9568aaec643f0d15cffdf3fe54ef3a1b2da50d5d8c7994d7a4a94e0a13a4d437443f0f1f39e93dd13ff06a80c66e4",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
expectedOutput: "7a0e643132750e9625205bc6fb10dc848c53b7cb5a654d1242aecb6191ad3b5114727e5044a0ee11311575873c54829a80f9471ac473a0bbe5e791a23be75062f7e8f2210d998f9fbbaf3a5bb3dacd494d42d82950e3ab273f821eb979168315a80ad20f",
recipeConfig: [
{
"op": "Triple DES Decrypt",