Введение

Эта статья будет интересным и более глубоким погружением в то, что я недавно обнаружил в очень широко используемой библиотеке C++ под названием PcapPlusPlus. Я подробно расскажу о том, как я пришел к этому и почему именно это опасно, а также закончу разговором о безопасности и операционной безопасности.

Что такое PcapPlusPlus?

PcapPlusPlus, на который я буду ссылаться как на (PCPP), представляет собой библиотеку для C++ для разбора пакетов, отправки и изменения пакетов, а также для загрузки ссылок и других вещей из этого списка. Разработчики этого проекта очень хорошо поработали, и это широко используемая библиотека с кучей руководств и очень хорошей репутацией. Он поддерживает системы Windows, MacOSX и даже Linux, где я сам в основном его и использую. Обычно я не использую сторонние пакеты, если они не от друзей, моих собственных или организации, на которую я могу положиться при просмотре кода. PCPP — это не то, на что я действительно потратил время, чтобы изучить его код только для нескольких вещей, таких как параметры уровня FTP и параметры уровня TCP / ETHER. В целом, до сих пор PCPP была отличной библиотекой для использования, и вы можете делать с ней много вещей, таких как создание мостов, и даже делать столько же, сколько создавать или изменять свои собственные пакеты с пользовательскими слоями и отправлять их на определенный хост или место. В целом, PCPP — это библиотека, которую следует использовать, если у них нет достаточного опыта программирования собственных библиотек для C++. Однако единственное, что я должен сказать, это то, что, к сожалению, код написан на C++11, что означает, что большая часть современного кода не будет работать в C++20, поэтому большая часть вашего кода должна будет использовать C++11. стили для работы. Я пытался вручную переключать флаги для компиляции и того, что я не делал, но если вы переключите версию C ++ без значительных изменений, вы на самом деле не сможете скомпилировать код на современном языке.

Опасности использования старых версий C++

В настоящее время версия C++, на которой мы работаем, — C++20, скоро выйдет C++23. Одна вещь, которую я и многие другие разработчики ненавидим в C++, это то, что язык постоянно обновляется. Разработчики за эти годы очень устали от этого и просто решили оставить свой код в рамках определенной версии C++, фактически не утруждая себя его обновлением, из-за количества изменений, которые разработчики C++ вносят, но на самом деле это не дает разработчикам веса. . На самом деле большинство обновлений в C++ состоят из обновлений безопасности / устаревания, которые заменяются новыми функциями и инструментами, а не полностью обновляют язык. Почему именно это может быть плохо? Причина, по которой это может быть плохо, заключается в том, что если люди или разработчики решат использовать более старую версию C++, может быть уязвимость в функции C++, которую, как поняли разработчики, необходимо устареть и заменить чем-то новым или обновленным. Когда разработчики сохраняют свой код в более старой версии, они, скорее всего, столкнутся с чем-то, что уязвимо или не будет работать так, как они предполагали, что приведет к появлению новых уязвимостей и ошибок в коде. В том смысле, что вы создаете базу данных, сервер, клиент, API, dll или даже простую программу, использующую эти устаревшие значения, может привести к их эксплуатации. Выдержите его через процесс инъекции DLL (динамическая инъекция библиотеки ссылок) или взлом API и бинарная эксплуатация через BOF. Как сказано в моей последней статье о git hub Advanced и Secure CXX, показанной ниже.



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

Говоря о взаимодействии, которое у меня было с PCPP

Недавно я создавал проект под названием frizz, который использует библиотеку google gopacket и библиотеку C++ PCPP для захвата пакетов и отображения данных в локальном веб-интерфейсе, который будет собирать все данные онлайн. Я не нашел способа получить все данные HTTP в файле pcap и воссоздать изображение с помощью go-packet, поэтому я взял код C++20, который у меня уже был, и хотел проанализировать уровни HTTP с помощью PCPP. Вот демонстрация проекта ниже и то, что он выведет, когда вы запустите захват пакетов (вкладка панели инструментов)

