WMF: баг года крис касперски ака мыщъх Хакер, номер #086, стр. 086-066-6 * wmf_checker_hexblog.cpp: создает wmf-файл, внедряет туда shell-код и проигрывает его; * wmfdata.cpp: откомилированный tell.asm с готовым wmf-заголовком; * wmfhdr.wmf: wmf-заголовок с escape-последовательностью и функций SetAbortProc; wmfdata.cpp представляет собой готовый wmf-файл с shell-кодом, который можно скормить Internet Exporer'у, IrfanView'у или любой другой программе подобного типа, но только предварительно необходимо преобразовать cpp в bin, поскольку у Ильфака двоичные данные представлены в виде массива uchar: static uchar array[] = { 0x01,0x00,0x09,0x00,0x00,0x03,0xED,0x00,0x00,0x00,0x06,0x00,0x3D,0x00,0x00,0x00, Теперь осталось только изменить тип массива uchar на char и добавить в wmfdata.cpp пару строк: #include <stdio.h> main(){ FILE *f = fopen("exploit.wmf","wb"); fwrite(array, sizeof(array), 1, f);} После этого осталось только собрать бинарник любым ANSI-совместимым компилятором и запустить полученный wmfdata.exe на выполнение. На диске образуется метафайл exploit.wmf. Откроем его с помощью Infan Viewr'а или любого другого просмотрщика wmf-файлов, и если наша система уязвима, то на экран выскочит симпатичное диалоговое окошко (см. рис. 16). Попробуем дизассемблировать wmf-файл. Для этого нам понадобится IDA Pro любой версии (можно ограничиться и hiew) и спецификация wmf-формата, которую можно нарыть на на нашем диске. Метафайл состоит из заголовка (standard metafile header) и произвольного количества фреймовых записей (standard metafile record) или просто фреймов. Расширенный метафайл устроен чуть-чуть сложнее, но мы не будем в него углубляться. Заголовок представляет собой структуру следующего типа: структура заголовка метафайла typedef struct _WindowsMetaHeader { WORD FileType; /* тип метафайла (0 == память, 1 == диск)*/ WORD HeaderSize; /* размер заголовка в словах (всегда 9) */ WORD Version; /* требуемая версия Windows */ DWORD FileSize; /* полный размер метафайла в словах */ WORD NumOfObjects; /* количество объектов в файле */ DWORD MaxRecordSize; /* размер наибольшей записи в словах */ WORD NumOfParams; /* не используется (== 0)*/ } WMFHEAD; А каждая фреймовая запись устроена так: структура фреймовых записей typedef struct _StandardMetaRecord { DWORD Size; /* полный размер записи в словах */ WORD Function; /* номер функции и количество параметров */ WORD Parameters[]; /* значения параметров, передаваемых функции */ } WMFRECORD; дизасэмблируем сплоит Последняя запись всегда имеет вид 0003h 0000h 0000h (размер заголовка - 03h слова, функция - NULL, параметров нет), что интерпретируется как «конец метафайла». Теперь покурим и начнем дизассемблировать exploit.wmf. В начале идет стандартный wmf-заголовок, большинство полей которого игнорируются и потому могут принимать любые значения. Главное, чтобы FileType == 1, HeaderSize == 9, Version было 100h или 300h, а FileSize содержало достоверный размер файла, в противном случае IrfanViewr и другие графические программы обломаются с открытием метафайла. Это обстоятельство можно использовать для создания полиморфных червей и прочей живности. Кстати говоря, функция PlayMetaFile допускает большую вольность, не проверяя поля FileType и FileSize. |