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