Используя C++ и библиотеку Go, в некотором смысле файлы JSON будут создаваться с данными анализируемого пакета, затем Go будет анализировать файлы JSON и загружать их в предварительно сгенерированные поля/шаблоны HTML/CSS/JS. Я использовал вкладку примеров PCPP, чтобы узнать больше о библиотеке перехвата пакетов для C++, и в одном из руководств у них был анализатор пакетов, который выводил данные HTTP, показанные здесь. Ниже будет ссылка gists, которая покажет вам много кода C++, напрямую скопированного из файла кода, ссылка на него находится в примечании в самом верху.

Для тех, кто не знаком, позвольте мне разбить этот код и дать ему описание. Таким образом, эта программа берет первый пакет в файле захвата пакетов из чего-то вроде tcp-dump, анализирует первый пакет и выводит данные. Но почему только первый пакет? Большинство людей, которые хотят анализировать файлы pcap, хотят выводить все пакеты, а не только один конкретный. Код начинается с определения функции с именем

‘std::string getProtocolTypeAsString(pcpp::ProtocolType protocolType)’

Эта функция просто возвращает тип протокола анализируемого пакета или уровень, это TCP или это HTTP, Ethernet или так далее. В этой функции нет ничего плохого, она работает нормально, как и функция printTcpFlags, которая возвращает или печатает флаг TCP уровня TCP. Эта функция проверяет все от SYN до FIN. двигаясь дальше, есть другие функции с именами printTcpOptionType и printHttpMethod, которые, если их имена недостаточно очевидны, печатают параметры TCP и метод HTTP, который сводится к NOP, GET, POST и так далее. В основной функции программа сначала открывает файл и проверяет, не было ли что-то не так, или ридер вернулся пустым, если да, чтобы вернуть ошибку. Он запускает еще одну проверку, чтобы увидеть, может ли ридер открыться и не вернуть ли ошибку. При этом код определяет переменную с именем «RawPacket», которая является самым первым пакетом во всем файле pcap. В этом случае мы уже знаем, что наша основная функция будет анализировать ТОЛЬКО один пакет. Двигаясь дальше, мы видим, что считыватель закрывается с помощью вызова close, а затем передается в синтаксический анализатор уровней, который ниже проверяет наличие различных уровней, таких как Ethernet, tcp и т. д. оттуда. Но давайте сосредоточимся на разделе HTTP, который показан в самом конце основной функции, показанной ниже.

Когда мы запустим эту программу, она распечатает все данные, которые не нашли проблем, но что, если мы используем CPP для циклического просмотра каждого отдельного пакета в этом файле и анализа слоев по отдельности в каждой функции. Если бы мы разделили приведенный выше код на его собственную функцию и получили аргумент в виде пакета для функции, которую обработчик HTTP будет анализировать, когда мы НЕ анализируем только один пакет, мы получим то, что известно как ошибка сегментации. Прежде чем я продолжу, я хочу, чтобы вы заметили, что я использую свой собственный захват пакетов из tcp-dump, который будет проанализирован, где 3 пакета в файл, здесь виден слой HTTP.

Вот программа, которую я использую для анализа пакетов и передачи их в функцию HTTP. Для статьи, чтобы воссоздать ошибку сегментации, я решил выбрать захват пакета, в котором НЕ было определенного поля, и я взял много кода из учебника.

Короче говоря, эта программа отличается от другой ненамного, и БОЛЬШАЯ часть кода может быть пересмотрена, но сейчас это не главное. Мы берем тот же код из учебника, но разница в том, что с помощью ридера мы проверяем, пуст ли он, чем вызываем функцию Packet_INIT, которая определяет необработанный пакет и анализирует слои, в то время как чтение вызывает функцию под функцией разбора слоев, показанной ниже.

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

Эта функция выше берет точный код из учебника PCPP по разбору пакетов и распечатывает данные, это то, на что мы в основном будем обращать внимание. Поэтому, когда я запустил программу, я получил, как было сказано ранее, ошибку сегментации. Но где именно в программе происходит ошибка сегментации? Скорее в функции DATA_HTTP, так как именно здесь происходит сбой. Я буду самым раздражающим человеком в мире, и под каждым оператором для печати значения, такого как URI, мы будем использовать оператор печати для определения ошибки сегментации. Ниже приведен новый рефакторинг кода.

