Атака через back door
Для управления виртуальной машиной многие эмуляторы используют специальный (и, по обыкновению, недокументированный) back door механизм вроде того, что есть в soft-ice (см. INT 03h в Interrupt List'е Ральфа Брауна). Virtual PC использует для той же цели инвалидные инструкции процессора (например, 0Fh3Fh 07h 0Bh), а VM Ware "магический" порт ввода/вывода.
Рисунок 15 back-door интерфейс – мощное оружие, бьющие точно в цель
Остановимся на VM Ware как на самом популярном эмуляторе. Чтобы передать back door команду на выполнение, необходимо выполнить следующие действия:
q в регистр EAX занести магическое число 564D5868h ('VMXh' в ASCII-представлении);
q в регистр DX занести магическое число 5658h (номер порта, 'VX' в ASCII);
q в регистр CX занести номер команды, а в регистр EBX ее параметры;
q выполнить команду IN EAX, DX (or OUT DX, EAX);
q если программа исполняется не под VM Ware (или VM Ware был предварительно пропатчен) на прикладном уровне защищенного режима возникнет исключение типа "нарушение доступа";
q при выполнении под VM Ware регистр EBX будет содержать магическое число 564D5868h ('VMXh' в ASCII-представлении), а в остальных регистрах — возвращенные данные (если они есть);
VM Ware поддерживает большое количество самых различных команд, подробно исследованных Ken'ом Kato и описанных в его статье "VMware's back" (http://chitchat.at.infoseek.co.jp/vmware/backdoor.html). Здесь можно найти и установку даты/времени, и работу с буфером обмена и даже механизм удаленного вызова процедур (RPC), но… потенциально опасных команд среди них нет. Вирус не может просто взять и вырываться из виртуальной машины! Или… все-таки сможет? Свыше двух десятков команд еще остаются неисследованными и неясно зачем они и почему.
Никто не знает какие возможности нас ждут…
Рисунок 16 вороне где-то бог послал персональный компьютер
Из всех команд, исследованных на сегодняшний день, самой опасной была и остается 0Ch (Connect/disconnect a device), отвечающая за подключение/отключение IDE, SCSI и USB устройств. У вируса существует шикарная возможность подключить физический диск основной системы и нагадить на нем по полной программе (VM Ware позволяет создавать виртуальные диски на основе физических). Еще вирус может дотянуться до USB-"свистка" и заразить все имеющиеся на нем исполняемые файлы, которые кто-нибудь обязательно запустит на основной машине.
Рисунок 17 виртуальная машина по сути своей черепаха
Короче, возможностей много. Для защиты рекомендуется пропатчить VM Ware, изменив магический номер на что-то еще. Неофициальная заплатка лежит здесь: http://honeynet.rstack.org/tools/vmpatch.c, официальных пока нет и, по-видимому, в обозримом будущем и не предвидится. (Однако, даже залатанная система по-прежнему остается уязвимой, поскольку подобрать нужные магические числа можно и брут-форсом, возможных вариантов не так уж и много — 16-битный номер порта, плюс 32-битный "пирожок" дают менее 48-значимых битов! "менее" — это за вычетом стандартных номеров портов, которые нельзя использовать).
Ниже в качестве примера приводится программа, определяющая версию VM Ware.
#include <windows.h>
// строковые константны
#define VM "vmware"
#define VM_DETECTED "detected"
#define VM_NOT_DETECTED "not detected"
#define VM_NOT_RECOGNZD "detected, but not recognized"
// под vm-ware функция возвращает версию vm-ware
в регистре eax
// (нуль — это не vm-ware или версия неопознана),
// без vm-ware возбуждается исключение
__declspec(naked) get_vm() // "голая" функция без пролога и эпилога
{
__asm{
; подготавливаем аргументы и магические пирожки
mov ecx, 0Ah ; номер команды — определение версии
mov eax, 564d5868h ; 'VMXh' - магический номер типа "пирожок"
mov edx, 00005658h ; '..VX' - магический порт back-door интерфейса
; дергаем за "веревочку"
in eax, dx ; вызываем команду по back-door интерфейсу
; возвращенные параметры помещаются в EAX/EBX/ECX
; внимание!
; в среде чистой Windows
без vm-ware при обращении к порту ввода-вывода
; произойдет исключение и управление будет передано SEH-обработчику,
; который должен быть заранее установлен (иначе выполнение программы
; будет завершено системой)
; если же мы еще здесь, следовательно, исключения не произошло
; и, либо какой-то хитрый драйвер открыл порты ввода-вывода,
; либо мы находимся под управлением непатченной vm-ware
; или чего-то очень на нее похожего
cmp ebx, 'VMXh' ; анализируем возвращенный магический пирожок
je under_VMware ; если пирожок возвращен, мы под vm-ware
xor eax,eax ; возвращаем ноль в знак того, что мы не под vm-ware!
ret ; выходим из функции
under_VMware:
ret ; мы под непатченной vm-ware, в eax номер версии
}
}
main()
{
// вызываем функцию get_vm
из блока __try,
// чтобы отлавливать возникающие исключения
// для простоты и наглядности, версия vm-ware, возвращенная get_vm,
// не выводится на экран и сообщается лишь о том, был ли обнаружен
// непатченный эмулятор или нет (если исключения не произошло,
// vm-ware считается обнаруженной)
__try { printf("%s %s\n",VM, (get_vm())?VM_DETECTED:VM_NOT_RECOGNZD);}
// обработчик исключения, получающий управление при выполнении программы
// в среде чистой Windows, под патченной vm-ware или на другом эмуляторе
__except(1) {printf("%s %s\n",VM, VM_NOT_DETECTED);}
}
Листинг 1 программа, демонстрирующая взаимодействия с виртуальной машиной через back-door интерфейс и определяющая версию VM Ware (на экран она не выводится)