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

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

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

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

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

Категории

Все категории
Loading categories
codeql-workshop — Сделайте первые шаги в CodeQL для Python, написав запрос для поиска CVE-2024-32022 | Kitploit
Инструменты/GitHubGitHub/sylwia-budzynska/codeql-workshop
Статический анализАнализ уязвимостейАнализ КодаОбучение и ОбразованиеПодобранные РесурсыУчебные Маршруты и КурсыЛаборатории и Практика
GitHubsylwia-budzynska/codeql-workshop

codeql-workshop

Сделайте первые шаги в CodeQL для Python, написав запрос для поиска CVE-2024-32022

Репозиторий
1281 месяц назадЕщё не проверено

Популярное

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

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

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

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

Смотреть все инструменты →
Поделиться

Поиск уязвимостей с помощью CodeQL

Оригинальный воркшоп от Sylwia Budzynska

Предварительные требования • Ресурсы • Воркшоп

  • Для кого это: Инженеры по безопасности, исследователи безопасности, разработчики.
  • Что вы узнаете: Как использовать CodeQL для исследования кода и поиска проблем безопасности.
  • Что вы создадите: Создадите запрос CodeQL на основе уведомления безопасности для поиска внедрения команд.

📣 Предварительные требования

Вы можете выбрать один из двух вариантов для выполнения упражнений воркшопа:

  • Вариант A: Локальная установка (Использование VS Code - CodeQL выполняется локально на вашей машине)
  • Вариант B: GitHub Codespace (Использование браузера или VS Code - CodeQL выполняется удаленно на Linux-based GitHub Codespace в облаке)

Вариант A: Локальная установка

Используйте локальную установку CodeQL для работы над упражнениями воркшопа.

Предварительные требования

  • Visual Studio Code (VS Code) и git, установленные на вашей локальной машине.

