From 8f710461da78d0bc1a12483133a044385d133c6c Mon Sep 17 00:00:00 2001 From: Matt C Date: Sat, 17 Sep 2022 23:48:11 +0100 Subject: [PATCH 01/33] Update yara to 4.2.3 and fix output reading 0 matches --- package-lock.json | 14 +++++++------- package.json | 2 +- src/core/operations/YARARules.mjs | 2 +- tests/operations/tests/YARA.mjs | 23 +++++++++++++++++++++++ webpack.config.js | 3 ++- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index e6b2082e..cf8c212a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,7 @@ "jsrsasign": "^10.5.23", "kbpgp": "2.1.15", "libbzip2-wasm": "0.0.4", - "libyara-wasm": "^1.1.0", + "libyara-wasm": "^1.2.0", "lodash": "^4.17.21", "loglevel": "^1.8.0", "loglevel-message-prefix": "^3.0.0", @@ -9152,9 +9152,9 @@ "integrity": "sha512-RqscTx95+RTKhFAyjedsboR0Lmo3zd8//EuRwQXkdWmsCwYlzarVRaiYg6kS1O8m10MCQkGdrnlK9L4eAmZUwA==" }, "node_modules/libyara-wasm": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-1.1.0.tgz", - "integrity": "sha512-MI2C4v8JxPN46l3VPWK66HApLPO4rx7n4rGioaSOfbIZikTJIuvI+eRPPnW3K2BXzrOHYj5sMl/RoLlKbXtiLw==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-1.2.0.tgz", + "integrity": "sha512-Dx6lnwy/JIuYSAhLcRBqdNBOzzrFoCcthmIuiNHi89P3fObXAxQYajWxOv3OFjXfIyTLr8mqSUSiyzfonbQoXg==" }, "node_modules/lie": { "version": "3.3.0", @@ -21198,9 +21198,9 @@ "integrity": "sha512-RqscTx95+RTKhFAyjedsboR0Lmo3zd8//EuRwQXkdWmsCwYlzarVRaiYg6kS1O8m10MCQkGdrnlK9L4eAmZUwA==" }, "libyara-wasm": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-1.1.0.tgz", - "integrity": "sha512-MI2C4v8JxPN46l3VPWK66HApLPO4rx7n4rGioaSOfbIZikTJIuvI+eRPPnW3K2BXzrOHYj5sMl/RoLlKbXtiLw==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-1.2.0.tgz", + "integrity": "sha512-Dx6lnwy/JIuYSAhLcRBqdNBOzzrFoCcthmIuiNHi89P3fObXAxQYajWxOv3OFjXfIyTLr8mqSUSiyzfonbQoXg==" }, "lie": { "version": "3.3.0", diff --git a/package.json b/package.json index a0aa75c1..84c087a2 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "jsrsasign": "^10.5.23", "kbpgp": "2.1.15", "libbzip2-wasm": "0.0.4", - "libyara-wasm": "^1.1.0", + "libyara-wasm": "^1.2.0", "lodash": "^4.17.21", "loglevel": "^1.8.0", "loglevel-message-prefix": "^3.0.0", diff --git a/src/core/operations/YARARules.mjs b/src/core/operations/YARARules.mjs index e654cc6d..4d4346a0 100644 --- a/src/core/operations/YARARules.mjs +++ b/src/core/operations/YARARules.mjs @@ -100,7 +100,7 @@ class YARARules extends Operation { } meta = meta.slice(0, -2) + "]"; } - const countString = showCounts ? `${matches.size()} time${matches.size() > 1 ? "s" : ""}` : ""; + const countString = matches.size() === 0 ? "" : (showCounts ? `${matches.size()} time${matches.size() > 1 ? "s" : ""}` : ""); if (matches.size() === 0 || !(showStrings || showLengths)) { matchString += `Input matches rule "${rule.ruleName}"${meta}${countString.length > 0 ? ` ${countString}`: ""}.\n`; } else { diff --git a/tests/operations/tests/YARA.mjs b/tests/operations/tests/YARA.mjs index 267af2ef..307f10b7 100644 --- a/tests/operations/tests/YARA.mjs +++ b/tests/operations/tests/YARA.mjs @@ -20,5 +20,28 @@ TestRegister.addTests([ } ], }, + { + name: "YARA Match: hashing rules", + input: "Hello World!", + expectedOutput: "Input matches rule \"HelloWorldMD5\".\nInput matches rule \"HelloWorldSHA256\".\n", + recipeConfig: [ + { + "op": "YARA Rules", + "args": [ + `import "hash" + rule HelloWorldMD5 { + condition: + hash.md5(0,filesize) == "ed076287532e86365e841e92bfc50d8c" + } + + rule HelloWorldSHA256 { + condition: + hash.sha256(0,filesize) == "7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069" + }`, + true, true, true, true + ], + } + ], + }, ]); diff --git a/webpack.config.js b/webpack.config.js index 9db5462d..50c4c731 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -109,7 +109,8 @@ module.exports = { "buffer": require.resolve("buffer/"), "crypto": require.resolve("crypto-browserify"), "stream": require.resolve("stream-browserify"), - "zlib": require.resolve("browserify-zlib") + "zlib": require.resolve("browserify-zlib"), + "process": false } }, module: { From bf2afcd2eff517f975dd79ca857f8eb999b810b6 Mon Sep 17 00:00:00 2001 From: CPlusSharp Date: Sun, 18 Sep 2022 12:25:40 +0200 Subject: [PATCH 02/33] Support Ed25519 SSH host key parsing --- src/core/operations/ParseSSHHostKey.mjs | 4 +++- tests/operations/tests/ParseSSHHostKey.mjs | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/core/operations/ParseSSHHostKey.mjs b/src/core/operations/ParseSSHHostKey.mjs index 8a3bf5da..f1a1f58c 100644 --- a/src/core/operations/ParseSSHHostKey.mjs +++ b/src/core/operations/ParseSSHHostKey.mjs @@ -23,7 +23,7 @@ class ParseSSHHostKey extends Operation { this.name = "Parse SSH Host Key"; this.module = "Default"; - this.description = "Parses a SSH host key and extracts fields from it.
The key type can be:The key format can be either Hex or Base64."; + this.description = "Parses a SSH host key and extracts fields from it.
The key type can be:The key format can be either Hex or Base64."; this.infoURL = "https://wikipedia.org/wiki/Secure_Shell"; this.inputType = "string"; this.outputType = "string"; @@ -71,6 +71,8 @@ class ParseSSHHostKey extends Operation { } else if (keyType.startsWith("ecdsa-sha2")) { output += `\nCurve: ${Utils.byteArrayToChars(fromHex(fields[1]))}`; output += `\nPoint: 0x${fields.slice(2)}`; + } else if (keyType === "ssh-ed25519") { + output += `\nx: 0x${fields[1]}`; } else { output += "\nUnsupported key type."; output += `\nParameters: ${fields.slice(1)}`; diff --git a/tests/operations/tests/ParseSSHHostKey.mjs b/tests/operations/tests/ParseSSHHostKey.mjs index 00e13c6c..296c8bb2 100644 --- a/tests/operations/tests/ParseSSHHostKey.mjs +++ b/tests/operations/tests/ParseSSHHostKey.mjs @@ -49,6 +49,18 @@ Point: 0x046c59592006272250a15070142a6be36d1e45464313f930d985a6e6f0eba3cd39d0367 } ] }, + { + name: "SSH Host Key: Ed25519", + input: "AAAAC3NzaC1lZDI1NTE5AAAAIBOF6r99IkvqGu1kwZrHHIqjpTB5w79bpv67B/Aw3+WJ", + expectedOutput: `Key type: ssh-ed25519 +x: 0x1385eabf7d224bea1aed64c19ac71c8aa3a53079c3bf5ba6febb07f030dfe589`, + recipeConfig: [ + { + op: "Parse SSH Host Key", + args: ["Base64"] + } + ] + }, { name: "SSH Host Key: Extract key", input: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDiJZ/9W9Ix/Dk9b+K4E+RGCug1AtkGXaJ9vNIY0YHFHLpWsB8DAuh/cGEI9TLbL1gzR2wG+RJNQ2EAQVWe6ypkK63Jm4zw4re+vhEiszpnP889J0h5N9yzyTndesrl4d3cQtv861FcKDPxUJbRALdtl6gwOB7BCL8gsXJLLVLO4EesrbPXD454qpVt7CgJXEXByOFjcIm3XwkdOnXMPHHnMSD7EIN1SvQMD6PfIDrbDd6KQt5QXW/Rc/BsfX5cbUIV1QW5A/GbepXHHKmWRtLC2J/mH3hW2Zq/hITPEaJdG1CtIilQmJaZGXpfGIwFeb0Av9pSL926arZZ6vDi9ctF test@test", From 28ec56a27fe8121be1a1ec7044a863d77088df33 Mon Sep 17 00:00:00 2001 From: Matt C Date: Sun, 18 Sep 2022 16:11:04 +0100 Subject: [PATCH 03/33] Update libyara package to fix bug with compile messages and add support for console module --- package-lock.json | 14 +++++----- package.json | 2 +- src/core/operations/YARARules.mjs | 30 ++++++++++++++++---- tests/operations/tests/YARA.mjs | 46 ++++++++++++++++++++++++++++++- 4 files changed, 77 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index cf8c212a..a789a47c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,7 @@ "jsrsasign": "^10.5.23", "kbpgp": "2.1.15", "libbzip2-wasm": "0.0.4", - "libyara-wasm": "^1.2.0", + "libyara-wasm": "^1.2.1", "lodash": "^4.17.21", "loglevel": "^1.8.0", "loglevel-message-prefix": "^3.0.0", @@ -9152,9 +9152,9 @@ "integrity": "sha512-RqscTx95+RTKhFAyjedsboR0Lmo3zd8//EuRwQXkdWmsCwYlzarVRaiYg6kS1O8m10MCQkGdrnlK9L4eAmZUwA==" }, "node_modules/libyara-wasm": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-1.2.0.tgz", - "integrity": "sha512-Dx6lnwy/JIuYSAhLcRBqdNBOzzrFoCcthmIuiNHi89P3fObXAxQYajWxOv3OFjXfIyTLr8mqSUSiyzfonbQoXg==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-1.2.1.tgz", + "integrity": "sha512-PNqUNWnwjZLe55iA8Rv6vLQRjSdO2OnVg24aRE8v+ytR8CRB8agIG6pS9h2VQejuJP1A/uR4pwcBggUxoNC7DA==" }, "node_modules/lie": { "version": "3.3.0", @@ -21198,9 +21198,9 @@ "integrity": "sha512-RqscTx95+RTKhFAyjedsboR0Lmo3zd8//EuRwQXkdWmsCwYlzarVRaiYg6kS1O8m10MCQkGdrnlK9L4eAmZUwA==" }, "libyara-wasm": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-1.2.0.tgz", - "integrity": "sha512-Dx6lnwy/JIuYSAhLcRBqdNBOzzrFoCcthmIuiNHi89P3fObXAxQYajWxOv3OFjXfIyTLr8mqSUSiyzfonbQoXg==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-1.2.1.tgz", + "integrity": "sha512-PNqUNWnwjZLe55iA8Rv6vLQRjSdO2OnVg24aRE8v+ytR8CRB8agIG6pS9h2VQejuJP1A/uR4pwcBggUxoNC7DA==" }, "lie": { "version": "3.3.0", diff --git a/package.json b/package.json index 84c087a2..f6ba31d0 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "jsrsasign": "^10.5.23", "kbpgp": "2.1.15", "libbzip2-wasm": "0.0.4", - "libyara-wasm": "^1.2.0", + "libyara-wasm": "^1.2.1", "lodash": "^4.17.21", "loglevel": "^1.8.0", "loglevel-message-prefix": "^3.0.0", diff --git a/src/core/operations/YARARules.mjs b/src/core/operations/YARARules.mjs index 4d4346a0..d91f50ae 100644 --- a/src/core/operations/YARARules.mjs +++ b/src/core/operations/YARARules.mjs @@ -52,7 +52,17 @@ class YARARules extends Operation { name: "Show counts", type: "boolean", value: true - } + }, + { + name: "Show rule warnings", + type: "boolean", + value: true + }, + { + name: "Show console module messages", + type: "boolean", + value: true + }, ]; } @@ -64,7 +74,7 @@ class YARARules extends Operation { async run(input, args) { if (isWorkerEnvironment()) self.sendStatusMessage("Instantiating YARA..."); - const [rules, showStrings, showLengths, showMeta, showCounts] = args; + const [rules, showStrings, showLengths, showMeta, showCounts, showRuleWarns, showConsole] = args; return new Promise((resolve, reject) => { Yara().then(yara => { if (isWorkerEnvironment()) self.sendStatusMessage("Converting data for YARA."); @@ -83,11 +93,19 @@ class YARARules extends Operation { const compileError = resp.compileErrors.get(i); if (!compileError.warning) { reject(new OperationError(`Error on line ${compileError.lineNumber}: ${compileError.message}`)); - } else { - matchString += `Warning on line ${compileError.lineNumber}: ${compileError.message}`; + } else if (showRuleWarns) { + matchString += `Warning on line ${compileError.lineNumber}: ${compileError.message}\n`; } } } + + if (showConsole) { + const consoleLogs = resp.consoleLogs; + for (let i = 0; i < consoleLogs.size(); i++) { + matchString += consoleLogs.get(i) + "\n"; + } + } + const matchedRules = resp.matchedRules; for (let i = 0; i < matchedRules.size(); i++) { const rule = matchedRules.get(i); @@ -100,11 +118,11 @@ class YARARules extends Operation { } meta = meta.slice(0, -2) + "]"; } - const countString = matches.size() === 0 ? "" : (showCounts ? `${matches.size()} time${matches.size() > 1 ? "s" : ""}` : ""); + const countString = matches.size() === 0 ? "" : (showCounts ? ` (${matches.size()} time${matches.size() > 1 ? "s" : ""})` : ""); if (matches.size() === 0 || !(showStrings || showLengths)) { matchString += `Input matches rule "${rule.ruleName}"${meta}${countString.length > 0 ? ` ${countString}`: ""}.\n`; } else { - matchString += `Rule "${rule.ruleName}"${meta} matches (${countString}):\n`; + matchString += `Rule "${rule.ruleName}"${meta} matches${countString}:\n`; for (let j = 0; j < matches.size(); j++) { const match = matches.get(j); if (showStrings || showLengths) { diff --git a/tests/operations/tests/YARA.mjs b/tests/operations/tests/YARA.mjs index 307f10b7..d92c19aa 100644 --- a/tests/operations/tests/YARA.mjs +++ b/tests/operations/tests/YARA.mjs @@ -8,6 +8,22 @@ */ import TestRegister from "../../lib/TestRegister.mjs"; +const CONSOLE_COMPILE_WARNING_RULE = `import "console" +rule a +{ + strings: + $s=" " + condition: + $s and console.log("log rule a") +} +rule b +{ + strings: + $s=" " + condition: + $s and console.hex("log rule b: int8(0)=", int8(0)) +}`; + TestRegister.addTests([ { name: "YARA Match: simple foobar", @@ -38,10 +54,38 @@ TestRegister.addTests([ condition: hash.sha256(0,filesize) == "7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069" }`, - true, true, true, true + true, true, true, true, false, false ], } ], }, + { + name: "YARA Match: compile warnings", + input: "CyberChef Yara", + expectedOutput: "Warning on line 5: string \"$s\" may slow down scanning\n" + + "Warning on line 12: string \"$s\" may slow down scanning\n" + + "Input matches rule \"a\".\n" + + "Input matches rule \"b\".\n", + recipeConfig: [ + { + "op": "YARA Rules", + "args": [CONSOLE_COMPILE_WARNING_RULE, false, false, false, false, true, false], + } + ], + }, + { + name: "YARA Match: console messages", + input: "CyberChef Yara", + expectedOutput: "log rule a\n" + + "log rule b: int8(0)=0x43\n" + + "Input matches rule \"a\".\n" + + "Input matches rule \"b\".\n", + recipeConfig: [ + { + "op": "YARA Rules", + "args": [CONSOLE_COMPILE_WARNING_RULE, false, false, false, false, false, true], + } + ], + }, ]); From 1ec7033d46d04c168a1b8d70fd27bb637f86f95d Mon Sep 17 00:00:00 2001 From: Matt C Date: Mon, 19 Sep 2022 14:05:13 +0100 Subject: [PATCH 04/33] Add LZMA Compress operation --- package-lock.json | 14 +++++++ package.json | 1 + src/core/config/Categories.json | 3 +- src/core/operations/LZMACompress.mjs | 62 ++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/core/operations/LZMACompress.mjs diff --git a/package-lock.json b/package-lock.json index e6b2082e..45d18e0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/polyfill": "^7.12.1", + "@blu3r4y/lzma": "^2.3.3", "arrive": "^2.4.1", "avsc": "^5.7.4", "bcryptjs": "^2.4.3", @@ -1771,6 +1772,14 @@ "node": ">=6.9.0" } }, + "node_modules/@blu3r4y/lzma": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@blu3r4y/lzma/-/lzma-2.3.3.tgz", + "integrity": "sha512-2ckRSsYewLAgq/s8tUW3o5gurtCNYga1f9l0egV4QlT8hgVEilQHRt18s+behmPL2M/BPBxUINaOz67u++r0wA==", + "bin": { + "lzma.js": "bin/lzma.js" + } + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -15446,6 +15455,11 @@ "to-fast-properties": "^2.0.0" } }, + "@blu3r4y/lzma": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@blu3r4y/lzma/-/lzma-2.3.3.tgz", + "integrity": "sha512-2ckRSsYewLAgq/s8tUW3o5gurtCNYga1f9l0egV4QlT8hgVEilQHRt18s+behmPL2M/BPBxUINaOz67u++r0wA==" + }, "@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", diff --git a/package.json b/package.json index a0aa75c1..3c847422 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ }, "dependencies": { "@babel/polyfill": "^7.12.1", + "@blu3r4y/lzma": "^2.3.3", "arrive": "^2.4.1", "avsc": "^5.7.4", "bcryptjs": "^2.4.3", diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 8ac60048..24963c99 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -331,7 +331,8 @@ "Tar", "Untar", "LZString Compress", - "LZString Decompress" + "LZString Decompress", + "LZMA Compress" ] }, { diff --git a/src/core/operations/LZMACompress.mjs b/src/core/operations/LZMACompress.mjs new file mode 100644 index 00000000..5c038786 --- /dev/null +++ b/src/core/operations/LZMACompress.mjs @@ -0,0 +1,62 @@ +/** + * @author Matt C [me@mitt.dev] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; + +import { compress } from "@blu3r4y/lzma"; + +/** + * LZMA Compress operation + */ +class LZMACompress extends Operation { + + /** + * LZMACompress constructor + */ + constructor() { + super(); + + this.name = "LZMA Compress"; + this.module = "Compression"; + this.description = "Compresses data using the Lempel\u2013Ziv\u2013Markov chain algorithm. Compression mode determines the speed and effectiveness of the compression: 1 is fastest and less effective, 9 is slowest and most effective"; + this.infoURL = "https://wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Markov_chain_algorithm"; + this.inputType = "ArrayBuffer"; + this.outputType = "ArrayBuffer"; + this.args = [ + { + name: "Compression Mode", + type: "option", + value: [ + "1", "2", "3", "4", "5", "6", "7", "8", "9" + ], + "defaultIndex": 6 + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {ArrayBuffer} + */ + run(input, args) { + return new Promise((resolve, reject) => { + compress(new Uint8Array(input), Number(args[0]), (result, error) => { + if (error) { + reject(new OperationError(`Failed to compress input: ${error.message}`)); + } + // The compression returns as an Int8Array, but we can just get the unsigned data from the buffer + resolve(new Int8Array(result).buffer); + }, (percent) => { + self.sendStatusMessage(`Compressing input: ${(percent*100).toFixed(2)}%`); + }); + }); + } + +} + +export default LZMACompress; From d502dd9857f3880e483200bf46bcb01b7ad63dd5 Mon Sep 17 00:00:00 2001 From: Matt C Date: Mon, 19 Sep 2022 14:20:27 +0100 Subject: [PATCH 05/33] Add LZMA Decompress operation --- src/core/config/Categories.json | 3 +- src/core/operations/LZMACompress.mjs | 3 +- src/core/operations/LZMADecompress.mjs | 51 ++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/core/operations/LZMADecompress.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 24963c99..7869893a 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -330,8 +330,9 @@ "Bzip2 Compress", "Tar", "Untar", - "LZString Compress", "LZString Decompress", + "LZString Compress", + "LZMA Decompress", "LZMA Compress" ] }, diff --git a/src/core/operations/LZMACompress.mjs b/src/core/operations/LZMACompress.mjs index 5c038786..0be27089 100644 --- a/src/core/operations/LZMACompress.mjs +++ b/src/core/operations/LZMACompress.mjs @@ -44,8 +44,9 @@ class LZMACompress extends Operation { * @returns {ArrayBuffer} */ run(input, args) { + const mode = Number(args[0]); return new Promise((resolve, reject) => { - compress(new Uint8Array(input), Number(args[0]), (result, error) => { + compress(new Uint8Array(input), mode, (result, error) => { if (error) { reject(new OperationError(`Failed to compress input: ${error.message}`)); } diff --git a/src/core/operations/LZMADecompress.mjs b/src/core/operations/LZMADecompress.mjs new file mode 100644 index 00000000..44908f32 --- /dev/null +++ b/src/core/operations/LZMADecompress.mjs @@ -0,0 +1,51 @@ +/** + * @author Matt C [me@mitt.dev] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import {decompress} from "@blu3r4y/lzma"; + +/** + * LZMA Decompress operation + */ +class LZMADecompress extends Operation { + + /** + * LZMADecompress constructor + */ + constructor() { + super(); + + this.name = "LZMA Decompress"; + this.module = "Compression"; + this.description = "Decompresses data using the Lempel-Ziv-Markov chain Algorithm."; + this.infoURL = "https://wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Markov_chain_algorithm"; + this.inputType = "ArrayBuffer"; + this.outputType = "ArrayBuffer"; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {ArrayBuffer} + */ + run(input, args) { + return new Promise((resolve, reject) => { + decompress(new Uint8Array(input), (result, error) => { + if (error) { + reject(new OperationError(`Failed to decompress input: ${error.message}`)); + } + // The decompression returns as an Int8Array, but we can just get the unsigned data from the buffer + resolve(new Int8Array(result).buffer); + }, (percent) => { + self.sendStatusMessage(`Decompressing input: ${(percent*100).toFixed(2)}%`); + }); + }); + } + +} + +export default LZMADecompress; From 98a70c2dd26ab954e7bfcb8bc5ee032ff346d5ff Mon Sep 17 00:00:00 2001 From: Matt C Date: Mon, 19 Sep 2022 17:33:55 +0100 Subject: [PATCH 06/33] Add tests and handle decompress returning string or array --- src/core/operations/LZMACompress.mjs | 5 ++- src/core/operations/LZMADecompress.mjs | 14 +++++-- tests/operations/tests/Compress.mjs | 52 ++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/src/core/operations/LZMACompress.mjs b/src/core/operations/LZMACompress.mjs index 0be27089..5a252db2 100644 --- a/src/core/operations/LZMACompress.mjs +++ b/src/core/operations/LZMACompress.mjs @@ -8,6 +8,7 @@ import Operation from "../Operation.mjs"; import OperationError from "../errors/OperationError.mjs"; import { compress } from "@blu3r4y/lzma"; +import {isWorkerEnvironment} from "../Utils.mjs"; /** * LZMA Compress operation @@ -43,7 +44,7 @@ class LZMACompress extends Operation { * @param {Object[]} args * @returns {ArrayBuffer} */ - run(input, args) { + async run(input, args) { const mode = Number(args[0]); return new Promise((resolve, reject) => { compress(new Uint8Array(input), mode, (result, error) => { @@ -53,7 +54,7 @@ class LZMACompress extends Operation { // The compression returns as an Int8Array, but we can just get the unsigned data from the buffer resolve(new Int8Array(result).buffer); }, (percent) => { - self.sendStatusMessage(`Compressing input: ${(percent*100).toFixed(2)}%`); + if (isWorkerEnvironment()) self.sendStatusMessage(`Compressing input: ${(percent*100).toFixed(2)}%`); }); }); } diff --git a/src/core/operations/LZMADecompress.mjs b/src/core/operations/LZMADecompress.mjs index 44908f32..3bebb860 100644 --- a/src/core/operations/LZMADecompress.mjs +++ b/src/core/operations/LZMADecompress.mjs @@ -7,6 +7,7 @@ import Operation from "../Operation.mjs"; import OperationError from "../errors/OperationError.mjs"; import {decompress} from "@blu3r4y/lzma"; +import Utils, {isWorkerEnvironment} from "../Utils.mjs"; /** * LZMA Decompress operation @@ -32,16 +33,21 @@ class LZMADecompress extends Operation { * @param {Object[]} args * @returns {ArrayBuffer} */ - run(input, args) { + async run(input, args) { return new Promise((resolve, reject) => { decompress(new Uint8Array(input), (result, error) => { if (error) { reject(new OperationError(`Failed to decompress input: ${error.message}`)); } - // The decompression returns as an Int8Array, but we can just get the unsigned data from the buffer - resolve(new Int8Array(result).buffer); + // The decompression returns either a String or an untyped unsigned int8 array, but we can just get the unsigned data from the buffer + + if (typeof result == "string") { + resolve(Utils.strToArrayBuffer(result)); + } else { + resolve(new Int8Array(result).buffer); + } }, (percent) => { - self.sendStatusMessage(`Decompressing input: ${(percent*100).toFixed(2)}%`); + if (isWorkerEnvironment()) self.sendStatusMessage(`Decompressing input: ${(percent*100).toFixed(2)}%`); }); }); } diff --git a/tests/operations/tests/Compress.mjs b/tests/operations/tests/Compress.mjs index a1e895bb..015277b1 100644 --- a/tests/operations/tests/Compress.mjs +++ b/tests/operations/tests/Compress.mjs @@ -23,4 +23,56 @@ TestRegister.addTests([ } ], }, + { + name: "LZMA compress & decompress", + input: "The cat sat on the mat.", + // Generated using command `echo -n "The cat sat on the mat." | lzma -z -6 | xxd -p` + expectedOutput: "The cat sat on the mat.", + recipeConfig: [ + { + "op": "LZMA Compress", + "args": ["6"] + }, + { + "op": "LZMA Decompress", + "args": [] + }, + ], + }, + { + name: "LZMA decompress: binary", + // Generated using command `echo "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10" | xxd -r -p | lzma -z -6 | xxd -p` + input: "5d00008000ffffffffffffffff00000052500a84f99bb28021a969d627e03e8a922effffbd160000", + expectedOutput: "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10", + recipeConfig: [ + { + "op": "From Hex", + "args": ["Space"] + }, + { + "op": "LZMA Decompress", + "args": [] + }, + { + "op": "To Hex", + "args": ["Space", 0] + } + ], + }, + { + name: "LZMA decompress: string", + // Generated using command `echo -n "The cat sat on the mat." | lzma -z -6 | xxd -p` + input: "5d00008000ffffffffffffffff002a1a08a202b1a4b814b912c94c4152e1641907d3fd8cd903ffff4fec0000", + expectedOutput: "The cat sat on the mat.", + recipeConfig: [ + { + "op": "From Hex", + "args": ["Space"] + }, + { + "op": "LZMA Decompress", + "args": [] + } + ], + }, ]); From a7b83787360818757e2f4ce8e0544beb81038e63 Mon Sep 17 00:00:00 2001 From: Ethan Block Date: Wed, 21 Sep 2022 11:37:06 -0400 Subject: [PATCH 07/33] Adding PTR to possiable values for Resolver --- src/core/operations/DNSOverHTTPS.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/operations/DNSOverHTTPS.mjs b/src/core/operations/DNSOverHTTPS.mjs index 4dde2f13..a7ab3aff 100644 --- a/src/core/operations/DNSOverHTTPS.mjs +++ b/src/core/operations/DNSOverHTTPS.mjs @@ -54,7 +54,8 @@ class DNSOverHTTPS extends Operation { "TXT", "MX", "DNSKEY", - "NS" + "NS", + "PTR" ] }, { From f450240094fdd8f908bf1d2dcf43fafa2d292583 Mon Sep 17 00:00:00 2001 From: john19696 Date: Thu, 22 Sep 2022 16:30:36 +0100 Subject: [PATCH 08/33] Parameterise All hashes --- src/core/operations/GenerateAllHashes.mjs | 141 +++++++++++++------ tests/operations/index.mjs | 1 + tests/operations/tests/GenerateAllHashes.mjs | 110 +++++++++++++++ 3 files changed, 208 insertions(+), 44 deletions(-) create mode 100644 tests/operations/tests/GenerateAllHashes.mjs diff --git a/src/core/operations/GenerateAllHashes.mjs b/src/core/operations/GenerateAllHashes.mjs index 0b4560cc..94479650 100644 --- a/src/core/operations/GenerateAllHashes.mjs +++ b/src/core/operations/GenerateAllHashes.mjs @@ -51,7 +51,73 @@ class GenerateAllHashes extends Operation { this.infoURL = "https://wikipedia.org/wiki/Comparison_of_cryptographic_hash_functions"; this.inputType = "ArrayBuffer"; this.outputType = "string"; - this.args = []; + this.args = [ + { + "name": "Length", + "type": "option", + "value": [ + "All", "32", "40", "56", "64", "80", "96", "128" + ] + }, + { + "name": "Output hash names", + "type": "boolean", + "value": true + }, + ]; + this.hashes = [ + {"name": "MD2", "hash": (new MD2()), "type": "arrayBuffer", params: []}, + {"name": "MD4", "hash": (new MD4()), "type": "arrayBuffer", params: []}, + {"name": "MD5", "hash": (new MD5()), "type": "arrayBuffer", params: []}, + {"name": "MD6", "hash": (new MD6()), "type": "str", params: []}, + {"name": "SHA0", "hash": (new SHA0()), "type": "arrayBuffer", params: []}, + {"name": "SHA1", "hash": (new SHA1()), "type": "arrayBuffer", params: []}, + {"name": "SHA2 224", "hash": (new SHA2()), "type": "arrayBuffer", params: ["224"]}, + {"name": "SHA2 256", "hash": (new SHA2()), "type": "arrayBuffer", params: ["256"]}, + {"name": "SHA2 384", "hash": (new SHA2()), "type": "arrayBuffer", params: ["384"]}, + {"name": "SHA2 512", "hash": (new SHA2()), "type": "arrayBuffer", params: ["512"]}, + {"name": "SHA3 224", "hash": (new SHA3()), "type": "arrayBuffer", params: ["224"]}, + {"name": "SHA3 256", "hash": (new SHA3()), "type": "arrayBuffer", params: ["256"]}, + {"name": "SHA3 384", "hash": (new SHA3()), "type": "arrayBuffer", params: ["384"]}, + {"name": "SHA3 512", "hash": (new SHA3()), "type": "arrayBuffer", params: ["512"]}, + {"name": "Keccak 224", "hash": (new Keccak()), "type": "arrayBuffer", params: ["224"]}, + {"name": "Keccak 256", "hash": (new Keccak()), "type": "arrayBuffer", params: ["256"]}, + {"name": "Keccak 384", "hash": (new Keccak()), "type": "arrayBuffer", params: ["384"]}, + {"name": "Keccak 512", "hash": (new Keccak()), "type": "arrayBuffer", params: ["512"]}, + {"name": "Shake 128", "hash": (new Shake()), "type": "arrayBuffer", params: ["128", 256]}, + {"name": "Shake 256", "hash": (new Shake()), "type": "arrayBuffer", params: ["256", 512]}, + {"name": "RIPEMD-128", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["128"]}, + {"name": "RIPEMD-160", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["160"]}, + {"name": "RIPEMD-256", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["256"]}, + {"name": "RIPEMD-320", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["320"]}, + {"name": "HAS-160", "hash": (new HAS160()), "type": "arrayBuffer", params: []}, + {"name": "Whirlpool-0", "hash": (new Whirlpool()), "type": "arrayBuffer", params: ["Whirlpool-0"]}, + {"name": "Whirlpool-T", "hash": (new Whirlpool()), "type": "arrayBuffer", params: ["Whirlpool-T"]}, + {"name": "Whirlpool", "hash": (new Whirlpool()), "type": "arrayBuffer", params: ["Whirlpool"]}, + {"name": "BLAKE2b-128", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["128","Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2b-160", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["160","Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2b-256", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["256","Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2b-384", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["384","Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2b-512", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["512","Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2s-128", "hash": (new BLAKE2s), "type": "arrayBuffer", params: ["128","Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2s-160", "hash": (new BLAKE2s), "type": "arrayBuffer", params: ["160","Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2s-256", "hash": (new BLAKE2s), "type": "arrayBuffer", params: ["256","Hex", {string: "", option: "UTF8"}]}, + {"name": "Streebog-256", "hash": (new Streebog), "type": "arrayBuffer", params: ["256"]}, + {"name": "Streebog-512", "hash": (new Streebog), "type": "arrayBuffer", params: ["512"]}, + {"name": "GOST", "hash": (new GOSTHash), "type": "arrayBuffer", params: ["D-A"]}, + {"name": "SSDEEP", "hash": (new SSDEEP()), "type": "str"}, + {"name": "CTPH", "hash": (new CTPH()), "type": "str"} + ]; + this.checksums = [ + {"name": "Fletcher-8: ", "checksum": (new Fletcher8Checksum), "type": "byteArray", "params": []}, + {"name": "Fletcher-16: ", "checksum": (new Fletcher16Checksum), "type": "byteArray", "params": []}, + {"name": "Fletcher-32: ", "checksum": (new Fletcher32Checksum), "type": "byteArray", "params": []}, + {"name": "Fletcher-64: ", "checksum": (new Fletcher64Checksum), "type": "byteArray", "params": []}, + {"name": "Adler-32: ", "checksum": (new Adler32Checksum), "type": "byteArray", "params": []}, + {"name": "CRC-8: ", "checksum": (new CRC8Checksum), "type": "arrayBuffer", "params": ["CRC-8"]}, + {"name": "CRC-16: ", "checksum": (new CRC16Checksum), "type": "arrayBuffer", "params": []}, + {"name": "CRC-32: ", "checksum": (new CRC32Checksum), "type": "arrayBuffer", "params": []} + ]; } /** @@ -60,51 +126,37 @@ class GenerateAllHashes extends Operation { * @returns {string} */ run(input, args) { + const length = args[0]; + const names = args[1]; + const arrayBuffer = input, str = Utils.arrayBufferToStr(arrayBuffer, false), - byteArray = new Uint8Array(arrayBuffer), - output = "MD2: " + (new MD2()).run(arrayBuffer, []) + - "\nMD4: " + (new MD4()).run(arrayBuffer, []) + - "\nMD5: " + (new MD5()).run(arrayBuffer, []) + - "\nMD6: " + (new MD6()).run(str, []) + - "\nSHA0: " + (new SHA0()).run(arrayBuffer, []) + - "\nSHA1: " + (new SHA1()).run(arrayBuffer, []) + - "\nSHA2 224: " + (new SHA2()).run(arrayBuffer, ["224"]) + - "\nSHA2 256: " + (new SHA2()).run(arrayBuffer, ["256"]) + - "\nSHA2 384: " + (new SHA2()).run(arrayBuffer, ["384"]) + - "\nSHA2 512: " + (new SHA2()).run(arrayBuffer, ["512"]) + - "\nSHA3 224: " + (new SHA3()).run(arrayBuffer, ["224"]) + - "\nSHA3 256: " + (new SHA3()).run(arrayBuffer, ["256"]) + - "\nSHA3 384: " + (new SHA3()).run(arrayBuffer, ["384"]) + - "\nSHA3 512: " + (new SHA3()).run(arrayBuffer, ["512"]) + - "\nKeccak 224: " + (new Keccak()).run(arrayBuffer, ["224"]) + - "\nKeccak 256: " + (new Keccak()).run(arrayBuffer, ["256"]) + - "\nKeccak 384: " + (new Keccak()).run(arrayBuffer, ["384"]) + - "\nKeccak 512: " + (new Keccak()).run(arrayBuffer, ["512"]) + - "\nShake 128: " + (new Shake()).run(arrayBuffer, ["128", 256]) + - "\nShake 256: " + (new Shake()).run(arrayBuffer, ["256", 512]) + - "\nRIPEMD-128: " + (new RIPEMD()).run(arrayBuffer, ["128"]) + - "\nRIPEMD-160: " + (new RIPEMD()).run(arrayBuffer, ["160"]) + - "\nRIPEMD-256: " + (new RIPEMD()).run(arrayBuffer, ["256"]) + - "\nRIPEMD-320: " + (new RIPEMD()).run(arrayBuffer, ["320"]) + - "\nHAS-160: " + (new HAS160()).run(arrayBuffer, []) + - "\nWhirlpool-0: " + (new Whirlpool()).run(arrayBuffer, ["Whirlpool-0"]) + - "\nWhirlpool-T: " + (new Whirlpool()).run(arrayBuffer, ["Whirlpool-T"]) + - "\nWhirlpool: " + (new Whirlpool()).run(arrayBuffer, ["Whirlpool"]) + - "\nBLAKE2b-128: " + (new BLAKE2b).run(arrayBuffer, ["128", "Hex", {string: "", option: "UTF8"}]) + - "\nBLAKE2b-160: " + (new BLAKE2b).run(arrayBuffer, ["160", "Hex", {string: "", option: "UTF8"}]) + - "\nBLAKE2b-256: " + (new BLAKE2b).run(arrayBuffer, ["256", "Hex", {string: "", option: "UTF8"}]) + - "\nBLAKE2b-384: " + (new BLAKE2b).run(arrayBuffer, ["384", "Hex", {string: "", option: "UTF8"}]) + - "\nBLAKE2b-512: " + (new BLAKE2b).run(arrayBuffer, ["512", "Hex", {string: "", option: "UTF8"}]) + - "\nBLAKE2s-128: " + (new BLAKE2s).run(arrayBuffer, ["128", "Hex", {string: "", option: "UTF8"}]) + - "\nBLAKE2s-160: " + (new BLAKE2s).run(arrayBuffer, ["160", "Hex", {string: "", option: "UTF8"}]) + - "\nBLAKE2s-256: " + (new BLAKE2s).run(arrayBuffer, ["256", "Hex", {string: "", option: "UTF8"}]) + - "\nStreebog-256: " + (new Streebog).run(arrayBuffer, ["256"]) + - "\nStreebog-512: " + (new Streebog).run(arrayBuffer, ["512"]) + - "\nGOST: " + (new GOSTHash).run(arrayBuffer, ["D-A"]) + - "\nSSDEEP: " + (new SSDEEP()).run(str) + - "\nCTPH: " + (new CTPH()).run(str) + - "\n\nChecksums:" + + byteArray = new Uint8Array(arrayBuffer); + + var value, output = ""; + // iterate over each of the hashes + this.hashes.forEach(function (hash) { + // calculate the hash value + if (hash.type == "arrayBuffer") { + value = hash.hash.run(arrayBuffer, hash.params); + } else if (hash.type == "str") { + if ("params" in hash) { + value = hash.hash.run(str, hash.params); + } else { + value = hash.hash.run(str); + } + } + // output the values base on the args: length & names + if (length == "All" || value.length === parseInt(length)) { + if (names) { + output += hash.name + ":" + " ".repeat(13-hash.name.length); + } + output += value + "\n"; + } + }); + + if (length == "All") { + output += "\nChecksums:" + "\nFletcher-8: " + (new Fletcher8Checksum).run(byteArray, []) + "\nFletcher-16: " + (new Fletcher16Checksum).run(byteArray, []) + "\nFletcher-32: " + (new Fletcher32Checksum).run(byteArray, []) + @@ -113,6 +165,7 @@ class GenerateAllHashes extends Operation { "\nCRC-8: " + (new CRC8Checksum).run(arrayBuffer, ["CRC-8"]) + "\nCRC-16: " + (new CRC16Checksum).run(arrayBuffer, []) + "\nCRC-32: " + (new CRC32Checksum).run(arrayBuffer, []); + } return output; } diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index f4294cad..c267d5f5 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -45,6 +45,7 @@ import "./tests/DateTime.mjs"; import "./tests/ExtractEmailAddresses.mjs"; import "./tests/Fork.mjs"; import "./tests/FromDecimal.mjs"; +import "./tests/GenerateAllHashes.mjs"; import "./tests/Gzip.mjs"; import "./tests/Gunzip.mjs"; import "./tests/Hash.mjs"; diff --git a/tests/operations/tests/GenerateAllHashes.mjs b/tests/operations/tests/GenerateAllHashes.mjs new file mode 100644 index 00000000..6c067f23 --- /dev/null +++ b/tests/operations/tests/GenerateAllHashes.mjs @@ -0,0 +1,110 @@ +/** + * GetAllCasings tests. + * + * @author n1073645 [n1073645@gmail.com] + * @copyright Crown Copyright 2020 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Full generate all hashes", + input: "test", + expectedOutput: `MD2: dd34716876364a02d0195e2fb9ae2d1b +MD4: db346d691d7acc4dc2625db19f9e3f52 +MD5: 098f6bcd4621d373cade4e832627b4f6 +MD6: 93c8a7d0ff132f325138a82b2baa98c12a7c9ac982feb6c5b310a1ca713615bd +SHA0: f8d3b312442a67706057aeb45b983221afb4f035 +SHA1: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3 +SHA2 224: 90a3ed9e32b2aaf4c61c410eb925426119e1a9dc53d4286ade99a809 +SHA2 256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 +SHA2 384: 768412320f7b0aa5812fce428dc4706b3cae50e02a64caa16a782249bfe8efc4b7ef1ccb126255d196047dfedf17a0a9 +SHA2 512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff +SHA3 224: 3797bf0afbbfca4a7bbba7602a2b552746876517a7f9b7ce2db0ae7b +SHA3 256: 36f028580bb02cc8272a9a020f4200e346e276ae664e45ee80745574e2f5ab80 +SHA3 384: e516dabb23b6e30026863543282780a3ae0dccf05551cf0295178d7ff0f1b41eecb9db3ff219007c4e097260d58621bd +SHA3 512: 9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7b710110c0a678288166e7fbe796883a4f2e9b3ca9f484f521d0ce464345cc1aec96779149c14 +Keccak 224: 3be30a9ff64f34a5861116c5198987ad780165f8366e67aff4760b5e +Keccak 256: 9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658 +Keccak 384: 53d0ba137307d4c2f9b6674c83edbd58b70c0f4340133ed0adc6fba1d2478a6a03b7788229e775d2de8ae8c0759d0527 +Keccak 512: 1e2e9fc2002b002d75198b7503210c05a1baac4560916a3c6d93bcce3a50d7f00fd395bf1647b9abb8d1afcc9c76c289b0c9383ba386a956da4b38934417789e +Shake 128: d3b0aa9cd8b7255622cebc631e867d4093d6f6010191a53973c45fec9b07c774 +Shake 256: b54ff7255705a71ee2925e4a3e30e41aed489a579d5595e0df13e32e1e4dd202a7c7f68b31d6418d9845eb4d757adda6ab189e1bb340db818e5b3bc725d992fa +RIPEMD-128: f1abb5083c9ff8a9dbbca9cd2b11fead +RIPEMD-160: 5e52fee47e6b070565f74372468cdc699de89107 +RIPEMD-256: fe0289110d07daeee9d9500e14c57787d9083f6ba10e6bcb256f86bb4fe7b981 +RIPEMD-320: 3b0a2e841e589cf583634a5dd265d2b5d497c4cc44b241e34e0f62d03e98c1b9dc72970b9bc20eb5 +HAS-160: cb15e491eec6e769771d1f811315139c93071084 +Whirlpool-0: d50ff71342b521974bae166539871922669afcfc7181250ebbae015c317ebb797173a69e7a05afd11099a9f0918159cd5bc88434d3ca44513d7263caea9244fe +Whirlpool-T: e6b4aa087751b4428171777f1893ba585404c7e0171787720eba0d8bccd710dc2c42f874c572bfae4cedabf50f2c80bf923805d4e31c504b86ca3bc59265e7dd +Whirlpool: b913d5bbb8e461c2c5961cbe0edcdadfd29f068225ceb37da6defcf89849368f8c6c2eb6a4c4ac75775d032a0ecfdfe8550573062b653fe92fc7b8fb3b7be8d6 +BLAKE2b-128: 44a8995dd50b6657a037a7839304535b +BLAKE2b-160: a34fc3b6d2cce8beb3216c2bbb5e55739e8121ed +BLAKE2b-256: 928b20366943e2afd11ebc0eae2e53a93bf177a4fcf35bcc64d503704e65e202 +BLAKE2b-384: 8a84b8666c8fcfb69f2ec41f578d7c85fbdb504ea6510fb05b50fcbf7ed8153c77943bc2da73abb136834e1a0d4f22cb +BLAKE2b-512: a71079d42853dea26e453004338670a53814b78137ffbed07603a41d76a483aa9bc33b582f77d30a65e6f29a896c0411f38312e1d66e0bf16386c86a89bea572 +BLAKE2s-128: e9ddd9926b9dcb382e09be39ba403d2c +BLAKE2s-160: d6197dabec2bd6f4ff303b8e519e8f15d42a453d +BLAKE2s-256: f308fc02ce9172ad02a7d75800ecfc027109bc67987ea32aba9b8dcc7b10150e +Streebog-256: 12a50838191b5504f1e5f2fd078714cf6b592b9d29af99d0b10d8d02881c3857 +Streebog-512: 7200bf5dea560f0d7960d07fdc8874ad9f3b86ece2e45f5502ae2e176f2c928e0e581152281f5aee818318bed7cbe6aa69999589234723ceb33175598365b5c8 +GOST: ee67303696d205ddd2b2363e8e01b4b7199a80957d94d7678eaad3fc834c5a27 +SSDEEP: 3:Hn:Hn +CTPH: A:E:E + +Checksums: +Fletcher-8: 3d +Fletcher-16: 5dc1 +Fletcher-32: 045901c0 +Fletcher-64: 00000459000001c0 +Adler-32: 045d01c1 +CRC-8: b9 +CRC-16: f82e +CRC-32: d87f7e0c`, + recipeConfig: [ + { + "op": "Generate all hashes", + "args": ["All", true] + } + ] + }, + { + name: "Hashes with length 32", + input: "test", + expectedOutput: `MD2: dd34716876364a02d0195e2fb9ae2d1b +MD4: db346d691d7acc4dc2625db19f9e3f52 +MD5: 098f6bcd4621d373cade4e832627b4f6 +RIPEMD-128: f1abb5083c9ff8a9dbbca9cd2b11fead +BLAKE2b-128: 44a8995dd50b6657a037a7839304535b +BLAKE2s-128: e9ddd9926b9dcb382e09be39ba403d2c +`, + recipeConfig: [ + { + "op": "Generate all hashes", + "args": ["32", true] + } + ] + }, + { + name: "Hashes without names", + input: "test", + expectedOutput: `93c8a7d0ff132f325138a82b2baa98c12a7c9ac982feb6c5b310a1ca713615bd +9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 +36f028580bb02cc8272a9a020f4200e346e276ae664e45ee80745574e2f5ab80 +9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658 +d3b0aa9cd8b7255622cebc631e867d4093d6f6010191a53973c45fec9b07c774 +fe0289110d07daeee9d9500e14c57787d9083f6ba10e6bcb256f86bb4fe7b981 +928b20366943e2afd11ebc0eae2e53a93bf177a4fcf35bcc64d503704e65e202 +f308fc02ce9172ad02a7d75800ecfc027109bc67987ea32aba9b8dcc7b10150e +12a50838191b5504f1e5f2fd078714cf6b592b9d29af99d0b10d8d02881c3857 +ee67303696d205ddd2b2363e8e01b4b7199a80957d94d7678eaad3fc834c5a27 +`, + recipeConfig: [ + { + "op": "Generate all hashes", + "args": ["64", false] + } + ] + } +]); From 00f010172317902f72e76cae41875d1844f19805 Mon Sep 17 00:00:00 2001 From: john19696 Date: Thu, 22 Sep 2022 16:39:51 +0100 Subject: [PATCH 09/33] author fix --- src/core/operations/GenerateAllHashes.mjs | 4 ++-- tests/operations/tests/GenerateAllHashes.mjs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/operations/GenerateAllHashes.mjs b/src/core/operations/GenerateAllHashes.mjs index 94479650..0e77bc5d 100644 --- a/src/core/operations/GenerateAllHashes.mjs +++ b/src/core/operations/GenerateAllHashes.mjs @@ -1,6 +1,6 @@ /** - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 + * @author john19696 [john19696@protonmail.com] + * @copyright Crown Copyright 2023 * @license Apache-2.0 */ diff --git a/tests/operations/tests/GenerateAllHashes.mjs b/tests/operations/tests/GenerateAllHashes.mjs index 6c067f23..857135e6 100644 --- a/tests/operations/tests/GenerateAllHashes.mjs +++ b/tests/operations/tests/GenerateAllHashes.mjs @@ -1,8 +1,8 @@ /** - * GetAllCasings tests. + * GenerateAllHashes tests. * - * @author n1073645 [n1073645@gmail.com] - * @copyright Crown Copyright 2020 + * @author john19696 [john19696@protonmail.com] + * @copyright Crown Copyright 2022 * @license Apache-2.0 */ import TestRegister from "../../lib/TestRegister.mjs"; From be97a0062e6b9a33b12541f04fc3ec0844b4aba2 Mon Sep 17 00:00:00 2001 From: john19696 Date: Thu, 22 Sep 2022 16:53:29 +0100 Subject: [PATCH 10/33] linted --- src/core/operations/GenerateAllHashes.mjs | 92 +++++++++++------------ 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/core/operations/GenerateAllHashes.mjs b/src/core/operations/GenerateAllHashes.mjs index 0e77bc5d..41817e25 100644 --- a/src/core/operations/GenerateAllHashes.mjs +++ b/src/core/operations/GenerateAllHashes.mjs @@ -66,47 +66,47 @@ class GenerateAllHashes extends Operation { }, ]; this.hashes = [ - {"name": "MD2", "hash": (new MD2()), "type": "arrayBuffer", params: []}, - {"name": "MD4", "hash": (new MD4()), "type": "arrayBuffer", params: []}, - {"name": "MD5", "hash": (new MD5()), "type": "arrayBuffer", params: []}, - {"name": "MD6", "hash": (new MD6()), "type": "str", params: []}, - {"name": "SHA0", "hash": (new SHA0()), "type": "arrayBuffer", params: []}, - {"name": "SHA1", "hash": (new SHA1()), "type": "arrayBuffer", params: []}, - {"name": "SHA2 224", "hash": (new SHA2()), "type": "arrayBuffer", params: ["224"]}, - {"name": "SHA2 256", "hash": (new SHA2()), "type": "arrayBuffer", params: ["256"]}, - {"name": "SHA2 384", "hash": (new SHA2()), "type": "arrayBuffer", params: ["384"]}, - {"name": "SHA2 512", "hash": (new SHA2()), "type": "arrayBuffer", params: ["512"]}, - {"name": "SHA3 224", "hash": (new SHA3()), "type": "arrayBuffer", params: ["224"]}, - {"name": "SHA3 256", "hash": (new SHA3()), "type": "arrayBuffer", params: ["256"]}, - {"name": "SHA3 384", "hash": (new SHA3()), "type": "arrayBuffer", params: ["384"]}, - {"name": "SHA3 512", "hash": (new SHA3()), "type": "arrayBuffer", params: ["512"]}, - {"name": "Keccak 224", "hash": (new Keccak()), "type": "arrayBuffer", params: ["224"]}, - {"name": "Keccak 256", "hash": (new Keccak()), "type": "arrayBuffer", params: ["256"]}, - {"name": "Keccak 384", "hash": (new Keccak()), "type": "arrayBuffer", params: ["384"]}, - {"name": "Keccak 512", "hash": (new Keccak()), "type": "arrayBuffer", params: ["512"]}, - {"name": "Shake 128", "hash": (new Shake()), "type": "arrayBuffer", params: ["128", 256]}, - {"name": "Shake 256", "hash": (new Shake()), "type": "arrayBuffer", params: ["256", 512]}, - {"name": "RIPEMD-128", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["128"]}, - {"name": "RIPEMD-160", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["160"]}, - {"name": "RIPEMD-256", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["256"]}, - {"name": "RIPEMD-320", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["320"]}, - {"name": "HAS-160", "hash": (new HAS160()), "type": "arrayBuffer", params: []}, - {"name": "Whirlpool-0", "hash": (new Whirlpool()), "type": "arrayBuffer", params: ["Whirlpool-0"]}, - {"name": "Whirlpool-T", "hash": (new Whirlpool()), "type": "arrayBuffer", params: ["Whirlpool-T"]}, - {"name": "Whirlpool", "hash": (new Whirlpool()), "type": "arrayBuffer", params: ["Whirlpool"]}, - {"name": "BLAKE2b-128", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["128","Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2b-160", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["160","Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2b-256", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["256","Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2b-384", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["384","Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2b-512", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["512","Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2s-128", "hash": (new BLAKE2s), "type": "arrayBuffer", params: ["128","Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2s-160", "hash": (new BLAKE2s), "type": "arrayBuffer", params: ["160","Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2s-256", "hash": (new BLAKE2s), "type": "arrayBuffer", params: ["256","Hex", {string: "", option: "UTF8"}]}, - {"name": "Streebog-256", "hash": (new Streebog), "type": "arrayBuffer", params: ["256"]}, - {"name": "Streebog-512", "hash": (new Streebog), "type": "arrayBuffer", params: ["512"]}, - {"name": "GOST", "hash": (new GOSTHash), "type": "arrayBuffer", params: ["D-A"]}, - {"name": "SSDEEP", "hash": (new SSDEEP()), "type": "str"}, - {"name": "CTPH", "hash": (new CTPH()), "type": "str"} + {"name": "MD2", "hash": (new MD2()), "type": "arrayBuffer", params: []}, + {"name": "MD4", "hash": (new MD4()), "type": "arrayBuffer", params: []}, + {"name": "MD5", "hash": (new MD5()), "type": "arrayBuffer", params: []}, + {"name": "MD6", "hash": (new MD6()), "type": "str", params: []}, + {"name": "SHA0", "hash": (new SHA0()), "type": "arrayBuffer", params: []}, + {"name": "SHA1", "hash": (new SHA1()), "type": "arrayBuffer", params: []}, + {"name": "SHA2 224", "hash": (new SHA2()), "type": "arrayBuffer", params: ["224"]}, + {"name": "SHA2 256", "hash": (new SHA2()), "type": "arrayBuffer", params: ["256"]}, + {"name": "SHA2 384", "hash": (new SHA2()), "type": "arrayBuffer", params: ["384"]}, + {"name": "SHA2 512", "hash": (new SHA2()), "type": "arrayBuffer", params: ["512"]}, + {"name": "SHA3 224", "hash": (new SHA3()), "type": "arrayBuffer", params: ["224"]}, + {"name": "SHA3 256", "hash": (new SHA3()), "type": "arrayBuffer", params: ["256"]}, + {"name": "SHA3 384", "hash": (new SHA3()), "type": "arrayBuffer", params: ["384"]}, + {"name": "SHA3 512", "hash": (new SHA3()), "type": "arrayBuffer", params: ["512"]}, + {"name": "Keccak 224", "hash": (new Keccak()), "type": "arrayBuffer", params: ["224"]}, + {"name": "Keccak 256", "hash": (new Keccak()), "type": "arrayBuffer", params: ["256"]}, + {"name": "Keccak 384", "hash": (new Keccak()), "type": "arrayBuffer", params: ["384"]}, + {"name": "Keccak 512", "hash": (new Keccak()), "type": "arrayBuffer", params: ["512"]}, + {"name": "Shake 128", "hash": (new Shake()), "type": "arrayBuffer", params: ["128", 256]}, + {"name": "Shake 256", "hash": (new Shake()), "type": "arrayBuffer", params: ["256", 512]}, + {"name": "RIPEMD-128", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["128"]}, + {"name": "RIPEMD-160", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["160"]}, + {"name": "RIPEMD-256", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["256"]}, + {"name": "RIPEMD-320", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["320"]}, + {"name": "HAS-160", "hash": (new HAS160()), "type": "arrayBuffer", params: []}, + {"name": "Whirlpool-0", "hash": (new Whirlpool()), "type": "arrayBuffer", params: ["Whirlpool-0"]}, + {"name": "Whirlpool-T", "hash": (new Whirlpool()), "type": "arrayBuffer", params: ["Whirlpool-T"]}, + {"name": "Whirlpool", "hash": (new Whirlpool()), "type": "arrayBuffer", params: ["Whirlpool"]}, + {"name": "BLAKE2b-128", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["128", "Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2b-160", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["160", "Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2b-256", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["256", "Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2b-384", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["384", "Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2b-512", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["512", "Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2s-128", "hash": (new BLAKE2s), "type": "arrayBuffer", params: ["128", "Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2s-160", "hash": (new BLAKE2s), "type": "arrayBuffer", params: ["160", "Hex", {string: "", option: "UTF8"}]}, + {"name": "BLAKE2s-256", "hash": (new BLAKE2s), "type": "arrayBuffer", params: ["256", "Hex", {string: "", option: "UTF8"}]}, + {"name": "Streebog-256", "hash": (new Streebog), "type": "arrayBuffer", params: ["256"]}, + {"name": "Streebog-512", "hash": (new Streebog), "type": "arrayBuffer", params: ["512"]}, + {"name": "GOST", "hash": (new GOSTHash), "type": "arrayBuffer", params: ["D-A"]}, + {"name": "SSDEEP", "hash": (new SSDEEP()), "type": "str"}, + {"name": "CTPH", "hash": (new CTPH()), "type": "str"} ]; this.checksums = [ {"name": "Fletcher-8: ", "checksum": (new Fletcher8Checksum), "type": "byteArray", "params": []}, @@ -133,13 +133,13 @@ class GenerateAllHashes extends Operation { str = Utils.arrayBufferToStr(arrayBuffer, false), byteArray = new Uint8Array(arrayBuffer); - var value, output = ""; + let value, output = ""; // iterate over each of the hashes this.hashes.forEach(function (hash) { // calculate the hash value - if (hash.type == "arrayBuffer") { + if (hash.type === "arrayBuffer") { value = hash.hash.run(arrayBuffer, hash.params); - } else if (hash.type == "str") { + } else if (hash.type === "str") { if ("params" in hash) { value = hash.hash.run(str, hash.params); } else { @@ -147,7 +147,7 @@ class GenerateAllHashes extends Operation { } } // output the values base on the args: length & names - if (length == "All" || value.length === parseInt(length)) { + if (length === "All" || value.length === parseInt(length)) { if (names) { output += hash.name + ":" + " ".repeat(13-hash.name.length); } @@ -155,7 +155,7 @@ class GenerateAllHashes extends Operation { } }); - if (length == "All") { + if (length === "All") { output += "\nChecksums:" + "\nFletcher-8: " + (new Fletcher8Checksum).run(byteArray, []) + "\nFletcher-16: " + (new Fletcher16Checksum).run(byteArray, []) + From 312be4772c877191e0c6d8a6e6d4f58d93111d37 Mon Sep 17 00:00:00 2001 From: john19696 Date: Fri, 23 Sep 2022 11:38:15 +0100 Subject: [PATCH 11/33] rsdix --- src/core/operations/GenerateAllHashes.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/GenerateAllHashes.mjs b/src/core/operations/GenerateAllHashes.mjs index 41817e25..02e0016f 100644 --- a/src/core/operations/GenerateAllHashes.mjs +++ b/src/core/operations/GenerateAllHashes.mjs @@ -147,7 +147,7 @@ class GenerateAllHashes extends Operation { } } // output the values base on the args: length & names - if (length === "All" || value.length === parseInt(length)) { + if (length === "All" || value.length === parseInt(length, 10)) { if (names) { output += hash.name + ":" + " ".repeat(13-hash.name.length); } From f1ce67d79b932808e65d8eb3f2323093f7e7f27b Mon Sep 17 00:00:00 2001 From: BrunonDEV <43315279+BrunonDEV@users.noreply.github.com> Date: Tue, 27 Sep 2022 23:13:22 +0200 Subject: [PATCH 12/33] Added NTLM operation Hashing operation - MD4 on UTF16LE-encoded input --- src/core/config/Categories.json | 3 ++- src/core/operations/NTLM.mjs | 46 +++++++++++++++++++++++++++++++++ tests/operations/index.mjs | 2 +- tests/operations/tests/NTLM.mjs | 22 ++++++++++++++++ 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 src/core/operations/NTLM.mjs create mode 100644 tests/operations/tests/NTLM.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 8ac60048..30d1389b 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -376,7 +376,8 @@ "CRC-8 Checksum", "CRC-16 Checksum", "CRC-32 Checksum", - "TCP/IP Checksum" + "TCP/IP Checksum", + "NTLM" ] }, { diff --git a/src/core/operations/NTLM.mjs b/src/core/operations/NTLM.mjs new file mode 100644 index 00000000..432b9aee --- /dev/null +++ b/src/core/operations/NTLM.mjs @@ -0,0 +1,46 @@ +/** + * @author brun0ne [brunonblok@gmail.com] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; + +import cptable from "codepage"; +import {runHash} from "../lib/Hash.mjs"; + +/** + * NTLM operation + */ +class NTLM extends Operation { + + /** + * NTLM constructor + */ + constructor() { + super(); + + this.name = "NTLM"; + this.module = "Crypto"; + this.description = "Performs NTLM hashing on the input. It works by running MD4 on UTF16LE-encoded input. NTLM hashes are considered weak because they can be brute-forced very easily with modern hardware."; + this.infoURL = "https://en.wikipedia.org/wiki/NT_LAN_Manager"; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const format = 1200; + const encoded = cptable.utils.encode(format, input); + const hashed = runHash("md4", encoded); + + return hashed.toUpperCase(); + } +} + +export default NTLM; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index f4294cad..9879552c 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -121,7 +121,7 @@ import "./tests/Subsection.mjs"; import "./tests/CaesarBoxCipher.mjs"; import "./tests/LS47.mjs"; import "./tests/LZString.mjs"; - +import "./tests/NTLM.mjs"; // Cannot test operations that use the File type yet // import "./tests/SplitColourChannels.mjs"; diff --git a/tests/operations/tests/NTLM.mjs b/tests/operations/tests/NTLM.mjs new file mode 100644 index 00000000..1dc39d5c --- /dev/null +++ b/tests/operations/tests/NTLM.mjs @@ -0,0 +1,22 @@ +/** + * NTLM test. + * + * @author brun0ne [brunonblok@gmail.com] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "NTLM Hashing", + input: "QWERTYUIOPASDFGHJKLZXCVBNM1234567890!@#$%^&*()_+.,?/", + expectedOutput: "C5FA1C40E55734A8E528DBFE21766D23", + recipeConfig: [ + { + op: "NTLM", + args: [], + }, + ], + } +]); From 026e9ca9c36a5280496e02e505ab6e7a236c74ab Mon Sep 17 00:00:00 2001 From: Igor Gariev Date: Wed, 28 Sep 2022 20:32:21 -0700 Subject: [PATCH 13/33] Added escape sequence "\a" (audible bell, 0x07) to Utils.parseEscapedChars(). The sequece is part of C and C++ standard, as well as protocol buffer encoding. - https://en.wikipedia.org/wiki/Escape_sequences_in_C - https://en.cppreference.com/w/cpp/language/escape - https://developers.google.com/protocol-buffers/docs/text-format-spec#string --- src/core/Utils.mjs | 4 +- tests/operations/index.mjs | 1 + tests/operations/tests/UnescapeString.mjs | 55 +++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 tests/operations/tests/UnescapeString.mjs diff --git a/src/core/Utils.mjs b/src/core/Utils.mjs index 66a98c36..31e17d1a 100755 --- a/src/core/Utils.mjs +++ b/src/core/Utils.mjs @@ -206,7 +206,7 @@ class Utils { * Utils.parseEscapedChars("\\n"); */ static parseEscapedChars(str) { - return str.replace(/\\([bfnrtv'"]|[0-3][0-7]{2}|[0-7]{1,2}|x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]{1,6}\}|\\)/g, function(m, a) { + return str.replace(/\\([abfnrtv'"]|[0-3][0-7]{2}|[0-7]{1,2}|x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]{1,6}\}|\\)/g, function(m, a) { switch (a[0]) { case "\\": return "\\"; @@ -219,6 +219,8 @@ class Utils { case "6": case "7": return String.fromCharCode(parseInt(a, 8)); + case "a": + return String.fromCharCode(7); case "b": return "\b"; case "t": diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index f4294cad..5245ba2f 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -119,6 +119,7 @@ import "./tests/SIGABA.mjs"; import "./tests/ELFInfo.mjs"; import "./tests/Subsection.mjs"; import "./tests/CaesarBoxCipher.mjs"; +import "./tests/UnescapeString.mjs"; import "./tests/LS47.mjs"; import "./tests/LZString.mjs"; diff --git a/tests/operations/tests/UnescapeString.mjs b/tests/operations/tests/UnescapeString.mjs new file mode 100644 index 00000000..7d3f9fda --- /dev/null +++ b/tests/operations/tests/UnescapeString.mjs @@ -0,0 +1,55 @@ +/** + * UnescapeString tests. + * + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "UnescapeString: escape sequences", + input: "\\a\\b\\f\\n\\r\\t\\v\\'\\\"", + expectedOutput: String.fromCharCode(0x07, 0x08, 0x0c, 0x0a, 0x0d, 0x09, + 0x0b, 0x27, 0x22), + recipeConfig: [ + { + op: "Unescape string", + args: [], + }, + ], + }, + { + name: "UnescapeString: octals", + input: "\\0\\01\\012\\1\\12", + expectedOutput: String.fromCharCode(0, 1, 10, 1, 10), + recipeConfig: [ + { + op: "Unescape string", + args: [], + }, + ], + }, + { + name: "UnescapeString: hexadecimals", + input: "\\x00\\xAA\\xaa", + expectedOutput: String.fromCharCode(0, 170, 170), + recipeConfig: [ + { + op: "Unescape string", + args: [], + }, + ], + }, + { + name: "UnescapeString: unicode", + input: "\\u0061\\u{0062}", + expectedOutput: "ab", + recipeConfig: [ + { + op: "Unescape string", + args: [], + }, + ], + }, +]); From a68ce5a5af9ca85703f4c6b44ceef0e61a7ff28b Mon Sep 17 00:00:00 2001 From: Frazer Smith Date: Thu, 6 Oct 2022 13:58:01 +0100 Subject: [PATCH 14/33] Update GitHub Actions --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/master.yml | 6 +++--- .github/workflows/pull_requests.yml | 4 ++-- .github/workflows/releases.yml | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e7877799..3fa7a23b 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -22,12 +22,12 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 4271e5da..d7880ff9 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -10,10 +10,10 @@ jobs: main: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set node version - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: node-version: '18.x' @@ -47,7 +47,7 @@ jobs: - name: Deploy to GitHub Pages if: success() && github.ref == 'refs/heads/master' - uses: crazy-max/ghaction-github-pages@v2 + uses: crazy-max/ghaction-github-pages@v3 with: target_branch: gh-pages build_dir: ./build/prod diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index 0c191607..0e746497 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -9,10 +9,10 @@ jobs: main: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set node version - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: node-version: '18.x' diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml index 9f09e99f..966fe1d5 100644 --- a/.github/workflows/releases.yml +++ b/.github/workflows/releases.yml @@ -10,10 +10,10 @@ jobs: main: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set node version - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: node-version: '18.x' From 32bee35f85df86addfd00698db8459faba6e2bdb Mon Sep 17 00:00:00 2001 From: XlogicX Date: Thu, 6 Oct 2022 13:53:32 -0400 Subject: [PATCH 15/33] Removal of unnecessary error checking routine This situation occurs because the dependancy (zlibjs/bin/rawinflate.min.js) doesn't do a sanity check on distances going back farther than the current buffer. For example: DEFLATE data of '123' and then a length of 9 going back a distance of 6 ASCIIHEX: 333432869300 ! infgen 3.0 output ! last ! 1 fixed ! 01 literal '1 ! 10000110 literal '2 ! 01000110 literal '3 ! 11000110 match 9 6 ! 1 00100 1110000 infgen warning: distance too far back (6/3) end ! 0000000 ! 0 We only have 3 characters, we shouldn't be able to seek 6 characters back. But rawinflate.min.js doesn't check for this like the infgen debug tool (and others) would. So CyberChef would happily provide this as the result: 123...123... Where the dots are just nulls of likley empty memory preceding the actual buffer So with the example in this source // e.g. Input data of [8b, 1d, dc, 44] last ! 1 fixed ! 01 literal '] ! 10110001 match 158 5 ! 0 00100 11011 10000011 infgen warning: distance too far back (5/1) This means we have a literal ']' and then we are asking for 158 more characters and to find them a distance of 5 back. This explains why the ']', why it repeats every 5, and why it is a length > 158. This code should just be removed; it isn't justified. Being that this issue is a lack of sanity checking in a dependancy, and that this routine only catches the symptom of one of the nearly unlimited edge cases like this, AND it could filter out correct inputs, such as a recipe of this as input to RAWDEFLATE ]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX Then getting an error with the INFLATE even though the input is actually valid. --- src/core/operations/RawInflate.mjs | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/core/operations/RawInflate.mjs b/src/core/operations/RawInflate.mjs index 4555f287..5bbb6e8e 100644 --- a/src/core/operations/RawInflate.mjs +++ b/src/core/operations/RawInflate.mjs @@ -83,24 +83,6 @@ class RawInflate extends Operation { }), result = new Uint8Array(inflate.decompress()); - // Raw Inflate sometimes messes up and returns nonsense like this: - // ]....]....]....]....]....]....]....]....]....]....]....]....]....]... - // e.g. Input data of [8b, 1d, dc, 44] - // Look for the first two square brackets: - if (result.length > 158 && result[0] === 93 && result[5] === 93) { - // If the first two square brackets are there, check that the others - // are also there. If they are, throw an error. If not, continue. - let valid = false; - for (let i = 0; i < 155; i += 5) { - if (result[i] !== 93) { - valid = true; - } - } - - if (!valid) { - throw new OperationError("Error: Unable to inflate data"); - } - } // This seems to be the easiest way... return result.buffer; } From 1a9a070c3bdf1b9de636e13c548e90d6e97bd853 Mon Sep 17 00:00:00 2001 From: XlogicX Date: Thu, 6 Oct 2022 14:02:27 -0400 Subject: [PATCH 16/33] Removal of unnecessary error condition This situation occurs because the dependancy (zlibjs/bin/rawinflate.min.js) doesn't do a sanity check on distances going back farther than the current buffer. For example: DEFLATE data of '123' and then a length of 9 going back a distance of 6 ASCIIHEX: 333432869300 ! infgen 3.0 output ! last ! 1 fixed ! 01 literal '1 ! 10000110 literal '2 ! 01000110 literal '3 ! 11000110 match 9 6 ! 1 00100 1110000 infgen warning: distance too far back (6/3) end ! 0000000 ! 0 We only have 3 characters, we shouldn't be able to seek 6 characters back. But rawinflate.min.js doesn't check for this like the infgen debug tool (and others) would. So CyberChef would happily provide this as the result: 123...123... Where the dots are just nulls of likley empty memory preceding the actual buffer So with the example in this source // e.g. Input data of [8b, 1d, dc, 44] last ! 1 fixed ! 01 literal '] ! 10110001 match 158 5 ! 0 00100 11011 10000011 infgen warning: distance too far back (5/1) This means we have a literal ']' and then we are asking for 158 more characters and to find them a distance of 5 back. This explains why the ']', why it repeats every 5, and why it is a length > 158. This code should just be removed; it isn't justified. Being that this issue is a lack of sanity checking in a dependancy, and that this routine only catches the symptom of one of the nearly unlimited edge cases like this, AND it could filter out correct inputs, such as a recipe of this as input to RAWDEFLATE ]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX[]OMG[]HAX Then getting an error with the INFLATE even though the input is actually valid. --- src/core/operations/RawInflate.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/operations/RawInflate.mjs b/src/core/operations/RawInflate.mjs index 5bbb6e8e..43ca07e9 100644 --- a/src/core/operations/RawInflate.mjs +++ b/src/core/operations/RawInflate.mjs @@ -7,7 +7,6 @@ import Operation from "../Operation.mjs"; import {INFLATE_BUFFER_TYPE} from "../lib/Zlib.mjs"; import rawinflate from "zlibjs/bin/rawinflate.min.js"; -import OperationError from "../errors/OperationError.mjs"; const Zlib = rawinflate.Zlib; From 674649ca7f8a867280a71c811640d00918eff932 Mon Sep 17 00:00:00 2001 From: Manatsawin Hanmongkolchai Date: Sun, 9 Oct 2022 14:57:02 +0700 Subject: [PATCH 17/33] Added checks to JWTDecode operation --- src/core/operations/JWTDecode.mjs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/operations/JWTDecode.mjs b/src/core/operations/JWTDecode.mjs index 07f19477..b6356b5a 100644 --- a/src/core/operations/JWTDecode.mjs +++ b/src/core/operations/JWTDecode.mjs @@ -26,6 +26,13 @@ class JWTDecode extends Operation { this.inputType = "string"; this.outputType = "JSON"; this.args = []; + this.checks = [ + { + pattern: "^ey([A-Za-z0-9_-]+)\\.ey([A-Za-z0-9_-]+)\\.([A-Za-z0-9_-]+)$", + flags: "", + args: [] + }, + ]; } /** From d5bcdc8eedbe81e007b79dd2edbce1dbb2f32adf Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 14 Oct 2022 13:57:00 +0100 Subject: [PATCH 18/33] Dependency fixes --- package-lock.json | 108 +++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/package-lock.json b/package-lock.json index a789a47c..7d116e95 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1920,13 +1920,13 @@ } }, "node_modules/@jimp/jpeg": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.16.1.tgz", - "integrity": "sha512-8352zrdlCCLFdZ/J+JjBslDvml+fS3Z8gttdml0We759PnnZGqrnPRhkOEOJbNUlE+dD4ckLeIe6NPxlS/7U+w==", + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.16.2.tgz", + "integrity": "sha512-BW5gZydgq6wdIwHd+3iUNgrTklvoQc/FUKSj9meM6A0FU21lUaansRX5BDdJqHkyXJLnnlDGwDt27J+hQuBAVw==", "dependencies": { "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.1", - "jpeg-js": "0.4.2" + "@jimp/utils": "^0.16.2", + "jpeg-js": "^0.4.2" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" @@ -2278,9 +2278,9 @@ } }, "node_modules/@jimp/utils": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.16.1.tgz", - "integrity": "sha512-8fULQjB0x4LzUSiSYG6ZtQl355sZjxbv8r9PPAuYHzS9sGiSHJQavNqK/nKnpDsVkU88/vRGcE7t3nMU0dEnVw==", + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.16.2.tgz", + "integrity": "sha512-XENrPvmigiXZQ8E2nxJqO6UVvWBLzbNwyYi3Y8Q1IECoYhYI3kgOQ0fmy4G269Vz1V0omh1bNmC42r4OfXg1Jg==", "dependencies": { "@babel/runtime": "^7.7.2", "regenerator-runtime": "^0.13.3" @@ -5086,9 +5086,9 @@ } }, "node_modules/d3-color": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.0.1.tgz", - "integrity": "sha512-6/SlHkDOBLyQSJ1j1Ghs82OIUXpKWlR0hCsw0XrLSQhuUPuCSmLQ1QPH98vpnQxMUQM2/gfAkUEWsupVpd9JGw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", "engines": { "node": ">=12" } @@ -8921,9 +8921,9 @@ } }, "node_modules/jpeg-js": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.2.tgz", - "integrity": "sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw==" + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==" }, "node_modules/jquery": { "version": "3.6.0", @@ -9037,9 +9037,9 @@ "integrity": "sha512-dxLob7q65Xg2DvstYkRpkYtmKm2sPJ9oFhrhmudT1dZvNFFTlroai3AWSpLey/w5vMcLBXRgOJsbXpdN9HzU/A==" }, "node_modules/jsrsasign": { - "version": "10.5.23", - "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.5.23.tgz", - "integrity": "sha512-e3hy//LH8EbRhzqyHJuf3pbehxYcnUZgGUjQKKTukWJ1M5uQTZBgFvItRK5ik8pixpYDAKY6xj527cEa1NQGPg==", + "version": "10.5.27", + "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.5.27.tgz", + "integrity": "sha512-1F4LmDeJZHYwoVvB44jEo2uZL3XuwYNzXCDOu53Ui6vqofGQ/gCYDmaxfVZtN0TGd92UKXr/BONcfrPonUIcQQ==", "funding": { "url": "https://github.com/kjur/jsrsasign#donations" } @@ -10114,17 +10114,17 @@ } }, "node_modules/moment": { - "version": "2.29.3", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz", - "integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw==", + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", "engines": { "node": "*" } }, "node_modules/moment-timezone": { - "version": "0.5.34", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.34.tgz", - "integrity": "sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==", + "version": "0.5.37", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.37.tgz", + "integrity": "sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==", "dependencies": { "moment": ">= 2.9.0" }, @@ -12481,7 +12481,7 @@ "node_modules/shelljs": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", - "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=", + "integrity": "sha512-C2FisSSW8S6TIYHHiMHN0NqzdjWfTekdMpA2FJTbRWnQMLO1RRIXEB9eVZYOlofYmjZA7fY3ChoFu09MeI3wlQ==", "dev": true, "bin": { "shjs": "bin/shjs" @@ -12863,9 +12863,9 @@ } }, "node_modules/terser": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.0.tgz", - "integrity": "sha512-JC6qfIEkPBd9j1SMO3Pfn+A6w2kQV54tv+ABQLgZr7dA3k/DL/OBoYSWxzVpZev3J+bUHXfr55L8Mox7AaNo6g==", + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", + "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.2", @@ -15561,13 +15561,13 @@ } }, "@jimp/jpeg": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.16.1.tgz", - "integrity": "sha512-8352zrdlCCLFdZ/J+JjBslDvml+fS3Z8gttdml0We759PnnZGqrnPRhkOEOJbNUlE+dD4ckLeIe6NPxlS/7U+w==", + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.16.2.tgz", + "integrity": "sha512-BW5gZydgq6wdIwHd+3iUNgrTklvoQc/FUKSj9meM6A0FU21lUaansRX5BDdJqHkyXJLnnlDGwDt27J+hQuBAVw==", "requires": { "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.1", - "jpeg-js": "0.4.2" + "@jimp/utils": "^0.16.2", + "jpeg-js": "^0.4.2" } }, "@jimp/plugin-blit": { @@ -15825,9 +15825,9 @@ } }, "@jimp/utils": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.16.1.tgz", - "integrity": "sha512-8fULQjB0x4LzUSiSYG6ZtQl355sZjxbv8r9PPAuYHzS9sGiSHJQavNqK/nKnpDsVkU88/vRGcE7t3nMU0dEnVw==", + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.16.2.tgz", + "integrity": "sha512-XENrPvmigiXZQ8E2nxJqO6UVvWBLzbNwyYi3Y8Q1IECoYhYI3kgOQ0fmy4G269Vz1V0omh1bNmC42r4OfXg1Jg==", "requires": { "@babel/runtime": "^7.7.2", "regenerator-runtime": "^0.13.3" @@ -18099,9 +18099,9 @@ } }, "d3-color": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.0.1.tgz", - "integrity": "sha512-6/SlHkDOBLyQSJ1j1Ghs82OIUXpKWlR0hCsw0XrLSQhuUPuCSmLQ1QPH98vpnQxMUQM2/gfAkUEWsupVpd9JGw==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==" }, "d3-contour": { "version": "3.0.1", @@ -21000,9 +21000,9 @@ } }, "jpeg-js": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.2.tgz", - "integrity": "sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw==" + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==" }, "jquery": { "version": "3.6.0", @@ -21093,9 +21093,9 @@ "integrity": "sha512-dxLob7q65Xg2DvstYkRpkYtmKm2sPJ9oFhrhmudT1dZvNFFTlroai3AWSpLey/w5vMcLBXRgOJsbXpdN9HzU/A==" }, "jsrsasign": { - "version": "10.5.23", - "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.5.23.tgz", - "integrity": "sha512-e3hy//LH8EbRhzqyHJuf3pbehxYcnUZgGUjQKKTukWJ1M5uQTZBgFvItRK5ik8pixpYDAKY6xj527cEa1NQGPg==" + "version": "10.5.27", + "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.5.27.tgz", + "integrity": "sha512-1F4LmDeJZHYwoVvB44jEo2uZL3XuwYNzXCDOu53Ui6vqofGQ/gCYDmaxfVZtN0TGd92UKXr/BONcfrPonUIcQQ==" }, "jszip": { "version": "2.5.0", @@ -21970,14 +21970,14 @@ } }, "moment": { - "version": "2.29.3", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz", - "integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw==" + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" }, "moment-timezone": { - "version": "0.5.34", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.34.tgz", - "integrity": "sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==", + "version": "0.5.37", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.37.tgz", + "integrity": "sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==", "requires": { "moment": ">= 2.9.0" } @@ -23802,7 +23802,7 @@ "shelljs": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", - "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=", + "integrity": "sha512-C2FisSSW8S6TIYHHiMHN0NqzdjWfTekdMpA2FJTbRWnQMLO1RRIXEB9eVZYOlofYmjZA7fY3ChoFu09MeI3wlQ==", "dev": true }, "signal-exit": { @@ -24096,9 +24096,9 @@ } }, "terser": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.0.tgz", - "integrity": "sha512-JC6qfIEkPBd9j1SMO3Pfn+A6w2kQV54tv+ABQLgZr7dA3k/DL/OBoYSWxzVpZev3J+bUHXfr55L8Mox7AaNo6g==", + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", + "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", "dev": true, "requires": { "@jridgewell/source-map": "^0.3.2", From 40b58aa14485e1b295415fb876c5e40acd7f596b Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 14 Oct 2022 13:57:35 +0100 Subject: [PATCH 19/33] 9.46.6 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7d116e95..919f5ccf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.46.5", + "version": "9.46.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.46.5", + "version": "9.46.6", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index f6ba31d0..be608cdd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.46.5", + "version": "9.46.6", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 576905e8b8fe2faf7ab201d488d95d0eab8ab1d2 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 14 Oct 2022 14:01:05 +0100 Subject: [PATCH 20/33] 9.46.7 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 919f5ccf..dc5f8fc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.46.6", + "version": "9.46.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.46.6", + "version": "9.46.7", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index be608cdd..11b39874 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.46.6", + "version": "9.46.7", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 11902e322004dc4f7fe8621b133ca092b2199535 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 14 Oct 2022 14:07:42 +0100 Subject: [PATCH 21/33] Updated CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5d0712d..3d13c50d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ All major and minor version changes will be documented in this file. Details of ## Details +### [9.47.0] - 2022-10-14 +- Added 'LZMA Decompress' and 'LZMA Compress' operations [@mattnotmitt] | [#1421] + ### [9.46.0] - 2022-07-08 - Added 'Cetacean Cipher Encode' and 'Cetacean Cipher Decode' operations [@valdelaseras] | [#1308] @@ -315,6 +318,7 @@ All major and minor version changes will be documented in this file. Details of +[9.47.0]: https://github.com/gchq/CyberChef/releases/tag/v9.47.0 [9.46.0]: https://github.com/gchq/CyberChef/releases/tag/v9.46.0 [9.45.0]: https://github.com/gchq/CyberChef/releases/tag/v9.45.0 [9.44.0]: https://github.com/gchq/CyberChef/releases/tag/v9.44.0 @@ -552,4 +556,5 @@ All major and minor version changes will be documented in this file. Details of [#1266]: https://github.com/gchq/CyberChef/pull/1266 [#1250]: https://github.com/gchq/CyberChef/pull/1250 [#1308]: https://github.com/gchq/CyberChef/pull/1308 +[#1421]: https://github.com/gchq/CyberChef/pull/1421 From 9ba9c56361604d430c966ec6ff5b7c3f7126d173 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 14 Oct 2022 14:07:47 +0100 Subject: [PATCH 22/33] 9.47.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a53169bb..b675d17f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.46.7", + "version": "9.47.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.46.7", + "version": "9.47.0", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 0eda9a6b..a890b1ee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.46.7", + "version": "9.47.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 66277cd71f1517efb527309cc6aa751dc22474b1 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 14 Oct 2022 14:47:19 +0100 Subject: [PATCH 23/33] Added more DNS request types --- src/core/operations/DNSOverHTTPS.mjs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/core/operations/DNSOverHTTPS.mjs b/src/core/operations/DNSOverHTTPS.mjs index a7ab3aff..87381226 100644 --- a/src/core/operations/DNSOverHTTPS.mjs +++ b/src/core/operations/DNSOverHTTPS.mjs @@ -51,11 +51,27 @@ class DNSOverHTTPS extends Operation { value: [ "A", "AAAA", - "TXT", - "MX", + "ANAME", + "CERT", + "CNAME", "DNSKEY", + "HTTPS", + "IPSECKEY", + "LOC", + "MX", "NS", - "PTR" + "OPENPGPKEY", + "PTR", + "RRSIG", + "SIG", + "SOA", + "SPF", + "SRV", + "SSHFP", + "TA", + "TXT", + "URI", + "ANY" ] }, { From 04ef095b881687fcb7e1a333da0b7411b821cd0e Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 14 Oct 2022 14:47:30 +0100 Subject: [PATCH 24/33] 9.47.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b675d17f..0ef70177 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.47.0", + "version": "9.47.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.47.0", + "version": "9.47.1", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index a890b1ee..4d6d3330 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.47.0", + "version": "9.47.1", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 5d65cb419f4c00f9bbf4092c86fde225102021c7 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 14 Oct 2022 16:10:01 +0100 Subject: [PATCH 25/33] Tidied up 'Generate all hashes' operation --- src/core/operations/GenerateAllHashes.mjs | 208 +++++++++++-------- tests/operations/tests/GenerateAllHashes.mjs | 7 +- 2 files changed, 121 insertions(+), 94 deletions(-) diff --git a/src/core/operations/GenerateAllHashes.mjs b/src/core/operations/GenerateAllHashes.mjs index 02e0016f..8678ef65 100644 --- a/src/core/operations/GenerateAllHashes.mjs +++ b/src/core/operations/GenerateAllHashes.mjs @@ -1,6 +1,7 @@ /** + * @author n1474335 [n1474335@gmail.com] * @author john19696 [john19696@protonmail.com] - * @copyright Crown Copyright 2023 + * @copyright Crown Copyright 2016 * @license Apache-2.0 */ @@ -33,6 +34,7 @@ import BLAKE2b from "./BLAKE2b.mjs"; import BLAKE2s from "./BLAKE2s.mjs"; import Streebog from "./Streebog.mjs"; import GOSTHash from "./GOSTHash.mjs"; +import OperationError from "../errors/OperationError.mjs"; /** * Generate all hashes operation @@ -53,70 +55,70 @@ class GenerateAllHashes extends Operation { this.outputType = "string"; this.args = [ { - "name": "Length", - "type": "option", - "value": [ - "All", "32", "40", "56", "64", "80", "96", "128" + name: "Length (bits)", + type: "option", + value: [ + "All", "128", "160", "224", "256", "320", "384", "512" ] }, { - "name": "Output hash names", - "type": "boolean", - "value": true + name: "Include names", + type: "boolean", + value: true }, ]; this.hashes = [ - {"name": "MD2", "hash": (new MD2()), "type": "arrayBuffer", params: []}, - {"name": "MD4", "hash": (new MD4()), "type": "arrayBuffer", params: []}, - {"name": "MD5", "hash": (new MD5()), "type": "arrayBuffer", params: []}, - {"name": "MD6", "hash": (new MD6()), "type": "str", params: []}, - {"name": "SHA0", "hash": (new SHA0()), "type": "arrayBuffer", params: []}, - {"name": "SHA1", "hash": (new SHA1()), "type": "arrayBuffer", params: []}, - {"name": "SHA2 224", "hash": (new SHA2()), "type": "arrayBuffer", params: ["224"]}, - {"name": "SHA2 256", "hash": (new SHA2()), "type": "arrayBuffer", params: ["256"]}, - {"name": "SHA2 384", "hash": (new SHA2()), "type": "arrayBuffer", params: ["384"]}, - {"name": "SHA2 512", "hash": (new SHA2()), "type": "arrayBuffer", params: ["512"]}, - {"name": "SHA3 224", "hash": (new SHA3()), "type": "arrayBuffer", params: ["224"]}, - {"name": "SHA3 256", "hash": (new SHA3()), "type": "arrayBuffer", params: ["256"]}, - {"name": "SHA3 384", "hash": (new SHA3()), "type": "arrayBuffer", params: ["384"]}, - {"name": "SHA3 512", "hash": (new SHA3()), "type": "arrayBuffer", params: ["512"]}, - {"name": "Keccak 224", "hash": (new Keccak()), "type": "arrayBuffer", params: ["224"]}, - {"name": "Keccak 256", "hash": (new Keccak()), "type": "arrayBuffer", params: ["256"]}, - {"name": "Keccak 384", "hash": (new Keccak()), "type": "arrayBuffer", params: ["384"]}, - {"name": "Keccak 512", "hash": (new Keccak()), "type": "arrayBuffer", params: ["512"]}, - {"name": "Shake 128", "hash": (new Shake()), "type": "arrayBuffer", params: ["128", 256]}, - {"name": "Shake 256", "hash": (new Shake()), "type": "arrayBuffer", params: ["256", 512]}, - {"name": "RIPEMD-128", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["128"]}, - {"name": "RIPEMD-160", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["160"]}, - {"name": "RIPEMD-256", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["256"]}, - {"name": "RIPEMD-320", "hash": (new RIPEMD()), "type": "arrayBuffer", params: ["320"]}, - {"name": "HAS-160", "hash": (new HAS160()), "type": "arrayBuffer", params: []}, - {"name": "Whirlpool-0", "hash": (new Whirlpool()), "type": "arrayBuffer", params: ["Whirlpool-0"]}, - {"name": "Whirlpool-T", "hash": (new Whirlpool()), "type": "arrayBuffer", params: ["Whirlpool-T"]}, - {"name": "Whirlpool", "hash": (new Whirlpool()), "type": "arrayBuffer", params: ["Whirlpool"]}, - {"name": "BLAKE2b-128", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["128", "Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2b-160", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["160", "Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2b-256", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["256", "Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2b-384", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["384", "Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2b-512", "hash": (new BLAKE2b), "type": "arrayBuffer", params: ["512", "Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2s-128", "hash": (new BLAKE2s), "type": "arrayBuffer", params: ["128", "Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2s-160", "hash": (new BLAKE2s), "type": "arrayBuffer", params: ["160", "Hex", {string: "", option: "UTF8"}]}, - {"name": "BLAKE2s-256", "hash": (new BLAKE2s), "type": "arrayBuffer", params: ["256", "Hex", {string: "", option: "UTF8"}]}, - {"name": "Streebog-256", "hash": (new Streebog), "type": "arrayBuffer", params: ["256"]}, - {"name": "Streebog-512", "hash": (new Streebog), "type": "arrayBuffer", params: ["512"]}, - {"name": "GOST", "hash": (new GOSTHash), "type": "arrayBuffer", params: ["D-A"]}, - {"name": "SSDEEP", "hash": (new SSDEEP()), "type": "str"}, - {"name": "CTPH", "hash": (new CTPH()), "type": "str"} + {name: "MD2", algo: (new MD2()), inputType: "arrayBuffer", params: []}, + {name: "MD4", algo: (new MD4()), inputType: "arrayBuffer", params: []}, + {name: "MD5", algo: (new MD5()), inputType: "arrayBuffer", params: []}, + {name: "MD6", algo: (new MD6()), inputType: "str", params: []}, + {name: "SHA0", algo: (new SHA0()), inputType: "arrayBuffer", params: []}, + {name: "SHA1", algo: (new SHA1()), inputType: "arrayBuffer", params: []}, + {name: "SHA2 224", algo: (new SHA2()), inputType: "arrayBuffer", params: ["224"]}, + {name: "SHA2 256", algo: (new SHA2()), inputType: "arrayBuffer", params: ["256"]}, + {name: "SHA2 384", algo: (new SHA2()), inputType: "arrayBuffer", params: ["384"]}, + {name: "SHA2 512", algo: (new SHA2()), inputType: "arrayBuffer", params: ["512"]}, + {name: "SHA3 224", algo: (new SHA3()), inputType: "arrayBuffer", params: ["224"]}, + {name: "SHA3 256", algo: (new SHA3()), inputType: "arrayBuffer", params: ["256"]}, + {name: "SHA3 384", algo: (new SHA3()), inputType: "arrayBuffer", params: ["384"]}, + {name: "SHA3 512", algo: (new SHA3()), inputType: "arrayBuffer", params: ["512"]}, + {name: "Keccak 224", algo: (new Keccak()), inputType: "arrayBuffer", params: ["224"]}, + {name: "Keccak 256", algo: (new Keccak()), inputType: "arrayBuffer", params: ["256"]}, + {name: "Keccak 384", algo: (new Keccak()), inputType: "arrayBuffer", params: ["384"]}, + {name: "Keccak 512", algo: (new Keccak()), inputType: "arrayBuffer", params: ["512"]}, + {name: "Shake 128", algo: (new Shake()), inputType: "arrayBuffer", params: ["128", 256]}, + {name: "Shake 256", algo: (new Shake()), inputType: "arrayBuffer", params: ["256", 512]}, + {name: "RIPEMD-128", algo: (new RIPEMD()), inputType: "arrayBuffer", params: ["128"]}, + {name: "RIPEMD-160", algo: (new RIPEMD()), inputType: "arrayBuffer", params: ["160"]}, + {name: "RIPEMD-256", algo: (new RIPEMD()), inputType: "arrayBuffer", params: ["256"]}, + {name: "RIPEMD-320", algo: (new RIPEMD()), inputType: "arrayBuffer", params: ["320"]}, + {name: "HAS-160", algo: (new HAS160()), inputType: "arrayBuffer", params: []}, + {name: "Whirlpool-0", algo: (new Whirlpool()), inputType: "arrayBuffer", params: ["Whirlpool-0"]}, + {name: "Whirlpool-T", algo: (new Whirlpool()), inputType: "arrayBuffer", params: ["Whirlpool-T"]}, + {name: "Whirlpool", algo: (new Whirlpool()), inputType: "arrayBuffer", params: ["Whirlpool"]}, + {name: "BLAKE2b-128", algo: (new BLAKE2b), inputType: "arrayBuffer", params: ["128", "Hex", {string: "", option: "UTF8"}]}, + {name: "BLAKE2b-160", algo: (new BLAKE2b), inputType: "arrayBuffer", params: ["160", "Hex", {string: "", option: "UTF8"}]}, + {name: "BLAKE2b-256", algo: (new BLAKE2b), inputType: "arrayBuffer", params: ["256", "Hex", {string: "", option: "UTF8"}]}, + {name: "BLAKE2b-384", algo: (new BLAKE2b), inputType: "arrayBuffer", params: ["384", "Hex", {string: "", option: "UTF8"}]}, + {name: "BLAKE2b-512", algo: (new BLAKE2b), inputType: "arrayBuffer", params: ["512", "Hex", {string: "", option: "UTF8"}]}, + {name: "BLAKE2s-128", algo: (new BLAKE2s), inputType: "arrayBuffer", params: ["128", "Hex", {string: "", option: "UTF8"}]}, + {name: "BLAKE2s-160", algo: (new BLAKE2s), inputType: "arrayBuffer", params: ["160", "Hex", {string: "", option: "UTF8"}]}, + {name: "BLAKE2s-256", algo: (new BLAKE2s), inputType: "arrayBuffer", params: ["256", "Hex", {string: "", option: "UTF8"}]}, + {name: "Streebog-256", algo: (new Streebog), inputType: "arrayBuffer", params: ["256"]}, + {name: "Streebog-512", algo: (new Streebog), inputType: "arrayBuffer", params: ["512"]}, + {name: "GOST", algo: (new GOSTHash), inputType: "arrayBuffer", params: ["D-A"]}, + {name: "SSDEEP", algo: (new SSDEEP()), inputType: "str"}, + {name: "CTPH", algo: (new CTPH()), inputType: "str"} ]; this.checksums = [ - {"name": "Fletcher-8: ", "checksum": (new Fletcher8Checksum), "type": "byteArray", "params": []}, - {"name": "Fletcher-16: ", "checksum": (new Fletcher16Checksum), "type": "byteArray", "params": []}, - {"name": "Fletcher-32: ", "checksum": (new Fletcher32Checksum), "type": "byteArray", "params": []}, - {"name": "Fletcher-64: ", "checksum": (new Fletcher64Checksum), "type": "byteArray", "params": []}, - {"name": "Adler-32: ", "checksum": (new Adler32Checksum), "type": "byteArray", "params": []}, - {"name": "CRC-8: ", "checksum": (new CRC8Checksum), "type": "arrayBuffer", "params": ["CRC-8"]}, - {"name": "CRC-16: ", "checksum": (new CRC16Checksum), "type": "arrayBuffer", "params": []}, - {"name": "CRC-32: ", "checksum": (new CRC32Checksum), "type": "arrayBuffer", "params": []} + {name: "Fletcher-8", algo: (new Fletcher8Checksum), inputType: "byteArray", params: []}, + {name: "Fletcher-16", algo: (new Fletcher16Checksum), inputType: "byteArray", params: []}, + {name: "Fletcher-32", algo: (new Fletcher32Checksum), inputType: "byteArray", params: []}, + {name: "Fletcher-64", algo: (new Fletcher64Checksum), inputType: "byteArray", params: []}, + {name: "Adler-32", algo: (new Adler32Checksum), inputType: "byteArray", params: []}, + {name: "CRC-8", algo: (new CRC8Checksum), inputType: "arrayBuffer", params: ["CRC-8"]}, + {name: "CRC-16", algo: (new CRC16Checksum), inputType: "arrayBuffer", params: []}, + {name: "CRC-32", algo: (new CRC32Checksum), inputType: "arrayBuffer", params: []} ]; } @@ -126,50 +128,74 @@ class GenerateAllHashes extends Operation { * @returns {string} */ run(input, args) { - const length = args[0]; - const names = args[1]; + const [length, includeNames] = args; + this.inputArrayBuffer = input; + this.inputStr = Utils.arrayBufferToStr(input, false); + this.inputByteArray = new Uint8Array(input); - const arrayBuffer = input, - str = Utils.arrayBufferToStr(arrayBuffer, false), - byteArray = new Uint8Array(arrayBuffer); - - let value, output = ""; + let digest, output = ""; // iterate over each of the hashes - this.hashes.forEach(function (hash) { - // calculate the hash value - if (hash.type === "arrayBuffer") { - value = hash.hash.run(arrayBuffer, hash.params); - } else if (hash.type === "str") { - if ("params" in hash) { - value = hash.hash.run(str, hash.params); - } else { - value = hash.hash.run(str); - } - } - // output the values base on the args: length & names - if (length === "All" || value.length === parseInt(length, 10)) { - if (names) { - output += hash.name + ":" + " ".repeat(13-hash.name.length); - } - output += value + "\n"; - } + this.hashes.forEach(hash => { + digest = this.executeAlgo(hash.algo, hash.inputType, hash.params || []); + output += this.formatDigest(digest, length, includeNames, hash.name); }); if (length === "All") { - output += "\nChecksums:" + - "\nFletcher-8: " + (new Fletcher8Checksum).run(byteArray, []) + - "\nFletcher-16: " + (new Fletcher16Checksum).run(byteArray, []) + - "\nFletcher-32: " + (new Fletcher32Checksum).run(byteArray, []) + - "\nFletcher-64: " + (new Fletcher64Checksum).run(byteArray, []) + - "\nAdler-32: " + (new Adler32Checksum).run(byteArray, []) + - "\nCRC-8: " + (new CRC8Checksum).run(arrayBuffer, ["CRC-8"]) + - "\nCRC-16: " + (new CRC16Checksum).run(arrayBuffer, []) + - "\nCRC-32: " + (new CRC32Checksum).run(arrayBuffer, []); + output += "\nChecksums:\n"; + this.checksums.forEach(checksum => { + digest = this.executeAlgo(checksum.algo, checksum.inputType, checksum.params || []); + output += this.formatDigest(digest, length, includeNames, checksum.name); + }); } return output; } + /** + * Executes a hash or checksum algorithm + * + * @param {Function} algo - The hash or checksum algorithm + * @param {string} inputType + * @param {Object[]} [params=[]] + * @returns {string} + */ + executeAlgo(algo, inputType, params=[]) { + let digest = null; + switch (inputType) { + case "arrayBuffer": + digest = algo.run(this.inputArrayBuffer, params); + break; + case "str": + digest = algo.run(this.inputStr, params); + break; + case "byteArray": + digest = algo.run(this.inputByteArray, params); + break; + default: + throw new OperationError("Unknown hash input type: " + inputType); + } + + return digest; + } + + /** + * Formats the digest depending on user-specified arguments + * @param {string} digest + * @param {string} length + * @param {boolean} includeNames + * @param {string} name + * @returns {string} + */ + formatDigest(digest, length, includeNames, name) { + if (length !== "All" && (digest.length * 4) !== parseInt(length, 10)) + return ""; + + if (!includeNames) + return digest + "\n"; + + return `${name}:${" ".repeat(13-name.length)}${digest}\n`; + } + } export default GenerateAllHashes; diff --git a/tests/operations/tests/GenerateAllHashes.mjs b/tests/operations/tests/GenerateAllHashes.mjs index 857135e6..3e9b82b8 100644 --- a/tests/operations/tests/GenerateAllHashes.mjs +++ b/tests/operations/tests/GenerateAllHashes.mjs @@ -61,7 +61,8 @@ Fletcher-64: 00000459000001c0 Adler-32: 045d01c1 CRC-8: b9 CRC-16: f82e -CRC-32: d87f7e0c`, +CRC-32: d87f7e0c +`, recipeConfig: [ { "op": "Generate all hashes", @@ -82,7 +83,7 @@ BLAKE2s-128: e9ddd9926b9dcb382e09be39ba403d2c recipeConfig: [ { "op": "Generate all hashes", - "args": ["32", true] + "args": ["128", true] } ] }, @@ -103,7 +104,7 @@ ee67303696d205ddd2b2363e8e01b4b7199a80957d94d7678eaad3fc834c5a27 recipeConfig: [ { "op": "Generate all hashes", - "args": ["64", false] + "args": ["256", false] } ] } From e33950961e52165840d5dfc37e195671b02c527c Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 14 Oct 2022 16:10:19 +0100 Subject: [PATCH 26/33] 9.47.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0ef70177..98d16237 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.47.1", + "version": "9.47.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.47.1", + "version": "9.47.2", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 4d6d3330..d5d28f92 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.47.1", + "version": "9.47.2", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From e4db23f85767fb597b5f9cd0dfb678e5194796e2 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 14 Oct 2022 16:20:34 +0100 Subject: [PATCH 27/33] Removed extra comment from Raw Inflate --- src/core/operations/RawInflate.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/operations/RawInflate.mjs b/src/core/operations/RawInflate.mjs index 43ca07e9..f5b57bde 100644 --- a/src/core/operations/RawInflate.mjs +++ b/src/core/operations/RawInflate.mjs @@ -82,7 +82,6 @@ class RawInflate extends Operation { }), result = new Uint8Array(inflate.decompress()); - // This seems to be the easiest way... return result.buffer; } From 0f1175bf15bac17e615b99f197a955b24edc0c7c Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 14 Oct 2022 16:20:38 +0100 Subject: [PATCH 28/33] 9.47.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 98d16237..14571ebe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.47.2", + "version": "9.47.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.47.2", + "version": "9.47.3", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index d5d28f92..95375b14 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.47.2", + "version": "9.47.3", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From f332ca461766af1de47d2a62de5e3b55bc1fbc8a Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 14 Oct 2022 16:24:33 +0100 Subject: [PATCH 29/33] 9.47.4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 14571ebe..2a7fa973 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.47.3", + "version": "9.47.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.47.3", + "version": "9.47.4", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 95375b14..d02827cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.47.3", + "version": "9.47.4", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 64c009f266955da5114927d6fde6226ce3773203 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 14 Oct 2022 16:28:10 +0100 Subject: [PATCH 30/33] 9.47.5 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2a7fa973..3e851ebe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.47.4", + "version": "9.47.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.47.4", + "version": "9.47.5", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index d02827cd..f15eae76 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.47.4", + "version": "9.47.5", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 142f91425cd2a0654a30b5d64ce5987fdb9e6359 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Sat, 15 Oct 2022 00:13:39 +0100 Subject: [PATCH 31/33] Added 'LM Hash' opertaion --- package-lock.json | 14 +++++++ package.json | 3 +- src/core/config/Categories.json | 5 ++- src/core/operations/GenerateAllHashes.mjs | 4 ++ src/core/operations/LMHash.mjs | 41 ++++++++++++++++++++ src/core/operations/{NTLM.mjs => NTHash.mjs} | 16 ++++---- tests/operations/tests/GenerateAllHashes.mjs | 4 ++ tests/operations/tests/NTLM.mjs | 18 +++++++-- 8 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 src/core/operations/LMHash.mjs rename src/core/operations/{NTLM.mjs => NTHash.mjs} (57%) diff --git a/package-lock.json b/package-lock.json index 3e851ebe..f731b882 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,6 +66,7 @@ "node-md6": "^0.1.0", "nodom": "^2.4.0", "notepack.io": "^3.0.1", + "ntlm": "^0.1.3", "nwmatcher": "^1.4.4", "otp": "0.1.3", "path": "^0.12.7", @@ -10537,6 +10538,14 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/ntlm": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ntlm/-/ntlm-0.1.3.tgz", + "integrity": "sha512-pPlHxhAegZP4QAaOYd51vRd6VXTGfF7VLKJwuwN0iEB1aIi3SnqXYuS/bH/6wWBOq+Ehdil49mHm1Nseon085w==", + "engines": [ + "node" + ] + }, "node_modules/nwmatcher": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", @@ -22304,6 +22313,11 @@ "boolbase": "^1.0.0" } }, + "ntlm": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ntlm/-/ntlm-0.1.3.tgz", + "integrity": "sha512-pPlHxhAegZP4QAaOYd51vRd6VXTGfF7VLKJwuwN0iEB1aIi3SnqXYuS/bH/6wWBOq+Ehdil49mHm1Nseon085w==" + }, "nwmatcher": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", diff --git a/package.json b/package.json index f15eae76..51ec1adb 100644 --- a/package.json +++ b/package.json @@ -142,6 +142,7 @@ "node-md6": "^0.1.0", "nodom": "^2.4.0", "notepack.io": "^3.0.1", + "ntlm": "^0.1.3", "nwmatcher": "^1.4.4", "otp": "0.1.3", "path": "^0.12.7", @@ -170,7 +171,7 @@ "build": "npx grunt prod", "node": "npx grunt node", "repl": "node --experimental-modules --experimental-json-modules --experimental-specifier-resolution=node --no-warnings src/node/repl.mjs", - "test": "npx grunt configTests && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation tests/node/index.mjs && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation tests/operations/index.mjs", + "test": "npx grunt configTests && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation --openssl-legacy-provider tests/node/index.mjs && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation --openssl-legacy-provider tests/operations/index.mjs", "testnodeconsumer": "npx grunt testnodeconsumer", "testui": "npx grunt testui", "testuidev": "npx nightwatch --env=dev", diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 1db99db1..43d5dc4e 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -369,6 +369,8 @@ "Bcrypt compare", "Bcrypt parse", "Scrypt", + "NT Hash", + "LM Hash", "Fletcher-8 Checksum", "Fletcher-16 Checksum", "Fletcher-32 Checksum", @@ -378,8 +380,7 @@ "CRC-8 Checksum", "CRC-16 Checksum", "CRC-32 Checksum", - "TCP/IP Checksum", - "NTLM" + "TCP/IP Checksum" ] }, { diff --git a/src/core/operations/GenerateAllHashes.mjs b/src/core/operations/GenerateAllHashes.mjs index 8678ef65..2a4a2b1a 100644 --- a/src/core/operations/GenerateAllHashes.mjs +++ b/src/core/operations/GenerateAllHashes.mjs @@ -34,6 +34,8 @@ import BLAKE2b from "./BLAKE2b.mjs"; import BLAKE2s from "./BLAKE2s.mjs"; import Streebog from "./Streebog.mjs"; import GOSTHash from "./GOSTHash.mjs"; +import LMHash from "./LMHash.mjs"; +import NTHash from "./NTHash.mjs"; import OperationError from "../errors/OperationError.mjs"; /** @@ -107,6 +109,8 @@ class GenerateAllHashes extends Operation { {name: "Streebog-256", algo: (new Streebog), inputType: "arrayBuffer", params: ["256"]}, {name: "Streebog-512", algo: (new Streebog), inputType: "arrayBuffer", params: ["512"]}, {name: "GOST", algo: (new GOSTHash), inputType: "arrayBuffer", params: ["D-A"]}, + {name: "LM Hash", algo: (new LMHash), inputType: "str", params: []}, + {name: "NT Hash", algo: (new NTHash), inputType: "str", params: []}, {name: "SSDEEP", algo: (new SSDEEP()), inputType: "str"}, {name: "CTPH", algo: (new CTPH()), inputType: "str"} ]; diff --git a/src/core/operations/LMHash.mjs b/src/core/operations/LMHash.mjs new file mode 100644 index 00000000..2bedf0e8 --- /dev/null +++ b/src/core/operations/LMHash.mjs @@ -0,0 +1,41 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import {smbhash} from "ntlm"; + +/** + * LM Hash operation + */ +class LMHash extends Operation { + + /** + * LMHash constructor + */ + constructor() { + super(); + + this.name = "LM Hash"; + this.module = "Crypto"; + this.description = "An LM Hash, or LAN Manager Hash, is a deprecated way of storing passwords on old Microsoft operating systems. It is particularly weak and can be cracked in seconds on modern hardware using rainbow tables."; + this.infoURL = "https://wikipedia.org/wiki/LAN_Manager#Password_hashing_algorithm"; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return smbhash.lmhash(input); + } + +} + +export default LMHash; diff --git a/src/core/operations/NTLM.mjs b/src/core/operations/NTHash.mjs similarity index 57% rename from src/core/operations/NTLM.mjs rename to src/core/operations/NTHash.mjs index 432b9aee..51318135 100644 --- a/src/core/operations/NTLM.mjs +++ b/src/core/operations/NTHash.mjs @@ -10,20 +10,20 @@ import cptable from "codepage"; import {runHash} from "../lib/Hash.mjs"; /** - * NTLM operation + * NT Hash operation */ -class NTLM extends Operation { +class NTHash extends Operation { /** - * NTLM constructor + * NTHash constructor */ constructor() { super(); - this.name = "NTLM"; + this.name = "NT Hash"; this.module = "Crypto"; - this.description = "Performs NTLM hashing on the input. It works by running MD4 on UTF16LE-encoded input. NTLM hashes are considered weak because they can be brute-forced very easily with modern hardware."; - this.infoURL = "https://en.wikipedia.org/wiki/NT_LAN_Manager"; + this.description = "An NT Hash, sometimes referred to as an NTLM hash, is a method of storing passwords on Windows systems. It works by running MD4 on UTF-16LE encoded input. NTLM hashes are considered weak because they can be brute-forced very easily with modern hardware."; + this.infoURL = "https://wikipedia.org/wiki/NT_LAN_Manager"; this.inputType = "string"; this.outputType = "string"; this.args = []; @@ -35,7 +35,7 @@ class NTLM extends Operation { * @returns {string} */ run(input, args) { - const format = 1200; + const format = 1200; // UTF-16LE const encoded = cptable.utils.encode(format, input); const hashed = runHash("md4", encoded); @@ -43,4 +43,4 @@ class NTLM extends Operation { } } -export default NTLM; +export default NTHash; diff --git a/tests/operations/tests/GenerateAllHashes.mjs b/tests/operations/tests/GenerateAllHashes.mjs index 3e9b82b8..28707bde 100644 --- a/tests/operations/tests/GenerateAllHashes.mjs +++ b/tests/operations/tests/GenerateAllHashes.mjs @@ -50,6 +50,8 @@ BLAKE2s-256: f308fc02ce9172ad02a7d75800ecfc027109bc67987ea32aba9b8dcc7b10150e Streebog-256: 12a50838191b5504f1e5f2fd078714cf6b592b9d29af99d0b10d8d02881c3857 Streebog-512: 7200bf5dea560f0d7960d07fdc8874ad9f3b86ece2e45f5502ae2e176f2c928e0e581152281f5aee818318bed7cbe6aa69999589234723ceb33175598365b5c8 GOST: ee67303696d205ddd2b2363e8e01b4b7199a80957d94d7678eaad3fc834c5a27 +LM Hash: 01FC5A6BE7BC6929AAD3B435B51404EE +NT Hash: 0CB6948805F797BF2A82807973B89537 SSDEEP: 3:Hn:Hn CTPH: A:E:E @@ -79,6 +81,8 @@ MD5: 098f6bcd4621d373cade4e832627b4f6 RIPEMD-128: f1abb5083c9ff8a9dbbca9cd2b11fead BLAKE2b-128: 44a8995dd50b6657a037a7839304535b BLAKE2s-128: e9ddd9926b9dcb382e09be39ba403d2c +LM Hash: 01FC5A6BE7BC6929AAD3B435B51404EE +NT Hash: 0CB6948805F797BF2A82807973B89537 `, recipeConfig: [ { diff --git a/tests/operations/tests/NTLM.mjs b/tests/operations/tests/NTLM.mjs index 1dc39d5c..6dfa704c 100644 --- a/tests/operations/tests/NTLM.mjs +++ b/tests/operations/tests/NTLM.mjs @@ -9,14 +9,26 @@ import TestRegister from "../../lib/TestRegister.mjs"; TestRegister.addTests([ { - name: "NTLM Hashing", + name: "NT Hash", input: "QWERTYUIOPASDFGHJKLZXCVBNM1234567890!@#$%^&*()_+.,?/", expectedOutput: "C5FA1C40E55734A8E528DBFE21766D23", recipeConfig: [ { - op: "NTLM", + op: "NT Hash", args: [], }, ], - } + }, + { + name: "LM Hash", + input: "QWERTYUIOPASDFGHJKLZXCVBNM1234567890!@#$%^&*()_+.,?/", + expectedOutput: "6D9DF16655336CA75A3C13DD18BA8156", + recipeConfig: [ + { + op: "LM Hash", + args: [], + }, + ], + }, + ]); From 5c72791279c0a0883bd02c7f8eb01035f9aac4d2 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Sat, 15 Oct 2022 00:15:39 +0100 Subject: [PATCH 32/33] Updated CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d13c50d..f4d21a41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ All major and minor version changes will be documented in this file. Details of ## Details +### [9.48.0] - 2022-10-14 +- Added 'LM Hash' and 'NT Hash' operations [@n1474335] [@brun0ne] | [#1427] + ### [9.47.0] - 2022-10-14 - Added 'LZMA Decompress' and 'LZMA Compress' operations [@mattnotmitt] | [#1421] @@ -318,6 +321,7 @@ All major and minor version changes will be documented in this file. Details of +[9.48.0]: https://github.com/gchq/CyberChef/releases/tag/v9.48.0 [9.47.0]: https://github.com/gchq/CyberChef/releases/tag/v9.47.0 [9.46.0]: https://github.com/gchq/CyberChef/releases/tag/v9.46.0 [9.45.0]: https://github.com/gchq/CyberChef/releases/tag/v9.45.0 @@ -454,6 +458,7 @@ All major and minor version changes will be documented in this file. Details of [@crespyl]: https://github.com/crespyl [@thomasleplus]: https://github.com/thomasleplus [@valdelaseras]: https://github.com/valdelaseras +[@brun0ne]: https://github.com/brun0ne [8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7 [9a33498]: https://github.com/gchq/CyberChef/commit/9a33498fed26a8df9c9f35f39a78a174bf50a513 @@ -557,4 +562,5 @@ All major and minor version changes will be documented in this file. Details of [#1250]: https://github.com/gchq/CyberChef/pull/1250 [#1308]: https://github.com/gchq/CyberChef/pull/1308 [#1421]: https://github.com/gchq/CyberChef/pull/1421 +[#1427]: https://github.com/gchq/CyberChef/pull/1427 From ed8bd34915a70e15def593df4105a7f112b2ff69 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Sat, 15 Oct 2022 00:15:49 +0100 Subject: [PATCH 33/33] 9.48.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f731b882..cbb61cc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.47.5", + "version": "9.48.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.47.5", + "version": "9.48.0", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 51ec1adb..9f7ab0f7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.47.5", + "version": "9.48.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef",