2
0
mirror of https://github.com/gchq/CyberChef synced 2025-12-05 23:53:27 +00:00

Compare commits

..

21 Commits

Author SHA1 Message Date
n1474335
22e8883934 8.6.0 2018-08-29 18:04:55 +00:00
n1474335
552a18d89a Updated CHANGELOG 2018-08-29 18:04:49 +00:00
n1474335
6b725e9114 Merge branch 'GCHQ77703-master' 2018-08-29 18:00:06 +00:00
n1474335
415beaa0b0 Tidied up Geohash operations 2018-08-29 17:59:48 +00:00
n1474335
e9fe227ed7 Merge branch 'master' of https://github.com/GCHQ77703/CyberChef into GCHQ77703-master 2018-08-29 17:48:23 +00:00
n1474335
c1be109592 8.5.1 2018-08-29 17:36:05 +00:00
n1474335
88e603bbf1 Merge branch 'PenguinGeorge-cascadexor-new' 2018-08-29 17:35:13 +00:00
n1474335
c7b2095bb4 Updated package-lock.json 2018-08-29 17:34:47 +00:00
n1474335
7396117d89 Merge branch 'cascadexor-new' of https://github.com/PenguinGeorge/CyberChef into PenguinGeorge-cascadexor-new 2018-08-29 17:31:59 +00:00
GCHQ 77703
91133172d5 Remove subdomain from Wikipedia 2018-08-26 18:51:52 +01:00
GCHQ 77703
001f3f30cd Remove multi-line operations 2018-08-26 18:06:02 +01:00
GCHQ 77703
a1b1059ad1 Revert package-lock.json changes 2018-08-26 17:39:33 +01:00
GCHQ 77703
69a0122fea Fix "From Geohash" test 2018-08-26 17:20:50 +01:00
GCHQ 77703
3d505b4248 Add ToGeohash and FromGeohash operations 2018-08-26 14:27:15 +01:00
George J
70d4e3394c Updated XOR to include Cascade scheme 2018-08-24 22:33:24 +01:00
n1474335
3905c01a0d 8.5.0 2018-08-24 01:07:56 +01:00
n1474335
2a49af1ec3 'To Braille' and 'From Braille' operations added. Closes #255 2018-08-24 01:07:51 +01:00
n1474335
3d4f54e8bc 8.4.3 2018-08-24 00:32:57 +01:00
n1474335
61f2f2d2e3 'Show Base64 offsets' operation show supports base64 input. Closes #276 2018-08-24 00:32:52 +01:00
n1474335
00058bd5c7 8.4.2 2018-08-23 23:24:05 +01:00
n1474335
383fe50fc9 Support for negative values in 'Drop bytes' and 'Take bytes'. Closes #266 2018-08-23 23:23:00 +01:00
18 changed files with 479 additions and 26 deletions

View File

