2
0
mirror of https://github.com/gchq/CyberChef synced 2025-12-27 13:43:30 +00:00

Compare commits

..

23 Commits

Author SHA1 Message Date
n1474335
4563c86acd 9.24.5 2021-02-09 14:24:08 +00:00
n1474335
0a59f8068e Merge branch 'aussieklutz-master' 2021-02-09 14:23:18 +00:00
n1474335
24548e3a48 Tidied up JWT tests 2021-02-09 14:23:02 +00:00
n1474335
f4784d49e7 Merge branch 'master' of https://github.com/aussieklutz/CyberChef into aussieklutz-master 2021-02-09 14:16:36 +00:00
n1474335
14d5069c6e Merge branch 'mt3571-1073-jwt-verify' 2021-02-09 14:15:12 +00:00
n1474335
9fdd55c5c6 Tidied up JWT ops 2021-02-09 14:14:59 +00:00
n1474335
5bc523aeff Merge branch '1073-jwt-verify' of https://github.com/mt3571/CyberChef into mt3571-1073-jwt-verify 2021-02-09 14:02:21 +00:00
n1474335
3ae2e2e2c8 Fixed highlighting of op names where only the description has hit 2021-02-09 11:50:20 +00:00
n1474335
83e49da7f6 Fixed description hiighlighting issue 2021-02-09 11:37:25 +00:00
n1474335
fe6df8778f Fixed year in CHANGELOG records. Closes #1168 2021-02-09 11:26:00 +00:00
aussieklutz
d5a0adea0c Update JWTVerify.mjs 2021-02-06 18:35:46 +10:00
aussieklutz
1bcb8e433d Update JWTVerify.mjs 2021-02-06 18:10:54 +10:00
aussieklutz
fa05cf1d78 Update JWTVerify.mjs
Enabled ESRSA verification.
2021-02-06 17:58:49 +10:00
aussieklutz
63dff0d34d Update JWTVerify.mjs
Enabled validation of ECSHA256 JWT tokens in the tests
2021-02-06 17:55:44 +10:00
aussieklutz
e228b197f9 Update JWTVerify.mjs 2021-02-06 17:45:42 +10:00
aussieklutz
4bbeb6caa3 Update JWTVerify.mjs
Add expectation for working RSASHA256 test, and comment out unused privatekey.
2021-02-06 17:42:42 +10:00
aussieklutz
139d25dff9 Update JWTVerify.mjs
Update RSASHA256 test with the public key derived from the pre-existing private key, and expect a working testcase.
2021-02-06 17:40:04 +10:00
aussieklutz
6984258404 Update JWTVerify.mjs
Enable verification of RSASHA256 and 512 tokens
2021-02-06 17:27:54 +10:00
n1474335
ba66fd6546 Fixed recursive matching arguments 2021-02-05 19:04:27 +00:00
n1474335
47bbefd81f Fixed recursive scoring results in fuzzy match lib 2021-02-05 18:24:15 +00:00
n1474335
50f796049c Fixed search test 2021-02-05 18:07:20 +00:00
mt3571
887ea0cf06 Changed an incorrect name 2020-12-01 13:49:34 +00:00
mt3571
3e0525ee9e Added in a new file to store the list of JWT algorithms that can be used, as this error was occurring due to a mismatch between what you could sign and what you could verify 2020-12-01 13:38:01 +00:00
11 changed files with 74 additions and 52 deletions

View File

