Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #45, АВГУСТ 2004 г.

Защитись и замети!

Коваленко Дмитрий aka Ingrem

Спецвыпуск Xakep, номер #045, стр. 045-068-6


Функция сначала находит длину строки, которую нужно скопировать. Затем с помощью двух последовательных сдвигов на 1 бит вправо нацело делит эту длину на 4 – получается размер строки, выраженный в двойных словах. Правда, полученный размер обязательно кратен 4, поэтому, если длина строки не делится нацело на 4, теряется остаток ("хвостик" строки в 1, 2 или 3 байта длиной). Происходит копирование строки двойными словами; его выполняет инструкция по адресу 0x0047366A. Затем функция путем обнуления старших 30 битов ecx находит остаток от деления длины строки на 4 (потерянный при предыдущем копировании "хвостик") и копирует его уже побайтно. Такой идиотский, на первый взгляд, код генерируется компилятором С++ для увеличения скорости.

Заметим, что функция никак не контролирует длину копируемой строки – отсюда, очевидно, и переполнение буфера. Теперь посмотрим в IDA код, который вызвал эту процедуру перед аварийным завершением программы. Идем на адрес 0x00453D69 (мы его выловили отладкой, помнишь?) и видим там вот что:

Листинг

loc_453D62: ; CODE XREF: sub_453D20+6j

.text:00453D62 push edx;

.text:00453D63 push ecx;

.text:00453D64 call sub_473648; >-- сравнение строк

.text:00453D69 add esp, 8

......

В CODE XREF – единственная ссылка. Кликаем по ней, приходим к следующему:

Листинг

.text:00453D20 sub_453D20 proc near ; CODE XREF: sub_453C95+Fp

.text:00453D20 ; sub_453CD6+Fp…

.text:00453D20 push ebx

.text:00453D21 cmp eax, 80000001h

.text:00453D26 jnz short loc_453D62

......

Смотрим CODE XREF – шесть ссылок:

Что ж, не так и много. Вполне можно проверить на отладке. Загружаем WinRAR в Soft-Ice, ставим и временно отключаем брейкпоинт:

:bpx 00453D20

:bd *

WinRAR загрузился, подводим курсор к 29A.RAR, включаем брейкпоинт. Открываем архив. При каждом всплывании Soft-Ice смотрим на стек и запоминаем адрес, откуда пришел вызов. После тринадцатого всплывания Soft-Ice происходит аварийное завершение. Адрес вызова 0x00453CEA. Опять идем в IDA. Видим процедуру:

Листинг

.text:00453CD6 var_104 = dword ptr -104h

.text:00453CD6 SubKey = byte ptr -100h

.text:00453CD6

.text:00453CD6 push ebx

.text:00453CD7 add esp, -104h; >-- резервируем буфер (260 байт!)

.text:00453CDD mov ebx, eax

.text:00453CDF lea ecx, [esp+104h+SubKey]

.text:00453CE3 mov eax, ebx

.text:00453CE5 call sub_453D20; >-- копирование строки

.text:00453CEA push esp

......

.text:00453D05 add esp, 104h

.text:00453D0B pop ebx

.text:00453D0C retn; >-- управление отдается на 0048671A

Загрузим WinRAR в Soft-Ice, поставим и отключим брейкпоинт на 00453CD6, это начало процедуры. Перед открытием 29A.RAR включим брейкпоинт. При первом срабатывании трассируем код до 0x00453CDD, запоминаем адрес выделенного буфера и снимаем брейкпоинт. Потом ставим брейкпоинт на 0x00453CEA. Он будет срабатывать каждый раз, сразу после того как инструкция по адресу 0x00453CE5 вызвала процедуру копирования строки. Смотрим, что скопировалось в буфер. В конце концов в буфере оказывается наше длинное расширение ;-). Нажимая F10, трассируем процедуру до адреса 0x00453D0C и останавливаемся. Смотрим esp. Он указывает на двойное слово 0x0048671A. Вот мы и нашли уязвимость.

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