Когда мы запускаем программу, мы получаем следующий вывод

Мы видим, что до 5, но после 4 мы получаем ошибку сегментации, поэтому очевидно, что это не функция getUrl() или поле пользовательского агента. Теперь мы знаем, что ошибка сегментации возникает, когда мы пробуем поле HTTP cookie или, скорее, пытаемся вывести его. В процессе разработки я изначально думал, что это проблема с моим кодом, поэтому я попробовал следующее:

  • Проверка того, было ли значение NULL перед его выводом, и если это так, возвращает код ошибки, результат = ошибка сегментации
  • Сохранение вывода функции в переменной, а затем проверка ее NULL, результат = ошибка сегментации
  • Хранение переменной где-то еще, анализ ее индивидуально с использованием уникальных классов и расширенных функций, чтобы обойти ее, результат = ошибка сегментации.
  • Сохранение результата в массиве, но я даже не думал, что это сработает, ведь прогнозируемый результат = ошибка сегментации.
  • Индивидуальный анализ значения cookie и поля заголовка, результат = ошибка сегментации.

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

Я не буду подробно объяснять это, но это очень похоже на то, что, как я думал, происходит в программе на C++. Итак, я попытался предварительно заполнить его или, возможно, использовать захват пакета, в котором было поле cookie, но я, конечно, ожидал, что получил ошибку сегментации. Итак, после нескольких часов отладки и обратной трассировки я наконец решил использовать GDB/GEF.

Использование GDB для понимания того, что происходит в коде

Код, который мы сделали, выдает ошибку в нескольких функциях, если мы уберем значение, ошибка сегментации исчезнет, ​​но я все еще хочу исследовать и по-настоящему понять, почему это происходит или почему именно это вообще существует. Если вы не знаете, что такое GDB, GDB называют отладчиком GNU. Это утилита интерфейса командной строки для отладки и поиска программ, таких как двоичные файлы или процессы, такие как тот, который мы собираемся запустить. Год назад GDB выпустила GEF, который, по сути, является расширением GDB. Нам больше не нужно использовать модули для дампа стека, обратной трассировки или вызовов самих себя, поскольку GEF, когда мы запускаем программу и происходит сбой, делает все это за нас. Итак, давайте загрузим GDB и посмотрим, что произойдет. Чтобы запустить или запустить сеанс GDB, выполните следующую команду.

gdb executeable_file

В нашем случае мы используем команду gdb ./main, поскольку это имя нашего ELF-файла (исполняемого файла Linux), который был создан для 64-битной системы Linux x86. Мы переходим к дальнейшему запуску программы, и, поскольку нам нужен аргумент командной строки с программой, мы используем команду run, за которой следует путь к файлу нашего файла захвата пакетов, например.

Это программа, в которой она запускается, сразу же мы видим ошибку сегментации программы, как только она запускается. Давайте посмотрим вперед. На этом изображении мы видим множество проблем с GEF и GDB с его выводом и синтаксическим анализом, а также с его ошибками и адресами памяти. GEF сообщает нам, что ошибка сегментации произошла по адресу памяти.

0x00005555555ac555

убедитесь, что вы помните этот адрес памяти.

Если мы посмотрим дальше на регистры, которые GEF сбрасывает, мы увидим следующее.

В этом изображении GEF выводит все, что произошло до сбоя или что было близко до того, как программа, мы также видим вывод. Обратим внимание на регистры сбоку, из всех регистров мы видим красный регистр. Хмммм, этот регистр выглядит или на самом деле является тем же самым регистром, в котором произошел сбой программы, что привело к нарушению сегмента, что теперь мы можем на 100% проверить, что программа завершилась сбоем в следующей функции.

Мы можем увидеть это снова, когда посмотрим на дамп реестра выше. Я привел еще один пример этого ниже

