mirror of
https://github.com/gchq/CyberChef.git
synced 2026-02-25 11:11:43 +01:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4acf7b4e4f | ||
|
|
42e881326f | ||
|
|
3c4893d7c7 | ||
|
|
027aca4ab2 | ||
|
|
2d471f551f | ||
|
|
5c598b69b0 | ||
|
|
037300de79 | ||
|
|
6990dcae89 | ||
|
|
6e81d6dfcd | ||
|
|
cea30465d8 | ||
|
|
b301d16cb2 | ||
|
|
ba24e12454 | ||
|
|
3b3c27072f | ||
|
|
3089c39369 | ||
|
|
0cbb17f7ce | ||
|
|
54793f2b78 | ||
|
|
f1ffe19ec8 | ||
|
|
04ee2fb3e4 | ||
|
|
ac2466a304 |
@@ -1,6 +1,9 @@
|
||||
# Changelog
|
||||
All notable changes to CyberChef will be documented in this file.
|
||||
|
||||
### [8.10.0] - 2018-11-07
|
||||
- 'Remove Diacritics' operation added [@klaxon1] | [#387]
|
||||
|
||||
### [8.9.0] - 2018-11-07
|
||||
- 'Defang URL' operation added [@arnydo] | [#394]
|
||||
|
||||
@@ -80,6 +83,7 @@ All notable changes to CyberChef will be documented in this file.
|
||||
[@sevzero]: https://github.com/sevzero
|
||||
[@PenguinGeorge]: https://github.com/PenguinGeorge
|
||||
[@arnydo]: https://github.com/arnydo
|
||||
[@klaxon1]: https://github.com/klaxon1
|
||||
|
||||
[#95]: https://github.com/gchq/CyberChef/pull/299
|
||||
[#173]: https://github.com/gchq/CyberChef/pull/173
|
||||
@@ -99,4 +103,5 @@ All notable changes to CyberChef will be documented in this file.
|
||||
[#344]: https://github.com/gchq/CyberChef/pull/344
|
||||
[#348]: https://github.com/gchq/CyberChef/pull/348
|
||||
[#351]: https://github.com/gchq/CyberChef/pull/351
|
||||
[#387]: https://github.com/gchq/CyberChef/pull/387
|
||||
[#394]: https://github.com/gchq/CyberChef/pull/394
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "8.9.2",
|
||||
"version": "8.10.2",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "8.9.2",
|
||||
"version": "8.10.2",
|
||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
|
||||
@@ -9,6 +9,7 @@ import moment from "moment-timezone";
|
||||
import {fromBase64} from "./lib/Base64";
|
||||
import {fromHex} from "./lib/Hex";
|
||||
import {fromDecimal} from "./lib/Decimal";
|
||||
import {fromBinary} from "./lib/Binary";
|
||||
|
||||
|
||||
/**
|
||||
@@ -298,7 +299,7 @@ class Utils {
|
||||
* Accepts hex, Base64, UTF8 and Latin1 strings.
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {string} type - One of "Hex", "Decimal", "Base64", "UTF8" or "Latin1"
|
||||
* @param {string} type - One of "Binary", "Hex", "Decimal", "Base64", "UTF8" or "Latin1"
|
||||
* @returns {byteArray}
|
||||
*
|
||||
* @example
|
||||
@@ -313,6 +314,8 @@ class Utils {
|
||||
*/
|
||||
static convertToByteArray(str, type) {
|
||||
switch (type.toLowerCase()) {
|
||||
case "binary":
|
||||
return fromBinary(str);
|
||||
case "hex":
|
||||
return fromHex(str);
|
||||
case "decimal":
|
||||
@@ -333,7 +336,7 @@ class Utils {
|
||||
* Accepts hex, Base64, UTF8 and Latin1 strings.
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {string} type - One of "Hex", "Decimal", "Base64", "UTF8" or "Latin1"
|
||||
* @param {string} type - One of "Binary", "Hex", "Decimal", "Base64", "UTF8" or "Latin1"
|
||||
* @returns {string}
|
||||
*
|
||||
* @example
|
||||
@@ -348,6 +351,8 @@ class Utils {
|
||||
*/
|
||||
static convertToByteString(str, type) {
|
||||
switch (type.toLowerCase()) {
|
||||
case "binary":
|
||||
return Utils.byteArrayToChars(fromBinary(str));
|
||||
case "hex":
|
||||
return Utils.byteArrayToChars(fromHex(str));
|
||||
case "decimal":
|
||||
|
||||
@@ -168,6 +168,7 @@
|
||||
"ops": [
|
||||
"Encode text",
|
||||
"Decode text",
|
||||
"Remove Diacritics",
|
||||
"Unescape Unicode Characters"
|
||||
]
|
||||
},
|
||||
|
||||
70
src/core/lib/Binary.mjs
Normal file
70
src/core/lib/Binary.mjs
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Binary functions.
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Utils from "../Utils";
|
||||
|
||||
|
||||
/**
|
||||
* Convert a byte array into a binary string.
|
||||
*
|
||||
* @param {Uint8Array|byteArray} data
|
||||
* @param {string} [delim="Space"]
|
||||
* @param {number} [padding=8]
|
||||
* @returns {string}
|
||||
*
|
||||
* @example
|
||||
* // returns "00010000 00100000 00110000"
|
||||
* toHex([10,20,30]);
|
||||
*
|
||||
* // returns "00010000 00100000 00110000"
|
||||
* toHex([10,20,30], ":");
|
||||
*/
|
||||
export function toBinary(data, delim="Space", padding=8) {
|
||||
if (!data) return "";
|
||||
|
||||
delim = Utils.charRep(delim);
|
||||
let output = "";
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
output += data[i].toString(2).padStart(padding, "0") + delim;
|
||||
}
|
||||
|
||||
if (delim.length) {
|
||||
return output.slice(0, -delim.length);
|
||||
} else {
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a binary string into a byte array.
|
||||
*
|
||||
* @param {string} data
|
||||
* @param {string} [delim]
|
||||
* @param {number} [byteLen=8]
|
||||
* @returns {byteArray}
|
||||
*
|
||||
* @example
|
||||
* // returns [10,20,30]
|
||||
* fromBinary("00010000 00100000 00110000");
|
||||
*
|
||||
* // returns [10,20,30]
|
||||
* fromBinary("00010000:00100000:00110000", "Colon");
|
||||
*/
|
||||
export function fromBinary(data, delim="Space", byteLen=8) {
|
||||
const delimRegex = Utils.regexRep(delim);
|
||||
data = data.replace(delimRegex, "");
|
||||
|
||||
const output = [];
|
||||
for (let i = 0; i < data.length; i += byteLen) {
|
||||
output.push(parseInt(data.substr(i, byteLen), 2));
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -116,3 +116,9 @@ export function sub(operand, key) {
|
||||
const result = operand - key;
|
||||
return (result < 0) ? 256 + result : result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delimiter options for bitwise operations
|
||||
*/
|
||||
export const BITWISE_OP_DELIMS = ["Hex", "Decimal", "Binary", "Base64", "UTF8", "Latin1"];
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import { bitOp, add } from "../lib/BitwiseOp";
|
||||
import { bitOp, add, BITWISE_OP_DELIMS } from "../lib/BitwiseOp";
|
||||
|
||||
/**
|
||||
* ADD operation
|
||||
@@ -30,7 +30,7 @@ class ADD extends Operation {
|
||||
"name": "Key",
|
||||
"type": "toggleString",
|
||||
"value": "",
|
||||
"toggleValues": ["Hex", "Decimal", "Base64", "UTF8", "Latin1"]
|
||||
"toggleValues": BITWISE_OP_DELIMS
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import { bitOp, and } from "../lib/BitwiseOp";
|
||||
import { bitOp, and, BITWISE_OP_DELIMS } from "../lib/BitwiseOp";
|
||||
|
||||
/**
|
||||
* AND operation
|
||||
@@ -30,7 +30,7 @@ class AND extends Operation {
|
||||
"name": "Key",
|
||||
"type": "toggleString",
|
||||
"value": "",
|
||||
"toggleValues": ["Hex", "Decimal", "Base64", "UTF8", "Latin1"]
|
||||
"toggleValues": BITWISE_OP_DELIMS
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import {BIN_DELIM_OPTIONS} from "../lib/Delim";
|
||||
import {fromBinary} from "../lib/Binary";
|
||||
|
||||
/**
|
||||
* From Binary operation
|
||||
@@ -77,15 +78,7 @@ class FromBinary extends Operation {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
run(input, args) {
|
||||
const delimRegex = Utils.regexRep(args[0] || "Space");
|
||||
input = input.replace(delimRegex, "");
|
||||
|
||||
const output = [];
|
||||
const byteLen = 8;
|
||||
for (let i = 0; i < input.length; i += byteLen) {
|
||||
output.push(parseInt(input.substr(i, byteLen), 2));
|
||||
}
|
||||
return output;
|
||||
return fromBinary(input, args[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import { bitOp, or } from "../lib/BitwiseOp";
|
||||
import { bitOp, or, BITWISE_OP_DELIMS } from "../lib/BitwiseOp";
|
||||
|
||||
/**
|
||||
* OR operation
|
||||
@@ -30,7 +30,7 @@ class OR extends Operation {
|
||||
"name": "Key",
|
||||
"type": "toggleString",
|
||||
"value": "",
|
||||
"toggleValues": ["Hex", "Decimal", "Base64", "UTF8", "Latin1"]
|
||||
"toggleValues": BITWISE_OP_DELIMS
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
41
src/core/operations/RemoveDiacritics.mjs
Normal file
41
src/core/operations/RemoveDiacritics.mjs
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @author Klaxon [klaxon@veyr.com]
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
|
||||
/**
|
||||
* Remove Diacritics operation
|
||||
*/
|
||||
class RemoveDiacritics extends Operation {
|
||||
|
||||
/**
|
||||
* RemoveDiacritics constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Remove Diacritics";
|
||||
this.module = "Default";
|
||||
this.description = "Replaces accented characters with their latin character equivalent.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Diacritic";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
// reference: https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript/37511463
|
||||
return input.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default RemoveDiacritics;
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import { bitOp, sub } from "../lib/BitwiseOp";
|
||||
import { bitOp, sub, BITWISE_OP_DELIMS } from "../lib/BitwiseOp";
|
||||
|
||||
/**
|
||||
* SUB operation
|
||||
@@ -30,7 +30,7 @@ class SUB extends Operation {
|
||||
"name": "Key",
|
||||
"type": "toggleString",
|
||||
"value": "",
|
||||
"toggleValues": ["Hex", "Decimal", "Base64", "UTF8", "Latin1"]
|
||||
"toggleValues": BITWISE_OP_DELIMS
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class Sort extends Operation {
|
||||
{
|
||||
"name": "Order",
|
||||
"type": "option",
|
||||
"value": ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address", "Numeric"]
|
||||
"value": ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address", "Numeric", "Numeric (hexadecimal)"]
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -62,6 +62,8 @@ class Sort extends Operation {
|
||||
sorted = sorted.sort(Sort._ipSort);
|
||||
} else if (order === "Numeric") {
|
||||
sorted = sorted.sort(Sort._numericSort);
|
||||
} else if (order === "Numeric (hexadecimal)") {
|
||||
sorted = sorted.sort(Sort._hexadecimalSort);
|
||||
}
|
||||
|
||||
if (sortReverse) sorted.reverse();
|
||||
@@ -131,6 +133,44 @@ class Sort extends Operation {
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison operation for sorting of hexadecimal values.
|
||||
*
|
||||
* @author Chris van Marle
|
||||
* @private
|
||||
* @param {string} a
|
||||
* @param {string} b
|
||||
* @returns {number}
|
||||
*/
|
||||
static _hexadecimalSort(a, b) {
|
||||
let a_ = a.split(/([^\da-f]+)/i),
|
||||
b_ = b.split(/([^\da-f]+)/i);
|
||||
|
||||
a_ = a_.map(v => {
|
||||
const t = parseInt(v, 16);
|
||||
return isNaN(t) ? v : t;
|
||||
});
|
||||
|
||||
b_ = b_.map(v => {
|
||||
const t = parseInt(v, 16);
|
||||
return isNaN(t) ? v : t;
|
||||
});
|
||||
|
||||
for (let i = 0; i < a_.length && i < b.length; ++i) {
|
||||
if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers
|
||||
if (!isNaN(a_[i]) && isNaN(b_[i])) return -1;
|
||||
if (isNaN(a_[i]) && isNaN(b_[i])) {
|
||||
const ret = a_[i].localeCompare(b_[i]); // Compare strings
|
||||
if (ret !== 0) return ret;
|
||||
}
|
||||
if (!isNaN(a_[i]) && !isNaN(a_[i])) { // Compare numbers
|
||||
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
|
||||
}
|
||||
}
|
||||
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Sort;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import {BIN_DELIM_OPTIONS} from "../lib/Delim";
|
||||
import {toBinary} from "../lib/Binary";
|
||||
|
||||
/**
|
||||
* To Binary operation
|
||||
@@ -40,19 +41,7 @@ class ToBinary extends Operation {
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const delim = Utils.charRep(args[0] || "Space"),
|
||||
padding = 8;
|
||||
let output = "";
|
||||
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
output += input[i].toString(2).padStart(padding, "0") + delim;
|
||||
}
|
||||
|
||||
if (delim.length) {
|
||||
return output.slice(0, -delim.length);
|
||||
} else {
|
||||
return output;
|
||||
}
|
||||
return toBinary(input, args[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import { bitOp, xor } from "../lib/BitwiseOp";
|
||||
import { bitOp, xor, BITWISE_OP_DELIMS } from "../lib/BitwiseOp";
|
||||
|
||||
/**
|
||||
* XOR operation
|
||||
@@ -30,7 +30,7 @@ class XOR extends Operation {
|
||||
"name": "Key",
|
||||
"type": "toggleString",
|
||||
"value": "",
|
||||
"toggleValues": ["Hex", "Decimal", "Base64", "UTF8", "Latin1"]
|
||||
"toggleValues": BITWISE_OP_DELIMS
|
||||
},
|
||||
{
|
||||
"name": "Scheme",
|
||||
|
||||
@@ -63,6 +63,7 @@ import "./tests/operations/ParseIPRange";
|
||||
import "./tests/operations/PowerSet";
|
||||
import "./tests/operations/Regex";
|
||||
import "./tests/operations/Register";
|
||||
import "./tests/operations/RemoveDiacritics";
|
||||
import "./tests/operations/Rotate";
|
||||
import "./tests/operations/SeqUtils";
|
||||
import "./tests/operations/SetDifference";
|
||||
|
||||
22
test/tests/operations/RemoveDiacritics.mjs
Normal file
22
test/tests/operations/RemoveDiacritics.mjs
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Remove Diacritics tests.
|
||||
*
|
||||
* @author Klaxon [klaxon@veyr.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../TestRegister";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Remove Diacritics",
|
||||
input: "\xe0, \xe8, \xec, \xf2, \xf9 \xc0, \xc8, \xcc, \xd2, \xd9\n\xe1, \xe9, \xed, \xf3, \xfa, \xfd \xc1, \xc9, \xcd, \xd3, \xda, \xdd\n\xe2, \xea, \xee, \xf4, \xfb \xc2, \xca, \xce, \xd4, \xdb\n\xe3, \xf1, \xf5 \xc3, \xd1, \xd5\n\xe4, \xeb, \xef, \xf6, \xfc, \xff \xc4, \xcb, \xcf, \xd6, \xdc, \u0178\n\xe5, \xc5",
|
||||
expectedOutput: "a, e, i, o, u A, E, I, O, U\na, e, i, o, u, y A, E, I, O, U, Y\na, e, i, o, u A, E, I, O, U\na, n, o A, N, O\na, e, i, o, u, y A, E, I, O, U, Y\na, A",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Remove Diacritics",
|
||||
"args": []
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
@@ -30,4 +30,15 @@ TestRegister.addTests([
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "SeqUtils - Hexadecimal sort",
|
||||
input: "06,08,0a,0d,0f,1,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,2,3,4,5,7,9,b,c,e",
|
||||
expectedOutput: "1,2,3,4,5,06,7,08,9,0a,b,c,0d,e,0f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Sort",
|
||||
"args": ["Comma", false, "Numeric (hexadecimal)"]
|
||||
}
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user