Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
codeql-workshop-cve-2021-21380 — Семинар по CodeQL, посвящённый CVE-2021-21380 | Kitploit
Инструменты/GitHubGitHub/rvermeulen/codeql-workshop-cve-2021-21380
Статический анализАнализ уязвимостейАнализ КодаВеб-безопасностьОбучение и ОбразованиеЛаборатории и Практика
GitHubrvermeulen/codeql-workshop-cve-2021-21380

codeql-workshop-cve-2021-21380

Семинар по CodeQL, посвящённый CVE-2021-21380

Популярное

Смотреть все →

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

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий
1251 год назадЕщё не проверено

Практикум по CodeQL для Java: поиск SQL-инъекции

В этом практикуме мы будем использовать синтаксические и семантические рассуждения, чтобы найти SQL-инъекцию в компоненте API рейтингов платформы XWiki, описанную в CVE-2021-21380.

Содержание

  • Практикум по CodeQL для Java: поиск SQL-инъекции
    • Содержание
    • Предварительные требования и инструкции по настройке
      • На вашем локальном компьютере
        • Установка
        • Шаги настройки
    • Практикум
      • Чему вы научитесь
      • Постановка задачи
      • Упражнения
        • Упражнение 1
        • Интермеццо 1
        • Упражнение 2
        • Упражнение 3
        • Интермеццо 2
        • Упражнение 4
        • Упражнение 5
        • Интермеццо 3
        • Упражнение 6
        • Упражнение 7
        • Упражнение 8
    • Что дальше?

Предварительные требования и инструкции по настройке

На вашем локальном компьютере

Пожалуйста, по возможности выполните этот раздел до начала практикума.

Установка

  • Установите Visual Studio Code.

  • Установите расширение CodeQL для Visual Studio Code.

  • Вам не нужно устанавливать CodeQL CLI: расширение сделает это за вас.

  • Клонируйте этот репозиторий:

    root@kitploit:~
    git clone https://github.com/advanced-security/codeql-workshop-cve-2021-21380.git
    

Шаги настройки

  • Импортируйте базу данных CodeQL, которая будет использоваться на практикуме:
    • Щёлкните правой кнопкой мыши по файлу xwiki-platform-CVE-2021-21380.zip в представлении Explorer и выберите команду CodeQL: Set Current Database.
    • База данных появится в представлении CodeQL databases, доступном через значок QL на панели действий (Activity Bar).
  • Установите зависимости для анализа Java-кода и для запуска тестов упражнений и решений.
    • В палитре команд (Cmd/Ctrl+Shift+P) найдите и выполните команду CodeQL: Install Pack Dependencies.
    • В верхней части окна VS Code введите github в поле, чтобы отфильтровать список.
    • Установите флажки рядом с cve-2021-21380-exercises, cve-2021-21380-exercises-tests, cve-2021-21380-solutions и cve-2021-21380-solutions-tests.
    • Нажмите OK/Enter.
  • Убедитесь, что всё работает должным образом, запустив тесты для решений.

Практикум

Чему вы научитесь

Практикум разделён на несколько упражнений, знакомящих с поддержкой языка QL для Java, и завершается итоговым запросом для поиска известной SQL-инъекции. В этих упражнениях вы научитесь:

  • Рассуждать о синтаксической информации.
  • Рассуждать о семантической информации.
  • Исследовать поддержку языка QL для Java для выражения паттернов.
  • Исследовать, как переиспользовать и расширять существующее моделирование.
  • Использовать несколько строительных блоков для составления итогового запроса.

Постановка задачи

На этом практикуме мы будем искать известные уязвимости SQL-инъекций в компоненте API рейтингов XWiki Platform. Такие уязвимости могут возникать в приложениях, когда информация, контролируемая внешним пользователем, попадает в код приложения, который небезопасно формирует SQL-запрос и выполняет его.

Известная SQL-инъекция, рассматриваемая на этом практикуме, описана в GHSA-79rg-7mv3-jrr5 в GitHub Advisory Database. Чтобы найти SQL-инъекцию и возможные варианты, мы перейдём к следующим подзадачам:

  • Определите источник недоверенной информации и смоделируйте его в QL.
  • Определите сток (sink) — метод, выполняющий SQL-запросы, — и смоделируйте его в QL.
  • Объедините приведённые выше решения, чтобы с помощью taint tracking определить, существует ли поток информации между источником и стоком.

