Merge a65044004b27414506db0ec6067ed1355877fbd1 into 4290ea753912378913b1f3f54e0fc5720afeda5d
This commit is contained in:
commit
70415b81de
@ -64,6 +64,7 @@
|
||||
"Change IP format",
|
||||
"Encode text",
|
||||
"Decode text",
|
||||
"PowerShell -e Encode/Decode",
|
||||
"Text Encoding Brute Force",
|
||||
"Swap endianness",
|
||||
"To MessagePack",
|
||||
|
||||
67
src/core/operations/PowerShellEncodeDecode.mjs
Normal file
67
src/core/operations/PowerShellEncodeDecode.mjs
Normal file
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @author neoreo
|
||||
* @copyright Crown Copyright 2026
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import cptable from "codepage";
|
||||
import {toBase64, fromBase64} from "../lib/Base64.mjs";
|
||||
|
||||
// PowerShell -EncodedCommand uses UTF-16LE (code page 1200)
|
||||
const UTF_16LE = 1200;
|
||||
|
||||
/**
|
||||
* PowerShell -e Encode/Decode operation
|
||||
*/
|
||||
class PowerShellEncodeDecode extends Operation {
|
||||
|
||||
/**
|
||||
* PowerShellEncodeDecode constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "PowerShell -e Encode/Decode";
|
||||
this.module = "Encodings";
|
||||
this.description = [
|
||||
"Encodes or decodes a PowerShell <code>-EncodedCommand</code> (<code>-e</code>) payload in a single operation.",
|
||||
"<br><br>",
|
||||
"PowerShell's <code>-EncodedCommand</code> parameter expects the command encoded as UTF-16LE and then Base64'd. ",
|
||||
"This operation combines both steps so you don't have to chain 'Encode text' and 'To Base64' (or their decode equivalents) yourself.",
|
||||
"<br><br>",
|
||||
"<b>Encode:</b> <code>whoami</code> becomes <code>dwBoAG8AYQBtAGkA</code>, runnable as <code>powershell -e dwBoAG8AYQBtAGkA</code>.",
|
||||
"<br>",
|
||||
"<b>Decode:</b> <code>dwBoAG8AYQBtAGkA</code> becomes <code>whoami</code>."
|
||||
].join("\n");
|
||||
this.infoURL = "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe#-encodedcommand-base64encodedcommand";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Mode",
|
||||
type: "option",
|
||||
value: ["Encode", "Decode"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [mode] = args;
|
||||
|
||||
if (mode === "Encode") {
|
||||
const encoded = cptable.utils.encode(UTF_16LE, input);
|
||||
return toBase64(new Uint8Array(encoded).buffer);
|
||||
}
|
||||
const bytes = fromBase64(input, "A-Za-z0-9+/=", "byteArray");
|
||||
return cptable.utils.decode(UTF_16LE, new Uint8Array(bytes));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default PowerShellEncodeDecode;
|
||||
@ -168,7 +168,7 @@ TestRegister.addApiTests([
|
||||
|
||||
it("chef.help: returns multiple results", () => {
|
||||
const result = chef.help("base 64");
|
||||
assert.strictEqual(result.length, 14);
|
||||
assert.strictEqual(result.length, 15);
|
||||
}),
|
||||
|
||||
it("chef.help: looks in description for matches too", () => {
|
||||
|
||||
86
tests/operations/tests/PowerShellEncodeDecode.mjs
Normal file
86
tests/operations/tests/PowerShellEncodeDecode.mjs
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* PowerShell -e Encode/Decode tests.
|
||||
*
|
||||
* @author neoreo
|
||||
*
|
||||
* @copyright Crown Copyright 2026
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "PowerShell -e Encode/Decode: encode nothing",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PowerShell -e Encode/Decode",
|
||||
args: ["Encode"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "PowerShell -e Encode/Decode: encode whoami",
|
||||
input: "whoami",
|
||||
expectedOutput: "dwBoAG8AYQBtAGkA",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PowerShell -e Encode/Decode",
|
||||
args: ["Encode"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "PowerShell -e Encode/Decode: decode whoami",
|
||||
input: "dwBoAG8AYQBtAGkA",
|
||||
expectedOutput: "whoami",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PowerShell -e Encode/Decode",
|
||||
args: ["Decode"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "PowerShell -e Encode/Decode: round trip",
|
||||
input: "Get-Process | Where-Object {$_.CPU -gt 10}",
|
||||
expectedOutput: "Get-Process | Where-Object {$_.CPU -gt 10}",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PowerShell -e Encode/Decode",
|
||||
args: ["Encode"],
|
||||
},
|
||||
{
|
||||
op: "PowerShell -e Encode/Decode",
|
||||
args: ["Decode"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "PowerShell -e Encode/Decode: round trip with non-ASCII characters",
|
||||
input: "Write-Host \"café ☕\"",
|
||||
expectedOutput: "Write-Host \"café ☕\"",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PowerShell -e Encode/Decode",
|
||||
args: ["Encode"],
|
||||
},
|
||||
{
|
||||
op: "PowerShell -e Encode/Decode",
|
||||
args: ["Decode"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "PowerShell -e Encode/Decode: decode ignores characters outside the Base64 alphabet",
|
||||
input: "!!!@@@###",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PowerShell -e Encode/Decode",
|
||||
args: ["Decode"],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
Loading…
x
Reference in New Issue
Block a user