Add PowerShell Encode/Decode operation
This commit is contained in:
parent
c56dd23358
commit
b590aa6e69
@ -64,6 +64,7 @@
|
|||||||
"Change IP format",
|
"Change IP format",
|
||||||
"Encode text",
|
"Encode text",
|
||||||
"Decode text",
|
"Decode text",
|
||||||
|
"PowerShell -e Encode/Decode",
|
||||||
"Text Encoding Brute Force",
|
"Text Encoding Brute Force",
|
||||||
"Swap endianness",
|
"Swap endianness",
|
||||||
"To MessagePack",
|
"To MessagePack",
|
||||||
|
|||||||
71
src/core/operations/PowerShellEncodeDecode.mjs
Normal file
71
src/core/operations/PowerShellEncodeDecode.mjs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* @author neoreo
|
||||||
|
* @copyright Crown Copyright 2026
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
|
import cptable from "codepage";
|
||||||
|
import {toBase64, fromBase64} from "../lib/Base64.mjs";
|
||||||
|
|
||||||
|
// PowerShell -EncodedCommand uses UTF-16LE (code page 1200)
|
||||||
|
const UTF16LE = 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(UTF16LE, input);
|
||||||
|
return toBase64(new Uint8Array(encoded).buffer);
|
||||||
|
} else if (mode === "Decode") {
|
||||||
|
const bytes = fromBase64(input, "A-Za-z0-9+/=", "byteArray");
|
||||||
|
return cptable.utils.decode(UTF16LE, new Uint8Array(bytes));
|
||||||
|
} else {
|
||||||
|
throw new OperationError("Invalid mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PowerShellEncodeDecode;
|
||||||
60
tests/operations/tests/PowerShellEncodeDecode.mjs
Normal file
60
tests/operations/tests/PowerShellEncodeDecode.mjs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* 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"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
Loading…
x
Reference in New Issue
Block a user