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

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:

Назад на стр. 045-056-4  Содержание  Вперед на стр. 045-056-6