Payload Execution Control
The more actions malware performs, the more likely it is to be picked up by monitoring systems. Limiting the actions performed by malware and focusing on essential tasks is called "Execution Control".
Last updated
The more actions malware performs, the more likely it is to be picked up by monitoring systems. Limiting the actions performed by malware and focusing on essential tasks is called "Execution Control".
Last updated
A synchronization object is an object whose handle can be specified in one of the to coordinate the execution of multiple threads.
The following object types are provided exclusively for synchronization.
Event
Mutex
Semaphore
Waitable timer
notify one or more waiting threads that an event has occurred. They can be used to cooridinate the execution of multiple threads or processes. They can be either manual or automatic.
To use events in a program, the WinAPI can be employed. The usage of the function is demonstrated below:
To control execution of a payload, a named semaphore object will be created each time the payload is executed. If the binary is executed multiple times, the first execution will create the named semaphore and the payload will be executed as intended. On subsequent executions, the semaphore creation will fail as the semaphore with the same name is already running. This indicates that the payload is currently being executed from a previous run and therefore should not be run again to avoid duplication.
\
In some circumstances, you can also use a file, named pipe, or communications device as a synchronization object.
Example of setting up a named pipe and using it for inter-process communication (IPC).
Taken from microsoft docs:
Change notification
Console input
Job
Memory resource notification
Process
Thread
\
Notifies one or more waiting threads that an event has occurred. For more information, see .
Can be owned by only one thread at a time, enabling threads to coordinate mutually exclusive access to a shared resource. For more information, see .
Maintains a count between zero and some maximum value, limiting the number of threads that are simultaneously accessing a shared resource. For more information, see .
Notifies one or more waiting threads that a specified time has arrived. For more information, see .
can be owned by only one thread at a time, enabling threads to coordinate mutually exclusive access to a shared resource. Short for "mutual exclusion".
is used to create a named mutex as follows:
maintain a count between zero and some maximum value, limiting the number of threads that are simultaneously accessing a shared resource. There are two types of semaphores: binary and counting. A binary semaphore has a value of 1 or 0, indicating whether the resource is available or unavailable, respectively. A counting semaphore, on the other hand, has a value greater than 1, representing the number of available resources or the number of processes that can access the resource concurrently.
will be used to create a semaphore object. It is important to create it as a named semaphore to prevent executions after the initial binary run. If the named semaphore is already running, CreateSemaphoreA
will return a handle to the existing object and GetLastError
will return ERROR_ALREADY_EXISTS
. In the code below, if a "ControlString" semaphore is already running, GetLastError
will return ERROR_ALREADY_EXISTS
.
Using :
Created by the function, its state is set to signaled when a specified type of change occurs within a specified directory or directory tree. For more information, see .
Created when a console is created. The handle to console input is returned by the function when CONIN$ is specified, or by the function. Its state is set to signaled when there is unread input in the console's input buffer, and set to nonsignaled when the input buffer is empty. For more information about consoles, see
Created by calling the function. The state of a job object is set to signaled when all its processes are terminated because the specified end-of-job time limit has been exceeded. For more information about job objects, see .
Created by the function. Its state is set to signaled when a specified type of change occurs within physical memory. For more information about memory, see .
Created by calling the function. Its state is set to nonsignaled while the process is running, and set to signaled when the process terminates. For more information about processes, see .
Created when a new thread is created by calling the , , or function. Its state is set to nonsignaled while the thread is running, and set to signaled when the thread terminates. For more information about threads, see .