Упражнения

В первых нескольких упражнениях мы будем рассуждать о синтаксической информации, используя абстрактное синтаксическое дерево (AST), чтобы определить:

  • метод, описанный в бюллетене безопасности, чтобы понять уязвимость;
  • параметры, содержащие недоверенные данные, — наши источники;
  • вызовы методов, принимающих SQL-выражения, — наши стоки.

Упражнение 1

Найдите все методы с именем getAverageRating и их объявляющий тип в программе, дополнив запрос exercise1.ql

Подсказки
  • Модуль java предоставляет класс Method для рассуждений о методах в программе.
  • Класс Method предоставляет предикаты-члены getName и hasName для рассуждений об имени метода.
  • Класс Method предоставляет член getDeclaringType для рассуждений о типе, который объявляет метод.

Решение можно найти в запросе exercise1.ql

Интермеццо 1

Решение упражнения 1 возвращает список методов. Некоторые из них определены в интерфейсе RatingsManager, а некоторые — в классах AbstractRatingsManager и RatingsScriptService.

На основе информации, возвращённой запросом, и документации по компонентам XWiki можно сделать вывод, что:

  • XWiki использует компонентно-ориентированную архитектуру, чтобы поддерживать расширения и настройки.
  • Уязвимый метод является частью компонента.
  • Компонент состоит из интерфейса, аннотированного Role, и реализации, аннотированной Component.
  • Компонент, расширяющий ScriptService, становится доступным вики-страницам через скрипты.

Упражнение 2

Найдите все классы, аннотированные аннотацией Component, дополнив запрос exercise2.ql. Обратите внимание, что полное имя типа аннотации — org.xwiki.component.annotation.Component.

Подсказки
  • К /доменному типу класса/ — пересечению его супертипов — можно обратиться с помощью ключевого слова this в /характеристическом предикате/.
  • Класс Class предоставляет метод getAnAnnotation для получения связанных аннотаций.
  • Класс Annotation предоставляет предикат-член getType для рассуждений о его типе.
  • Класс Type предоставляет предикаты-члены getName и hasName для рассуждений об имени типа.
  • Класс RefType, представляющий классы и интерфейсы, предоставляет предикаты-члены getQualifiedName и hasQualifiedName для рассуждений о полном имени ref-типа.

Решение можно найти в запросе exercise2.ql

Упражнение 3

Найдите все компоненты, которые реализуют интерфейс ScriptService, дополнив запрос excercise3.ql

Подсказки
  • Класс Class предоставляет предикат-член getASuperType для рассуждений о супертипах класса, то есть типах, которые он расширяет (extends) или реализует (implements).

Решение можно найти в запросе exercise3.ql

Интермеццо 2

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

В следующем упражнении мы исследуем и определим возможные стоки. Из результатов упражнения 1 можно сделать вывод, что одна из реализаций вызывает метод getAverageRatingFromQuery. С помощью похожего запроса мы можем найти объявляющие типы getAverageRatingFromQuery, что позволяет установить, что реализация в классе AbstractRatingsManager формирует SQL-выражение, передаваемое методу search.

Метод search реализован в зависимости, и поэтому его реализация недоступна. В следующих упражнениях мы будем использовать доступную информацию о типах, чтобы определить этот вызов метода search и его объявляющий тип.

Упражнение 4

Найдите все вызовы метода search и определите его объявляющий тип, дополнив запрос exercise4.ql

Подсказки
  • Тип MethodCall предоставляет нам средства для рассуждений о вызовах методов.
  • Тип MethodAcccess предоставляет предикат-член getMethod для рассуждений о цели вызова метода.

Решение можно найти в запросе exercise4.ql

Упражнение 5

Найдите все вызовы методов, объявленных интерфейсом XWikiStorageInterface (с полным именем com.xpn.xwiki.store.XWikiStoreInterface), дополнив запрос exercise5.ql

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

    root@kitploit:~
    import java
    
    from MethodCall ma
    where ma.getMethod.getDeclaringType() instanceof Interface
    select ma
    

