Взгляд на использование уязвимостей

Поскольку я с нетерпением ждал продолжения обсуждения этой темы, позвольте мне рассказать вам немного истории, теории и практики уязвимостей. К настоящему времени все мы слышали, что недостатки безопасности могут стоить дорого, все мы знаем, что мы должны поддерживать наше программное обеспечение в актуальном состоянии, все мы знаем, что многие обновления вызваны ошибками безопасности. Но сегодня я расскажу вам немного о том, как эти ошибки обнаруживаются и используются 🙂 Но перед этим мы собираемся прояснить некоторые детали, чтобы иметь лучший обзор.

Прежде чем начать

Сначала я хочу сказать вам, что мы собираемся сосредоточиться на первой уязвимости, которую я научился использовать, известной Переполнение буфера, в этой уязвимости мы используем недостаток проверки памяти для забавных вещей 🙂 Но давайте проясним это немного подробнее.

Это не будет реальным сценарием

Я не могу позволить себе научить их ломать любую программу, которую они видят 🙂 во-первых, потому что это опасно для их компьютеров, во-вторых, потому что для этого потребуется больше, чем моя обычная квота слов.

Отправляемся в путешествие в 80-е

То, что я собираюсь показать вам, я могу делать на своем ноутбуке, но это не означает, что это можно сделать сегодня простым способом 🙂 многие из этих концепций уже использовались так много раз, что появились новые методы защиты и новые методы обхода 😛 но это возвращает нас в то же место, нет места, чтобы все это рассказать 🙂

Это может не работать на вашем процессоре

Хотя я собираюсь использовать очень простой пример, я хочу, чтобы с самого начала было совершенно ясно, что подробностей этого так много и так разнообразно, что, если вы хотите попробовать, он может оказаться таким же, как и я. , желаемый эффект также может не быть достигнут 🙂 Но вы можете себе представить, что я не могу объяснить это в этом пространстве, особенно потому, что во введении я уже взял более 300 слов, так что мы сразу переходим к нашей точке зрения.

Что такое Переполнение буфера

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

Буферы

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

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

Стек

Также известные как стеки, они представляют собой абстрактный тип данных, в котором мы можем стек информации, их основная характеристика в том, что они LIFO (последний пришел - первым ушел). Давайте на секунду подумаем о стопке тарелок, мы кладем их сверху одну за другой, а затем вынимаем их одну за другой сверху, это делает последнюю тарелку, которую мы поставили (та, которая находится наверху ) - это первая пластина, которую мы собираемся вынуть, очевидно, если мы можем вынимать только одну пластину за раз и мы решаем делать это в таком порядке: P.

Теперь, когда вы знаете эти две концепции, мы должны привести их в порядок. Стеки важны, потому что каждая программа, которую мы запускаем, имеет свои собственные стек выполнения. Но в этом стеке есть особая характеристикарастет вниз. Единственное, что вам нужно знать об этом, это то, что во время работы программы при вызове функции стек переходит от числа X в памяти к числу (Xn). Но чтобы продолжить, мы должны понять еще одну концепцию.

Указатели

Это концепция, которая сводит с ума многих программистов, когда они начинают работать с миром C, на самом деле большая сила программирования на C отчасти объясняется использованием указателей. Для простоты указатель указывает на адрес памяти. Звучит сложно, но не так уж сложно, ведь у всех нас есть ОЗУ, верно? Что ж, это можно определить как последовательное расположение блоковэти местоположения обычно выражаются в шестнадцатеричных числах (от 0 до 9, а затем от A до F, например 0x0, 0x1, 0x6, 0xA, 0xF, 0x10). Вот любопытная заметка, 0x10 НЕТ равно 10 😛, если мы преобразуем его в десятичный порядок, это будет то же самое, что сказать 15. Это то, что сначала сбивает с толку больше, чем один, но давайте приступим к этому.

Учет

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

Теперь практика

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

GDB

Отличная программа, которая, несомненно, является одной из наиболее часто используемых программистами на C. Среди ее многих достоинств мы имеем тот факт, что она позволяет нам видеть все, о чем мы до сих пор говорили, регистры, стек, буферы и т. Д. 🙂 Давайте посмотрим на программу, которую мы будем использовать для нашего примера.

retinput.c

Своя. Кристофер Диас Риверос

