Асинхронный вызов процедур (Asynchronous Procedure Call, APC) - это техника внедрения процесса, которая позволяет злоумышленникам выполнять вредоносный код, ставя его в очередь как APC-рутину в легитимном процессе. Эта техника использует встроенный в Windows механизм APC, который позволяет выполнять функции асинхронно в контексте определенного потока. Внедряя вредоносный код в процесс и заставляя существующий поток выполнить его, атакующие могут избежать обнаружения и незаметно выполнить полезную нагрузку.
Что такое асинхронный вызов процедур (APC)?
Асинхронные вызовы процедур - это функции, выполняемые асинхронно в контексте определенного потока. Когда APC ставится в очередь на поток, он добавляется в очередь APC этого потока. Когда поток планируется запустить снова, он проверяет свою очередь APC на наличие ожидающих APC и выполняет их, прежде чем продолжить обычное выполнение. Разработчики вредоносного ПО часто используют этот механизм, прикрепляя вредоносный код к очереди APC целевого потока.
APC ставятся в очередь APC потока, и поток получает уведомление, когда APC готов к выполнению. Затем поток может выполнить APC, вызвав функцию KeWaitForSingleObject с объектом APC в качестве параметра.
Существует два типа APC: APC ядра и пользовательские APC. APC ядра выполняются в контексте ядра системы, а пользовательские APC - в контексте процесса в пользовательском режиме. APC часто используются в реализации драйверов устройств Windows для выполнения таких задач, как чтение и запись данных на устройство. Они также используются системными библиотеками и приложениями для асинхронного выполнения задач, таких как ожидание завершения операции ввода-вывода.
Использование злоумышленниками асинхронного вызова процедур (APC)
Одним из способов использования злоумышленниками APC является постановка APC ядра в очередь APC системного потока, например потока, запущенного с повышенными привилегиями. При выполнении APC код будет выполняться в контексте системного потока, что позволит злоумышленнику выполнять действия с привилегиями этого потока.
Еще один способ, которым злоумышленники могут использовать APC, - это внедрение PE в процесс и использование APC для выполнения кода из внедренного PE в контексте процесса. Это может быть использовано для обхода мер безопасности, предназначенных для предотвращения инъекции кода в процесс, поскольку APC выполняется прозрачно для самого процесса.
В отличие от предыдущих методов, которые предполагают прямое манипулирование контекстами потоков или PE-образами, что может быть обнаружено средствами защиты, APC-инъекция ставит функцию в очередь на выполнение, когда поток находится в состоянии, допускающем предупреждение. Вот обзор жизненного цикла атаки APC-инъекции:
- Получение хэндлов процессов и потоков: Атакующий получает хэндл целевого процесса с помощью OpenProcess с необходимыми привилегиями, такими как PROCESS_VM_OPERATION и PROCESS_VM_WRITE. Затем выбирается поток внутри целевого процесса. Хендл к этому потоку получают через OpenThread с правами доступа, позволяющими ставить APC в очередь (например, THREAD_SET_CONTEXT).
- Выделение памяти в целевом процессе: Используя VirtualAllocEx, атакующий выделяет память в адресном пространстве целевого процесса, куда будет помещена вредоносная полезная нагрузка (шелл-код). Разрешения на память устанавливаются таким образом, чтобы разрешить действия чтения, записи и выполнения, часто PAGE_EXECUTE_READWRITE.
- Запись шелл-кода: Атакующий записывает вредоносный код в выделенный участок памяти в целевом процессе с помощью WriteProcessMemory.
- Постановка APC в очередь: APC ставится в очередь на целевой поток с помощью QueueUserAPC. APC указывает на шелл-код в выделенной области памяти. APC будет выполняться только тогда, когда поток перейдет в состояние готовности, что может быть достигнуто вызовом определенных функций, таких как SleepEx, SignalObjectAndWait или WaitForSingleObjectEx, с соответствующими флагами, чтобы перевести поток в состояние готовности.
- Запуск выполнения: Атакующий ждет, пока поток перейдет в состояние готовности, или сам инициирует такое состояние. Когда поток переходит в состояние готовности, выполняется поставленный в очередь APC, и, следовательно, вредоносный шеллкод запускается в контексте целевого потока.
Асинхронная оболочка процедур (Asynchronous Procedure Shell, APC) также имела свою долю среди злоумышленников в 2024 году. Вредоносная программа PythonRatLoader использует APC-инъекции для развертывания вредоносного ПО XWORM [1]. Злоумышленники использовали обфусцированный Python-код для создания процесса notepad.exe и внедрения в него полезной нагрузки до начала выполнения потока. Расшифрованный Python-код, использованный для APC-инъекции, приведен ниже.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | key = 'evr8pl5K'.encode('ascii') shellcode = rc4_decrypt(key, encrypted_data) # Allocate memory with executable permissions shellcode_buffer = ctypes.create_string_buffer(shellcode) ctypes.windll.kernel32.VirtualProtect( ctypes.byref(shellcode_buffer), ctypes.sizeof(shellcode_buffer), 0x40, # PAGE_EXECUTE_READWRITE ctypes.byref(ctypes.c_ulong()) ) # Execute the shellcode shellcode_func = ctypes.cast(shellcode_buffer, ctypes.CFUNCTYPE(ctypes.c_void_p)) shellcode_func() execute_shellcode () |