Решение можно найти в запросе exercise5.ql

Интермеццо 3

На данный момент мы синтаксически описали возможные источники и стоки с помощью QL. Чтобы определить, передаётся ли информация между этими точками программы, мы проведём семантический анализ программы с использованием taint tracking. Стандартные библиотеки поддерживаемых нами языков предоставляют два механизма потоков данных:

  1. Модуль DataFlow поддерживает поток информации с сохранением значений.
  2. Модуль TaintTracking поддерживает поток информации даже при изменении значений.

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

На этом практикуме мы переиспользуем существующую конфигурацию taint tracking для SQL-инъекций и расширим её смоделированными источниками и стоками, чтобы найти SQL-инъекцию. Чтобы понять, как можно расширить конфигурацию, начнём с рассмотрения её определения ниже.

root@kitploit:~
class QueryInjectionFlowConfig extends TaintTracking::Configuration {
  QueryInjectionFlowConfig() { this = "SqlInjectionLib::QueryInjectionFlowConfig" }

  override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }

  override predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink }

  override predicate isSanitizer(DataFlow::Node node) {
    node.getType() instanceof PrimitiveType or
    node.getType() instanceof BoxedType or
    node.getType() instanceof NumberType
  }

  override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
    any(AdditionalQueryInjectionTaintStep s).step(node1, node2)
  }
}

Оба предиката — isSource и isSink — используемые конфигурацией для идентификации этих мест в программе, применяют ключевое слово instanceof, которое мы уже видели. Оба класса RemoteFlowSource и QueryInjectionSink являются abstract-классами. Это распространённый паттерн, который вы встретите в стандартных библиотеках; такой паттерн позволяет расширять множество значений, представляемых классами RemoteFlowSource и QueryInjectionSink.

QL class, расширяющий abstract class, не уточняет множество значений, представляемых суперклассом, а добавляет к суперклассу значения, представляемые подклассом. В следующих упражнениях мы реализуем эти подклассы и составим итоговый запрос.

Упражнение 6

Расширьте множество значений RemoteFlowSource параметрами публичных методов классов-компонентов, определённых в упражнении 3, дополнив запрос exercise6.ql.

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

    root@kitploit:~
    import java
    
    from MethodCall ma
    where ma.getMethod.getDeclaringType() instanceof Interface
    select ma
    

Решение можно найти в запросе exercise6.ql

Упражнение 7

Расширьте множество значений QueryInjectionSink аргументами вызовов методов интерфейса хранилища, определённого в упражнении 5, дополнив запрос exercise7.ql

Подсказки
  • Формула exists позволяет вводить временную переменную, о которой можно рассуждать в области действия exists.

    В следующем примере выражение exists используется для сокращения множества методов до вызываемых методов.

    root@kitploit:~
    from Method m
    where m.hasName("foo") and exists(MethodCall ma | ma.getMethod() = m)
    select m
    
  • Класс MethodCall предоставляет предикат-член getQualifer для рассуждений о квалификаторе обращения к методу.

Решение можно найти в запросе exercise7.ql

Упражнение 8

Объедините ваши решения из предыдущего упражнения в итоговое решение, дополнив запрос exercise8.ql.

Решение можно найти в запросе exercise8.ql

Что дальше?

  • Запрос включает модуль для моделирования частей платформы XWiki. Вынесите его в отдельный файл модуля и используйте в своём запросе.
  • Мы ограничили наш источник недоверенных данных компонентами ScriptService. Изучите, как расширить это другими источниками.
  • Что касается стока, мы ограничились прямым использованием XWikiStoreInterface. Расширьте сток, включив в него прямое использование реализаций интерфейса. Класс Class предоставляет предикат-член extendsOrImplements, а класс Method — предикат-член overridesOrInstantiates, которые могут помочь.
  • Используйте определение источников, чтобы найти интересные случаи использования недоверенных данных с помощью запроса 'Untrusted data passed to external API'.
Скачать инструмент
  • Откройте представление Testing и нажмите run tests (значок воспроизведения появляется при наведении на solutions) рядом с элементом solutions в дереве.