Это довольно простая программа, мы будем использовать библиотеку stdio.h чтобы иметь возможность получать информацию и отображать ее в терминале. Мы видим функцию под названием return_input что порождает буфер называемый массив, длина которого 30 байт (тип данных char имеет длину 1 байт).

Функция gets(array); запросить информацию с помощью консоли и функции printf() возвращает содержимое массива и отображает его на экране.

Каждая программа, написанная на C, начинается с функции main(), это будет отвечать только за вызов return_input, теперь мы собираемся скомпилировать программу.

Своя. Кристофер Диас Риверос

Возьмем немного того, что я только что сделал. Опция -ggdb сообщает gcc, что он должен скомпилировать программу с информацией, чтобы gdb мог правильно отлаживать. -fno-stack-protector Это вариант, который, очевидно, нам не следует использовать, но мы собираемся использовать, потому что в противном случае было бы возможно создать переполнение буфера в стеке. В итоге я проверил результат. ./a.out он просто выполняет то, что я только что скомпилировал, он запрашивает у меня информацию и возвращает ее. Бег 🙂

Предупреждения

Еще одно замечание. Вы видите предупреждения? очевидно, что это нужно учитывать, когда мы работаем с кодом или компилируем, это немного очевидно, и есть несколько программ, которые сегодня имеют функцию gets() В коде. Одним из преимуществ Gentoo является то, что, компилируя каждую программу, я вижу, что может быть не так, «идеальная» программа не должна иметь их, но вы будете удивлены, сколько больших программ имеют эти предупреждения, потому что они просто ОЧЕНЬ большие, и их трудно отслеживать. опасные функции при одновременном выводе множества предупреждений. Теперь, если мы продолжим

Отладка программы

Своя. Кристофер Диас Риверос

Эта часть может немного сбивать с толку, но поскольку я уже написал достаточно, я не могу позволить себе все объяснить, так что извините, если вы видите, что я иду слишком быстро 🙂

Снятие кода с охраны

Начнем с рассмотрения нашей скомпилированной программы на машинном языке.

Своя. Кристофер Диас Риверос

Это код нашей основной функции в сборка, это то, что понимает наш процессор, строка слева - это физический адрес в памяти, <+ п> это известно как смещение, в основном расстояние от начала функции (main) до этого оператора (известного как опкод). Затем мы видим тип инструкции (push / mov / callq…) и один или несколько регистров. Подводя итог, можно сказать, что это указание, за которым следует источник / происхождение и пункт назначения. <return_input> относится к нашей второй функции, давайте посмотрим.

Возврат_вход

Своя. Кристофер Диас Риверос

Это немного сложнее, но я просто хочу, чтобы вы проверили пару вещей, есть тег под названием <gets@plt> и последний код операции называется retq обозначающий конец функции. Мы собираемся поставить пару точек останова, одну в функции gets и еще один в retq.

Своя. Кристофер Диас Риверос

Run

Теперь мы запустим программу, чтобы увидеть, как начинается действие.

Своя. Кристофер Диас Риверос

Мы видим, что появляется небольшая стрелка, указывающая код операции, где мы находимся, я хочу, чтобы они приняли во внимание направление 0x000055555555469b, это адрес после звонка на return_input в функции main , это важно, так как именно сюда программа должна вернуться, когда вы закончите получать вход, перейдем к функции. Теперь мы собираемся проверить память перед входом в функцию gets.

Своя. Кристофер Диас Риверос

Я добавил для вас основную функцию и выделил код, который имел в виду, как видите, из-за порядок байтов был разделен на два сегмента, я хочу, чтобы они учитывали направление 0x7fffffffdbf0 (первый слева после коммандос x/20x $rsp), поскольку это место, которое мы должны использовать для проверки результатов get, продолжим:

Нарушение программы

Своя. Кристофер Диас Риверос

Я выделил те 0x44444444потому что они представляют нашу Ds 🙂 теперь мы начали добавлять вход в программу, и, как вы можете видеть, мы находимся всего в двух строках от желаемого адреса, мы собираемся заполнить его до тех пор, пока не окажемся прямо перед адресами, которые мы выделили на предыдущем шаге.

Изменение обратного пути