Инструкции

  1. Установите расширение VS Code для CodeQL
  2. Запустите в терминале:```bash git clone https://github.com/sylwia-budzynska/codeql-workshop cd codeql-workshop git submodule init git submodule update --recursive --depth 1

Download CodeQL databases

curl -L -O "https://github.com/sylwia-budzynska/codeql-workshop/releases/download/v1/test-app-db.zip" curl -L -O "https://github.com/sylwia-budzynska/codeql-workshop/releases/download/v1/kohya_ss-db.zip"

root@kitploit:~
3. В VS Code: Файл -> **Открыть рабочую область из файла…** `vscode-codeql-starter.code-workspace`
4. Продолжите с [Выбор базы данных CodeQL](#select-codeql-database)
5. Затем [Проверьте вашу установку](#test-your-installation)

### Вариант B: GitHub Codespace

Используйте удаленный GitHub Codespace для выполнения упражнений воркшопа.

#### Предварительные требования

* Учетная запись GitHub ([зарегистрироваться](https://github.com/) бесплатно)
* Браузер (можно выполнить весь воркшоп в браузере — это самый быстрый способ установки) или [Visual Studio Code](https://code.visualstudio.com/download) (VS Code) с установленным расширением [GitHub Codespaces](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces) на вашем локальном компьютере.

Примечание. Первые 120 часов на ядро использования Codespace бесплатны в месяц; мы используем codespace с 4 ядрами для этого воркшопа, так как 4 ядра — это текущий максимум для бесплатных учетных записей. (Если у вас есть Pro-аккаунт, рекомендуем переключиться на машину с 8 ядрами.)

#### Инструкции

1. Войдите в свою учетную запись [GitHub](https://github.com/login)
2. Перейдите в репозиторий https://github.com/sylwia-budzynska/codeql-workshop
3. Нажмите «Code» -> «Codespaces»
4. Нажмите на знак плюса (+), чтобы создать новый codespace.

<img src="https://assets.kitploit.com/production/public/readmes/33098/c86e537f9e7891fb6bdb5da727cae5b6ad0b2c9ac94f67854d48296f2dad89cb.png"  width="439" alt="Скриншот: Создание Codespace, нажмите плюс">

VS Code запустится в вашем браузере, и будет построен удаленный Codespace. Это может занять несколько минут.
Если вам предложат открыть рабочую область `vscode-codeql-starter.code-workspace`, нажмите «Open Workspace».

5. Если вы хотите использовать VS Code локально, нажмите кнопку с тремя линиями в левом верхнем углу и выберите «Open VS Code Desktop». Эта опция может появиться не сразу, подождите до нескольких минут.

<img src="https://assets.kitploit.com/production/public/readmes/33098/f2c8c2fe6da80142344b17c208da31a23c3fa68a3917a124f0e2f7871b6a20f7.png" width="300" alt="Скриншот: Нажмите кнопку с тремя линиями и выберите Open in VS Code Desktop">

6. Продолжите с [Выбор базы данных CodeQL](#select-codeql-database)
7. Затем [Проверьте вашу установку](#test-your-installation)

Вы можете просматривать ваши codespace на странице [github.com/codespaces](https://github.com/codespaces). Codespace автоматически отключится через несколько часов бездействия, но чтобы не расходовать дополнительные часы из 120 бесплатных, не забудьте после воркшопа перейти в [github.com/codespaces](https://github.com/codespaces) > три точки > «Stop codespace».

#### Устранение неполадок при установке

Если вы видите ошибки, такие как:
* `Failed to run query: Could not resolve library path for [..]`
* `Could not resolve module [..]`
* `Could not resolve type [..]`

Скорее всего, вы забыли клонировать git-подмодули (а именно репозиторий ql). Чтобы исправить это, выполните `git submodule init && git submodule update --recursive`.

### Выбор базы данных CodeQL

1. Убедитесь, что в VS Code открыта рабочая область `vscode-codeql-starter.code-workspace`.
2. Щелкните значок «QL» на левой панели вкладок, чтобы перейти к представлению CodeQL.
3. Щелкните «Choose Database from Archive» и выберите файл `test-app-db.zip` в корне репозитория.
   Примечание. На этом этапе в VSCode может появиться всплывающее сообщение с предложением установить CodeQL CLI. Согласитесь на установку — это должно решить проблему. После завершения установки CLI вы сможете завершить выбор базы данных.
   <img src="https://assets.kitploit.com/production/public/readmes/33098/65cc5790b8b49113623bc9a9b34a1be61575b05bea2428c46f83115e2271148b.png"  alt="Скриншот: Сообщение об ошибке VSCode о CodeQL">
   <img src="https://assets.kitploit.com/production/public/readmes/33098/c3bf9c304d9c1f6199f591c9bcbf6e446ee4f5388ab209e30887326698129f84.png"  alt="Скриншот: VSCode устанавливает CodeQL CLI">

### Проверка установки

#### Предварительные требования

Убедитесь, что в представлении CodeQL выбрана ранее выбранная база данных CodeQL. (Нажмите «Select», если это не так.)

Когда база данных выбрана, это должно выглядеть так (обратите внимание на галочку):

<img src="https://assets.kitploit.com/production/public/readmes/33098/fee6e47c0d9b0754c7ac9e29e2f0b3a721093aa5ce882615b3839a99f4862506.png"  alt="Скриншот: База данных CodeQL выбрана">

#### Инструкции

1. В VS Code: перейдите в папку рабочей области: `codeql-custom-queries-python`
2. Создайте новый файл `test.ql`
3. Добавьте следующее содержимое: `select "Hello World!"`
4. Сохраните файл, щелкните правой кнопкой мыши в области файла и выберите «CodeQL: Run Query on Selected Database»
5. Должна открыться новая вкладка с результатом «Hello World!»

## :books: Ресурсы

- [Учебники по QL](https://codeql.github.com/docs/writing-codeql-queries/ql-tutorials/)
- [Руководство по языку CodeQL для Python](https://codeql.github.com/docs/codeql-language-guides/codeql-for-python/)
- [Документация CodeQL](https://codeql.github.com/docs/)
- [Справочник по языку QL](https://codeql.github.com/docs/ql-language-reference/)
- [Библиотека CodeQL для Python](https://codeql.github.com/codeql-standard-libraries/python/)
- [Базовый запрос для кода Python](https://codeql.github.com/docs/codeql-language-guides/basic-query-for-python-code/)
- [Классы QL](https://codeql.github.com/docs/ql-language-reference/types/#classes)
- [CodeQL от нуля до героя, часть 1: основы статического анализа для исследования уязвимостей](https://github.blog/2023-03-31-codeql-zero-to-hero-part-1-the-fundamentals-of-static-analysis-for-vulnerability-research/)
- [CodeQL от нуля до героя, часть 2: начало работы с CodeQL](https://github.blog/2023-06-15-codeql-zero-to-hero-part-2-getting-started-with-codeql/)
- [CodeQL от нуля до героя, часть 3: исследование безопасности](https://github.blog/2024-04-29-codeql-zero-to-hero-part-3-security-research-with-codeql/)
- [CodeQL от нуля до героя, часть 4: пример с Gradio](https://github.blog/security/vulnerability-research/codeql-zero-to-hero-part-4-gradio-framework-case-study/)
- [CodeQL от нуля до героя, часть 5: отладка запросов](https://github.blog/security/vulnerability-research/codeql-zero-to-hero-part-5-debugging-queries/)

## Воркшоп

Добро пожаловать на воркшоп «Поиск уязвимостей с помощью CodeQL»!

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

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

Воркшоп разделен на несколько разделов, каждый из которых состоит из упражнений, ведущих к финальному запросу.
Для каждого раздела мы предоставим *рекомендации*, которые помогут вам выполнить упражнение, давая ссылки на классы QL и предикаты-члены, которые можно использовать.

### Обзор

В этом воркшопе мы будем искать известные *уязвимости внедрения команд* в [kohya_ss](https://securitylab.github.com/advisories/GHSL-2024-019_GHSL-2024-024_kohya_ss/). Такие уязвимости возникают, когда информация, контролируемая пользователем, попадает в код приложения, который небезопасно формирует команду и выполняет ее. Команда, небезопасно сформированная из пользовательского ввода, может быть переписана для выполнения непредусмотренных действий, таких как произвольное выполнение команд, раскрытие конфиденциальной информации.

Внедрения команд, обсуждаемые в этом воркшопе: [CVE-2024-32022, CVE-2024-32026, CVE-2024-32025, CVE-2024-32027](https://securitylab.github.com/advisories/GHSL-2024-019_GHSL-2024-024_kohya_ss/).

## Теория

### Источники и стоки

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

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

Пользовательский ввод обычно поступает из точек входа в приложение — источника данных. К ним относятся параметры в HTTP-методах, таких как GET и POST, а также аргументы командной строки программы. Они называются «**источниками**».

Продолжая наш пример с внедрением команд, примером опасной функции, которую не следует вызывать с несанитизированными недоверенными данными, может быть `os.system`. Эти опасные функции называются «**стоками**». Обратите внимание: то, что функция потенциально опасна, не означает, что она сразу является эксплуатируемой уязвимостью и должна быть удалена. Многие стоки имеют способы безопасного использования. Другими примерами стоков, которые не следует использовать с пользовательским вводом, являются MySQLCursor.execute() из библиотеки MySQLdb в Python (вызывает SQL-инъекцию) или встроенная функция Python eval(), которая вычисляет произвольные выражения (вызывает внедрение кода).

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

<img src="https://assets.kitploit.com/production/public/readmes/33098/ff60a1649737805a71bd27710209dba66203a77159cc72ae435c165353e56491.png">

### Шпаргалка по CodeQL
Основная структура запроса```codeql
import python

