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

Unicode-Buffer Overflows

Мысла Владислав

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


Листинг

Наш декодер в формате Unicode

Decoder:

A4 movs byte ptr [edi],byte ptr [esi]

00 45 00 add byte ptr [ebp],al

46 inc esi

00 45 00 add byte ptr [ebp],al

E2 F6 loop Decoder

Количество итераций зависит от значения, занесенного в ecx (как и в прошлом shell-коде), то есть ecx – это длина shell-кода. В esi и edi должен храниться адрес начала shell-кода. Остался один вопрос: каким образом организовать цикл, ведь операция loop занимает два отличных от нуля байта? Можно опять патчить декодер, но это увеличит размер. Давай схитрим. Наш декодер копирует shell-код, удаляя из него нули, поэтому после декодировки рабочий shell-код окажется прямо за декодером. Мы не замкнем цикл декодера и оставим его в таком виде:

Листинг

Decoder:

A4 movs byte ptr [edi],byte ptr [esi]

00 45 00 add byte ptr [ebp],al

46 inc esi

00 45 00 add byte ptr [ebp],al

E2 00 loop Shellcode

Shellcode:

Таким образом, после первой итерации управление переходит на shell-код, потому что esi и edi указывают прямо на него. А что если edi будет указывать на операнд операции loop? Тогда первый байт shell-кода будет записан операндом к loop и повлияет на исполнение декодера. Причем повлияет сразу при первой итерации, так как исполнится movs, которая изменит loop. И ход исполнения декодера в этот момент может измениться. Более того, если первый байт shell-кода будет 0xF6, то цикл замкнется.

Значит, можно сделать декодер, который пропатчит сам себя и таким образом замкнет цикл расшифровки shell-кода. Достаточно только перед декодируемым shell-кодом указать смещение для прыжка и подправить стартовые настройки: ecx – длина shell-кода + 1, edi – адрес операции loop +1, esi – адрес shell-кода.

Таким образом, нам удалось написать декодер для основного shell-кода, уложившись всего в 6 байт + настройки для его работы. Я думаю, это неплохой результат :).

Формат UTF-8 и другие

Часто данные конвертируются не только в Unicode, но и в такие форматы, как UTF-4, UTF-8, UCS, EUC и т.д. В этом случае появляются и другие ограничения, и новые возможности. Жаль, что объем статьи не позволяет рассказать об этом подробно. Но если эта тема кого-то заинтересует, то мы еще к ней вернемся. А на этом пока все.

Выравнивание кода

Для того чтобы эксплоит работал в формате Unicode, каждый второй его байт должен быть нулевым. Более того, иногда для прыжков или вычислений своей позиции мы манипулируем некоторыми числами, а бывает так, что нам важна их позиция, кратность адреса какому либо числу и т.д. В таких случаях в обычных shell-кодах используют nop’ы. Но в Unicode они их использовать нельзя, поэтому приходиться искать заменители:

00 45 00 add byte ptr[ebp+0x0], al

04 00 add al,0x0

00 EC add ah, ch ; ecx = 0

Если тебя интересует полный список, то ты сможешь найти его самостоятельно, проанализировав байт-коды допустимых к использованию команд.

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