thefLink / Hunt-Sleeping-Beacons

Aims to identify sleeping beacons

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Hunt-Sleeping-Beacons

The idea of this project is to identify beacons which are unpacked at runtime or running in the context of an other process.

All metrics applied are based on the observation that beacons tend to wait between their callbacks and this project aims to identify abnormal behaviour which caused the delay.

DelayExecution

Most C2 agents tend to call Kernel32!Sleep which in turn calls Ntdll!NtDelayExecution to delay the execution of the beacon. This method sets the state of the thread to Wait:DelayExecution while it waits.

Beacons using this method can be identified by enumerating all threads in state Wait:DelayExecution which have an abnormal calltrace to Ntdll!NtDelayExecution:

  • Unknown/private committed memory in calltrace
  • Stomped Modules in calltrace

Sample non file backed beacon:

[!] Suspicious Process: PhantomDllHollower.exe

        [*] Thread (9192) has State: DelayExecution and abnormal calltrace:

                NtDelayExecution -> C:\WINDOWS\SYSTEM32\ntdll.dll
                SleepEx -> C:\WINDOWS\System32\KERNELBASE.dll
                0x00007FF8C13A103F -> Unknown or modified module
                0x000001E3C3F48FD0 -> Unknown or modified module
                0x00007FF700000000 -> Unknown or modified module
                0x00007FF7C00000BB -> Unknown or modified module

        [*] Suspicious Sleep() found
        [*] Sleep Time: 600s

Sample Beacon using module stomping:

[!] Suspicious Process: beacon.exe (5296)

       [*] Thread (2968) has State: DelayExecution and uses potentially stomped module
       [*] Potentially stomped module: C:\Windows\SYSTEM32\xpsservices.dll

               NtDelayExecution -> C:\Windows\SYSTEM32\ntdll.dll
               SleepEx -> C:\Windows\System32\KERNELBASE.dll
               DllGetClassObject -> C:\Windows\SYSTEM32\xpsservices.dll

       [*] Suspicious Sleep() found
       [*] Sleep Time: 5s

Foliage

Foliage and it's implementations, such as AceLdr, avoid the state Wait:DelayExecution and additionally encrypt themselves while waiting by queueing a series of APCs to Ntdll!NtContinue one of which triggers the execution of Ntdll!WaitForSingleObject to delay the execution.

This effectively sets the state of the thread to Wait:UserRequest. Simply walking the callstack for unknown/tampered memory regions produces to many false positives in this case.

The observation here is that a call to Ntdll!WaitForSingleObject initiated by an APC is abnormal and sufficient to build a detection upon.

AceLdr, can thus be identified by enumerating all threads in state Wait:UserRequest which have a return address to Ntdll!KiUserApcDispatcher somewhere on the stack.

AceLdr:

* Now enumerating all thread in state wait:UserRequest
* Found 783 threads, now checking for delays caused by APC
! Possible Foliage identified in process: 16436
        * Thread 15768 state Wait:UserRequest seems to be triggered by KiUserApcDispatcher
* End

Waitable Timers Callbacks

The detection of sleep encryption methods using waitable timers like Ekko is almost the same. MSDN explicitly states that timer callbacks should not be blocking, however the sleep encryption does exactly that.

In this project, I first locate the dispatcher of callbacks in ntdll.dll by queueing my own timer callback and then use RtlCaptureContext to be able to walk my own stack. Then, threads in state wait:userRequest are enumerated and checked for a return address to the dispatcher.

Ekko:

! Possible Ekko/Nighthawk identified in process: 3996
        * Thread 14756 state Wait:UserRequest seems to be triggered by Callback of waitable Timer

Usage

Requirements:

  • mingw-w64
make

Executable does not take any parameters

Credits

About

Aims to identify sleeping beacons


Languages

Language:C 99.1%Language:Makefile 0.9%