1
0
mirror of synced 2025-01-19 00:04:08 +01:00

Merge branch 'newMagic' of https://github.com/n1073645/CyberChef into n1073645-newMagic

This commit is contained in:
n1474335 2020-03-20 14:51:40 +00:00
commit 26fa66ef64
44 changed files with 907 additions and 408 deletions

View File

@ -1182,6 +1182,7 @@ class Utils {
"CRLF": /\r\n/g,
"Forward slash": /\//g,
"Backslash": /\\/g,
"0x with comma": /,?0x/g,
"0x": /0x/g,
"\\x": /\\x/g,
"None": /\s+/g // Included here to remove whitespace when there shouldn't be any

View File

@ -42,13 +42,32 @@ for (const opObj in Ops) {
outputType: op.presentType,
flowControl: op.flowControl,
manualBake: op.manualBake,
args: op.args
args: op.args,
};
if ("patterns" in op) {
operationConfig[op.name].patterns = op.patterns;
if ("checks" in op) {
if ("input" in op.checks) {
operationConfig[op.name].input = {};
if ("regex" in op.checks.input) {
operationConfig[op.name].input.regex = op.checks.input.regex;
}
if ("entropy" in op.checks.input) {
operationConfig[op.name].input.entropy = op.checks.input.entropy;
}
}
if ("output" in op.checks) {
operationConfig[op.name].output = {};
if ("regex" in op.checks.output) {
operationConfig[op.name].output.regex = op.checks.output.regex;
}
if ("entropy" in op.checks.output) {
operationConfig[op.name].output.entropy = op.checks.output.entropy;
}
if ("mime" in op.checks.output) {
operationConfig[op.name].output.mime = op.checks.output.mime;
}
}
}
if (!(op.module in modules))
modules[op.module] = {};
modules[op.module][op.name] = opObj;

View File

@ -26,7 +26,7 @@ export function ipv4CidrRange(cidr, includeNetworkInfo, enumerateAddresses, allo
let output = "";
if (cidrRange < 0 || cidrRange > 31) {
return "IPv4 CIDR must be less than 32";
throw new OperationError("IPv4 CIDR must be less than 32");
}
const mask = ~(0xFFFFFFFF >>> cidrRange),
@ -64,7 +64,7 @@ export function ipv6CidrRange(cidr, includeNetworkInfo) {
cidrRange = parseInt(cidr[cidr.length-1], 10);
if (cidrRange < 0 || cidrRange > 127) {
return "IPv6 CIDR must be less than 128";
throw new OperationError("IPv6 CIDR must be less than 128");
}
const ip1 = new Array(8),
@ -211,7 +211,7 @@ export function ipv4ListedRange(match, includeNetworkInfo, enumerateAddresses, a
const network = strToIpv4(ipv4CidrList[i].split("/")[0]);
const cidrRange = parseInt(ipv4CidrList[i].split("/")[1], 10);
if (cidrRange < 0 || cidrRange > 31) {
return "IPv4 CIDR must be less than 32";
throw new OperationError("IPv4 CIDR must be less than 32");
}
const mask = ~(0xFFFFFFFF >>> cidrRange),
cidrIp1 = network & mask,
@ -254,7 +254,7 @@ export function ipv6ListedRange(match, includeNetworkInfo) {
const cidrRange = parseInt(ipv6CidrList[i].split("/")[1], 10);
if (cidrRange < 0 || cidrRange > 127) {
return "IPv6 CIDR must be less than 128";
throw new OperationError("IPv6 CIDR must be less than 128");
}
const cidrIp1 = new Array(8),

View File

@ -2,7 +2,7 @@ import OperationConfig from "../config/OperationConfig.json";
import Utils, { isWorkerEnvironment } from "../Utils.mjs";
import Recipe from "../Recipe.mjs";
import Dish from "../Dish.mjs";
import {detectFileType} from "./FileType.mjs";
import {detectFileType, isType} from "./FileType.mjs";
import chiSquared from "chi-squared";
/**
@ -19,28 +19,30 @@ class Magic {
* Magic constructor.
*
* @param {ArrayBuffer} buf
* @param {Object[]} [opPatterns]
* @param {Object} prevOp
*/
constructor(buf, opPatterns) {
constructor(buf, opPatterns, prevOp) {
this.inputBuffer = new Uint8Array(buf);
this.inputStr = Utils.arrayBufferToStr(buf);
this.opPatterns = opPatterns || Magic._generateOpPatterns();
this.opPatterns = opPatterns || Magic._generateOpCriteria();
this.prevOp = prevOp;
}
/**
* Finds operations that claim to be able to decode the input based on regular
* expression matches.
* Finds operations that claim to be able to decode the input based on
* regular expression matches.
*
* @returns {Object[]}
* @param {[Object]} opPatterns
* @returns {Array}
*/
findMatchingOps() {
inputRegexMatch(opPatterns) {
const matches = [];
for (let i = 0; i < this.opPatterns.length; i++) {
const pattern = this.opPatterns[i],
regex = new RegExp(pattern.match, pattern.flags);
for (let i = 0; i < opPatterns.length; i++) {
const pattern = opPatterns[i];
if (regex.test(this.inputStr)) {
if (pattern.match.test(this.inputStr)) {
matches.push(pattern);
}
}
@ -48,6 +50,37 @@ class Magic {
return matches;
}
/**
* Finds operations that claim to be able to decode the input based on entropy
* matches.
*
* @param {[Object]} opPatterns
* @returns {Array}
*/
entropyInputMatch(opPatterns) {
const matches = [];
const entropyOfInput = this.calcEntropy();
for (let i = 0; i < opPatterns.length; i++) {
const currOp = opPatterns[i];
if ((entropyOfInput > currOp.entropy[0]) && (entropyOfInput < currOp.entropy[1]))
matches.push(currOp);
}
return matches;
}
/**
* Finds operations that claim to be able to decode the input based on criteria.
*
* @returns {Object[]}
*/
findMatchingInputOps() {
let matches = this.inputRegexMatch(this.opPatterns.regex);
matches = matches.concat(this.entropyInputMatch(this.opPatterns.entropy));
return [...new Set(matches)];
}
/**
* Attempts to detect the language of the input by comparing its byte frequency
* to that of several known languages.
@ -264,6 +297,35 @@ class Magic {
return results;
}
/**
*
*/
checkRegexes(regexes) {
for (const elem of regexes) {
const regex = new RegExp(elem.match, elem.flags);
if (regex.test(this.inputStr))
return true;
}
return false;
}
/**
*
*/
checkOutputFromPrevious() {
let score = 0;
if ("regex" in this.prevOp.output) {
if (this.checkRegexes(this.prevOp.output.regex)) score++;
}
if ("entropy" in this.prevOp.output) {
const inputEntropy = this.calcEntropy();
if ((inputEntropy > this.prevOp.output.entropy[0]) && (inputEntropy < this.prevOp.output.entropy[1])) score++;
}
if ("mime" in this.prevOp.output) {
if (isType(this.prevOp.output.mime, this.inputBuffer)) score++;
}
return score > 0;
}
/**
* Speculatively executes matching operations, recording metadata of each result.
*
@ -281,8 +343,15 @@ class Magic {
if (depth < 0) return [];
// Find any operations that can be run on this data
const matchingOps = this.findMatchingOps();
if (this.prevOp) {
if ("output" in this.prevOp) {
if (!(this.checkOutputFromPrevious())) {
return [];
}
}
}
const matchingOps = this.findMatchingInputOps();
let results = [];
// Record the properties of the current data
@ -305,8 +374,7 @@ class Magic {
const opConfig = {
op: op.op,
args: op.args
},
output = await this._runRecipe([opConfig]);
}, output = await this._runRecipe([opConfig]);
// If the recipe is repeating and returning the same data, do not continue
if (prevOp && op.op === prevOp.op && _buffersEqual(output, this.inputBuffer)) {
@ -318,7 +386,8 @@ class Magic {
return;
}
const magic = new Magic(output, this.opPatterns),
const magic = new Magic(output, this.opPatterns, OperationConfig[op.op]),
speculativeResults = await magic.speculativeExecution(
depth-1, extLang, intensive, [...recipeConfig, opConfig], op.useful, crib);
@ -330,7 +399,7 @@ class Magic {
const bfEncodings = await this.bruteForce();
await Promise.all(bfEncodings.map(async enc => {
const magic = new Magic(enc.data, this.opPatterns),
const magic = new Magic(enc.data, this.opPatterns, undefined),
bfResults = await magic.speculativeExecution(
depth-1, extLang, false, [...recipeConfig, enc.conf], false, crib);
@ -447,24 +516,34 @@ class Magic {
* @private
* @returns {Object[]}
*/
static _generateOpPatterns() {
const opPatterns = [];
static _generateOpCriteria() {
const opCriteria = {
regex: [],
entropy: []
};
for (const op in OperationConfig) {
if (!("patterns" in OperationConfig[op])) continue;
OperationConfig[op].patterns.forEach(pattern => {
opPatterns.push({
op: op,
match: pattern.match,
flags: pattern.flags,
args: pattern.args,
useful: pattern.useful || false
});
});
if ("input" in OperationConfig[op]) {
if ("regex" in OperationConfig[op].input)
OperationConfig[op].input.regex.forEach(pattern => {
opCriteria.regex.push({
op: op,
match: new RegExp(pattern.match, pattern.flags),
args: pattern.args,
useful: pattern.useful || false
});
});
if ("entropy" in OperationConfig[op].input) {
opCriteria.entropy.push({
op: op,
entropy: OperationConfig[op].input.entropy.input,
args: OperationConfig[op].input.entropy.args
});
}
}
}
return opPatterns;
return opCriteria;
}
/**

View File

@ -0,0 +1,12 @@
/**
* Constants for the entropy of text.
*
* @author n1073645 [n1073645@gmail.com]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
export const compressedToDecompressed = [6.5, 8];
export const binary = [1, 1.5];
export const entropyOfText = [3.5, 6];

View File

@ -33,6 +33,42 @@ class A1Z26CipherDecode extends Operation {
value: DELIM_OPTIONS
}
];
this.checks = {
input: {
regex: [
{
match: "^\\s*([12]?[0-9] )+[12]?[0-9]\\s*$",
flags: "",
args: ["Space"]
},
{
match: "^\\s*([12]?[0-9],)+[12]?[0-9]\\s*$",
flags: "",
args: ["Comma"]
},
{
match: "^\\s*([12]?[0-9];)+[12]?[0-9]\\s*$",
flags: "",
args: ["Semi-colon"]
},
{
match: "^\\s*([12]?[0-9]:)+[12]?[0-9]\\s*$",
flags: "",
args: ["Colon"]
},
{
match: "^\\s*([12]?[0-9]\\n)+[12]?[0-9]\\s*$",
flags: "",
args: ["Line feed"]
},
{
match: "^\\s*([12]?[0-9]\\r\\n)+[12]?[0-9]\\s*$",
flags: "",
args: ["CRLF"]
}
]
}
};
}
/**

View File

@ -44,6 +44,52 @@ class BaconCipherDecode extends Operation {
"value": false
}
];
this.checks = {
input: {
regex: [
{
match: "^\\s*([01]{5}\\s?)+$",
flags: "",
args: ["Standard (I=J and U=V)", "0/1", false]
},
{
match: "^\\s*([01]{5}\\s?)+$",
flags: "",
args: ["Standard (I=J and U=V)", "0/1", true]
},
{
match: "^\\s*([AB]{5}\\s?)+$",
flags: "",
args: ["Standard (I=J and U=V)", "A/B", false]
},
{
match: "^\\s*([AB]{5}\\s?)+$",
flags: "",
args: ["Standard (I=J and U=V)", "A/B", true]
},
{
match: "^\\s*([01]{5}\\s?)+$",
flags: "",
args: ["Complete", "0/1", false]
},
{
match: "^\\s*([01]{5}\\s?)+$",
flags: "",
args: ["Complete", "0/1", true]
},
{
match: "^\\s*([AB]{5}\\s?)+$",
flags: "",
args: ["Complete", "A/B", false]
},
{
match: "^\\s*([AB]{5}\\s?)+$",
flags: "",
args: ["Complete", "A/B", true]
}
]
}
};
}
/**

View File

@ -33,13 +33,17 @@ class Bzip2Decompress extends Operation {
value: false
}
];
this.patterns = [
{
"match": "^\\x42\\x5a\\x68",
"flags": "",
"args": []
this.checks = {
input: {
regex: [
{
"match": "^\\x42\\x5a\\x68",
"flags": "",
"args": []
}
]
}
];
};
}
/**

View File

@ -24,6 +24,17 @@ class DechunkHTTPResponse extends Operation {
this.inputType = "string";
this.outputType = "string";
this.args = [];
this.checks = {
input: {
regex: [
{
match: "^\\s*[0-9A-F]+\r\n",
flags: "i",
args: []
}
]
}
};
}
/**

View File

@ -30,6 +30,17 @@ class DecodeNetBIOSName extends Operation {
"value": 65
}
];
this.checks = {
input: {
regex: [
{
match: "^\\s*\\S{32}$",
flags: "",
args: [65]
}
]
}
};
}
/**

View File

@ -25,7 +25,27 @@ class DefangIPAddresses extends Operation {
this.inputType = "string";
this.outputType = "string";
this.args = [];
this.checks = {
input: {
regex: [
{
match: "^\\s*(([0-9]{1,3}\\.){3}[0-9]{1,3}|([0-9a-f]{4}:){7}[0-9a-f]{4})\\s*$",
flags: "i",
args: [],
}
]
},
output: {
regex: [
{
match: "^\\s*(([0-9]{1,3}\\[\\.\\]){3}[0-9]{1,3}|([0-9a-f]{4}\\[\\:\\]){7}[0-9a-f]{4})\\s*$",
flags: "i",
shouldMatch: true,
args: []
}
]
}
};
}
/**

View File

@ -44,23 +44,27 @@ class EscapeUnicodeCharacters extends Operation {
"value": true
}
];
this.patterns = [
{
match: "\\\\u(?:[\\da-f]{4,6})",
flags: "i",
args: ["\\u"]
},
{
match: "%u(?:[\\da-f]{4,6})",
flags: "i",
args: ["%u"]
},
{
match: "U\\+(?:[\\da-f]{4,6})",
flags: "i",
args: ["U+"]
},
];
this.checks = {
input: {
regex: [
{
match: "\\\\u(?:[\\da-f]{4,6})",
flags: "i",
args: ["\\u"]
},
{
match: "%u(?:[\\da-f]{4,6})",
flags: "i",
args: ["%u"]
},
{
match: "U\\+(?:[\\da-f]{4,6})",
flags: "i",
args: ["U+"]
}
]
}
};
}
/**

View File

@ -49,13 +49,17 @@ class FromBCD extends Operation {
"value": FORMAT
}
];
this.patterns = [
{
match: "^(?:\\d{4} ){3,}\\d{4}$",
flags: "",
args: ["8 4 2 1", true, false, "Nibbles"]
},
];
this.checks = {
input: {
regex: [
{
match: "^(?:\\d{4} ){3,}\\d{4}$",
flags: "",
args: ["8 4 2 1", true, false, "Nibbles"]
},
]
}
};
}
/**

View File

@ -36,13 +36,18 @@ class FromBase32 extends Operation {
value: true
}
];
this.patterns = [
this.checks = {
input:
{
match: "^(?:[A-Z2-7]{8})+(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}={1})?$",
flags: "",
args: ["A-Z2-7=", false]
},
];
regex: [
{
match: "^(?:[A-Z2-7]{8})+(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}={1})?$",
flags: "",
args: ["A-Z2-7=", false]
}
]
}
};
}
/**

View File

@ -38,18 +38,23 @@ class FromBase58 extends Operation {
"value": true
}
];
this.patterns = [
this.checks = {
input:
{
match: "^[1-9A-HJ-NP-Za-km-z]{20,}$",
flags: "",
args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", false]
},
{
match: "^[1-9A-HJ-NP-Za-km-z]{20,}$",
flags: "",
args: ["rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz", false]
},
];
regex: [
{
match: "^[1-9A-HJ-NP-Za-km-z]{20,}$",
flags: "",
args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", false]
},
{
match: "^[1-9A-HJ-NP-Za-km-z]{20,}$",
flags: "",
args: ["rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz", false]
},
]
}
};
}
/**

View File

@ -36,73 +36,77 @@ class FromBase64 extends Operation {
value: true
}
];
this.patterns = [
{
match: "^\\s*(?:[A-Z\\d+/]{4})+(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
flags: "i",
args: ["A-Za-z0-9+/=", true]
},
{
match: "^\\s*[A-Z\\d\\-_]{20,}\\s*$",
flags: "i",
args: ["A-Za-z0-9-_", true]
},
{
match: "^\\s*(?:[A-Z\\d+\\-]{4}){5,}(?:[A-Z\\d+\\-]{2}==|[A-Z\\d+\\-]{3}=)?\\s*$",
flags: "i",
args: ["A-Za-z0-9+\\-=", true]
},
{
match: "^\\s*(?:[A-Z\\d./]{4}){5,}(?:[A-Z\\d./]{2}==|[A-Z\\d./]{3}=)?\\s*$",
flags: "i",
args: ["./0-9A-Za-z=", true]
},
{
match: "^\\s*[A-Z\\d_.]{20,}\\s*$",
flags: "i",
args: ["A-Za-z0-9_.", true]
},
{
match: "^\\s*(?:[A-Z\\d._]{4}){5,}(?:[A-Z\\d._]{2}--|[A-Z\\d._]{3}-)?\\s*$",
flags: "i",
args: ["A-Za-z0-9._-", true]
},
{
match: "^\\s*(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
flags: "i",
args: ["0-9a-zA-Z+/=", true]
},
{
match: "^\\s*(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
flags: "i",
args: ["0-9A-Za-z+/=", true]
},
{
match: "^[ !\"#$%&'()*+,\\-./\\d:;<=>?@A-Z[\\\\\\]^_]{20,}$",
flags: "",
args: [" -_", false]
},
{
match: "^\\s*[A-Z\\d+\\-]{20,}\\s*$",
flags: "i",
args: ["+\\-0-9A-Za-z", true]
},
{
match: "^\\s*[!\"#$%&'()*+,\\-0-689@A-NP-VX-Z[`a-fh-mp-r]{20,}\\s*$",
flags: "",
args: ["!-,-0-689@A-NP-VX-Z[`a-fh-mp-r", true]
},
{
match: "^\\s*(?:[N-ZA-M\\d+/]{4}){5,}(?:[N-ZA-M\\d+/]{2}==|[N-ZA-M\\d+/]{3}=)?\\s*$",
flags: "i",
args: ["N-ZA-Mn-za-m0-9+/=", true]
},
{
match: "^\\s*[A-Z\\d./]{20,}\\s*$",
flags: "i",
args: ["./0-9A-Za-z", true]
},
];
this.checks = {
input: {
regex: [
{
match: "^\\s*(?:[A-Z\\d+/]{4})+(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
flags: "i",
args: ["A-Za-z0-9+/=", true]
},
{
match: "^\\s*[A-Z\\d\\-_]{20,}\\s*$",
flags: "i",
args: ["A-Za-z0-9-_", true]
},
{
match: "^\\s*(?:[A-Z\\d+\\-]{4}){5,}(?:[A-Z\\d+\\-]{2}==|[A-Z\\d+\\-]{3}=)?\\s*$",
flags: "i",
args: ["A-Za-z0-9+\\-=", true]
},
{
match: "^\\s*(?:[A-Z\\d./]{4}){5,}(?:[A-Z\\d./]{2}==|[A-Z\\d./]{3}=)?\\s*$",
flags: "i",
args: ["./0-9A-Za-z=", true]
},
{
match: "^\\s*[A-Z\\d_.]{20,}\\s*$",
flags: "i",
args: ["A-Za-z0-9_.", true]
},
{
match: "^\\s*(?:[A-Z\\d._]{4}){5,}(?:[A-Z\\d._]{2}--|[A-Z\\d._]{3}-)?\\s*$",
flags: "i",
args: ["A-Za-z0-9._-", true]
},
{
match: "^\\s*(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
flags: "i",
args: ["0-9a-zA-Z+/=", true]
},
{
match: "^\\s*(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
flags: "i",
args: ["0-9A-Za-z+/=", true]
},
{
match: "^[ !\"#$%&'()*+,\\-./\\d:;<=>?@A-Z[\\\\\\]^_]{20,}$",
flags: "",
args: [" -_", false]
},
{
match: "^\\s*[A-Z\\d+\\-]{20,}\\s*$",
flags: "i",
args: ["+\\-0-9A-Za-z", true]
},
{
match: "^\\s*[!\"#$%&'()*+,\\-0-689@A-NP-VX-Z[`a-fh-mp-r]{20,}\\s*$",
flags: "",
args: ["!-,-0-689@A-NP-VX-Z[`a-fh-mp-r", true]
},
{
match: "^\\s*(?:[N-ZA-M\\d+/]{4}){5,}(?:[N-ZA-M\\d+/]{2}==|[N-ZA-M\\d+/]{3}=)?\\s*$",
flags: "i",
args: ["N-ZA-Mn-za-m0-9+/=", true]
},
{
match: "^\\s*[A-Z\\d./]{20,}\\s*$",
flags: "i",
args: ["./0-9A-Za-z", true]
},
],
}
};
}
/**

View File

@ -33,43 +33,47 @@ class FromBinary extends Operation {
"value": BIN_DELIM_OPTIONS
}
];
this.patterns = [
{
match: "^(?:[01]{8})+$",
flags: "",
args: ["None"]
},
{
match: "^(?:[01]{8})(?: [01]{8})*$",
flags: "",
args: ["Space"]
},
{
match: "^(?:[01]{8})(?:,[01]{8})*$",
flags: "",
args: ["Comma"]
},
{
match: "^(?:[01]{8})(?:;[01]{8})*$",
flags: "",
args: ["Semi-colon"]
},
{
match: "^(?:[01]{8})(?::[01]{8})*$",
flags: "",
args: ["Colon"]
},
{
match: "^(?:[01]{8})(?:\\n[01]{8})*$",
flags: "",
args: ["Line feed"]
},
{
match: "^(?:[01]{8})(?:\\r\\n[01]{8})*$",
flags: "",
args: ["CRLF"]
},
];
this.checks = {
input: {
regex: [
{
match: "^(?:[01]{8})+$",
flags: "",
args: ["None"]
},
{
match: "^(?:[01]{8})(?: [01]{8})*$",
flags: "",
args: ["Space"]
},
{
match: "^(?:[01]{8})(?:,[01]{8})*$",
flags: "",
args: ["Comma"]
},
{
match: "^(?:[01]{8})(?:;[01]{8})*$",
flags: "",
args: ["Semi-colon"]
},
{
match: "^(?:[01]{8})(?::[01]{8})*$",
flags: "",
args: ["Colon"]
},
{
match: "^(?:[01]{8})(?:\\n[01]{8})*$",
flags: "",
args: ["Line feed"]
},
{
match: "^(?:[01]{8})(?:\\r\\n[01]{8})*$",
flags: "",
args: ["CRLF"]
},
]
}
};
}
/**

View File

@ -36,38 +36,42 @@ class FromDecimal extends Operation {
"value": false
}
];
this.patterns = [
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?: (?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Space", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:,(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Comma", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:;(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Semi-colon", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?::(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Colon", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Line feed", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\r\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["CRLF", false]
},
];
this.checks = {
input: {
regex: [
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?: (?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Space", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:,(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Comma", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:;(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Semi-colon", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?::(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Colon", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Line feed", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\r\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["CRLF", false]
}
]
}
};
}
/**

View File

@ -25,13 +25,17 @@ class FromHTMLEntity extends Operation {
this.inputType = "string";
this.outputType = "string";
this.args = [];
this.patterns = [
{
match: "&(?:#\\d{2,3}|#x[\\da-f]{2}|[a-z]{2,6});",
flags: "i",
args: []
},
];
this.checks = {
input: {
regex: [
{
match: "&(?:#\\d{2,3}|#x[\\da-f]{2}|[a-z]{2,6});",
flags: "i",
args: []
}
]
}
};
}
/**

View File

@ -32,53 +32,62 @@ class FromHex extends Operation {
value: FROM_HEX_DELIM_OPTIONS
}
];
this.patterns = [
{
match: "^(?:[\\dA-F]{2})+$",
flags: "i",
args: ["None"]
},
{
match: "^[\\dA-F]{2}(?: [\\dA-F]{2})*$",
flags: "i",
args: ["Space"]
},
{
match: "^[\\dA-F]{2}(?:,[\\dA-F]{2})*$",
flags: "i",
args: ["Comma"]
},
{
match: "^[\\dA-F]{2}(?:;[\\dA-F]{2})*$",
flags: "i",
args: ["Semi-colon"]
},
{
match: "^[\\dA-F]{2}(?::[\\dA-F]{2})*$",
flags: "i",
args: ["Colon"]
},
{
match: "^[\\dA-F]{2}(?:\\n[\\dA-F]{2})*$",
flags: "i",
args: ["Line feed"]
},
{
match: "^[\\dA-F]{2}(?:\\r\\n[\\dA-F]{2})*$",
flags: "i",
args: ["CRLF"]
},
{
match: "^[\\dA-F]{2}(?:0x[\\dA-F]{2})*$",
flags: "i",
args: ["0x"]
},
{
match: "^[\\dA-F]{2}(?:\\\\x[\\dA-F]{2})*$",
flags: "i",
args: ["\\x"]
this.checks = {
input: {
regex: [
{
match: "^(?:[\\dA-F]{2})+$",
flags: "i",
args: ["None"]
},
{
match: "^[\\dA-F]{2}(?: [\\dA-F]{2})*$",
flags: "i",
args: ["Space"]
},
{
match: "^[\\dA-F]{2}(?:,[\\dA-F]{2})*$",
flags: "i",
args: ["Comma"]
},
{
match: "^[\\dA-F]{2}(?:;[\\dA-F]{2})*$",
flags: "i",
args: ["Semi-colon"]
},
{
match: "^[\\dA-F]{2}(?::[\\dA-F]{2})*$",
flags: "i",
args: ["Colon"]
},
{
match: "^[\\dA-F]{2}(?:\\n[\\dA-F]{2})*$",
flags: "i",
args: ["Line feed"]
},
{
match: "^[\\dA-F]{2}(?:\\r\\n[\\dA-F]{2})*$",
flags: "i",
args: ["CRLF"]
},
{
match: "^(?:0x[\\dA-F]{2})+$",
flags: "i",
args: ["0x"]
},
{
match: "^0x[\\dA-F]{2}(?:,0x[\\dA-F]{2})*$",
flags: "i",
args: ["0x with comma"]
},
{
match: "^(?:\\\\x[\\dA-F]{2})+$",
flags: "i",
args: ["\\x"]
}
]
}
];
};
}
/**

View File

@ -26,6 +26,17 @@ class FromHexContent extends Operation {
this.inputType = "string";
this.outputType = "byteArray";
this.args = [];
this.checks = {
input: {
regex: [
{
match: "^\\s*.*?\\|([0-9a-f]{2})+\\|.*$",
flags: "i",
args: []
}
],
}
};
}
/**

View File

@ -27,13 +27,17 @@ class FromHexdump extends Operation {
this.inputType = "string";
this.outputType = "byteArray";
this.args = [];
this.patterns = [
{
match: "^(?:(?:[\\dA-F]{4,16}h?:?)?[ \\t]*((?:[\\dA-F]{2} ){1,8}(?:[ \\t]|[\\dA-F]{2}-)(?:[\\dA-F]{2} ){1,8}|(?:[\\dA-F]{4} )*[\\dA-F]{4}|(?:[\\dA-F]{2} )*[\\dA-F]{2})[^\\n]*\\n?){2,}$",
flags: "i",
args: []
},
];
this.checks = {
input: {
regex: [
{
match: "^(?:(?:[\\dA-F]{4,16}h?:?)?[ \\t]*((?:[\\dA-F]{2} ){1,8}(?:[ \\t]|[\\dA-F]{2}-)(?:[\\dA-F]{2} ){1,8}|(?:[\\dA-F]{4} )*[\\dA-F]{4}|(?:[\\dA-F]{2} )*[\\dA-F]{2})[^\\n]*\\n?){2,}$",
flags: "i",
args: []
},
]
}
};
}
/**

View File

@ -37,13 +37,17 @@ class FromMorseCode extends Operation {
"value": WORD_DELIM_OPTIONS
}
];
this.patterns = [
{
match: "(?:^[-. \\n]{5,}$|^[_. \\n]{5,}$|^(?:dash|dot| |\\n){5,}$)",
flags: "i",
args: ["Space", "Line feed"]
},
];
this.checks = {
input: {
regex: [
{
match: "(?:^[-. \\n]{5,}$|^[_. \\n]{5,}$|^(?:dash|dot| |\\n){5,}$)",
flags: "i",
args: ["Space", "Line feed"]
}
]
}
};
}
/**

View File

@ -32,38 +32,42 @@ class FromOctal extends Operation {
"value": DELIM_OPTIONS
}
];
this.patterns = [
{
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?: (?:[0-7]{1,2}|[123][0-7]{2}))*$",
flags: "",
args: ["Space"]
},
{
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:,(?:[0-7]{1,2}|[123][0-7]{2}))*$",
flags: "",
args: ["Comma"]
},
{
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:;(?:[0-7]{1,2}|[123][0-7]{2}))*$",
flags: "",
args: ["Semi-colon"]
},
{
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?::(?:[0-7]{1,2}|[123][0-7]{2}))*$",
flags: "",
args: ["Colon"]
},
{
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$",
flags: "",
args: ["Line feed"]
},
{
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\r\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$",
flags: "",
args: ["CRLF"]
},
];
this.checks = {
input: {
regex: [
{
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?: (?:[0-7]{1,2}|[123][0-7]{2}))*$",
flags: "",
args: ["Space"]
},
{
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:,(?:[0-7]{1,2}|[123][0-7]{2}))*$",
flags: "",
args: ["Comma"]
},
{
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:;(?:[0-7]{1,2}|[123][0-7]{2}))*$",
flags: "",
args: ["Semi-colon"]
},
{
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?::(?:[0-7]{1,2}|[123][0-7]{2}))*$",
flags: "",
args: ["Colon"]
},
{
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$",
flags: "",
args: ["Line feed"]
},
{
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\r\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$",
flags: "",
args: ["CRLF"]
}
]
}
};
}
/**

View File

@ -28,13 +28,17 @@ class FromQuotedPrintable extends Operation {
this.inputType = "string";
this.outputType = "byteArray";
this.args = [];
this.patterns = [
{
match: "^[\\x21-\\x3d\\x3f-\\x7e \\t]{0,76}(?:=[\\da-f]{2}|=\\r?\\n)(?:[\\x21-\\x3d\\x3f-\\x7e \\t]|=[\\da-f]{2}|=\\r?\\n)*$",
flags: "i",
args: []
},
];
this.checks = {
input: {
regex: [
{
match: "^[\\x21-\\x3d\\x3f-\\x7e \\t]{0,76}(?:=[\\da-f]{2}|=\\r?\\n)(?:[\\x21-\\x3d\\x3f-\\x7e \\t]|=[\\da-f]{2}|=\\r?\\n)*$",
flags: "i",
args: []
},
]
}
};
}
/**

View File

@ -33,28 +33,32 @@ class FromUNIXTimestamp extends Operation {
"value": UNITS
}
];
this.patterns = [
{
match: "^1?\\d{9}$",
flags: "",
args: ["Seconds (s)"]
},
{
match: "^1?\\d{12}$",
flags: "",
args: ["Milliseconds (ms)"]
},
{
match: "^1?\\d{15}$",
flags: "",
args: ["Microseconds (μs)"]
},
{
match: "^1?\\d{18}$",
flags: "",
args: ["Nanoseconds (ns)"]
},
];
this.checks = {
input: {
regex: [
{
match: "^1?\\d{9}$",
flags: "",
args: ["Seconds (s)"]
},
{
match: "^1?\\d{12}$",
flags: "",
args: ["Milliseconds (ms)"]
},
{
match: "^1?\\d{15}$",
flags: "",
args: ["Microseconds (μs)"]
},
{
match: "^1?\\d{18}$",
flags: "",
args: ["Nanoseconds (ns)"]
}
]
}
};
}
/**

View File

@ -27,13 +27,17 @@ class Gunzip extends Operation {
this.inputType = "ArrayBuffer";
this.outputType = "ArrayBuffer";
this.args = [];
this.patterns = [
{
match: "^\\x1f\\x8b\\x08",
flags: "",
args: []
},
];
this.checks = {
input: {
regex: [
{
match: "^\\x1f\\x8b\\x08",
flags: "",
args: []
}
]
}
};
}
/**

View File

@ -25,6 +25,17 @@ class ObjectIdentifierToHex extends Operation {
this.inputType = "string";
this.outputType = "string";
this.args = [];
this.checks = {
input: {
regex: [
{
match: "^\\s*([0-9]{1,3}\\.)+[0-9]{1,3}\\s*$",
flags: "",
args: []
}
]
}
};
}
/**

View File

@ -33,14 +33,18 @@ class ParseQRCode extends Operation {
"value": false
}
];
this.patterns = [
{
"match": "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)",
"flags": "",
"args": [false],
"useful": true
this.checks = {
input: {
regex: [
{
"match": "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)",
"flags": "",
"args": [false],
"useful": true
}
]
}
];
};
}
/**

View File

@ -38,6 +38,17 @@ class ParseSSHHostKey extends Operation {
]
}
];
this.checks = {
input: {
regex: [
{
match: "^\\s*([A-F\\d]{2}[,;:]){15,}[A-F\\d]{2}\\s*$",
flags: "i",
args: ["Hex"]
}
]
}
};
}
/**

View File

@ -25,6 +25,17 @@ class ParseUNIXFilePermissions extends Operation {
this.inputType = "string";
this.outputType = "string";
this.args = [];
this.checks = {
input: {
regex: [
{
match: "^\\s*d[rxw-]{9}\\s*$",
flags: "",
args: []
}
]
}
};
}
/**

View File

@ -25,6 +25,17 @@ class ParseUserAgent extends Operation {
this.inputType = "string";
this.outputType = "string";
this.args = [];
this.checks = {
input: {
regex: [
{
match: "^(User-Agent:|Mozilla\\/)[^\\n\\r]+\\s*$",
flags: "i",
args: []
}
]
}
};
}
/**

View File

@ -35,15 +35,17 @@ class ParseX509Certificate extends Operation {
"value": ["PEM", "DER Hex", "Base64", "Raw"]
}
];
this.patterns = [
{
"match": "^-+BEGIN CERTIFICATE-+\\r?\\n[\\da-z+/\\n\\r]+-+END CERTIFICATE-+\\r?\\n?$",
"flags": "i",
"args": [
"PEM"
this.checks = {
input: {
regex: [
{
"match": "^-+BEGIN CERTIFICATE-+\\r?\\n[\\da-z+/\\n\\r]+-+END CERTIFICATE-+\\r?\\n?$",
"flags": "i",
"args": ["PEM"]
}
]
}
];
};
}
/**

View File

@ -60,6 +60,14 @@ class RawInflate extends Operation {
value: false
}
];
this.checks = {
input: {
entropy: {
input: [7.5, 8],
args: [0, 0, INFLATE_BUFFER_TYPE, false, false]
}
}
};
}
/**

View File

@ -163,7 +163,7 @@ class RegularExpression extends Operation {
case "List matches with capture groups":
return Utils.escapeHtml(regexList(input, regex, displayTotal, true, true));
default:
return "Error: Invalid output format";
throw new OperationError("Error: Invalid output format");
}
} catch (err) {
throw new OperationError("Invalid regex. Details: " + err.message);

View File

@ -35,14 +35,21 @@ class RenderImage extends Operation {
"value": ["Raw", "Base64", "Hex"]
}
];
this.patterns = [
{
"match": "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)",
"flags": "",
"args": ["Raw"],
"useful": true
this.checks = {
input: {
regex: [
{
"match": "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)",
"flags": "",
"args": ["Raw"],
"useful": true
}
]
},
output: {
mime: "image"
}
];
};
}
/**

View File

@ -35,6 +35,17 @@ class StripHTMLTags extends Operation {
"value": true
}
];
this.checks = {
input: {
regex: [
{
match: "^<html>(\\S|\\s)*</html>$",
flags: "i",
args: [true, true]
}
]
}
};
}
/**

View File

@ -24,6 +24,17 @@ class StripHTTPHeaders extends Operation {
this.inputType = "string";
this.outputType = "string";
this.args = [];
this.checks = {
input: {
regex: [
{
match: "^\\s*HTTP(.|\\s)+?(\\r?\\n){2}",
flags: "",
args: []
}
]
}
};
}
/**

View File

@ -24,13 +24,17 @@ class URLDecode extends Operation {
this.inputType = "string";
this.outputType = "string";
this.args = [];
this.patterns = [
{
match: ".*(?:%[\\da-f]{2}.*){4}",
flags: "i",
args: []
},
];
this.checks = {
input: {
regex: [
{
match: ".*(?:%[\\da-f]{2}.*){4}",
flags: "i",
args: []
},
]
}
};
}
/**

View File

@ -27,13 +27,17 @@ class Untar extends Operation {
this.outputType = "List<File>";
this.presentType = "html";
this.args = [];
this.patterns = [
{
"match": "^.{257}\\x75\\x73\\x74\\x61\\x72",
"flags": "",
"args": []
this.checks = {
input: {
regex: [
{
"match": "^.{257}\\x75\\x73\\x74\\x61\\x72",
"flags": "",
"args": []
}
]
}
];
};
}
/**

View File

@ -40,13 +40,17 @@ class Unzip extends Operation {
value: false
}
];
this.patterns = [
{
match: "^\\x50\\x4b(?:\\x03|\\x05|\\x07)(?:\\x04|\\x06|\\x08)",
flags: "",
args: ["", false]
},
];
this.checks = {
input: {
regex: [
{
match: "^\\x50\\x4b(?:\\x03|\\x05|\\x07)(?:\\x04|\\x06|\\x08)",
flags: "",
args: ["", false]
}
]
}
};
}
/**

View File

@ -59,13 +59,17 @@ class ZlibInflate extends Operation {
value: false
}
];
this.patterns = [
{
match: "^\\x78(\\x01|\\x9c|\\xda|\\x5e)",
flags: "",
args: [0, 0, "Adaptive", false, false]
},
];
this.checks = {
input: {
regex: [
{
match: "^\\x78(\\x01|\\x9c|\\xda|\\x5e)",
flags: "",
args: [0, 0, "Adaptive", false, false]
},
]
}
};
}
/**

View File

@ -92,6 +92,19 @@ TestRegister.addTests([
]
}
]
},
{
name: "0x with Comma to Ascii",
input: "0x74,0x65,0x73,0x74,0x20,0x73,0x74,0x72,0x69,0x6e,0x67",
expectedOutput: "test string",
recipeConfig: [
{
"op": "From Hex",
"args": [
"0x with comma"
]
}
]
}
},
]);

View File

@ -54,4 +54,70 @@ TestRegister.addTests([
}
],
},
{
name: "Magic Chain of Base64",
input: "WkVkV2VtUkRRbnBrU0Vwd1ltMWpQUT09",
expectedMatch: /From_Base64\('A-Za-z0-9\+\/=',true\)\nFrom_Base64\('A-Za-z0-9\+\/=',true\)\nFrom_Base64\('A-Za-z0-9\+\/=',true\)/,
recipeConfig: [
{
op: "Magic",
args: [3, true, false]
}
],
},
{
name: "Magic Chain of Hex to Hexdump to Base64",
input: "MDAwMDAwMDAgIDM3IDM0IDIwIDM2IDM1IDIwIDM3IDMzIDIwIDM3IDM0IDIwIDMyIDMwIDIwIDM3ICB8NzQgNjUgNzMgNzQgMjAgN3wKMDAwMDAwMTAgIDMzIDIwIDM3IDM0IDIwIDM3IDMyIDIwIDM2IDM5IDIwIDM2IDY1IDIwIDM2IDM3ICB8MyA3NCA3MiA2OSA2ZSA2N3w=",
expectedMatch: /From_Base64\('A-Za-z0-9\+\/=',true\)\nFrom_Hexdump\(\)\nFrom_Hex\('Space'\)/,
recipeConfig: [
{
op: "Magic",
args: [3, true, false]
}
],
},
{
name: "Magic Chain of Charcode to Octal to Base32",
input: "GY3SANRUEA2DAIBWGYQDMNJAGQYCANRXEA3DGIBUGAQDMNZAGY2CANBQEA3DEIBWGAQDIMBAGY3SANRTEA2DAIBWG4QDMNBAGQYCANRXEA3DEIBUGAQDMNRAG4YSANBQEA3DMIBRGQ2SANBQEA3DMIBWG4======",
expectedMatch: /From_Base32\('A-Z2-7=',false\)\nFrom_Octal\('Space'\)\nFrom_Hex\('Space'\)/,
recipeConfig: [
{
op: "Magic",
args: [3, true, false]
}
],
},
{
name: "Magic Chain of Base64 Output Check",
input: "WkVkV2VtUkRRbnBrU0Vwd1ltMWpQUT09",
expectedMatch: /test string/,
recipeConfig: [
{
op: "Magic",
args: [3, true, false]
}
],
},
{
name: "Magic Chain of Decimal to Base32 to Base32",
input: "I5CVSVCNJFBFER2BLFJUCTKKKJDVKUKEINGUUV2FIFNFIRKJIJJEORJSKNAU2SSSI5MVCRCDJVFFKRKBLFKECTSKIFDUKWKUIFEUEUSHIFNFCPJ5HU6Q====",
expectedMatch: /test string/,
recipeConfig: [
{
op: "Magic",
args: [3, true, false]
}
],
},
{
name: "Raw Inflate Result Text",
input: "\x4d\x52\xb1\x6e\xdc\x30\x0c\xdd\xf3\x15\x44\x80\x6e\xae\x91\x02\x4d\x80\x8e\x4d\x9a\x21\x53\x8b\xa6\x43\x56\x5a\xe2\x9d\x84\x93\x25\x43\x94\xed\xf8\xef\xf3\xe8\x6b\x0e\xb7\x1c\xce\xd4\x7b\x8f\x8f\x7c\x7c\xda\x06\xa9\x4f\x41\x0e\x14\x95\x98\x34\x8e\x53\x92\x8e\x62\x6e\x73\x6c\x71\x11\x5a\x65\x20\x9e\x26\x3a\x94\x4a\x8e\x6b\xdd\x62\x3e\x52\x99\x1b\x71\x4a\x34\x72\xce\x52\xa9\x1c\xe8\xd6\x99\xd0\x2d\x95\x49\x2a\xb7\x58\xb2\xd2\x1a\x5b\x88\x19\xa2\x26\x31\xd4\xb2\xaa\xd4\x9e\xfe\x05\x51\xb9\x86\xc5\xec\xd2\xec\xe5\x7f\x6b\x92\xec\x8a\xb7\x1e\x29\x9e\x84\xde\x7e\xff\x25\x34\x7e\x64\x95\x87\xef\x1d\x8d\xa5\x0a\xb9\x62\xc0\x77\x43\xd6\x6d\x32\x91\x33\xf6\xe7\xf3\x6b\x47\xbf\x9e\x5f\x89\xb3\xa7\xc7\x54\xd6\x43\xd4\xd0\x91\xab\x82\x4e\x10\x1c\x62\xe6\xba\xed\xaf\x41\xde\xfd\x3c\x4e\x8a\x57\x88\x55\x51\x35\x15\x7b\xf1\x72\x5d\xc1\x60\x9e\x1b\x03\xc6\xc9\xcd\xe9\xac\x13\x58\x31\xc3\x8e\x76\x41\xdc\x49\xe7\x11\x42\x2f\x7f\x96\x87\xbd\xf6\xd6\xdf\xdf\xfd\xa0\x89\xab\x02\x0c\x66\xe0\x7c\x34\x1a\xfe\x54\x76\x0d\xeb\xfa\x1c\x11\x2c\x23\x8c\xb3\x0b\xfb\x64\xfd\xcd\x0d\xb6\x43\xad\x94\x64\x69\x78\xd1\x78\xcc\xe2\x51\x00\x85\x07\x2c\x67\x28\x2d\x50\x13\x17\x72\x84\xa3\x9d\x9d\x4b\xfe\x7a\x5d\xe1\xb4\x69\x53\xe3\x20\x9c\x38\x99\x69\xd9\x87\xc0\xa2\x2f\xab\x5b\x79\x3b\xe7\x63\x41\x06\x5e\xcc\x1f\x18\x5e\x20\x61\xe5\x0b\xd0\xbc\xa8\x25\xc0\xe9\x58\x2a\x5e\x46\xed\xe9\xa5\x41\x40\x81\xc9\x4e\x70\x22\xbe\xbb\x58\xed\x68\x98\x63\xc2\x6d\xc0\x18\x72\xad\x32\x4a\x6e\x38\x94\x8d\x10\x6e\x2d\xc0\xd2\x60\x09\x7c\xfa\x34\x4f\x2d\x48\xac\xf4\xed\xee\x0b\x3e\x72\x59\xf6\xab\xa0\x16\x47\x1c\xc9\x82\x65\xa9\xe0\x17\xb6\x36\xc1\x46\xfb\x0f",
expectedMatch: /#recipe=Raw_Inflate(.|\n)+CyberChef is a simple, intuitive web app for carrying out all manner of /,
recipeConfig: [
{
op: "Magic",
args: [1, true, false]
}
]
}
]);