mirror of
https://github.com/gchq/CyberChef
synced 2025-12-05 23:53:27 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dcc28438ff | ||
|
|
df7c1721f5 | ||
|
|
403296cc59 | ||
|
|
addb2b4448 | ||
|
|
8556bdcdeb | ||
|
|
8fc5f59647 | ||
|
|
f7729c0fd2 | ||
|
|
e2376c7c71 | ||
|
|
2cefd3b941 | ||
|
|
68ab2da866 | ||
|
|
72f7f0b70c | ||
|
|
411bba53a8 | ||
|
|
e2af3c78e7 |
2532
package-lock.json
generated
2532
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
32
package.json
32
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "7.10.1",
|
||||
"version": "7.11.1",
|
||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
@@ -30,7 +30,7 @@
|
||||
"main": "build/node/CyberChef.js",
|
||||
"bugs": "https://github.com/gchq/CyberChef/issues",
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-loader": "^7.1.4",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
@@ -50,33 +50,33 @@
|
||||
"grunt-execute": "^0.2.2",
|
||||
"grunt-jsdoc": "^2.2.1",
|
||||
"grunt-webpack": "^3.1.1",
|
||||
"html-webpack-plugin": "^3.1.0",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"imports-loader": "^0.8.0",
|
||||
"ink-docstrap": "^1.3.2",
|
||||
"jsdoc-babel": "^0.4.0",
|
||||
"less": "^3.0.1",
|
||||
"less": "^3.0.2",
|
||||
"less-loader": "^4.1.0",
|
||||
"postcss-css-variables": "^0.8.1",
|
||||
"postcss-import": "^11.1.0",
|
||||
"postcss-loader": "^2.1.3",
|
||||
"postcss-loader": "^2.1.4",
|
||||
"sitemap": "^1.13.0",
|
||||
"style-loader": "^0.20.3",
|
||||
"style-loader": "^0.21.0",
|
||||
"url-loader": "^1.0.1",
|
||||
"val-loader": "^1.1.0",
|
||||
"web-resource-inliner": "^4.2.1",
|
||||
"webpack": "^4.3.0",
|
||||
"webpack-dev-server": "^3.1.1",
|
||||
"webpack-node-externals": "^1.6.0",
|
||||
"webpack": "^4.6.0",
|
||||
"webpack-dev-server": "^3.1.3",
|
||||
"webpack-node-externals": "^1.7.2",
|
||||
"worker-loader": "^1.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"bignumber.js": "^6.0.0",
|
||||
"bignumber.js": "^7.0.1",
|
||||
"bootstrap": "^3.3.7",
|
||||
"bootstrap-colorpicker": "^2.5.2",
|
||||
"bootstrap-switch": "^3.3.4",
|
||||
"bson": "^2.0.4",
|
||||
"bson": "^2.0.6",
|
||||
"crypto-api": "^0.8.0",
|
||||
"crypto-js": "^3.1.9-1",
|
||||
"ctph.js": "0.0.5",
|
||||
@@ -94,14 +94,14 @@
|
||||
"jsbn": "^1.1.0",
|
||||
"jsesc": "^2.5.1",
|
||||
"jsonpath": "^1.0.0",
|
||||
"jsrsasign": "8.0.7",
|
||||
"lodash": "^4.17.5",
|
||||
"jsrsasign": "8.0.12",
|
||||
"lodash": "^4.17.10",
|
||||
"loglevel": "^1.6.1",
|
||||
"kbpgp": "^2.0.77",
|
||||
"loglevel-message-prefix": "^3.0.0",
|
||||
"moment": "^2.21.0",
|
||||
"moment-timezone": "^0.5.14",
|
||||
"node-forge": "^0.7.4",
|
||||
"moment": "^2.22.1",
|
||||
"moment-timezone": "^0.5.16",
|
||||
"node-forge": "^0.7.5",
|
||||
"node-md6": "^0.1.0",
|
||||
"nwmatcher": "^1.4.4",
|
||||
"otp": "^0.1.3",
|
||||
|
||||
@@ -718,10 +718,10 @@ const Utils = {
|
||||
* Utils.fromHex("0a:14:1e", "Colon");
|
||||
*/
|
||||
fromHex: function(data, delim, byteLen) {
|
||||
delim = delim || (data.indexOf(" ") >= 0 ? "Space" : "None");
|
||||
delim = delim || "Auto";
|
||||
byteLen = byteLen || 2;
|
||||
if (delim !== "None") {
|
||||
const delimRegex = Utils.regexRep[delim];
|
||||
const delimRegex = delim === "Auto" ? /[^a-f\d]/gi : Utils.regexRep[delim];
|
||||
data = data.replace(delimRegex, "");
|
||||
}
|
||||
|
||||
@@ -737,37 +737,43 @@ const Utils = {
|
||||
* Parses CSV data and returns it as a two dimensional array or strings.
|
||||
*
|
||||
* @param {string} data
|
||||
* @param {string[]} [cellDelims=[","]]
|
||||
* @param {string[]} [lineDelims=["\n", "\r"]]
|
||||
* @returns {string[][]}
|
||||
*
|
||||
* @example
|
||||
* // returns [["head1", "head2"], ["data1", "data2"]]
|
||||
* Utils.parseCSV("head1,head2\ndata1,data2");
|
||||
*/
|
||||
parseCSV: function(data) {
|
||||
|
||||
parseCSV: function(data, cellDelims=[","], lineDelims=["\n", "\r"]) {
|
||||
let b,
|
||||
ignoreNext = false,
|
||||
next,
|
||||
renderNext = false,
|
||||
inString = false,
|
||||
cell = "",
|
||||
line = [],
|
||||
lines = [];
|
||||
|
||||
// Remove BOM, often present in Excel CSV files
|
||||
if (data.length && data[0] === "\uFEFF") data = data.substr(1);
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
b = data[i];
|
||||
if (ignoreNext) {
|
||||
next = data[i+1] || "";
|
||||
if (renderNext) {
|
||||
cell += b;
|
||||
ignoreNext = false;
|
||||
renderNext = false;
|
||||
} else if (b === "\\") {
|
||||
cell += b;
|
||||
ignoreNext = true;
|
||||
renderNext = true;
|
||||
} else if (b === "\"" && !inString) {
|
||||
inString = true;
|
||||
} else if (b === "\"" && inString) {
|
||||
inString = false;
|
||||
} else if (b === "," && !inString) {
|
||||
if (next === "\"") renderNext = true;
|
||||
else inString = false;
|
||||
} else if (!inString && cellDelims.indexOf(b) >= 0) {
|
||||
line.push(cell);
|
||||
cell = "";
|
||||
} else if ((b === "\n" || b === "\r") && !inString) {
|
||||
} else if (!inString && lineDelims.indexOf(b) >= 0) {
|
||||
line.push(cell);
|
||||
cell = "";
|
||||
lines.push(line);
|
||||
|
||||
@@ -182,6 +182,7 @@ const Categories = [
|
||||
"To Lower case",
|
||||
"Add line numbers",
|
||||
"Remove line numbers",
|
||||
"To Table",
|
||||
"Reverse",
|
||||
"Sort",
|
||||
"Unique",
|
||||
|
||||
@@ -37,6 +37,7 @@ import SeqUtils from "../operations/SeqUtils.js";
|
||||
import Shellcode from "../operations/Shellcode.js";
|
||||
import StrUtils from "../operations/StrUtils.js";
|
||||
import Tidy from "../operations/Tidy.js";
|
||||
import ToTable from "../operations/ToTable.js";
|
||||
import Unicode from "../operations/Unicode.js";
|
||||
import URL_ from "../operations/URL.js";
|
||||
|
||||
@@ -613,6 +614,34 @@ const OperationConfig = {
|
||||
}
|
||||
]
|
||||
},
|
||||
"To Table": {
|
||||
module: "Default",
|
||||
description: "Data can be split on different characters and rendered as an HTML or ASCII table with an optional header row.<br><br>Supports the CSV (Comma Separated Values) file format by default. Change the cell delimiter argument to <code>\\t</code> to support TSV (Tab Separated Values) or <code>|</code> for PSV (Pipe Separated Values).<br><br>You can enter as many delimiters as you like. Each character will be treat as a separate possible delimiter.",
|
||||
inputType: "string",
|
||||
outputType: "html",
|
||||
args: [
|
||||
{
|
||||
name: "Cell delimiters",
|
||||
type: "binaryShortString",
|
||||
value: ","
|
||||
},
|
||||
{
|
||||
name: "Row delimiters",
|
||||
type: "binaryShortString",
|
||||
value: "\\n\\r"
|
||||
},
|
||||
{
|
||||
name: "Make first row header",
|
||||
type: "boolean",
|
||||
value: false
|
||||
},
|
||||
{
|
||||
name: "Format",
|
||||
type: "option",
|
||||
value: ToTable.FORMATS
|
||||
}
|
||||
]
|
||||
},
|
||||
"From Hex": {
|
||||
module: "Default",
|
||||
description: "Converts a hexadecimal byte string back into its raw value.<br><br>e.g. <code>ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a</code> becomes the UTF-8 encoded string <code>Γειά σου</code>",
|
||||
@@ -624,7 +653,7 @@ const OperationConfig = {
|
||||
{
|
||||
name: "Delimiter",
|
||||
type: "option",
|
||||
value: ByteRepr.HEX_DELIM_OPTIONS
|
||||
value: ByteRepr.FROM_HEX_DELIM_OPTIONS
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -639,7 +668,7 @@ const OperationConfig = {
|
||||
{
|
||||
name: "Delimiter",
|
||||
type: "option",
|
||||
value: ByteRepr.HEX_DELIM_OPTIONS
|
||||
value: ByteRepr.TO_HEX_DELIM_OPTIONS
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -27,6 +27,7 @@ import Rotate from "../../operations/Rotate.js";
|
||||
import SeqUtils from "../../operations/SeqUtils.js";
|
||||
import StrUtils from "../../operations/StrUtils.js";
|
||||
import Tidy from "../../operations/Tidy.js";
|
||||
import ToTable from "../../operations/ToTable.js";
|
||||
import Unicode from "../../operations/Unicode.js";
|
||||
import UUID from "../../operations/UUID.js";
|
||||
import XKCD from "../../operations/XKCD.js";
|
||||
@@ -163,6 +164,7 @@ OpModules.Default = {
|
||||
"Mean": Arithmetic.runMean,
|
||||
"Median": Arithmetic.runMedian,
|
||||
"Standard Deviation": Arithmetic.runStdDev,
|
||||
"To Table": ToTable.runToTable,
|
||||
"Windows Filetime to UNIX Timestamp": Filetime.runFromFiletimeToUnix,
|
||||
"UNIX Timestamp to Windows Filetime": Filetime.runToFiletimeFromUnix,
|
||||
"XKCD Random Number": XKCD.runRandomNumber,
|
||||
|
||||
@@ -29,7 +29,7 @@ const BSON = {
|
||||
const data = JSON.parse(input);
|
||||
return bson.serialize(data).buffer;
|
||||
} catch (err) {
|
||||
return err.toString();
|
||||
throw err.toString();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -21,7 +21,12 @@ const ByteRepr = {
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
HEX_DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"],
|
||||
TO_HEX_DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"],
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
FROM_HEX_DELIM_OPTIONS: ["Auto", "Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"],
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
|
||||
@@ -90,13 +90,16 @@ const PGP = {
|
||||
try {
|
||||
const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
||||
armored: privateKey,
|
||||
opts: {
|
||||
"no_check_keys": true
|
||||
}
|
||||
});
|
||||
if (key.is_pgp_locked() && passphrase) {
|
||||
if (key.is_pgp_locked()) {
|
||||
if (passphrase) {
|
||||
await promisify(key.unlock_pgp.bind(key))({
|
||||
passphrase
|
||||
});
|
||||
} else if (!passphrase) {
|
||||
} else {
|
||||
throw "Did not provide passphrase with locked private key.";
|
||||
}
|
||||
}
|
||||
@@ -118,6 +121,9 @@ const PGP = {
|
||||
try {
|
||||
const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
||||
armored: publicKey,
|
||||
opts: {
|
||||
"no_check_keys": true
|
||||
}
|
||||
});
|
||||
return key;
|
||||
} catch (err) {
|
||||
|
||||
164
src/core/operations/ToTable.js
Executable file
164
src/core/operations/ToTable.js
Executable file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* ToTable operations.
|
||||
*
|
||||
* @author Mark Jones [github.com/justanothermark]
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*
|
||||
* @namespace
|
||||
*/
|
||||
import Utils from "../Utils.js";
|
||||
|
||||
const ToTable = {
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
FORMATS: [
|
||||
"ASCII",
|
||||
"HTML"
|
||||
],
|
||||
|
||||
|
||||
/**
|
||||
* To Table operation.
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {html}
|
||||
*/
|
||||
runToTable: function (input, args) {
|
||||
const [cellDelims, rowDelims, firstRowHeader, format] = args;
|
||||
|
||||
// Process the input into a nested array of elements.
|
||||
const tableData = Utils.parseCSV(input, cellDelims.split(""), rowDelims.split(""));
|
||||
|
||||
if (!tableData.length) return "";
|
||||
|
||||
// Render the data in the requested format.
|
||||
switch (format) {
|
||||
case "ASCII":
|
||||
return asciiOutput(tableData);
|
||||
case "HTML":
|
||||
default:
|
||||
return htmlOutput(tableData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs an array of data as an ASCII table.
|
||||
*
|
||||
* @param {string[][]} tableData
|
||||
* @returns {string}
|
||||
*/
|
||||
function asciiOutput(tableData) {
|
||||
const horizontalBorder = "-";
|
||||
const verticalBorder = "|";
|
||||
const crossBorder = "+";
|
||||
|
||||
let output = "";
|
||||
let longestCells = [];
|
||||
|
||||
// Find longestCells value per column to pad cells equally.
|
||||
tableData.forEach(function(row, index) {
|
||||
row.forEach(function(cell, cellIndex) {
|
||||
if (longestCells[cellIndex] === undefined || cell.length > longestCells[cellIndex]) {
|
||||
longestCells[cellIndex] = cell.length;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Add the top border of the table to the output.
|
||||
output += outputHorizontalBorder(longestCells);
|
||||
|
||||
// If the first row is a header, remove the row from the data and
|
||||
// add it to the output with another horizontal border.
|
||||
if (firstRowHeader) {
|
||||
let row = tableData.shift();
|
||||
output += outputRow(row, longestCells);
|
||||
output += outputHorizontalBorder(longestCells);
|
||||
}
|
||||
|
||||
// Add the rest of the table rows.
|
||||
tableData.forEach(function(row, index) {
|
||||
output += outputRow(row, longestCells);
|
||||
});
|
||||
|
||||
// Close the table with a final horizontal border.
|
||||
output += outputHorizontalBorder(longestCells);
|
||||
|
||||
return output;
|
||||
|
||||
/**
|
||||
* Outputs a row of correctly padded cells.
|
||||
*/
|
||||
function outputRow(row, longestCells) {
|
||||
let rowOutput = verticalBorder;
|
||||
row.forEach(function(cell, index) {
|
||||
rowOutput += " " + cell + " ".repeat(longestCells[index] - cell.length) + " " + verticalBorder;
|
||||
});
|
||||
rowOutput += "\n";
|
||||
return rowOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a horizontal border with a different character where
|
||||
* the horizontal border meets a vertical border.
|
||||
*/
|
||||
function outputHorizontalBorder(longestCells) {
|
||||
let rowOutput = crossBorder;
|
||||
longestCells.forEach(function(cellLength) {
|
||||
rowOutput += horizontalBorder.repeat(cellLength + 2) + crossBorder;
|
||||
});
|
||||
rowOutput += "\n";
|
||||
return rowOutput;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a table of data as a HTML table.
|
||||
*
|
||||
* @param {string[][]} tableData
|
||||
* @returns {string}
|
||||
*/
|
||||
function htmlOutput(tableData) {
|
||||
// Start the HTML output with suitable classes for styling.
|
||||
let output = "<table class='table table-hover table-condensed table-bordered table-nonfluid'>";
|
||||
|
||||
// If the first row is a header then put it in <thead> with <th> cells.
|
||||
if (firstRowHeader) {
|
||||
let row = tableData.shift();
|
||||
output += "<thead>";
|
||||
output += outputRow(row, "th");
|
||||
output += "</thead>";
|
||||
}
|
||||
|
||||
// Output the rest of the rows in the <tbody>.
|
||||
output += "<tbody>";
|
||||
tableData.forEach(function(row, index) {
|
||||
output += outputRow(row, "td");
|
||||
});
|
||||
|
||||
// Close the body and table elements.
|
||||
output += "</tbody></table>";
|
||||
return output;
|
||||
|
||||
/**
|
||||
* Outputs a table row.
|
||||
*
|
||||
* @param {string[]} row
|
||||
* @param {string} cellType
|
||||
*/
|
||||
function outputRow(row, cellType) {
|
||||
let output = "<tr>";
|
||||
row.forEach(function(cell) {
|
||||
output += "<" + cellType + ">" + cell + "</" + cellType + ">";
|
||||
});
|
||||
output += "</tr>";
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default ToTable;
|
||||
Reference in New Issue
Block a user