если мы посмотрим на дамп регистра 15 в строке 9 сути, мы увидим, что мы получили ошибку, и заметим из точно такого же адреса памяти / регистра, что он точно такой же, как тот, который выделен красным на изображении выше? Мы продолжаем видеть его основное местоположение, что означает, что он находится по адресу

0x00005555555ac555.

Как было сказано выше, теперь у нас есть доказательство того, что наша функция или программа дала сбой в функции DATA_HTTP в строке 53, где основной поток отправляет результат переменной на выход. Теперь давайте углубимся в этот аспект. Давайте посмотрим, что GDB отослал выше, если вам нужен краткий обзор, вот изображение того, что он отослал на консоль при сбое программы.

Как вы можете заметить, мы видим несколько ошибок, одна из которых связана с тем, что наша программа получила так называемое нарушение сегмента. Я не проходил через это раньше, так что я должен сейчас. Короче говоря, нарушение сегмента в программе — это состояние отказа, которое происходит в этой памяти. Когда программа получает нарушение сегмента, это означает, что программа фактически превысила свои пределы и попыталась получить доступ к части памяти, в которую она НЕ должна была входить. Когда мы используем GDB, мы, очевидно, снова получаем ошибку сегментации, это могло быть связано с кучей вещей, которые мы сейчас рассмотрим. Под ошибкой сегментации мы видим 4 вещи, которые сразу бросаются в глаза. Первый — это адрес памяти, который показывает функцию, которая вызывает константу со значением this = 0x0 (NULL), которая показывает, что наше значение из этой функции или результат был NULL. Затем мы получаем странную ошибку, она говорит нам, что в строке 619 кода, который мы запускаем с оператором if, произошла ошибка, вызвавшая утечку памяти, но что? Почему? В нашей программе нет даже строки 619!??? Вы правы, это не так, здесь мы углубляемся в кроличью нору понимания источника этой уязвимости в коде библиотеки PCPP, которую мы используем. Если мы перейдем к файлу в их репо, который виден здесь



мы видим следующее

Вау! Это именно то, что GDB сказал нам, что все идет не так, как указано в операторе if.

если (m_ValueOffsetInMessage != -1)