from <type> <name> 		//variables used in the query

where <conditions for variables>

select <output>			//results, referring to the variables

Найти ссылки на os.system() вызовы```codeql import python import semmle.python.ApiGraphs

from API::CallNode call where call = API::moduleImport("os") .getMember("system") .getACall() select call, "Call to os.system"

root@kitploit:~
Найти ссылки на вызовы `os.system()`, на этот раз с предикатом```codeql
predicate isOsSystemSink(API::CallNode call) {
	call = API::moduleImport("os")
	.getMember("system").getACall()
  }


from API::CallNode call
where isOsSystemSink(call)
select call, "Call to os.system"

Найдите ссылки на вызовы os.system(), на этот раз с классом```codeql class OsSystemSink extends API::CallNode { OsSystemSink() { this = API::moduleImport("os") .getMember("system").getACall() } }

from API::CallNode call where call instanceof OsSystemSink select call, "Call to os.system"

root@kitploit:~
Найдите ссылки на вызовы `os.system()`, на этот раз с классом. Укажите, что тип, с которого мы начинаем — это `OsSystemSink`.```codeql
class OsSystemSink extends API::CallNode {
  OsSystemSink() {
    this = API::moduleImport("os")
    .getMember("system").getACall()
	}
}


from OsSystemSink s
select s, "Call to os.system"

