Оперируем WinAmp Ichwill (artem_king@rambler.ru) Хакер, номер #075, стр. 075-056-4 Листинг дешифровщика xor ecx,ecx mov cl,255 jmp short end_call begin: pop eax push eax haha: mov bl,byte ptr[eax] add bl,-124 mov byte ptr[eax],bl inc eax loop haha jmp start_exp end_call: call begin start_exp: Структура эксплойта Теперь перейдем к основной части шелл-кода, но перед этим рассмотрим его логическую схему: Логическое устройство шелл-кода расшифровщик строка «Win» (без нулевого байта) ; это число команд для выполнения (один байт) ; зашифрованная сами строки с командами (оканчиваются нулевыми байтами) ; часть ………………………………………………………………….. ; нашего основная часть шелл-кода ; шелл-кода После переполнения буфера управление получает дешифровщик. Он расшифровывает оставшуюся часть шелл-кода и передает управление основной части, причем на вершине стека будет адрес строки «Win» (как раз для этого мы вставили в код дешифровщика команду pop eax) и регистр ecx примет нулевое значение (вследствие действия команды loop). Далее в основной части шелл-кода мы помещаем в регистр cl тройку (длина строки «Win») и вызываем функцию поиска API-адреса. После работы этой функции регистр edx будет содержать адрес WinExec(), а регистр edi - адрес строки «Win». Потом прибавляем все ту же тройку к регистру edx. Теперь он уже содержит адрес числа команд. Читаем это число в регистр bl, потом увеличиваем регистр edi на единицу, теперь он будет содержать адрес первой команды. И в самом конце шелл-кода у нас будет располагаться цикл, выполняющий наши команды. Алгоритм цикла очень прост. Вначале мы сохраняем все регистры в стеке и помещаем в стек регистр eax - второй параметр функции WinExec, отвечающий за способ отображения запускаемого приложения. А так как eax у нас равен нулю, то приложение запустится в режиме SW_HIDE. Дальше мы кладем в стек регистр edi - первый параметр функции WinExec, который является указателем на выполняемую строку. Потом вызываем WinExec и восстанавливаем значения регистров. Изменяем edi так, чтобы он указывал на следующую строку, уменьшаем bl на единицу, и если bl не равно нулю, то передаем управление на начало цикла. Усложнять себе жизнь мы не будем, поэтому после выполнения наших полезных действий шелл-код просто передаст управление на следующую инструкцию. В этом случае на 99,9% WinAmp вызовет ошибку и завершит свое выполнение. Конечная реализация К сожалению, размер нашего шелл-кода не должен превышать 235 байт. Это связано с тем, что для каждой строки с именем файла WinAmp выделяет лишь 259 байт. Отсюда получаем ограничения на количество выполняемых команд и длину NOP’овой дорожки. Как ты видишь из таблицы, адрес нашей строки с именем файла в WinAmp’е версий 5.0 - 5.3, 5.4 - 5.5 и 5.6 сильно различается. Но если посмотреть на таблицу повнимательнее, можно увидеть, что кроме места расположения шелл-кода также изменяются и номера байт строки, влияющих на адрес, на который передастся управление после переполнения буфера. Если мы возьмем переполняющую строку «C:\1234567890abcdefghijklmnopqr.cda», то получим: |