Пожалуйста, обратите внимание, что пользователь заблокирован
Эта статья содержит обзор методов разработки шелл-кода и их специфических аспектов. Понимание этих концепций позволяет вам написать свой собственный шелл-код. Кроме того, вы можете изменить существующие эксплойты, содержащие уже созданный шелл-код, для выполнения необходимых вам пользовательских функций.
Вступление
Допустим, у вас есть рабочий эксплойт в Internet Explorer или Flash Player, который открывает calc.exe. Это не очень полезно, не так ли? Что вы действительно хотите - это выполнить некоторые удаленные команды или выполнить другие полезные функции.
В этой ситуации вы можете захотеть использовать стандартные существующие шелл-коды, например, из базы данных Shell Storm или сгенерированные из инструмента Metasploit msfvenom. Однако вы должны сначала понять основные принципы шелл-кодирования, чтобы вы могли эффективно использовать их в своих подвигах.
Для тех, кто не знаком с этим термином, как говорит Википедия:
«В области компьютерной безопасности шелл-код - это небольшой фрагмент кода, используемый в качестве полезной нагрузки при использовании уязвимости программного обеспечения. Он называется «шеллкод», потому что он обычно запускает командную оболочку, из которой злоумышленник может управлять скомпрометированной машиной, но любой фрагмент кода, выполняющий аналогичную задачу, может называться шеллкодом… Шеллкод обычно пишется на машинном коде ».
Шелл-код - это фрагмент машинного кода, который мы можем использовать в качестве полезной нагрузки для эксплойта. Что это за «машинный код»? Давайте возьмем в качестве примера следующий код C:
Это переводится в ASM как следующий код:
Здесь важно отметить, что есть основная процедура и вызов функции printf.
Этот код собран в машинный код, как вы можете видеть выделенным в отладчике:
Таким образом, «55 8B EC 68 00 B0 33 01…» - это машинный код для нашего кода C.
Как шелл-код используется внутри эксплойта?
Возьмем в качестве примера простой эксплойт, уязвимость переполнения буфера в стеке.
Основная идея использования этой уязвимости заключается в следующем (обратите внимание, что целью данной статьи не является подробное описание работы эксплойтов переполнения буфера):
Особенности Shellcode
Шелл-код - это не какой-либо машинный код. Есть несколько конкретных аспектов, которые мы должны учитывать при написании нашего собственного шелл-кода:
Поскольку нам нужен позиционно-независимый код, мы хотим, чтобы строки были частью нашего кода, поэтому мы должны хранить строку в стеке, как вы увидите в следующих частях этой статьи.
В шеллкоде мы не можем этого сделать. Мы не знаем, загружена ли в память библиотека, содержащая нашу требуемую функцию, и не знаем адрес требуемой функции. DLL из-за ASLR (рандомизации размещения адресного пространства) не будет загружаться каждый раз по одному и тому же адресу. Кроме того, DLL может изменяться с каждым новым обновлением Windows, поэтому мы не можем полагаться на конкретное смещение в DLL.
Мы должны загрузить DLL в память и найти нужные функции прямо из шеллкода. К счастью, Windows API предлагает две полезные функции: LoadLibrary и GetProcAddress, которые мы можем использовать для поиска адресов наших функций.
Даже такая ситуация не является обязательной, в таких распространенных случаях, как переполнение буфера, используется функция strcpy (). Эта функция будет копировать строку за байтом, и она остановится, когда встретит нулевой байт. Таким образом, если шелл-код содержит байт NULL, функция strcpy останавливается на этом байте, а шелл-код не будет завершенным и, как вы можете догадаться, он не будет работать правильно.
Две инструкции из рисунка выше эквивалентны по функциональности, но, как вы можете видеть, первая содержит NULL-байты, а вторая - нет. Даже если в скомпилированном коде часто встречаются NULL-байты, их не так сложно избежать.
Кроме того, существуют конкретные случаи, когда шелл-код должен избегать символов, таких как \ r или \ n, или даже использовать только буквенно-цифровые символы.
Linux против Windows шеллкоды
Проще написать шеллкод для Linux, хотя бы базовый. Это связано с тем, что в Linux можно очень легко использовать системные вызовы (системные «функции»), такие как us write, execve или send, с прерыванием 0x80 (воспринимайте это как «вызов функции»). Вы можете найти список системных вызовов здесь.
Например, шеллкод «Hello, world» в Linux требует следующих шагов:
В Windows это сложнее. Есть более необходимые шаги для создания надежного шелл-кода.
Это первая часть из серии статей о том, как написать шелл-код Windows для начинающих. Это введение требуется для того, чтобы понять, что такое шелл-код, каковы ограничения и каковы различия между шелл-кодом Windows и Linux.
Вторая часть будет содержать краткое введение в язык ассемблера, формат файлов PE (Portable Executable) и PEB (Process Environment Block). Позже вы увидите, как это поможет вам написать собственный шелл-код.
Источник: https://xss.pro
Переводчик статьи - https://xss.pro/members/177895/
Вступление
Допустим, у вас есть рабочий эксплойт в Internet Explorer или Flash Player, который открывает calc.exe. Это не очень полезно, не так ли? Что вы действительно хотите - это выполнить некоторые удаленные команды или выполнить другие полезные функции.
В этой ситуации вы можете захотеть использовать стандартные существующие шелл-коды, например, из базы данных Shell Storm или сгенерированные из инструмента Metasploit msfvenom. Однако вы должны сначала понять основные принципы шелл-кодирования, чтобы вы могли эффективно использовать их в своих подвигах.
Для тех, кто не знаком с этим термином, как говорит Википедия:
«В области компьютерной безопасности шелл-код - это небольшой фрагмент кода, используемый в качестве полезной нагрузки при использовании уязвимости программного обеспечения. Он называется «шеллкод», потому что он обычно запускает командную оболочку, из которой злоумышленник может управлять скомпрометированной машиной, но любой фрагмент кода, выполняющий аналогичную задачу, может называться шеллкодом… Шеллкод обычно пишется на машинном коде ».
Шелл-код - это фрагмент машинного кода, который мы можем использовать в качестве полезной нагрузки для эксплойта. Что это за «машинный код»? Давайте возьмем в качестве примера следующий код C:
Это переводится в ASM как следующий код:
Здесь важно отметить, что есть основная процедура и вызов функции printf.
Этот код собран в машинный код, как вы можете видеть выделенным в отладчике:
Таким образом, «55 8B EC 68 00 B0 33 01…» - это машинный код для нашего кода C.
Как шелл-код используется внутри эксплойта?
Возьмем в качестве примера простой эксплойт, уязвимость переполнения буфера в стеке.
Основная идея использования этой уязвимости заключается в следующем (обратите внимание, что целью данной статьи не является подробное описание работы эксплойтов переполнения буфера):
- Отправьте приложению строку размером более 20 байт, которая также содержит ваш шелл-код
- Стек поврежден из-за перезаписи за пределами статически выделенного буфера. Ваш шеллкод будет помещен в стек
- Ваша строка перезапишет часть важных данных в стеке (например, сохраненный EIP или указатель функции) с адресом пользовательской памяти
- Приложение перейдет к вашему шелл-коду из стека и начнет выполнять инструкции машинного кода внутри
Особенности Shellcode
Шелл-код - это не какой-либо машинный код. Есть несколько конкретных аспектов, которые мы должны учитывать при написании нашего собственного шелл-кода:
- Мы не можем использовать прямые смещения для строк
- Мы не знаем адреса функций (напр. Printf)
- Мы должны избегать некоторых конкретных байтов (например, NULL байтов)
- Прямые смещения в строки
Поскольку нам нужен позиционно-независимый код, мы хотим, чтобы строки были частью нашего кода, поэтому мы должны хранить строку в стеке, как вы увидите в следующих частях этой статьи.
- Адреса функций
В шеллкоде мы не можем этого сделать. Мы не знаем, загружена ли в память библиотека, содержащая нашу требуемую функцию, и не знаем адрес требуемой функции. DLL из-за ASLR (рандомизации размещения адресного пространства) не будет загружаться каждый раз по одному и тому же адресу. Кроме того, DLL может изменяться с каждым новым обновлением Windows, поэтому мы не можем полагаться на конкретное смещение в DLL.
Мы должны загрузить DLL в память и найти нужные функции прямо из шеллкода. К счастью, Windows API предлагает две полезные функции: LoadLibrary и GetProcAddress, которые мы можем использовать для поиска адресов наших функций.
- Избегать пустых байтов
Даже такая ситуация не является обязательной, в таких распространенных случаях, как переполнение буфера, используется функция strcpy (). Эта функция будет копировать строку за байтом, и она остановится, когда встретит нулевой байт. Таким образом, если шелл-код содержит байт NULL, функция strcpy останавливается на этом байте, а шелл-код не будет завершенным и, как вы можете догадаться, он не будет работать правильно.
Две инструкции из рисунка выше эквивалентны по функциональности, но, как вы можете видеть, первая содержит NULL-байты, а вторая - нет. Даже если в скомпилированном коде часто встречаются NULL-байты, их не так сложно избежать.
Кроме того, существуют конкретные случаи, когда шелл-код должен избегать символов, таких как \ r или \ n, или даже использовать только буквенно-цифровые символы.
Linux против Windows шеллкоды
Проще написать шеллкод для Linux, хотя бы базовый. Это связано с тем, что в Linux можно очень легко использовать системные вызовы (системные «функции»), такие как us write, execve или send, с прерыванием 0x80 (воспринимайте это как «вызов функции»). Вы можете найти список системных вызовов здесь.
Например, шеллкод «Hello, world» в Linux требует следующих шагов:
- Укажите номер системного вызова (например, «запись»)
- Укажите параметры системного вызова (например, stdout, «Hello, world», length)
- Прервите 0x80, чтобы выполнить системный вызов
В Windows это сложнее. Есть более необходимые шаги для создания надежного шелл-кода.
- Получить базовый адрес kernel32.dll
- Найти адрес функции GetProcAddress
- Используйте GetProcAddress, чтобы найти адрес функции LoadLibrary
- Используйте LoadLibrary для загрузки DLL (например, user32.dll)
- Используйте GetProcAddress, чтобы найти адрес функции (например, MessageBox)
- Укажите параметры функции
- Вызвать функцию
Это первая часть из серии статей о том, как написать шелл-код Windows для начинающих. Это введение требуется для того, чтобы понять, что такое шелл-код, каковы ограничения и каковы различия между шелл-кодом Windows и Linux.
Вторая часть будет содержать краткое введение в язык ассемблера, формат файлов PE (Portable Executable) и PEB (Process Environment Block). Позже вы увидите, как это поможет вам написать собственный шелл-код.
Источник: https://xss.pro
Переводчик статьи - https://xss.pro/members/177895/