На главную | Содержание | Назад | Вперёд
Наши друзья

 

 

Структура полезной нагрузки для платформы AlX/PowerPC

Платформа AlX/PowerPC также основана на RISC-архитектуре. Как и большинство исследованных нами чипов, этот процессор может работать как с прямым, так и обратным порядком байтов (big или little endian). Используются команды размером 32 бит.

К счастью, работать с PowerPC на ALX немного проще, чем на HP/UX. Стек растет сверху вниз и локальные буферы растут в направлении сохраненного адреса возврата.
Определение положения в памяти
Определить свое положение в памяти достаточно просто. Выполните команду перехода на одну команду и воспользуйтесь командой mf lr ("move from link register"), чтобы узнать свое текущее положение. Код выглядит примерно следующим образом.
.shellcode:
хог 2 0,20,20 bnel .shellcode
mflr 31
Этот код на ассемблере написан для отладчика gcc. Операция XOR приводит к неисполнению команды перехода. Однако хотя для команды bnel ("branch if not equal and link") переход не выполняется, но связь устанавливается все равно. Текущий указатель команд сохраняется в регистре lr (link register). Следующая команда mflr сохраняет значение из регистра lr в регистр 31. И, что очень радует, эти машинные коды не содержат байтов NULL Действительные машинные коды выглядят следующим образом.
0х7е94а278 0x4082fffd 0x7fe802a6
Защита для кода командного интерпретатора PowerPC
Теперь добавим еще одно действие для нашего кода командного интерпретатора для платформы AIX/PowerPC. Пусть в наш код командного интерпретатора добавлена команда для обнаружения отладчика. При обнаружении отладчика, код сам себя искажает, а это значительно усложняет взлом и восстановление такого кода. Наш пример очень простой, но в нем есть один крайне важный момент. Код командного интерпретатора можно защитить не только с помощью шифрования и самоискажения, но и посредством вредоносного ответного удара, наносимого при попытке восстановления исходного кода. Например, код командного интерпретатора способен выявить проведение отладки и перейти к выполнению процедуры, которая полностью стирает содержимое жесткого диска.
.shellcode:
хог 2 0,20,20 bnel .shellcode
mflr 31
.A: lwz 4,8 (31) stw 31,-4 (1)
.C: andi. 4, 4, OxFFFF
.D: cmpli 0, 4, OxFFFC
.E: beql .coast_is_clear
.F: addi 1, 1, 66
.coast_is_clear: mr 31,1

В этом примере не предпринимается попытки избежать появления символов NULL. Мы можем исправить эту проблему, создав более сложные строки команд, которые приводят к тому же результату (команды для удаления символов NULL мы рассмотрим в следующем разделе). Другим вариантом является добавление хитростей с машинным кодом, подобных тем, что заложены в закодированной части по­лезной нагрузки.
В этом коде командного интерпретатора текущее положение в памяти сохраняется в регистре 31. Следующая команда (обозначенная буквой А) выполняет загрузку данных в регистр 4. Эта команда загружает машинный код, который был сохранен для команды, обозначенной буквой В. Другими словами, она загружает машинный код для следующей команды. Если кто-то попытается провести пошаговую отладку кода, то эта команда будет искажена. Оригинальный машинный код не будет загружен. Вместо этого будет использован машинный код для останова отладки. Причина этого очень проста — при пошаговом исследовании программы отладчик вставляет команду останова непосредственно перед нашей текущей позицией.
Затем в точке, обозначенной буквой С, выполняется маскирование сохраненного машинного кода, так что остаются только два младших байта. Команда, обозначенная буквой D, сравнивает эти два байта с ожидаемым значением. При выявлении совпадения код добавляет 66 к текущей позиции указателя стека (обозначение буквой F) в целях его искажения. В противном случае выполняется переход к команде, обозначенной coast_is_clear. Очевидно, что можно все сделать еще сложнее, но искажения значения указателя стека уже достаточно для прекращения выполнения кода и для блокирования большинства попыток вторжения.
Удаление символов NULL
В последующем примере будет показано, как удалять символы NULL из нашего защищенного кода. Для каждой команды, в которой вычисляется смещение относительно текущей позиции (например команды перехода и загрузки), как правило, необходимо использовать отрицательное значение смещения. В приведенном ранее защищенном коде использовалась команда ldw, которая определяет, чтение какого адреса необходимо выполнить по отношению к базовому адресу, сохраненному в регистре 31 (т.е. смещение в памяти). Для удаления символов NULL нам нужно отнять значение от базового адреса. Для этого сначала нужно добавить достаточное значение к базовому адресу, чтобы смещение оказалось отрицательным. Как видно из строк main+12Hmain+16, мы используем машинные коды без символов NULL для добавления больших чисел к значению в регистре г 31, а затем кодируем результат с помощью операции XOR, чтобы получить значение 0x0015 в регистре 20. Затем мы добавляем значение г20 к значению г31. Используя в этой точке команду ldw со смещением -1, мы выполняем чтение команды как main+28.
0x10000258 <main>: xor r20,r20,r20
0х1000025с <main+4>: bnel+ 0x10000258 <main>
0x10000260 <main+8>: mflr r31
0x10000264 <main+12>: addi r20,r20,0x6673 ; значение 0x0015 Ъ закодировано с помощью операции хог по значению 0x6666
0x10000268 <main+16>: xori r20,r20,0x6666 ; хог-декодирование *Ь регистра

0x1000026с <main+20>: add г31,г31,г20 ; добавить 0x15 к г31
0x10000270 <main+24>: lwz r4,-l(r31) ; получить машинный
Ч> код по адресу г31-1 (оригинальное значение г31 + 0x14)
Окончательные машинные коды выглядят следующим образом.
0х7е94а278 0x4082fffd 0x7fe802a6 0хЗа946673 0х6а946666 0x7fffa214 0x809fffff
0х100002бс <main+20>: add r31,r31,r20 ; добавить 0x15 к г31
0x10000270 <main+24>: lwz r4,-l(r31) ; получить машинный
*Э> код по адресу г31-1 (оригинальное значение г31 + 0x14)
Окончательные машинные коды выглядят следующим образом.
0х7е94а278 0x4082fffd

 

На главную | Содержание | Назад | Вперёд
 
Яндекс.Метрика