@@ -1,6 +1,13 @@
# Changelog
All notable changes to CyberChef will be documented in this file.
### [8.6.0] - 2018-08-29
- 'To Geohash' and 'From Geohash' operations added [@GCHQ77703] | [#344]
### [8.5.0] - 2018-08-23
- 'To Braille' and 'From Braille' operations added [@n1474335] | [#255]
### [8.4.0] - 2018-08-23
- 'To Base85' and 'From Base85' operations added [@PenguinGeorge] | [#340]
@@ -41,6 +48,8 @@ All notable changes to CyberChef will be documented in this file.
- Initial open source commit [@n1474335] | [b1d73a72](https://github.com/gchq/CyberChef/commit/b1d73a725dc7ab9fb7eb789296efd2b7e4b08306)
[8.6.0]: https://github.com/gchq/CyberChef/releases/tag/v8.6.0
[8.5.0]: https://github.com/gchq/CyberChef/releases/tag/v8.5.0
[8.4.0]: https://github.com/gchq/CyberChef/releases/tag/v8.4.0
[8.3.0]: https://github.com/gchq/CyberChef/releases/tag/v8.3.0
[8.2.0]: https://github.com/gchq/CyberChef/releases/tag/v8.2.0
@@ -53,6 +62,7 @@ All notable changes to CyberChef will be documented in this file.
[@n1474335]: https://github.com/n1474335
[@d98762625]: https://github.com/d98762625
[@GCHQ77703]: https://github.com/GCHQ77703
[@artemisbot]: https://github.com/artemisbot
[@picapi]: https://github.com/picapi
[@Dachande663]: https://github.com/Dachande663
@@ -65,6 +75,7 @@ All notable changes to CyberChef will be documented in this file.
[#224]: https://github.com/gchq/CyberChef/pull/224
[#239]: https://github.com/gchq/CyberChef/pull/239
[#248]: https://github.com/gchq/CyberChef/pull/248
[#255]: https://github.com/gchq/CyberChef/issues/255
[#281]: https://github.com/gchq/CyberChef/pull/281
[#284]: https://github.com/gchq/CyberChef/pull/284
[#294]: https://github.com/gchq/CyberChef/pull/294
@@ -74,3 +85,4 @@ All notable changes to CyberChef will be documented in this file.
[#325]: https://github.com/gchq/CyberChef/pull/325
[#338]: https://github.com/gchq/CyberChef/pull/338
[#340]: https://github.com/gchq/CyberChef/pull/340
[#344]: https://github.com/gchq/CyberChef/pull/344

7
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "8.4.1",
"version": "8.6.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -7265,6 +7265,11 @@
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
"dev": true
},
"ngeohash": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/ngeohash/-/ngeohash-0.6.0.tgz",
"integrity": "sha1-MpcT6ec9HxpG2SqrC5StuUUz9oc="
},
"nice-try": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "8.4.1",
"version": "8.6.0",
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
"author": "n1474335 <n1474335@gmail.com>",
"homepage": "https://gchq.github.io/CyberChef",
@@ -106,6 +106,7 @@
"loglevel-message-prefix": "^3.0.0",
"moment": "^2.22.2",
"moment-timezone": "^0.5.21",
"ngeohash": "^0.6.0",
"node-forge": "^0.7.5",
"node-md6": "^0.1.0",
"notepack.io": "^2.1.3",

View File

@@ -51,7 +51,9 @@
"Decode text",
"Swap endianness",
"To MessagePack",
"From MessagePack"
"From MessagePack",
"To Braille",
"From Braille"
]
},
{
@@ -287,7 +289,9 @@
"Adler-32 Checksum",
"CRC-16 Checksum",
"CRC-32 Checksum",
"TCP/IP Checksum"
"TCP/IP Checksum",
"To Geohash",
"From Geohash"
]
},
{

View File

@@ -81,6 +81,7 @@ export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", r
return returnType === "string" ? "" : [];
}
alphabet = alphabet || "A-Za-z0-9+/=";
alphabet = Utils.expandAlphRange(alphabet).join("");
const output = [];

View File

@@ -25,6 +25,7 @@ export function bitOp (input, key, func, nullPreserving, scheme) {
for (let i = 0; i < input.length; i++) {
k = key[i % key.length];
if (scheme === "Cascade") k = input[i + 1] || 0;
o = input[i];
x = nullPreserving && (o === 0 || o === k) ? o : func(o, k);
result.push(x);

15
src/core/lib/Braille.mjs Normal file
View File

@@ -0,0 +1,15 @@
/**
* Braille resources.
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
/**
* Braille lookup table.
*/
export const BRAILLE_LOOKUP = {
ascii: " A1B'K2L@CIF/MSP\"E3H9O6R^DJG>NTQ,*5<-U8V.%[$+X!&;:4\\0Z7(_?W]#Y)=",
dot6: "⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿"
};

View File

@@ -5,7 +5,6 @@
*/
import Operation from "../Operation";
import OperationError from "../errors/OperationError";
/**
* Drop bytes operation
@@ -20,7 +19,7 @@ class DropBytes extends Operation {
this.name = "Drop bytes";
this.module = "Default";
this.description = "Cuts a slice of the specified number of bytes out of the data.";
this.description = "Cuts a slice of the specified number of bytes out of the data. Negative values are allowed.";
this.inputType = "ArrayBuffer";
this.outputType = "ArrayBuffer";
this.args = [
@@ -50,14 +49,25 @@ class DropBytes extends Operation {
* @throws {OperationError} if invalid input
*/
run(input, args) {
const start = args[0],
length = args[1],
applyToEachLine = args[2];
if (start < 0 || length < 0)
throw new OperationError("Error: Invalid value");
let start = args[0],
length = args[1];
const applyToEachLine = args[2];
if (!applyToEachLine) {
if (start < 0) { // Take from the end
start = input.byteLength + start;
}
if (length < 0) { // Flip start point
start = start + length;
if (start < 0) {
start = input.byteLength + start;
length = start - length;
} else {
length = -length;
}
}
const left = input.slice(0, start),
right = input.slice(start + length, input.byteLength);
const result = new Uint8Array(left.byteLength + right.byteLength);
@@ -82,10 +92,28 @@ class DropBytes extends Operation {
}
lines.push(line);
let output = [];
let output = [],
s = start,
l = length;
for (i = 0; i < lines.length; i++) {
output = output.concat(lines[i].slice(0, start).concat(lines[i].slice(start+length, lines[i].length)));
if (s < 0) { // Take from the end
s = lines[i].length + s;
}
if (l < 0) { // Flip start point
s = s + l;
if (s < 0) {
s = lines[i].length + s;
l = s - l;
} else {
l = -l;
}
}
output = output.concat(lines[i].slice(0, s).concat(lines[i].slice(s+l, lines[i].length)));
output.push(0x0a);
s = start;
l = length;
}
return new Uint8Array(output.slice(0, output.length-1)).buffer;
}

View File

@@ -0,0 +1,70 @@
/**
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation";
import {BRAILLE_LOOKUP} from "../lib/Braille";
/**
* From Braille operation
*/
class FromBraille extends Operation {
/**
* FromBraille constructor
*/
constructor() {
super();
this.name = "From Braille";
this.module = "Default";
this.description = "Converts six-dot braille symbols to text.";
this.infoURL = "https://wikipedia.org/wiki/Braille";
this.inputType = "string";
this.outputType = "string";
this.args = [];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
return input.split("").map(b => {
const idx = BRAILLE_LOOKUP.dot6.indexOf(b);
return idx < 0 ? b : BRAILLE_LOOKUP.ascii[idx];
}).join("");
}
/**
* Highlight From Braille
*
* @param {Object[]} pos
* @param {number} pos[].start
* @param {number} pos[].end
* @param {Object[]} args
* @returns {Object[]} pos
*/
highlight(pos, args) {
return pos;
}
/**
* Highlight From Braille in reverse
*
* @param {Object[]} pos
* @param {number} pos[].start
* @param {number} pos[].end
* @param {Object[]} args
* @returns {Object[]} pos
*/
highlightReverse(pos, args) {
return pos;
}
}
export default FromBraille;

View File

@@ -0,0 +1,44 @@
/**
* @author gchq77703 []
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation";
import geohash from "ngeohash";
/**
* From Geohash operation
*/
class FromGeohash extends Operation {
/**
* FromGeohash constructor
*/
constructor() {
super();
this.name = "From Geohash";
this.module = "Hashing";
this.description = "Converts Geohash strings into Lat/Long coordinates. For example, <code>ww8p1r4t8</code> becomes <code>37.8324,112.5584</code>.";
this.infoURL = "https://wikipedia.org/wiki/Geohash";
this.inputType = "string";
this.outputType = "string";
this.args = [];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
return input.split("\n").map(line => {
const coords = geohash.decode(line);
return [coords.latitude, coords.longitude].join(",");
}).join("\n");
}
}
export default FromGeohash;

View File

@@ -36,6 +36,11 @@ class ShowBase64Offsets extends Operation {
name: "Show variable chars and padding",
type: "boolean",
value: true
},
{
name: "Input format",
type: "option",
value: ["Raw", "Base64"]
}
];
}
@@ -46,7 +51,11 @@ class ShowBase64Offsets extends Operation {
* @returns {html}
*/
run(input, args) {
const [alphabet, showVariable] = args;
const [alphabet, showVariable, format] = args;
if (format === "Base64") {
input = fromBase64(Utils.byteArrayToUtf8(input), null, "byteArray");
}
let offset0 = toBase64(input, alphabet),
offset1 = toBase64([0].concat(input), alphabet),

View File

@@ -5,7 +5,6 @@
*/
import Operation from "../Operation";
import OperationError from "../errors/OperationError";
/**
* Take bytes operation
@@ -20,7 +19,7 @@ class TakeBytes extends Operation {
this.name = "Take bytes";
this.module = "Default";
this.description = "Takes a slice of the specified number of bytes from the data.";
this.description = "Takes a slice of the specified number of bytes from the data. Negative values are allowed.";
this.inputType = "ArrayBuffer";
this.outputType = "ArrayBuffer";
this.args = [
@@ -50,15 +49,27 @@ class TakeBytes extends Operation {
* @throws {OperationError} if invalid value
*/
run(input, args) {
const start = args[0],
length = args[1],
applyToEachLine = args[2];
let start = args[0],
length = args[1];
const applyToEachLine = args[2];
if (start < 0 || length < 0)
throw new OperationError("Error: Invalid value");
if (!applyToEachLine) {
if (start < 0) { // Take from the end
start = input.byteLength + start;
}
if (length < 0) { // Flip start point
start = start + length;
if (start < 0) {
start = input.byteLength + start;
length = start - length;
} else {
length = -length;
}
}
if (!applyToEachLine)
return input.slice(start, start+length);
}
// Split input into lines
const data = new Uint8Array(input);
@@ -77,9 +88,26 @@ class TakeBytes extends Operation {
lines.push(line);
let output = [];
let s = start,
l = length;
for (i = 0; i < lines.length; i++) {
output = output.concat(lines[i].slice(start, start+length));
if (s < 0) { // Take from the end
s = lines[i].length + s;
}
if (l < 0) { // Flip start point
s = s + l;
if (s < 0) {
s = lines[i].length + s;
l = s - l;
} else {
l = -l;
}
}
output = output.concat(lines[i].slice(s, s+l));
output.push(0x0a);
s = start;
l = length;
}
return new Uint8Array(output.slice(0, output.length-1)).buffer;
}

View File

@@ -0,0 +1,70 @@
/**
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation";
import {BRAILLE_LOOKUP} from "../lib/Braille";
/**
* To Braille operation
*/
class ToBraille extends Operation {
/**
* ToBraille constructor
*/
constructor() {
super();
this.name = "To Braille";
this.module = "Default";
this.description = "Converts text to six-dot braille symbols.";
this.infoURL = "https://wikipedia.org/wiki/Braille";
this.inputType = "string";
this.outputType = "string";
this.args = [];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
return input.split("").map(c => {
const idx = BRAILLE_LOOKUP.ascii.indexOf(c.toUpperCase());
return idx < 0 ? c : BRAILLE_LOOKUP.dot6[idx];
}).join("");
}
/**
* Highlight To Braille
*
* @param {Object[]} pos
* @param {number} pos[].start
* @param {number} pos[].end
* @param {Object[]} args
* @returns {Object[]} pos
*/
highlight(pos, args) {
return pos;
}
/**
* Highlight To Braille in reverse
*
* @param {Object[]} pos
* @param {number} pos[].start
* @param {number} pos[].end
* @param {Object[]} args
* @returns {Object[]} pos
*/
highlightReverse(pos, args) {
return pos;
}
}
export default ToBraille;

View File

@@ -0,0 +1,53 @@
/**
* @author gchq77703 []
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation";
import geohash from "ngeohash";
/**
* To Geohash operation
*/
class ToGeohash extends Operation {
/**
* ToGeohash constructor
*/
constructor() {
super();
this.name = "To Geohash";
this.module = "Hashing";
this.description = "Converts Lat/Long coordinates into a Geohash string. For example, <code>37.8324,112.5584</code> becomes <code>ww8p1r4t8</code>.";
this.infoURL = "https://wikipedia.org/wiki/Geohash";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
name: "Precision",
type: "number",
value: 9
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [precision] = args;
return input.split("\n").map(line => {
line = line.replace(/ /g, "");
if (line === "") return "";
return geohash.encode(...line.split(",").map(num => parseFloat(num)), precision);
}).join("\n");
}
}
export default ToGeohash;

View File

@@ -21,7 +21,7 @@ class XOR extends Operation {
this.name = "XOR";
this.module = "Default";
this.description = "XOR the input with the given key.<br>e.g. <code>fe023da5</code><br><br><strong>Options</strong><br><u>Null preserving:</u> If the current byte is 0x00 or the same as the key, skip it.<br><br><u>Scheme:</u><ul><li>Standard - key is unchanged after each round</li><li>Input differential - key is set to the value of the previous unprocessed byte</li><li>Output differential - key is set to the value of the previous processed byte</li></ul>";
this.description = "XOR the input with the given key.<br>e.g. <code>fe023da5</code><br><br><strong>Options</strong><br><u>Null preserving:</u> If the current byte is 0x00 or the same as the key, skip it.<br><br><u>Scheme:</u><ul><li>Standard - key is unchanged after each round</li><li>Input differential - key is set to the value of the previous unprocessed byte</li><li>Output differential - key is set to the value of the previous processed byte</li><li>Cascade - key is set to the input byte shifted by one</li></ul>";
this.infoURL = "https://wikipedia.org/wiki/XOR";
this.inputType = "byteArray";
this.outputType = "byteArray";
@@ -35,7 +35,7 @@ class XOR extends Operation {
{
"name": "Scheme",
"type": "option",
"value": ["Standard", "Input differential", "Output differential"]
"value": ["Standard", "Input differential", "Output differential", "Cascade"]
},
{
"name": "Null preserving",

View File

@@ -64,6 +64,8 @@ import "./tests/operations/SetUnion";
import "./tests/operations/SymmetricDifference";
import "./tests/operations/TranslateDateTimeFormat";
import "./tests/operations/Magic";
import "./tests/operations/ToGeohash.mjs";
import "./tests/operations/FromGeohash.mjs";
let allTestsPassing = true;
const testStatusCounts = {

View File

@@ -0,0 +1,55 @@
/**
* To Geohash tests
*
* @author gchq77703
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import TestRegister from "../../TestRegister";
TestRegister.addTests([
{
name: "From Geohash",
input: "ww8p1r4t8",
expectedOutput: "37.83238649368286,112.55838632583618",
recipeConfig: [
{
op: "From Geohash",
args: [],
},
],
},
{
name: "From Geohash",
input: "ww8p1r",
expectedOutput: "37.83416748046875,112.5604248046875",
recipeConfig: [
{
op: "From Geohash",
args: [],
},
],
},
{
name: "From Geohash",
input: "ww8",
expectedOutput: "37.265625,113.203125",
recipeConfig: [
{
op: "From Geohash",
args: [],
},
],
},
{
name: "From Geohash",
input: "w",
expectedOutput: "22.5,112.5",
recipeConfig: [
{
op: "From Geohash",
args: [],
},
],
},
]);

View File

@@ -0,0 +1,55 @@
/**
* To Geohash tests
*
* @author gchq77703
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import TestRegister from "../../TestRegister";
TestRegister.addTests([
{
name: "To Geohash",
input: "37.8324,112.5584",
expectedOutput: "ww8p1r4t8",
recipeConfig: [
{
op: "To Geohash",
args: [9],
},
],
},
{
name: "To Geohash",
input: "37.9324,-112.2584",
expectedOutput: "9w8pv3ruj",
recipeConfig: [
{
op: "To Geohash",
args: [9],
},
],
},
{
name: "To Geohash",
input: "37.8324,112.5584",
expectedOutput: "ww8",
recipeConfig: [
{
op: "To Geohash",
args: [3],
},
],
},
{
name: "To Geohash",
input: "37.9324,-112.2584",
expectedOutput: "9w8pv3rujxy5b99",
recipeConfig: [
{
op: "To Geohash",
args: [15],
},
],
},
]);