mirror of
https://github.com/gchq/CyberChef
synced 2025-01-16 06:23:53 +00:00
Merge pull request #1555 from sg5506844/rison-operation
RISON operation
This commit is contained in:
commit
d8be3dfa27
9 changed files with 202 additions and 10478 deletions
10468
package-lock.json
generated
10468
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -161,6 +161,7 @@
|
||||||
"protobufjs": "^7.2.6",
|
"protobufjs": "^7.2.6",
|
||||||
"qr-image": "^3.2.0",
|
"qr-image": "^3.2.0",
|
||||||
"reflect-metadata": "^0.2.1",
|
"reflect-metadata": "^0.2.1",
|
||||||
|
"rison": "^0.1.1",
|
||||||
"scryptsy": "^2.1.0",
|
"scryptsy": "^2.1.0",
|
||||||
"snackbarjs": "^1.1.0",
|
"snackbarjs": "^1.1.0",
|
||||||
"sortablejs": "^1.15.2",
|
"sortablejs": "^1.15.2",
|
||||||
|
|
|
@ -67,7 +67,9 @@
|
||||||
"JSON to CSV",
|
"JSON to CSV",
|
||||||
"Avro to JSON",
|
"Avro to JSON",
|
||||||
"CBOR Encode",
|
"CBOR Encode",
|
||||||
"CBOR Decode"
|
"CBOR Decode",
|
||||||
|
"Rison Encode",
|
||||||
|
"Rison Decode"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,17 +35,6 @@ class AnalyseHash extends Operation {
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
input = input.replace(/\s/g, "");
|
input = input.replace(/\s/g, "");
|
||||||
|
|
||||||
// analyze hash if it is bcrypt
|
|
||||||
if (/^\$2[abxy]?\$[0-9]+\$[a-zA-Z0-9/.]{53}$/.test(input)) {
|
|
||||||
input = input.split("$");
|
|
||||||
return "Hash algorithm Identifier: $" + input[1] + "$\n" +
|
|
||||||
"Rounds: " + input[2] + "\n" +
|
|
||||||
"Base64 encoded Input salt(22 bytes): " + input[3].slice(0, 22) + "\n" +
|
|
||||||
"Base64 encoded hash(31 bytes): " + input[3].slice(22) + "\n\n" +
|
|
||||||
"Based on the length, this hash could have been generated by one of the following hashing functions:\n" +
|
|
||||||
"bcrypt";
|
|
||||||
}
|
|
||||||
|
|
||||||
let output = "",
|
let output = "",
|
||||||
possibleHashFunctions = [];
|
possibleHashFunctions = [];
|
||||||
const byteLength = input.length / 2,
|
const byteLength = input.length / 2,
|
||||||
|
|
60
src/core/operations/RisonDecode.mjs
Normal file
60
src/core/operations/RisonDecode.mjs
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/**
|
||||||
|
* @author sg5506844 [sg5506844@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2021
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
|
import rison from "rison";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rison Decode operation
|
||||||
|
*/
|
||||||
|
class RisonDecode extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RisonDecode constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Rison Decode";
|
||||||
|
this.module = "Default";
|
||||||
|
this.description = "Rison, a data serialization format optimized for compactness in URIs. Rison is a slight variation of JSON that looks vastly superior after URI encoding. Rison still expresses exactly the same set of data structures as JSON, so data can be translated back and forth without loss or guesswork.";
|
||||||
|
this.infoURL = "https://github.com/Nanonid/rison";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "Object";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
name: "Decode Option",
|
||||||
|
type: "editableOption",
|
||||||
|
value: [
|
||||||
|
{ name: "Decode", value: "Decode", },
|
||||||
|
{ name: "Decode Object", value: "Decode Object", },
|
||||||
|
{ name: "Decode Array", value: "Decode Array", },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const [decodeOption] = args;
|
||||||
|
switch (decodeOption) {
|
||||||
|
case "Decode":
|
||||||
|
return rison.decode(input);
|
||||||
|
case "Decode Object":
|
||||||
|
return rison.decode_object(input);
|
||||||
|
case "Decode Array":
|
||||||
|
return rison.decode_array(input);
|
||||||
|
}
|
||||||
|
throw new OperationError("Invalid Decode option");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RisonDecode;
|
63
src/core/operations/RisonEncode.mjs
Normal file
63
src/core/operations/RisonEncode.mjs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* @author sg5506844 [sg5506844@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2021
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
|
import rison from "rison";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rison Encode operation
|
||||||
|
*/
|
||||||
|
class RisonEncode extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RisonEncode constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Rison Encode";
|
||||||
|
this.module = "Default";
|
||||||
|
this.description = "Rison, a data serialization format optimized for compactness in URIs. Rison is a slight variation of JSON that looks vastly superior after URI encoding. Rison still expresses exactly the same set of data structures as JSON, so data can be translated back and forth without loss or guesswork.";
|
||||||
|
this.infoURL = "https://github.com/Nanonid/rison";
|
||||||
|
this.inputType = "Object";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
name: "Encode Option",
|
||||||
|
type: "editableOption",
|
||||||
|
value: [
|
||||||
|
{ name: "Encode", value: "Encode", },
|
||||||
|
{ name: "Encode Object", value: "Encode Object", },
|
||||||
|
{ name: "Encode Array", value: "Encode Array", },
|
||||||
|
{ name: "Encode URI", value: "Encode URI", }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const [encodeOption] = args;
|
||||||
|
switch (encodeOption) {
|
||||||
|
case "Encode":
|
||||||
|
return rison.encode(input);
|
||||||
|
case "Encode Object":
|
||||||
|
return rison.encode_object(input);
|
||||||
|
case "Encode Array":
|
||||||
|
return rison.encode_array(input);
|
||||||
|
case "Encode URI":
|
||||||
|
return rison.encode_uri(input);
|
||||||
|
}
|
||||||
|
throw new OperationError("Invalid encode option");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RisonEncode;
|
|
@ -396,11 +396,7 @@ class RecipeWaiter {
|
||||||
const item = document.createElement("li");
|
const item = document.createElement("li");
|
||||||
|
|
||||||
item.classList.add("operation");
|
item.classList.add("operation");
|
||||||
|
|
||||||
if (this.app.operations[name] != null) {
|
|
||||||
item.innerHTML = name;
|
item.innerHTML = name;
|
||||||
}
|
|
||||||
|
|
||||||
this.buildRecipeOperation(item);
|
this.buildRecipeOperation(item);
|
||||||
document.getElementById("rec-list").appendChild(item);
|
document.getElementById("rec-list").appendChild(item);
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,7 @@ import "./tests/Unicode.mjs";
|
||||||
import "./tests/RSA.mjs";
|
import "./tests/RSA.mjs";
|
||||||
import "./tests/CBOREncode.mjs";
|
import "./tests/CBOREncode.mjs";
|
||||||
import "./tests/CBORDecode.mjs";
|
import "./tests/CBORDecode.mjs";
|
||||||
|
import "./tests/RisonEncodeDecode.mjs";
|
||||||
import "./tests/JA3Fingerprint.mjs";
|
import "./tests/JA3Fingerprint.mjs";
|
||||||
import "./tests/JA3SFingerprint.mjs";
|
import "./tests/JA3SFingerprint.mjs";
|
||||||
import "./tests/HASSH.mjs";
|
import "./tests/HASSH.mjs";
|
||||||
|
|
66
tests/operations/tests/RisonEncodeDecode.mjs
Normal file
66
tests/operations/tests/RisonEncodeDecode.mjs
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/**
|
||||||
|
* @author sg5506844 [sg5506844@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2021
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import TestRegister from "../../lib/TestRegister.mjs";
|
||||||
|
|
||||||
|
TestRegister.addTests([
|
||||||
|
{
|
||||||
|
name: "Rison Encode: Encoding example 1",
|
||||||
|
input: JSON.stringify({ any: "json", yes: true }),
|
||||||
|
expectedOutput: "(any:json,yes:!t)",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Rison Encode",
|
||||||
|
args: ["Encode"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Rison Encode: Encoding example 2",
|
||||||
|
input: JSON.stringify({ supportsObjects: true, ints: 435 }),
|
||||||
|
expectedOutput: "ints:435,supportsObjects:!t",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Rison Encode",
|
||||||
|
args: ["Encode Object"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Rison Encode: Encoding example 3",
|
||||||
|
input: JSON.stringify(["A", "B", { supportsObjects: true }]),
|
||||||
|
expectedOutput: "A,B,(supportsObjects:!t)",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Rison Encode",
|
||||||
|
args: ["Encode Array"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Rison Encode: Object for an array",
|
||||||
|
input: JSON.stringify({ supportsObjects: true, ints: 435 }),
|
||||||
|
expectedOutput: "Rison Encode - rison.encode_array expects an array argument",
|
||||||
|
expectedError: "Rison Encode - rison.encode_array expects an array argument",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Rison Encode",
|
||||||
|
args: ["Encode Array"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Rison Decode: Decoding example 1",
|
||||||
|
input: "(any:json,yes:!t)",
|
||||||
|
expectedOutput: JSON.stringify({ any: "json", yes: true }, null, 4),
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Rison Decode",
|
||||||
|
args: ["Decode"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]);
|
Loading…
Reference in a new issue