Workshop part I - test database

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

В первой части занятия мы напишем запросы CodeQL для поиска источников и стоков, вызовов os.system, в намеренно уязвимой кодовой базе. Во второй части занятия мы будем использовать эти запросы для поиска внедрения команд от источника к стоку в программном обеспечении с открытым исходным кодом — kohya_ss v22.6.1.

С помощью запроса CodeQL, который мы напишем, мы сможем находить такие внедрения команд, как показано ниже.

Пользовательский ввод поступает из интерактивного компонента Gradio (веб-фреймворка для приложений машинного обучения) gr.Textbox в пункте #1. gr.Button.click в пункте #2 привязывает нажатие кнопки к функции execute_cmd, передавая значения из folder. Это означает, что при нажатии gr.Button folder передаётся в execute_cmd, где folder конкатенируется в команду и выполняется в системе через вызов os.system в пункте #3.```python import gradio as gr import os

def execute_cmd(folder): cmd = f"python caption.py --dir={folder}" os.system(cmd) #3

with gr.Blocks() as demo: gr.Markdown("Create caption files for images in a directory") with gr.Row(): folder = gr.Textbox(placeholder="Directory to caption") #1 logs = gr.Checkbox(label="Add verbose logs")

root@kitploit:~
btn = gr.Button("Run")
btn.click(fn=execute_cmd, inputs=[folder]) #2

if name == "main": demo.launch(debug=True)