Теперь, когда нам удалось ввести этот раздел кода, где он указывает на возврат функции, давайте посмотрим, что произойдет, если мы изменим адрес 🙂 вместо того, чтобы перейти к местоположению кода операции, который следует за тем, который был у нас минуту назад, что вы думаете если мы вернемся к return_input? Но для этого необходимо записать нужный нам адрес в двоичном формате, мы сделаем это с помощью функции printf из bash 🙂

Своя. Кристофер Диас Риверос

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

Размышления

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

Это только первый шаг в почти бесконечном списке вещей, которые можно увидеть и добавить, есть способы добавить больше вещей, чем просто повторение заказа, но на этот раз я написал много и все, что связано с шеллкодирование это предмет для написания больше, чем статьи, я бы сказал, полные книги. Извините, если я не смог немного углубиться в темы, которые мне бы понравились, но, безусловно, будет возможность 🙂 Приветствую и спасибо, что пришли сюда.


Оставьте свой комментарий

Ваш электронный адрес не будет опубликован. Обязательные для заполнения поля помечены *

*

*

  1. Ответственный за данные: Мигель Анхель Гатон
  2. Назначение данных: контроль спама, управление комментариями.
  3. Легитимация: ваше согласие
  4. Передача данных: данные не будут переданы третьим лицам, кроме как по закону.
  5. Хранение данных: база данных, размещенная в Occentus Networks (ЕС)
  6. Права: в любое время вы можете ограничить, восстановить и удалить свою информацию.

  1.   2p2 сказал

    Будьте более откровенными. Пишите меньше и сосредотачивайтесь на главном

    1.    КрисADR сказал

      Привет, спасибо за комментарий.

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

      привет

      1.    анонимный сказал

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

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

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

    2.    анонимный сказал

      Я думаю то же самое.

      1.    КрисADR сказал

        Большое спасибо вам обоим !! Конечно, трудно понять, как достичь целевой аудитории, когда правда состоит в том, что количество людей с продвинутым уровнем программирования, которые читают эти статьи, невелико (по крайней мере, это можно сделать вывод на основе комментариев).

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

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

        привет

  2.   Марио сказал

    Откуда вы могли узнать больше по этому поводу? Любая рекомендованная книга?

    1.    КрисADR сказал

      Пример был взят из Руководства по Shellcoder, написанного Крисом Энли, Джоном Хисманом, Феликсом Линдером и Херардо Рихарте, но для того, чтобы сделать 64-битный перевод, мне пришлось изучить свою архитектуру, руководство разработчика Intel, тома 2 и 3 являются довольно надежный источник для этого. Также полезно прочитать документацию GDB, которая поставляется с командой 'info gdb'. Для изучения сборки и C есть много очень хороших книг, за исключением того, что книги по сборке немного устарели, поэтому есть пробел, который нужно заполнить другой. тип документации.

      Сам шеллкод в наши дни уже не так эффективен по разным причинам, но все еще интересно изучать новые методы.

      Надеюсь, это немного поможет 🙂 Приветствую

  3.   Франц сказал

    Хорошая статья, старый блог desdelinux снова возродился =)
    Когда вы говорите, что удаленная оболочка не так эффективна, вы имеете в виду контрмеры, разработанные для смягчения атак, они называют это наступательной безопасностью.
    Привет и так держать

    1.    КрисADR сказал

      Большое спасибо, Франц 🙂 очень добрые слова, на самом деле я имел в виду, что Shellcoding сегодня намного сложнее, чем то, что мы видим здесь. У нас есть ASLR (генератор случайных мест в памяти), защитник стека, различные меры и контрмеры, ограничивающие количество кодов операций, которые могут быть введены в программу, и это только начало.

      С уважением,

  4.   Свободное программное обеспечение сказал

    Здравствуйте, вы сделаете еще одну часть, расширяющую тему? Это интересно

    1.    КрисADR сказал

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

      Приветствую и спасибо, что поделились

  5.   кактус сказал

    Очень хорошо че! Вы публикуете отличные сообщения! Один вопрос: я начинаю заниматься ИТ-безопасностью с чтения книги под названием «Обеспечение безопасности с помощью пентеста». Рекомендуется ли эта книга? Как вы предлагаете мне начать выяснять эти проблемы?

    1.    КрисADR сказал

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

  6.   Эйцен сказал

    Эй.
    Большое спасибо за объяснение этой темы, а также за то, что для дополнительной информации у нас есть «Справочник Shellcoder». У меня уже есть отложенное чтение 😉