mirror of
https://github.com/gchq/CyberChef.git
synced 2026-03-19 05:12:42 -07:00
Merge branch 'master' into feat/newline-operation
This commit is contained in:
commit
a226be457c
13 changed files with 233 additions and 92 deletions
|
|
@ -91,9 +91,7 @@ export function toJA4(bytes) {
|
|||
let alpn = "00";
|
||||
for (const ext of tlsr.handshake.value.extensions.value) {
|
||||
if (ext.type.value === "application_layer_protocol_negotiation") {
|
||||
alpn = parseFirstALPNValue(ext.value.data);
|
||||
alpn = alpn.charAt(0) + alpn.charAt(alpn.length - 1);
|
||||
if (alpn.charCodeAt(0) > 127) alpn = "99";
|
||||
alpn = alpnFingerprint(parseFirstALPNValue(ext.value.data));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -212,9 +210,7 @@ export function toJA4S(bytes) {
|
|||
let alpn = "00";
|
||||
for (const ext of tlsr.handshake.value.extensions.value) {
|
||||
if (ext.type.value === "application_layer_protocol_negotiation") {
|
||||
alpn = parseFirstALPNValue(ext.value.data);
|
||||
alpn = alpn.charAt(0) + alpn.charAt(alpn.length - 1);
|
||||
if (alpn.charCodeAt(0) > 127) alpn = "99";
|
||||
alpn = alpnFingerprint(parseFirstALPNValue(ext.value.data));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -262,3 +258,33 @@ function tlsVersionMapper(version) {
|
|||
default: return "00"; // Unknown
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a byte is ASCII alphanumeric (0-9, A-Z, a-z).
|
||||
* @param {number} byte
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isAlphanumeric(byte) {
|
||||
return (byte >= 0x30 && byte <= 0x39) ||
|
||||
(byte >= 0x41 && byte <= 0x5A) ||
|
||||
(byte >= 0x61 && byte <= 0x7A);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the 2-character ALPN fingerprint from raw ALPN bytes.
|
||||
* If both first and last bytes are ASCII alphanumeric, returns their characters.
|
||||
* Otherwise, returns first hex digit of first byte + last hex digit of last byte.
|
||||
* @param {Uint8Array|null} rawBytes
|
||||
* @returns {string}
|
||||
*/
|
||||
function alpnFingerprint(rawBytes) {
|
||||
if (!rawBytes || rawBytes.length === 0) return "00";
|
||||
const firstByte = rawBytes[0];
|
||||
const lastByte = rawBytes[rawBytes.length - 1];
|
||||
if (isAlphanumeric(firstByte) && isAlphanumeric(lastByte)) {
|
||||
return String.fromCharCode(firstByte) + String.fromCharCode(lastByte);
|
||||
}
|
||||
const firstHex = firstByte.toString(16).padStart(2, "0");
|
||||
const lastHex = lastByte.toString(16).padStart(2, "0");
|
||||
return firstHex[0] + lastHex[1];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -863,15 +863,15 @@ export function parseHighestSupportedVersion(bytes) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Parses the application_layer_protocol_negotiation extension and returns the first value.
|
||||
* Parses the application_layer_protocol_negotiation extension and returns the first value as raw bytes.
|
||||
* @param {Uint8Array} bytes
|
||||
* @returns {number}
|
||||
* @returns {Uint8Array|null}
|
||||
*/
|
||||
export function parseFirstALPNValue(bytes) {
|
||||
const s = new Stream(bytes);
|
||||
const alpnExtLen = s.readInt(2);
|
||||
if (alpnExtLen < 3) return "00";
|
||||
if (alpnExtLen < 2) return null;
|
||||
const strLen = s.readInt(1);
|
||||
if (strLen < 2) return "00";
|
||||
return s.readString(strLen);
|
||||
if (strLen < 1) return null;
|
||||
return s.getBytes(strLen);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class FromHexdump extends Operation {
|
|||
*/
|
||||
run(input, args) {
|
||||
const output = [],
|
||||
regex = /^\s*(?:[\dA-F]{4,16}h?:?)?[ \t]+((?:[\dA-F]{2} ){1,8}(?:[ \t]|[\dA-F]{2}-)(?:[\dA-F]{2} ){1,8}|(?:[\dA-F]{4} )*[\dA-F]{4}|(?:[\dA-F]{2} )*[\dA-F]{2})/igm;
|
||||
regex = /^\s*(?:[\dA-F]{4,16}h?:?)?[ \t]+((?:[\dA-F]{2} ){1,8}(?:[ \t]|[\dA-F]{2}-)(?:[\dA-F]{2} ){1,8}|(?:[\dA-F]{4} )+(?:[\dA-F]{2})?|(?:[\dA-F]{2} )*[\dA-F]{2})/igm;
|
||||
let block, line;
|
||||
|
||||
while ((block = regex.exec(input))) {
|
||||
|
|
|
|||
|
|
@ -650,7 +650,7 @@ class App {
|
|||
|
||||
// const compareURL = `https://github.com/gchq/CyberChef/compare/v${prev.join(".")}...v${PKG_VERSION}`;
|
||||
|
||||
let compileInfo = `<a href='https://github.com/gchq/CyberChef/blob/master/CHANGELOG.md'>Last build: ${timeSinceCompile.substr(0, 1).toUpperCase() + timeSinceCompile.substr(1)} ago</a>`;
|
||||
let compileInfo = `<a href='https://github.com/gchq/CyberChef/blob/master/CHANGELOG.md'>Last build: ${timeSinceCompile.substring(0, 1).toUpperCase() + timeSinceCompile.substring(1)} ago</a>`;
|
||||
|
||||
if (window.compileMessage !== "") {
|
||||
compileInfo += " - " + window.compileMessage;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import sm from "sitemap";
|
||||
import OperationConfig from "../../core/config/OperationConfig.json" assert {type: "json"};
|
||||
|
||||
import OperationConfig from "../../core/config/OperationConfig.json" assert { type: "json" };
|
||||
|
||||
/**
|
||||
* Generates an XML sitemap for all CyberChef operations and a number of recipes.
|
||||
|
|
@ -10,25 +9,25 @@ import OperationConfig from "../../core/config/OperationConfig.json" assert {typ
|
|||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
const smStream = new sm.SitemapStream({
|
||||
hostname: "https://gchq.github.io/CyberChef",
|
||||
});
|
||||
const baseUrl = "https://gchq.github.io/CyberChef/";
|
||||
|
||||
const smStream = new sm.SitemapStream({});
|
||||
|
||||
smStream.write({
|
||||
url: "/",
|
||||
url: baseUrl,
|
||||
changefreq: "weekly",
|
||||
priority: 1.0
|
||||
priority: 1.0,
|
||||
});
|
||||
|
||||
for (const op in OperationConfig) {
|
||||
smStream.write({
|
||||
url: `/?op=${encodeURIComponent(op)}`,
|
||||
url: `${baseUrl}?op=${encodeURIComponent(op)}`,
|
||||
changeFreq: "yearly",
|
||||
priority: 0.5
|
||||
priority: 0.5,
|
||||
});
|
||||
}
|
||||
smStream.end();
|
||||
|
||||
sm.streamToPromise(smStream).then(
|
||||
buffer => console.log(buffer.toString()) // eslint-disable-line no-console
|
||||
(buffer) => console.log(buffer.toString()), // eslint-disable-line no-console
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue