Skip to content

Commit 35c2d43

Browse files
committed
Merge branch 'master' of https://github.com/gchq/CyberChef
2 parents a54522f + 6c97187 commit 35c2d43

File tree

11 files changed

+318
-10479
lines changed

11 files changed

+318
-10479
lines changed

package-lock.json

+7-10,461
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@
161161
"protobufjs": "^7.2.6",
162162
"qr-image": "^3.2.0",
163163
"reflect-metadata": "^0.2.1",
164+
"rison": "^0.1.1",
164165
"scryptsy": "^2.1.0",
165166
"snackbarjs": "^1.1.0",
166167
"sortablejs": "^1.15.2",

src/core/config/Categories.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@
6767
"JSON to CSV",
6868
"Avro to JSON",
6969
"CBOR Encode",
70-
"CBOR Decode"
70+
"CBOR Decode",
71+
"Rison Encode",
72+
"Rison Decode"
7173
]
7274
},
7375
{
@@ -294,7 +296,8 @@
294296
"Escape string",
295297
"Unescape string",
296298
"Pseudo-Random Number Generator",
297-
"Sleep"
299+
"Sleep",
300+
"File Tree"
298301
]
299302
},
300303
{

src/core/operations/AnalyseHash.mjs

-11
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,6 @@ class AnalyseHash extends Operation {
3535
run(input, args) {
3636
input = input.replace(/\s/g, "");
3737

38-
// analyze hash if it is bcrypt
39-
if (/^\$2[abxy]?\$[0-9]+\$[a-zA-Z0-9/.]{53}$/.test(input)) {
40-
input = input.split("$");
41-
return "Hash algorithm Identifier: $" + input[1] + "$\n" +
42-
"Rounds: " + input[2] + "\n" +
43-
"Base64 encoded Input salt(22 bytes): " + input[3].slice(0, 22) + "\n" +
44-
"Base64 encoded hash(31 bytes): " + input[3].slice(22) + "\n\n" +
45-
"Based on the length, this hash could have been generated by one of the following hashing functions:\n" +
46-
"bcrypt";
47-
}
48-
4938
let output = "",
5039
possibleHashFunctions = [];
5140
const byteLength = input.length / 2,

src/core/operations/FileTree.mjs

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/**
2+
* @author sw5678
3+
* @copyright Crown Copyright 2016
4+
* @license Apache-2.0
5+
*/
6+
7+
import Operation from "../Operation.mjs";
8+
import Utils from "../Utils.mjs";
9+
import {INPUT_DELIM_OPTIONS} from "../lib/Delim.mjs";
10+
11+
/**
12+
* Unique operation
13+
*/
14+
class FileTree extends Operation {
15+
16+
/**
17+
* Unique constructor
18+
*/
19+
constructor() {
20+
super();
21+
22+
this.name = "File Tree";
23+
this.module = "Default";
24+
this.description = "Creates file tree from list of file paths (Similar too tree linux command)";
25+
this.inputType = "string";
26+
this.outputType = "string";
27+
this.args = [
28+
{
29+
name: "File Path Delimiter",
30+
type: "binaryString",
31+
value: "/"
32+
},
33+
{
34+
name: "Delimiter",
35+
type: "option",
36+
value: INPUT_DELIM_OPTIONS
37+
}
38+
];
39+
}
40+
41+
/**
42+
* @param {string} input
43+
* @param {Object[]} args
44+
* @returns {string}
45+
*/
46+
run(input, args) {
47+
48+
// Set up arrow and pipe for nice output display
49+
const ARROW = "|---";
50+
const PIPE = "| ";
51+
52+
// Get args from input
53+
const fileDelim = args[0];
54+
const entryDelim = Utils.charRep(args[1]);
55+
56+
// Store path to print
57+
const completedList = [];
58+
const printList = [];
59+
60+
// Loop through all entries
61+
const filePaths = input.split(entryDelim).unique().sort();
62+
for (let i = 0; i < filePaths.length; i++) {
63+
// Split by file delimiter
64+
let path = filePaths[i].split(fileDelim);
65+
66+
if (path[0] === "") {
67+
path = path.slice(1, path.length);
68+
}
69+
70+
for (let j = 0; j < path.length; j++) {
71+
let printLine;
72+
let key;
73+
if (j === 0) {
74+
printLine = path[j];
75+
key = path[j];
76+
} else {
77+
printLine = PIPE.repeat(j-1) + ARROW + path[j];
78+
key = path.slice(0, j+1).join("/");
79+
}
80+
81+
// Check to see we have already added that path
82+
if (!completedList.includes(key)) {
83+
completedList.push(key);
84+
printList.push(printLine);
85+
}
86+
}
87+
}
88+
return printList.join("\n");
89+
}
90+
91+
}
92+
93+
export default FileTree;

src/core/operations/RisonDecode.mjs

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* @author sg5506844 [[email protected]]
3+
* @copyright Crown Copyright 2021
4+
* @license Apache-2.0
5+
*/
6+
7+
import Operation from "../Operation.mjs";
8+
import OperationError from "../errors/OperationError.mjs";
9+
import rison from "rison";
10+
11+
/**
12+
* Rison Decode operation
13+
*/
14+
class RisonDecode extends Operation {
15+
16+
/**
17+
* RisonDecode constructor
18+
*/
19+
constructor() {
20+
super();
21+
22+
this.name = "Rison Decode";
23+
this.module = "Default";
24+
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.";
25+
this.infoURL = "https://github.com/Nanonid/rison";
26+
this.inputType = "string";
27+
this.outputType = "Object";
28+
this.args = [
29+
{
30+
name: "Decode Option",
31+
type: "editableOption",
32+
value: [
33+
{ name: "Decode", value: "Decode", },
34+
{ name: "Decode Object", value: "Decode Object", },
35+
{ name: "Decode Array", value: "Decode Array", },
36+
]
37+
},
38+
];
39+
}
40+
41+
/**
42+
* @param {string} input
43+
* @param {Object[]} args
44+
* @returns {Object}
45+
*/
46+
run(input, args) {
47+
const [decodeOption] = args;
48+
switch (decodeOption) {
49+
case "Decode":
50+
return rison.decode(input);
51+
case "Decode Object":
52+
return rison.decode_object(input);
53+
case "Decode Array":
54+
return rison.decode_array(input);
55+
}
56+
throw new OperationError("Invalid Decode option");
57+
}
58+
}
59+
60+
export default RisonDecode;

src/core/operations/RisonEncode.mjs

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* @author sg5506844 [[email protected]]
3+
* @copyright Crown Copyright 2021
4+
* @license Apache-2.0
5+
*/
6+
7+
import Operation from "../Operation.mjs";
8+
import OperationError from "../errors/OperationError.mjs";
9+
import rison from "rison";
10+
11+
/**
12+
* Rison Encode operation
13+
*/
14+
class RisonEncode extends Operation {
15+
16+
/**
17+
* RisonEncode constructor
18+
*/
19+
constructor() {
20+
super();
21+
22+
this.name = "Rison Encode";
23+
this.module = "Default";
24+
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.";
25+
this.infoURL = "https://github.com/Nanonid/rison";
26+
this.inputType = "Object";
27+
this.outputType = "string";
28+
this.args = [
29+
{
30+
name: "Encode Option",
31+
type: "editableOption",
32+
value: [
33+
{ name: "Encode", value: "Encode", },
34+
{ name: "Encode Object", value: "Encode Object", },
35+
{ name: "Encode Array", value: "Encode Array", },
36+
{ name: "Encode URI", value: "Encode URI", }
37+
]
38+
},
39+
];
40+
}
41+
42+
/**
43+
* @param {Object} input
44+
* @param {Object[]} args
45+
* @returns {string}
46+
*/
47+
run(input, args) {
48+
const [encodeOption] = args;
49+
switch (encodeOption) {
50+
case "Encode":
51+
return rison.encode(input);
52+
case "Encode Object":
53+
return rison.encode_object(input);
54+
case "Encode Array":
55+
return rison.encode_array(input);
56+
case "Encode URI":
57+
return rison.encode_uri(input);
58+
}
59+
throw new OperationError("Invalid encode option");
60+
}
61+
}
62+
63+
export default RisonEncode;

src/web/waiters/RecipeWaiter.mjs

+1-5
Original file line numberDiff line numberDiff line change
@@ -396,11 +396,7 @@ class RecipeWaiter {
396396
const item = document.createElement("li");
397397

398398
item.classList.add("operation");
399-
400-
if (this.app.operations[name] != null) {
401-
item.innerHTML = name;
402-
}
403-
399+
item.innerHTML = name;
404400
this.buildRecipeOperation(item);
405401
document.getElementById("rec-list").appendChild(item);
406402

tests/operations/index.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ import "./tests/Unicode.mjs";
115115
import "./tests/RSA.mjs";
116116
import "./tests/CBOREncode.mjs";
117117
import "./tests/CBORDecode.mjs";
118+
import "./tests/RisonEncodeDecode.mjs";
118119
import "./tests/JA3Fingerprint.mjs";
119120
import "./tests/JA3SFingerprint.mjs";
120121
import "./tests/HASSH.mjs";

tests/operations/tests/FileTree.mjs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @author sw5678
3+
* @copyright Crown Copyright 2023
4+
* @license Apache-2.0
5+
*/
6+
import TestRegister from "../../lib/TestRegister.mjs";
7+
8+
TestRegister.addTests([
9+
{
10+
"name": "Swap Case: basic example",
11+
"input": "/test_dir1/test_file1.txt\n/test_dir1/test_file2.txt\n/test_dir2/test_file1.txt",
12+
"expectedOutput": "test_dir1\n|---test_file1.txt\n|---test_file2.txt\ntest_dir2\n|---test_file1.txt",
13+
"recipeConfig": [
14+
{
15+
"op": "File Tree",
16+
"args": [
17+
],
18+
},
19+
],
20+
}
21+
]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* @author sg5506844 [[email protected]]
3+
* @copyright Crown Copyright 2021
4+
* @license Apache-2.0
5+
*/
6+
7+
import TestRegister from "../../lib/TestRegister.mjs";
8+
9+
TestRegister.addTests([
10+
{
11+
name: "Rison Encode: Encoding example 1",
12+
input: JSON.stringify({ any: "json", yes: true }),
13+
expectedOutput: "(any:json,yes:!t)",
14+
recipeConfig: [
15+
{
16+
op: "Rison Encode",
17+
args: ["Encode"]
18+
}
19+
]
20+
},
21+
{
22+
name: "Rison Encode: Encoding example 2",
23+
input: JSON.stringify({ supportsObjects: true, ints: 435 }),
24+
expectedOutput: "ints:435,supportsObjects:!t",
25+
recipeConfig: [
26+
{
27+
op: "Rison Encode",
28+
args: ["Encode Object"]
29+
}
30+
]
31+
},
32+
{
33+
name: "Rison Encode: Encoding example 3",
34+
input: JSON.stringify(["A", "B", { supportsObjects: true }]),
35+
expectedOutput: "A,B,(supportsObjects:!t)",
36+
recipeConfig: [
37+
{
38+
op: "Rison Encode",
39+
args: ["Encode Array"]
40+
}
41+
]
42+
},
43+
{
44+
name: "Rison Encode: Object for an array",
45+
input: JSON.stringify({ supportsObjects: true, ints: 435 }),
46+
expectedOutput: "Rison Encode - rison.encode_array expects an array argument",
47+
expectedError: "Rison Encode - rison.encode_array expects an array argument",
48+
recipeConfig: [
49+
{
50+
op: "Rison Encode",
51+
args: ["Encode Array"]
52+
}
53+
]
54+
},
55+
{
56+
name: "Rison Decode: Decoding example 1",
57+
input: "(any:json,yes:!t)",
58+
expectedOutput: JSON.stringify({ any: "json", yes: true }, null, 4),
59+
recipeConfig: [
60+
{
61+
op: "Rison Decode",
62+
args: ["Decode"]
63+
}
64+
]
65+
}
66+
]);

0 commit comments

Comments
 (0)