Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #86, ФЕВРАЛЬ 2006 г.

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.

Назад на стр. 086-066-5  Содержание  Вперед на стр. 086-066-7