Unicode-Buffer Overflows Мысла Владислав Спецвыпуск Xakep, номер #045, стр. 045-056-5 Осталось определить адрес, по которому находится декодер. Если учесть, что код исполняется в стеке приложения, то патч где-то на вершине этого стека. Относительно него и делаются все смещения, так как он неизменного размера. То же самое касается и декодера. Его размер используется для поиска основного shell-кода (“main shellcode”). Но для начала его работы тебе надо занести настроечные данные в регистры: eax – адрес декодера, eax – адрес shell-кода в памяти, ecx – длина shell-кода, esp – адрес для записи. Первым делом определим адрес декодера в памяти. Он должен находиться где-то после патча. Поэтому можно допустить, что его смещение будет не больше чем 0х7F байт. А поскольку весь shell-код находится в начале стека, то несложно записать в eax его адрес: Листинг ; Get start of shellcode 54 push esp 00 45 00 add byte ptr [ebp],al 4C dec esp 00 45 00 add byte ptr [ebp],al 58 pop eax 00 45 00 add byte ptr [ebp],al 05 00 0F 00 01 add eax,1000F00h 00 45 00 add byte ptr [ebp],al 05 00 01 00 FF add eax,0FF000100h 00 45 00 add byte ptr [ebp],al 50 push eax 00 45 00 add byte ptr [ebp],al 44 inc esp 00 45 00 add byte ptr [ebp],al 58 pop eax Здесь ты указал, что смещение к декодеру 0х10. Это значение ты изменишь, когда узнаешь длину всего кода, который будет находиться перед декодером. А там будут патч для декодера и его настройки. Теперь тебе известно, что все настройки к декодеру занимают 0х7D байт. Следовательно, меняешь в блоке строку 05 00 0F 00 01 add eax,1000F00h на строку 05 00 7С 00 01 add eax,1007C00h. Тогда собственно сам декодер: ; Bad formatted decoder 43 inc ebx 14 88 adc al,88h 1C F7 sbb al,0F7h После декодера идет shell-код, который будет расшифрован и исполнен. Это может быть код, открывающий порт для shell’а, или же скачивание и запуск произвольного файла. Короче, все что угодно. Но такой подход к написанию shell-кода очень громоздкий. В результате ты получишь, мягко говоря, огромный декодер. А это неинтересно, так как в большинстве случаев объем shell-кода ограничен. Оптимизация декодера Чтобы немного упростить алгоритм, мы в качестве адреса для записи декодированного shell-кода взяли адрес прямо за декодером. Это избавило нас от необходимости делать вызовы на него, потому что он исполняется сразу после расшифровки. К тому же, мы не должны выбирать заранее определенное место для записи shell-кода, что делает его более переносимым. Но давай попробуем оптимизировать наш shell-кода. Обрати внимание на команду A4 movs byte ptr [edi],byte ptr [esi]. Она предназначена для копирования байт из адреса esi в edi. Команда очень удобна, если учесть, что ее объем составляет всего лишь один байт. Вспомни принцип работы декодера: он копирует из одного адреса в другой, просто адрес источника увеличивается на 2, а не на 1. Операция movs, автоматически инкрементирует esi и edi, чтобы обеспечить копирование строк в циклах. Но если после нее дополнительно увеличить esi на 1, то принцип работы станет таким же, как и у декодера! Вставив этот процесс в цикл, ты получишь наш декодер в Unicode: |