mirror of
https://github.com/gchq/CyberChef.git
synced 2024-11-02 06:01:02 +01:00
Merge branch 'master' of https://github.com/jarmovanlenthe/CyberChef into jarmovanlenthe-master
This commit is contained in:
commit
cfb6dd9471
@ -66,6 +66,7 @@ const Categories = [
|
||||
"Encode text",
|
||||
"Decode text",
|
||||
"Swap endianness",
|
||||
"PHP Deserialize",
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -35,6 +35,7 @@ import StrUtils from "../operations/StrUtils.js";
|
||||
import Tidy from "../operations/Tidy.js";
|
||||
import Unicode from "../operations/Unicode.js";
|
||||
import URL_ from "../operations/URL.js";
|
||||
import PhpSerialization from "../operations/PhpSerialization.js";
|
||||
|
||||
|
||||
/**
|
||||
@ -3845,6 +3846,19 @@ const OperationConfig = {
|
||||
}
|
||||
]
|
||||
},
|
||||
"PHP Deserialize": {
|
||||
module: "Default",
|
||||
description: "PHP Deserialize a given input.<br><br>This function does not support <code>object</code> tags.<br><br><u>Output valid JSON:</u> JSON doesn't support integers as keys, where as PHP serialization does. Enabling this will cast these integers to strings. This will also escape backslashes.",
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
args: [
|
||||
{
|
||||
name: "Output valid JSON",
|
||||
type: "boolean",
|
||||
value: PhpSerialization.OUTPUT_VALID_JSON
|
||||
}
|
||||
]
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ import StrUtils from "../../operations/StrUtils.js";
|
||||
import Tidy from "../../operations/Tidy.js";
|
||||
import Unicode from "../../operations/Unicode.js";
|
||||
import UUID from "../../operations/UUID.js";
|
||||
|
||||
import PhpSerialization from "../../operations/PhpSerialization";
|
||||
|
||||
/**
|
||||
* Default module.
|
||||
@ -155,6 +155,7 @@ OpModules.Default = {
|
||||
"Conditional Jump": FlowControl.runCondJump,
|
||||
"Return": FlowControl.runReturn,
|
||||
"Comment": FlowControl.runComment,
|
||||
"PHP Deserialize": PhpSerialization.PhpDeserialize,
|
||||
|
||||
|
||||
/*
|
||||
|
158
src/core/operations/PhpSerialization.js
Normal file
158
src/core/operations/PhpSerialization.js
Normal file
@ -0,0 +1,158 @@
|
||||
/**
|
||||
* Php Serialization operations.
|
||||
* This Javascript implementation is based on the Python implementation by
|
||||
* Armin Ronacher (2016), who released it under the 3-Clause BSD license.
|
||||
* See: https://github.com/mitsuhiko/phpserialize/
|
||||
*
|
||||
* @author Jarmo van Lenthe [github.com/jarmovanlenthe]
|
||||
* @copyright Jarmo van Lenthe
|
||||
* @license Apache-2.0
|
||||
*
|
||||
* @namespace
|
||||
*/
|
||||
|
||||
const PhpSerialization = {
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
OUTPUT_VALID_JSON: true,
|
||||
|
||||
/**
|
||||
* Deserializes a PHP serialized input
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
PhpDeserialize: function (input, args) {
|
||||
/**
|
||||
* Recursive method for deserializing.
|
||||
* @returns {*}
|
||||
*/
|
||||
function handleInput() {
|
||||
/**
|
||||
* Read `length` characters from the input, shifting them out the input.
|
||||
* @param length
|
||||
* @returns {string}
|
||||
*/
|
||||
function read(length) {
|
||||
let result = "";
|
||||
for (let idx = 0; idx < length; idx++) {
|
||||
let char = inputPart.shift();
|
||||
if (char === undefined) {
|
||||
throw "End of input reached before end of script";
|
||||
}
|
||||
result += char;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read characters from the input until `until` is found.
|
||||
* @param until
|
||||
* @returns {string}
|
||||
*/
|
||||
function readUntil(until) {
|
||||
let result = "";
|
||||
for (;;) {
|
||||
let char = read(1);
|
||||
if (char === until) {
|
||||
break;
|
||||
} else {
|
||||
result += char;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Read characters from the input that must be equal to `expect`
|
||||
* @param expect
|
||||
* @returns {string}
|
||||
*/
|
||||
function expect(expect) {
|
||||
let result = read(expect.length);
|
||||
if (result !== expect) {
|
||||
throw "Unexpected input found";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to handle deserialized arrays.
|
||||
* @returns {Array}
|
||||
*/
|
||||
function handleArray() {
|
||||
let items = parseInt(readUntil(":"), 10) * 2;
|
||||
expect("{");
|
||||
let result = [];
|
||||
let isKey = true;
|
||||
let lastItem = null;
|
||||
for (let idx = 0; idx < items; idx++) {
|
||||
let item = handleInput();
|
||||
if (isKey) {
|
||||
lastItem = item;
|
||||
isKey = false;
|
||||
} else {
|
||||
let numberCheck = lastItem.match(/[0-9]+/);
|
||||
if (args[0] && numberCheck && numberCheck[0].length === lastItem.length) {
|
||||
result.push("\"" + lastItem + "\": " + item);
|
||||
} else {
|
||||
result.push(lastItem + ": " + item);
|
||||
}
|
||||
isKey = true;
|
||||
}
|
||||
}
|
||||
expect("}");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
let kind = read(1).toLowerCase();
|
||||
|
||||
switch (kind) {
|
||||
case "n":
|
||||
expect(";");
|
||||
return "";
|
||||
|
||||
case "i":
|
||||
case "d":
|
||||
case "b": {
|
||||
expect(":");
|
||||
let data = readUntil(";");
|
||||
if (kind === "b") {
|
||||
return (parseInt(data, 10) !== 0);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
case "a":
|
||||
expect(":");
|
||||
return "{" + handleArray() + "}";
|
||||
|
||||
case "s": {
|
||||
expect(":");
|
||||
let length = readUntil(":");
|
||||
expect("\"");
|
||||
let value = read(length);
|
||||
expect("\";");
|
||||
if (args[0]) {
|
||||
return "\"" + value.replace(/"/g, "\\\"") + "\"";
|
||||
} else {
|
||||
return "\"" + value + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
throw "Unknown type: " + kind;
|
||||
}
|
||||
}
|
||||
|
||||
let inputPart = input.split("");
|
||||
return handleInput();
|
||||
}
|
||||
};
|
||||
|
||||
export default PhpSerialization;
|
@ -27,6 +27,7 @@ import "./tests/operations/MorseCode.js";
|
||||
import "./tests/operations/MS.js";
|
||||
import "./tests/operations/StrUtils.js";
|
||||
import "./tests/operations/SeqUtils.js";
|
||||
import "./tests/operations/PhpSerialization.js";
|
||||
|
||||
|
||||
let allTestsPassing = true;
|
||||
|
68
test/tests/operations/PhpSerialization.js
Normal file
68
test/tests/operations/PhpSerialization.js
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* PHP Serialization tests.
|
||||
*
|
||||
* @author Jarmo van Lenthe
|
||||
*
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import TestRegister from "../../TestRegister.js";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "PHP Deserialize empty array",
|
||||
input: "a:0:{}",
|
||||
expectedOutput: "{}",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Deserialize",
|
||||
args: [true],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "PHP Deserialize integer",
|
||||
input: "i:10;",
|
||||
expectedOutput: "10",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Deserialize",
|
||||
args: [true],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "PHP Deserialize string",
|
||||
input: "s:17:\"PHP Serialization\";",
|
||||
expectedOutput: "\"PHP Serialization\"",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Deserialize",
|
||||
args: [true],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "PHP Deserialize array (JSON)",
|
||||
input: "a:2:{s:1:\"a\";i:10;i:0;a:1:{s:2:\"ab\";b:1;}}",
|
||||
expectedOutput: "{\"a\": 10,\"0\": {\"ab\": true}}",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Deserialize",
|
||||
args: [true],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "PHP Deserialize array (non-JSON)",
|
||||
input: "a:2:{s:1:\"a\";i:10;i:0;a:1:{s:2:\"ab\";b:1;}}",
|
||||
expectedOutput: "{\"a\": 10,0: {\"ab\": true}}",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Deserialize",
|
||||
args: [false],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
Loading…
Reference in New Issue
Block a user