Защитись и замети! Коваленко Дмитрий aka Ingrem Спецвыпуск Xakep, номер #045, стр. 045-068-7 Затыкаем дыру Впишем в winrar.exe небольшой код, на который будет передаваться управление с адреса 0x00453CE5. Этот код будет проверять длину строки перед помещением ее в уязвимый буфер. Если проверка длины пройдет успешно, управление перейдет прямо на функцию по адресу 0x00453D20. Если же код обнаружит, что строка слишком длинная, он сперва "обрежет" ее, записав по смещению 259 от начала нулевой байт, а уже потом сделает jmp 00453D20h. В теории все очень красиво. Но на практике нам предварительно нужно решить две задачи. Первая: как код получит указатель на строку, которую нужно проверить. Вторая: куда его вписать. Легко сказать "вписать код", а куда? Исходников-то нету. Первая проблема решается с помощью отладчика. Загрузим winrar.exe в Soft-Ice, поставим брейкпоинт на адрес 0x00453CE5. ...... 001B:00453CE3 | MOV EAX, EBX 001B:00453CE5 | CALL 00453D20 001B:00453CEA | PUSH ESP ...... Попытаемся открыть 29A.RAR – всплывет отладка. Посмотрим, куда указывают регистры. Искомая строка очень быстро находится по адресу в edx. Вторая проблема – куда деть код – также не очень сложна. Впишем его в header EXE-файла. Сначала нужно найти свободное место. Загружаем winrar.exe в HIEW. Жмем F4, выбираем режим отображения HEX. Смотрим, по какому смещению от начала файла лежит заголовок PE: жмем F5, набираем "3C". По смещению 0x3C видим смещение заголовка PE: 00 02 00 00 (двойное слово 0x200 навыворот). Проверяем: жмем F5, набираем "200". Точно, PE-сигнатурка на месте ;-). Таким образом, под DOS stub выделены первые 512 байт winrar.exe. Причем в HIEW видно, что вторая половина этого пространства никак не используется – сплошные нулевые байты. Что ж, для программиста на ассемблере 256 байт – это немало! Итак, мы нашли место, в которое можно вписать код, проверяющий длину строки. Теперь дело за самим кодом. Он может быть, например, таким: Листинг ; сохраняем в стеке регистры и флаги pushad pushfd ; находим длину строки, адрес которой находится в edx mov ecx,-1 mov edi,edx xor al,al cld repne scasb not ecx ; сравниваем найденную длину строки с 259 cmp ecx, 103h jle @@1 ; если строка в edx длиннее 259, обрезаем ее mov byte ptr[edx+103h],0 ; восстанавливаем регистры @@1: popfd popad ; выходим, отдаем управление процедуре копирования строк push 00453CEAh jmp 00453D20h Ничего оригинального. Единственный принципиальный момент состоит в том, что перед jmp 00453D20h нужно положить на стек адрес возврата. Тогда процедура по адресу 0x00453D20 будет считать, что управление на нее передали c адреса 0x00453CE5 инструкцией call. Внесем этот код в заголовок winrar.exe по смещению 0x100. Воспользуемся встроенным в HIEW ассемблером. Для этого жмем F4, выбираем Decode. Потом жмем Ctrl+F1 – устанавливается 32-битный режим дизассемблирования. Переходим на 0x100 с помощью F5. Жмем F3 – включается режим редактирования. Теперь мы можем вписать свой код, нажав F2. Синтаксис встроенного в HIEW ассемблера немного специфичный, особенно в отображении адресов переходов. Поэтому наш код будет выглядеть так: |