2010-11-08 2 views
4

Это шеллкод для использования уязвимости bufferoverflow. это устанавливает Setuid (0) и порождает оболочки с помощью execve()Может ли кто-нибудь объяснить этот код сборки

  1. XOR% EBX,% EBX */
  2. LEA 0x17 (% EBX),% EAX */
  3. INT $ 0x80 */
  4. толчок% EBX */
  5. толчок $ 0x68732f6e */
  6. толчок $ 0x69622f2f */
  7. мов% особ,% EBX */
  8. толчок% EAX */
  9. толчок% EBX */
  10. мов% особ,% ECX */
  11. КДР */
  12. мов $ 0xB,% аль */
  13. INT $ 0x80

это путь я интерпретировал его ...

  1. XORing сделать значение EBX 0
  2. добавляет 23 к 0 и загружает эффективный addr в eax. для УИП()

3.interrupt

4.push EBX

5.push адрес // у только этот адрес ????

6.push адрес // тот же вопрос

12 мов execve SYS называют в Аль

13 прерывают

Может кто-нибудь объяснить целые шаги ясно ??

ответ

6

int - это код операции для запуска программного прерывания. Программные прерывания нумеруются (от 0 до 255) и обрабатываются ядром. В системах Linux прерывание 128 (0x80) является обычной точкой входа для системных вызовов. Ядро ожидает аргументы системного вызова в регистрах; в частности, регистр% eax определяет, какой системный вызов мы говорим.

  1. Set% EBX до 0
  2. Compute% EBX + 23 и сохранить результат в% EAX (опкод является lea в качестве «нагрузки эффективного адреса», но не доступ к памяти участвуют, это просто хитрый способ сделать дополнение).
  3. Системный вызов. % eax содержит 23, что означает, что системный вызов setuid. Этот системный вызов использует один аргумент (целевой UID), который можно найти в% ebx, который удобно содержит 0 в этой точке (он был установлен в первой инструкции). Примечание: после возврата регистры не изменяются, за исключением% eax, который содержит возвращаемое значение системного вызова, обычно 0 (если вызов был успешным).
  4. Нажмите% ebx на стек (который по-прежнему равен 0).
  5. Push $ 0x68732f6e в стеке.
  6. Push $ 0x69622f2f в стеке. Поскольку стек растет «вниз», и поскольку процессоры x86 используют малое кодирование endian, эффект от инструкций с 4 по 6 заключается в том, что% esp (указатель стека) теперь указывает на последовательность из двенадцати байтов, значений 2f 2f 62 69 6e 2f 73 68 00 00 00 00 (в шестнадцатеричной форме). Это кодировка строки «// bin/sh» (с завершающим нулем и тремя дополнительными нулями впоследствии).
  7. Переместить% esp на% ebx. Теперь% ebx содержит указатель на строку «// bin/sh», которая была построена выше.
  8. Push% eax в стеке (% eax - 0 в этой точке, это возвращаемый статус от setuid).
  9. Push% ebx в стеке (указатель на «// bin/sh»). Инструкции 8 и 9 строят на стеке массив из двух указателей, первый из которых является указателем на «// bin/sh», а второй - на указатель NULL. Этот массив является тем, что системный вызов execve будет использовать в качестве второго аргумента.
  10. Переместить% esp в% ecx. Теперь% ecx указывает на массив, построенный с инструкциями 8 и 9.
  11. Sign-extend% eax в% edx:% eax. cltd - это синтаксис AT & T, за который документация Intel вызывает cdq. Так как% eax равно нулю в этой точке, это также устанавливает% edx в ноль.
  12. Установите% al (младший старший байт% eax) на 11. Так как% eax равно нулю, теперь все значение% eax равно 11.
  13. Системный вызов. Значение% eax (11) идентифицирует системный вызов как execve. execve ожидает три аргумента, в% ebx (указатель на строку, называя исполняемый файл),% ecx (указатель на массив указателей на строки, которые являются аргументами программы, первая из которых является копией имени программы, будет использоваться самой вызываемой программой) и% edx (указатель на массив указателей на строки, которые являются переменными среды; Linux переносит это значение как NULL для пустой среды) соответственно.

Поэтому код сначала вызывает setuid(0), затем вызывает execve("//bin/sh", x, 0) где x указывает на массив из двух указателей, первый из которых указатель «// бен/ш», в то время как другой является NULL.

Этот код довольно запутан, потому что он хочет избежать нулей: при сборке в двоичные коды операций последовательность команд использует только ненулевые байты. Например, если 12-я инструкция была movl $0xb,%eax (установка всего% eax на 11), тогда двоичное представление этого кода операции содержало бы три байта значения 0. Отсутствие нуля делает эту последовательность пригодной для использования в качестве содержимого нулевая строка C. Разумеется, это предназначено для атаки на багги-программы через переполнение буфера.

+0

U r Great !!!! ... Thnx много !!!!!!!! –

+1

Pomin: на самом деле код запутан, потому что он пытается быть как можно меньше. Это модифицированная версия известного 24-байтового шеллкода, используемого Gera из Core Security (надеюсь, что я получил право на атрибуцию, я не знаю, как искать самый ранний вид этого кода в сети). – ninjalj

Смежные вопросы