root@kitploit:~
Вы также заметите другой пример внедрения команд в мастерской, в приложении, созданном с использованием фреймворка `Flask`. В этом случае пользовательский ввод поступает из GET-параметра запроса Flask (популярный веб-фреймворк на Python), который сохраняется в переменной `files` (см. #1). Затем `files` передаётся в вызов `os.system` и конкатенируется с `ls`, что приводит к внедрению команд (см. #2).```python
import os
from flask import Flask, request

app = Flask(__name__)

@app.route("/command1")
def command_injection1():
    files = request.args.get('files', '')   #1
    os.system("ls " + files)                #2

Мы начнем с постепенного построения запроса для обнаружения вызовов os.system, а затем запроса для источников.

1. Поиск всех вызовов функций из внешних библиотек

Мы можем найти все вызовы функций из внешних библиотек (не определенных в кодовой базе) с помощью модуля ApiGraphs CodeQL.

Используйте шаблон ниже:```codeql import python import semmle.python.ApiGraphs

from //TODO: fill me in. Start typing API:: and press Ctrl+Space to see a list of available types. Name your variable call select //TODO: fill me in

root@kitploit:~
Щелкните правой кнопкой мыши в области файла и выберите "CodeQL: Run Query on Selected Database", чтобы запустить запрос.

<details>
<summary>Рекомендации</summary>

- В предложении `from` начните с `API::` и нажмите `Ctrl + Space`, чтобы увидеть типы, доступные в модуле API Graphs.
- Вызов представлен типом `API::CallNode`. Создайте переменную с этим типом и именем `call`.
- Чтобы ограничить результаты только вызовами в корневой папке приложения (называемой `test-app`), добавьте предложение ` where` с условием `where call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*")`.

</details>
<details>
<summary>Решение</summary>```codeql
import python
import semmle.python.ApiGraphs

from API::CallNode call
where call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*")
select call, "A call"

2. Найти все вызовы os.system

Руководство
  • В предложении from создайте переменную call типа API::CallNode.
  • В предложении where используйте оператор равенства =, чтобы утверждать, что call равен вызовам os.system. Используйте логический оператор and для указания нескольких условий.
  • Чтобы найти узлы, соответствующие библиотеке os, используйте метод API::moduleImport() с аргументом os. Чтобы получить доступ к функции system библиотеки os, используйте предикат getMember() на . Наконец, получите любые вызовы с помощью предиката .

3. Найти первые аргументы в вызовах os.system

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

Руководство
  • Заполните шаблон:```codeql import python import semmle.python.ApiGraphs

from API::CallNode call where call = API::moduleImport("os").getMember("system").getACall() and call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*") select call // TODO: fill me in. Type a dot . right after call and press Ctrl+Space to see available predicates.

root@kitploit:~
</details>
<details>
<summary>Решение</summary>```codeql
import python
import semmle.python.ApiGraphs

from API::CallNode call
where call = API::moduleImport("os").getMember("system").getACall() and
call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*")
select call.getArg(0), "First argument of an `os.system` call"

4. Преобразуйте ваш запрос, находящий вызовы os.system, в класс CodeQL

классы в CodeQL могут использоваться для инкапсуляции переиспользуемых частей логики. Классы представляют собой отдельные наборы значений и могут также содержать операции (известные как предикаты-члены), специфичные для этого набора значений. Вы уже видели множество примеров классов CodeQL (API::CallNode) и предикатов-членов (getLocation() и т.д.)

Руководство
  • Чтобы создать новый тип, мы должны расширить супертип, здесь API::CallNode, дать ему имя и характеристический предикат с тем же именем. Назовем наш класс OsSystemSink.

Заполните шаблон:```codeql import python import semmle.python.ApiGraphs

class OsSystemSink extends API::CallNode { OsSystemSink() { //TODO: fill me in } }

from API::CallNode call where // TODO: fill me in and call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*") select call.getArg(0), "Call to os.system"

root@kitploit:~
- Используйте магическое ключевое слово `this`, которое ссылается на экземпляры узлов вызовов (`API::CallNode`s), которые мы описываем в классе. Используйте `this` для поиска вызовов `os.system` так же, как вы делали ранее с `API::moduleImport`.
- Измените предложение `where`, чтобы ваша переменная `call` была `instanceof` вашего нового класса `OsSystemSink`.

</details>
<details>
<summary>Решение</summary>```codeql
import python
import semmle.python.ApiGraphs

class OsSystemSink extends API::CallNode {
	OsSystemSink() {
		this = API::moduleImport("os").getMember("system").getACall()
	}
}


from API::CallNode call
where call instanceof OsSystemSink
and call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*")
select call.getArg(0), "First argument of an `os.system` call"

5. Найдите все источники с классом RemoteFlowSource

Теперь перейдём к поиску источников.

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

Рекомендации
  • Импортируйте semmle.python.dataflow.new.RemoteFlowSources, чтобы использовать тип RemoteFlowSource.
  • В части from нажмите Ctrl + Space, чтобы увидеть все доступные типы.

Заполните шаблон:```codeql import python import semmle.python.dataflow.new.RemoteFlowSources

from //TODO: fill me in where //TODO: fill me in select //TODO: fill me in

root@kitploit:~
</details>
<details>
<summary>Решение</summary>```codeql
import python
import semmle.python.dataflow.new.RemoteFlowSources

from RemoteFlowSource rfs
where rfs.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*")
select rfs

Часть II воркшопа - поиск внедрений команд в kohya_ss

Kohya_ss это графический интерфейс для скриптов Stable Diffusion от Kohya для обучения, генерации и утилит для Stable Diffusion.

Во второй части воркшопа мы переключим кодовую базу, по которой выполняем запросы, на kohya_ss и найдем потоки данных от источников к стокам в kohya_ss, которые приводят к внедрению команд: CVE-2024-32022, CVE-2024-32026, CVE-2024-32025, CVE-2024-32027

Перед началом следующего упражнения:

  • Перейдите на вкладку CodeQL в VSCode, раздел Databases, нажмите «Choose Database from Archive» и выберите файл kohya_ss-db.zip в корне репозитория. Должна появиться галочка. Это выберет базу данных CodeQL, с которой вы работаете.

6. Найдите потоки данных от источников к первому аргументу вызовов os.system

Руководство
  • Используйте шаблон ниже и обратите внимание:
  • в предикате isSource уточните переменную source, чтобы она имела тип RemoteFlowSource.
  • в предикате isSink уточните переменную sink, чтобы она была первым аргументом вызова os.system. Сделайте это с помощью механизма exists и вашего класса OsSystemSink.
    • exists — это механизм для введения временных переменных с ограниченной областью видимости. Вы можете думать о них как о собственных from-where-select. В данном случае используйте exists, чтобы ввести переменную call с типом OsSystemSink, а затем уточните sink как первый аргумент этого .```codeql /**

Бонусные упражнения, если останется время

7. Запрос к кодовой базе со стандартными запросами

Запросы CodeQL для Python находятся в папке ql/python/ql/src/Security. Уже существуют запросы для наиболее популярных уязвимостей: SQL-инъекции, внедрение команд, внедрение кода и т.д. Запустите запрос на SQL-инъекцию (CWE-089) на тестовой базе данных (вам нужно будет выбрать её в CodeQL extension > Databases. Обратите внимание на галочку).

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

8. Запуск собственных запросов с помощью многовариантного анализа репозиториев (MRVA)

Мощь CodeQL заключается в возможности повторно использовать запросы и модели CodeQL для запуска их на любой кодовой базе на том же языке. Мы можем запускать запросы CodeQL на до 1000 репозиториев одновременно с помощью многовариантного анализа репозиториев (MRVA). Проекты должны быть размещены на GitHub.

💡 Это очень интересно для исследователей безопасности — если вы нашли потенциально опасный сток или источник, вы можете добавить его в CodeQL (или запустить как запрос) и провести исследование на тысяче репозиториев одновременно.

  • Следуйте инструкциям по настройке в документации.
  • Обратите внимание, что MRVA запускается с помощью рабочих процессов GitHub Actions. Рабочие процессы Actions бесплатны для публичных репозиториев и платны для частных.
  • После настройки щёлкните правой кнопкой мыши и выберите "CodeQL: Run Variant Analysis"

Заключительные замечания

Сегодня вы узнали, как исследовать кодовую базу с помощью CodeQL и как выполнять CodeQL в собственном рабочем процессе исследования безопасности.

Ознакомьтесь с этими ресурсами, если хотите узнать больше о:

  • статическом анализе и о том, как он работает:
    • CodeQL от нуля до героя, часть 1: основы статического анализа для исследования уязвимостей.
  • основах использования CodeQL и его языка запросов:
    • CodeQL от нуля до героя, часть 2: начало работы с CodeQL.
  • исследовании безопасности с помощью CodeQL:
    • CodeQL от нуля до героя, часть 3: исследование безопасности.
  • Как моделировать CodeQL для веб-фреймворка на примере Gradio
    • CodeQL от нуля до героя, часть 4: пример Gradio.
  • Отладка причин, по которым запрос может не работать:
    • CodeQL от нуля до героя, часть 5: отладка запросов

Если в итоге вы найдёте уязвимость с помощью CodeQL, не стесняйтесь добавлять её в Зал славы CodeQL.

Скачать инструмент
API::moduleImport()
os.system
getACall()

Заполните шаблон:```codeql import python import semmle.python.ApiGraphs

from API::CallNode call where call //TODO: fill me in and call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*") select call, "Call to os.system"

root@kitploit:~
</details>
<details>
<summary>Решение</summary>```codeql
import python
import semmle.python.ApiGraphs

from API::CallNode call
where call = API::moduleImport("os").getMember("system").getACall() and
call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*")
select call, "Call to `os.system`"
call
  • @name Command injection in os.system sink
  • @kind path-problem
  • @id codeql-ws/dataflow-query */

import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import semmle.python.ApiGraphs import MyFlow::PathGraph import semmle.python.dataflow.new.RemoteFlowSources

//TODO: add previous class definition here

private module MyConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { // TODO: fill me in }

predicate isSink(DataFlow::Node sink) { // TODO: fill me in. Use the exists mechanism exists( | sink = ... ) } }

module MyFlow = TaintTracking::Global;

from MyFlow::PathNode source, MyFlow::PathNode sink where MyFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Command injection"

root@kitploit:~
</details>
<details>
<summary>Решение</summary>```codeql
/**
 * @name Command injection in os.system sink
 * @kind path-problem
 * @id codeql-ws/dataflow-query
 */

import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.ApiGraphs
import semmle.python.dataflow.new.RemoteFlowSources
import MyFlow::PathGraph

class OsSystemSink extends API::CallNode {
	OsSystemSink() {
		this = API::moduleImport("os").getMember("system").getACall()
	}
}

private module MyConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
	source instanceof RemoteFlowSource
}

predicate isSink(DataFlow::Node sink) {
	exists(OsSystemSink call |
	sink = call.getArg(0)
	)
}
}

module MyFlow = TaintTracking::Global<MyConfig>;

from MyFlow::PathNode source, MyFlow::PathNode sink
where MyFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "Command injection"