что-то пошло не так в этой функции. Если вы новичок в C++ и мало о нем знаете, то здесь все подходит. Когда компилятор вызывает код или решает скомпилировать любую библиотеку или любой файл, включенный в эту программу, даже стандартные библиотечные файлы, такие как stdlib.h, весь код в этом файле каким-то образом смешивается в один гигантский основной файл. Поэтому, когда мы включаем файл TextBasedProtocol.cpp, код пишется напрямую и компилируется с кодом, который мы написали. Теперь, что именно здесь происходит? Они в основном принимают значение, которое является целочисленным значением (в этом случае мы можем предположить, что это смещение из-за имени, обычно смещения, как правило, uint (целое число без знака). Таким образом, они в основном говорят, что если смещение в сообщении делает НЕ равно -1, чтобы затем присвоить результат переменной типа string символу, а также получить и отформатировать данные, как показано ниже.

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

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

Если вы не читали о MSVSC или не читали статью, которую я написал, то я кое-что объясню. Причина, по которой большинство разработчиков используют MSVSC (Microsoft Visual Studio Code), заключается в том, что вы можете без флагов выбирать параметры компиляции, такие как отладка или выпуск, x86 x64, а также выбирать параметры и наборы компоновщика, а также наборы символов. В каком-то смысле это то, что они сделали, они указывают версию C++ через

std=c++11

затем они указывают режим для выпуска (вместо отладки они используют выпуск)

O2

если вы не знаете режим O2 в релизе, это максимизировать скорость при компиляции программы.

Затем они также используют флаг -g в соответствии с G++ для

«Параметры, начинающиеся с -g, -f, -m, -O, -W или —param, автоматически
передаются различным подпроцессам, вызываемым g++. “

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

Я изменил название с tutorial на main только потому, что так было проще.

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

Глядя дальше в исходный код

Когда мы запускали GDB, была целая сторона GDB, о которой я даже не говорил и не объяснял. У меня осталось одно подозрение. Когда GDB выдал ошибку и что у программы была ошибка сегментации, я заметил, что прямо под ошибкой сегментации GDB выдал нам ошибку, которая предупреждала об устаревании, используемом для escape-последовательностей. Я подумал, что это странно, вторая ошибка сегментации, как если бы ошибка сегментации была настолько большой, что закончилась доступом к разделу исходного кода GDB, когда он был запущен или GDB анализировал последовательности. Ниже приведен журнал предупреждения, которое появляется из python при запуске GEF после возникновения ошибки сегментации.

Я подумал, что это СУПЕР странно, у нас есть два предупреждения и одна фатальная ошибка из исходного кода в обеих программах, может это тоже ошибка разработчика? Моей первой мыслью, помимо утечки памяти, было позволить мне перейти к этому файлу, чтобы увидеть, есть ли проблема или символ, учитывая набор символов, который python не распознает как используемый, или, возможно, он просто устарел, как сказано в предупреждении.

Давайте посмотрим на исходный код GEF и перейдем к строке 2488, где python выдал нам предупреждение об устаревании. Когда мы переходим к строке кода или области строки 2488, мы видим следующее определение.

Это очень простая функция, она считывает cstring из памяти с адресом и максимальной длиной с кодировкой, установленной на none в параметрах. Затем выполняется простая линейная проверка, чтобы убедиться, что кодировка не существует, тогда для кодировки установлено значение unicode_escape. Под этим мы видим переменную char_ptr, которая из моего предыдущего опыта означает CHARACTER POINTER, который является типом поиска как char для указателя. Затем переменная длины описывается или определяется с помощью функции min() в python, чтобы вернуть наименьший элемент в итерируемом объекте или, другими словами, найти наименьший элемент в пределах двух или более параметров, в нашем случае это ADDRESS | (DEFAULT_PAGE_SIZE-1) MAX_LENGTH+1.

как только это будет сделано с этой частью, он переходит к оператору try, чтобы объявить, что у него есть оператор try, и присвоить переменной с именем res функцию значения gdb, а затем вызвать для удаления результатов из этой функции. Внутри этого оператора try создается исключение из системы ошибок GDB, и если произошла ошибка, он пытается сделать res переменной, которая содержит результат чтения адреса памяти поверх его длины с вызовом для декодирования с использованием символа установить UTF-8. Подожди секунду! мы только что прошли, где произошла ошибка, которую вывел GDB, он сказал нам, что в строке 2488 произошла ошибка, строка 2488 содержит следующую строку кода.

Здесь происходит ошибка, но почему предупреждение об устаревании? может ли это быть python, вызывающим ошибку из-за синтаксического анализа некоторых символов, или переполнение буфера стало настолько большим, что это привело к переполнению программы? На данный момент я могу с уверенностью сказать, что нарушение/переполнение сегмента было НАСТОЛЬКО большим, что оно привело к утечке в другой процесс. Причина, по которой я говорю это, заключается в том, что когда программа исчерпывает количество ресурсов, которые ей даются, тогда что-то вроде malloc (функция, которая позволяет C/C++ динамически выделять память из кучи) переполнит другие процессы и приведет к сбою другого процесса или вызвать ошибки в этом процессе, такие как ошибка GEF / GDB, показанная выше с устаревшим. Наша ошибка становится все глубже и глубже! И это хорошо! Если мы посмотрим дальше в исходный код библиотеки PCPP, то обнаружим множество ошибок в коде, и с течением времени я увидел, что разработчикам пришлось исправить МНОГО уязвимостей в коде, включая переполнение буфера стека, утечки памяти и так далее. от других людей. если мы посмотрим на журнал BLAME того же файла TextBasedProtocol.cpp, то увидим следующее.

Если вы внимательно посмотрите на изображения, вы увидите, что многие исправления ошибок связаны с проблемами, о которых сообщали люди, из-за чего-то вроде переполнения буфера или ошибок сегментации в целом. Это тот, который НЕ был исправлен на момент написания (Пн, 12 сентября 2022 г., 13:27:45). Это означает, что если кто-то вроде меня или других проведет разведку с помощью чего-то вроде GDB, мы, вероятно, сможем найти множество уязвимостей, застрявших внутри программы.

Конечная нота

Это был долгий путь, и каждый день (у меня было всего два дня на это) я, кажется, сталкивался с большим количеством ошибок сегментации в библиотеке кода. Я всегда был большим сторонником кибербезопасности, если вы знаете меня лично, и вы программист, или я учил вас, вы знаете, что я ВСЕГДА говорил вам следить за своим кодом и действительно понимать, что вы делаете на самом низком уровне, особенно когда вы пишете или продаете код людям, даже используя его против людей. Если вы являетесь экспертом по кибербезопасности, который также имеет опыт разработки эксплойтов, или даже тем, кто только начинает, вы всегда должны точно знать, что делает функция, особенно если вы пишете на таких языках, как C, Assembly, C++, Web Assembly. , Rust, Fortran, pascal, haskell, scala и даже до чего-то вроде brainfu** — это хорошая идея знать, когда что-то пойдет не так. Если вы являетесь начинающим разработчиком, я также настоятельно рекомендую вам начать использовать GDB. Использование GDB очень помогло мне при обратном проектировании приложений, таких как игры, и использовании двоичных файлов, таких как мои собственные, или даже при выполнении разведки и отладки моих программ, когда что-то идет не так. Я много программирую на языке программирования Go, и при работе с потоками и даже с захватом пакетов я буду делать много ошибок, которые вызывают ошибки SIGSEV, AKA SIGNAL SEGMENT VIOLATION, что то же самое, что мы только что получили, единственная разница в том, что GDB помог мне исправить то, что было происходит и как это исправить в смысле.

Краткое содержание

Код постоянно работает в нашей жизни, каждый день, когда мы открываем наши телефоны, процесс выполняется, если не сотни, каждый раз, когда мы слушаем музыку или создаем Bluetooth или даже посещаем веб-сайт, одновременно выполняется более миллиардов строк кода. время, чтобы помочь вам каждый день. Как разработчики и эксперты по кибербезопасности, мы должны поощрять людей и разработчиков перестать лениться и делать все проще. Как человек, который был в этой области в течение достаточно долгого времени, я не могу сосчитать, сколько раз я видел, как люди говорят use if statements they are easier, но не совсем понимают, почему вы должны или не должны использовать операторы if в больших или малых количествах вместо таких вещей, как карты и словари. Ленивость — это не ответ, не выбирайте язык программирования, потому что он облегчает вам работу, и не полагайтесь на то, что говорят другие люди. Как писатель, я хочу, чтобы ВЫ, читатели, обратили внимание на следующие несколько вещей.

  • Никогда не доверяйте стороннему программному обеспечению или библиотекам кода: прежде чем вы начнете программировать или если вы заметите для себя, что НИКОГДА сразу не доверяйте чужому коду, это серьезная проблема, которую я вижу в сообществе, проведите свое исследование и поймите, как кодовая база фактически был разработан. Например — этот проект PCPP, который я действительно не понимал, что происходит внутри, он работает хорошо, но в нем ОЧЕНЬ много уязвимостей, чтобы я хотел сохранить или продолжить использовать, что означает, что я сам мог бы построить форк и изменить весь проект с учетом того, что я знаю, что код будет работать, и хороший процесс, который поможет мне предотвратить выпуск уязвимых версий. Не каждый код является благочестивым из-за количества людей, которые его используют, то же самое происходит и с языками программирования. Просто потому, что многие люди говорят вам писать на языке программирования, или просто потому, что многие люди пишут на языке программирования, не означает, что вы должны делать то же самое, не каждый язык предназначен для всех, и не каждый человек должен использовать этот язык. или не следует использовать его, если это имеет смысл.
  • Всегда будьте в поиске уязвимостей: в современном мире я вижу, как появляется много уязвимостей, и из-за этого я смотрю внутрь своего кода. Хороший способ узнать, что вы можете обойти это, — анализировать код с помощью анализаторов кода так же, как вы сканируете веб-сайт с уязвимостями, слишком много разработчиков не тестируют свой код, что подводит меня к следующему пункту.
  • ПРОВЕРЬТЕ СВОЙ КОД: Если вы разработчик, пишущий приложения, такие как инфраструктура безопасности, предназначенная для обеспечения безопасности пользователей, автоматизации или даже создания базы данных, вы хотите убедиться, что ваш код защищен. если вы используете какой-либо из следующих языков ….. C++, C, C#, F, F#, Crystal, Fortran, ALGOL. АЛГОЛ 60. АЛГОЛ 68. МАЛЕНЬКИЙ Ada, Carbon, CLEO, COBOL, D, Go, Erlang, Kotlin, Scala, Java, Haxe, Haskell и любой другой язык программирования, который компилируется ЗАПУСКАЙТЕ СВОЙ КОД ЧЕРЕЗ ОТЛАДЧИКИ! Бинарные уязвимости могут проявляться во многих формах и часто являются наиболее опасными для системы, такими как бинарная эксплуатация, внедрение DLL, внедрение PROC и так далее. Использование отладчиков, таких как GDB/GEF, отладчик Windows на MSVSC, или других форм больших комплектов и отладчиков или даже сред обратного проектирования, является хорошей идеей. Это не только дает вам больше опыта работы с вашим кодом, но вы также получаете возможность тестировать свои приложения, чтобы увидеть, уязвимы ли они, и каждый раз узнавать что-то новое.
  • Поймите код, который вы пишете: при программировании вы часто оказываетесь в цикле написания кода, поэтому вы можете пойти в Google, скопировать и вставить свою ошибку и посмотреть на переполнение стека, чтобы узнать, были ли у кого-то проблемы. Иногда вы даже можете скопировать и вставить код, который люди считают правильным, чтобы он соответствовал вашей кодовой базе, это УЖАСНАЯ практика, прекратите это, просто прекратите. Причина, по которой это плохая практика, заключается в том, что тот же принцип never trust the user or trust user input. Здесь следует то же самое, никогда не доверяйте людям писать безопасный и применимый код, даже я обнаружил, что копирую и вставляю код, чтобы он соответствовал моей основе кода, что в итоге привело к более работа и больше отладки и больше уязвимостей. В сообществах программирования реверс-инжиниринга вы узнаете, что ВСЕГДА пишите свой код, а не просто копируйте и вставляйте код, потому что он выполняет свою работу, это РАЗРУШИТ ваш код и вашу рабочую этику. Всегда полезно посмотреть на примеры кода людей на что-то вроде переполнения стека, но, как я видел в прошлом, это создает уязвимости. Однажды я взял код из поста о переполнении стека и добавил его в свой проект, как вы знаете segment violation . Поэтому, пожалуйста, НЕ берите код, не понимая, что он на самом деле делает, понимайте и по-настоящему анализируйте код и смотрите на функции или вызовы, которые он выполняет, должен ли он использовать системный вызов или должен использовать что-то еще для вызова вызовов?

Это в основном подводит итог этой статье! Я, конечно же, надеюсь, что вы прошли со мной эту кроличью нору и смогли понять основы безопасности с помощью C++ и то, как уязвимости проявляются во всех формах и размерах. Также я надеюсь, что как программист вы стремитесь к тому, чтобы ваш код был безопасным, иначе я мог бы просто прийти за вами LOL. Мы все устаем от программирования и иногда прибегаем к плохим практикам. Я не такой, я иногда делаю то же самое. Однако со временем я и даже некоторые из моих друзей поняли, что лучшее, что вы можете сделать, это просто немного отойти от кода, потому что чем больше вы разочарованы, тем больше ошибок и предупреждений вы вызываете, тем больше ошибок вы вызываете, что, конечно же, как известно, чем больше ошибок, тем больше уязвимостей.