@@ -13,10 +13,10 @@ All major and minor version changes will be documented in this file. Details of
## Details
### [9.24.0] - 2020-02-02
### [9.24.0] - 2021-02-02
- 'SM3' hashing function added along with more configuration options for other hashing operations [@n1073645] [@n1474335] | [#1022]
### [9.23.0] - 2020-02-01
### [9.23.0] - 2021-02-01
- Various RSA operations added to encrypt, decrypt, sign, verify and generate keys [@mattnotmitt] [@GCHQ77703] | [#652]
### [9.22.0] - 2021-02-01

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "9.24.4",
"version": "9.24.5",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "9.24.4",
"version": "9.24.5",
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
"author": "n1474335 <n1474335@gmail.com>",
"homepage": "https://gchq.github.io/CyberChef",

View File

@@ -71,12 +71,12 @@ function fuzzyMatchRecursive(
// Return if recursion limit is reached.
if (++recursionCount >= recursionLimit) {
return [false, outScore];
return [false, outScore, []];
}
// Return if we reached ends of strings.
if (patternCurIndex === pattern.length || strCurrIndex === str.length) {
return [false, outScore];
return [false, outScore, []];
}
// Recursion params
@@ -92,7 +92,7 @@ function fuzzyMatchRecursive(
pattern[patternCurIndex].toLowerCase() === str[strCurrIndex].toLowerCase()
) {
if (nextMatch >= maxMatches) {
return [false, outScore];
return [false, outScore, []];
}
if (firstMatch && srcMatches) {
@@ -100,8 +100,7 @@ function fuzzyMatchRecursive(
firstMatch = false;
}
const recursiveMatches = [];
const [matched, recursiveScore] = fuzzyMatchRecursive(
const [matched, recursiveScore, recursiveMatches] = fuzzyMatchRecursive(
pattern,
str,
patternCurIndex,
@@ -181,17 +180,17 @@ function fuzzyMatchRecursive(
// Return best result
if (recursiveMatch && (!matched || bestRecursiveScore > outScore)) {
// Recursive score is better than "this"
matches = [...bestRecursiveMatches];
matches = bestRecursiveMatches;
outScore = bestRecursiveScore;
return [true, outScore, calcMatchRanges(matches)];
return [true, outScore, matches];
} else if (matched) {
// "this" score is better than recursive
return [true, outScore, calcMatchRanges(matches)];
return [true, outScore, matches];
} else {
return [false, outScore];
return [false, outScore, matches];
}
}
return [false, outScore];
return [false, outScore, matches];
}
/**
@@ -201,7 +200,7 @@ function fuzzyMatchRecursive(
* @param [number] matches
* @returns [[number]]
*/
function calcMatchRanges(matches) {
export function calcMatchRanges(matches) {
const ranges = [];
let start = matches[0],
curr = start;

24
src/core/lib/JWT.mjs Normal file
View File

@@ -0,0 +1,24 @@
/**
* JWT resources
*
* @author mt3571 [mt3571@protonmail.com]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
/**
* List of the JWT algorithms that can be used
*/
export const JWT_ALGORITHMS = [
"HS256",
"HS384",
"HS512",
"RS256",
"RS384",
"RS512",
"ES256",
"ES384",
"ES512",
"None"
];

View File

@@ -3,10 +3,11 @@
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import jwt from "jsonwebtoken";
import OperationError from "../errors/OperationError.mjs";
import {JWT_ALGORITHMS} from "../lib/JWT.mjs";
/**
* JWT Sign operation
@@ -34,18 +35,7 @@ class JWTSign extends Operation {
{
name: "Signing algorithm",
type: "option",
value: [
"HS256",
"HS384",
"HS512",
"RS256",
"RS384",
"RS512",
"ES256",
"ES384",
"ES512",
"None"
]
value: JWT_ALGORITHMS
}
];
}

View File

@@ -3,10 +3,11 @@
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import jwt from "jsonwebtoken";
import OperationError from "../errors/OperationError.mjs";
import {JWT_ALGORITHMS} from "../lib/JWT.mjs";
/**
* JWT Verify operation
@@ -27,7 +28,7 @@ class JWTVerify extends Operation {
this.outputType = "JSON";
this.args = [
{
name: "Private/Secret Key",
name: "Public/Secret Key",
type: "text",
value: "secret"
},
@@ -41,14 +42,11 @@ class JWTVerify extends Operation {
*/
run(input, args) {
const [key] = args;
const algos = JWT_ALGORITHMS;
algos[algos.indexOf("None")] = "none";
try {
const verified = jwt.verify(input, key, { algorithms: [
"HS256",
"HS384",
"HS512",
"none"
]});
const verified = jwt.verify(input, key, { algorithms: algos });
if (Object.prototype.hasOwnProperty.call(verified, "name") && verified.name === "JsonWebTokenError") {
throw new OperationError(verified.message);

View File

@@ -97,12 +97,13 @@ class HTMLOperation {
* @param {[[number]]} descIdxs - Indexes of the search strings in the operation description [[start, length]]
*/
highlightSearchStrings(nameIdxs, descIdxs) {
if (nameIdxs.length) {
if (nameIdxs.length && typeof nameIdxs[0][0] === "number") {
let opName = "",
pos = 0;
nameIdxs.forEach(idxs => {
const [start, length] = idxs;
if (typeof start !== "number") return;
opName += this.name.slice(pos, start) + "<b>" +
this.name.slice(start, start + length) + "</b>";
pos = start + length;
@@ -111,7 +112,7 @@ class HTMLOperation {
this.name = opName;
}
if (this.description && descIdxs.length) {
if (this.description && descIdxs.length && descIdxs[0][0] >= 0) {
// Find HTML tag offsets
const re = /<[^>]+>/g;
let match;

View File

@@ -6,7 +6,7 @@
import HTMLOperation from "../HTMLOperation.mjs";
import Sortable from "sortablejs";
import {fuzzyMatch} from "../../core/lib/FuzzySearch.mjs";
import {fuzzyMatch, calcMatchRanges} from "../../core/lib/FuzzySearch.mjs";
/**
@@ -109,8 +109,6 @@ class OperationsWaiter {
const matchedOps = [];
const matchedDescs = [];
const searchStr = inStr.toLowerCase();
for (const opName in this.app.operations) {
const op = this.app.operations[opName];
@@ -118,12 +116,12 @@ class OperationsWaiter {
const [nameMatch, score, idxs] = fuzzyMatch(inStr, opName);
// Match description based on exact match
const descPos = op.description.toLowerCase().indexOf(searchStr);
const descPos = op.description.toLowerCase().indexOf(inStr.toLowerCase());
if (nameMatch || descPos >= 0) {
const operation = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager);
if (highlight) {
operation.highlightSearchStrings(idxs || [], [[descPos, searchStr.length]]);
operation.highlightSearchStrings(calcMatchRanges(idxs) || [], [[descPos, inStr.length]]);
}
if (nameMatch) {

View File

@@ -218,7 +218,7 @@ module.exports = {
.clearValue("#search")
.setValue("#search", "md5")
.useXpath()
.waitForElementVisible("//ul[@id='search-results']//u[text()='MD5']", 1000);
.waitForElementVisible("//ul[@id='search-results']//b[text()='MD5']", 1000);
},
after: browser => {

View File

@@ -14,10 +14,9 @@ const outputObject = JSON.stringify({
iat: 1
}, null, 4);
const invalidAlgorithm = "JsonWebTokenError: invalid algorithm";
const hsKey = "secret_cat";
const rsKey = `-----BEGIN RSA PRIVATE KEY-----
/* Retaining private key as a comment
const rsPriv = `-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw
33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW
+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQAB
@@ -32,11 +31,24 @@ fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/SySDOxQ4G/523
Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDabxrE9MNUZ2aP
FaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw==
-----END RSA PRIVATE KEY-----`;
const esKey = `-----BEGIN PRIVATE KEY-----
*/
const rsPub = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd
UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs
HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D
o2kQ+X5xK9cipRgEKwIDAQAB
-----END PUBLIC KEY-----`;
/* Retaining private key as a comment
const esPriv = `-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgevZzL1gdAFr88hb2
OF/2NxApJCzGCEDdfSp6VQO30hyhRANCAAQRWz+jn65BtOMvdyHKcvjBeBSDZH2r
1RTwjmYSi9R/zpBnuQ4EiMnCqfMPWiZqB4QdbAd0E7oH50VpuZ1P087G
-----END PRIVATE KEY-----`;
*/
const esPub = `-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEVs/o5+uQbTjL3chynL4wXgUg2R9
q9UU8I5mEovUf86QZ7kOBIjJwqnzD1omageEHWwHdBO6B+dFabmdT9POxg==
-----END PUBLIC KEY-----`;
TestRegister.addTests([
{
@@ -53,22 +65,22 @@ TestRegister.addTests([
{
name: "JWT Verify: RS",
input: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.MjEJhtZk2nXzigi24piMzANmrj3mILHJcDl0xOjl5a8EgdKVL1oaMEjTkMQp5RA8YrqeRBFaX-BGGCKOXn5zPY1DJwWsBUyN9C-wGR2Qye0eogH_3b4M9EW00TPCUPXm2rx8URFj7Wg9VlsmrGzLV2oKkPgkVxuFSxnpO3yjn1Y",
expectedOutput: invalidAlgorithm,
expectedOutput: outputObject,
recipeConfig: [
{
op: "JWT Verify",
args: [rsKey],
args: [rsPub],
}
],
},
{
name: "JWT Verify: ES",
input: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.WkECT51jSfpRkcpQ4x0h5Dwe7CFBI6u6Et2gWp91HC7mpN_qCFadRpsvJLtKubm6cJTLa68xtei0YrDD8fxIUA",
expectedOutput: invalidAlgorithm,
expectedOutput: outputObject,
recipeConfig: [
{
op: "JWT Verify",
args: [esKey],
args: [esPub],
}
],
}