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

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

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

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

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

Категории

Все категории
Loading categories
codeql-sample-polkit — Все этапы исследования polkit CVE-2021-4034 с помощью codeql | Kitploit
Инструменты/GitHubGitHub/hohn/codeql-sample-polkit
Статический анализАнализ уязвимостейАнализ КодаСтатьи и ИсследованияОбучение и Образование
GitHubhohn/codeql-sample-polkit

codeql-sample-polkit

Все этапы исследования polkit CVE-2021-4034 с помощью codeql

Репозиторий
24 лет назадЕщё не проверено

Популярное

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

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

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

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

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

-- coding: utf-8 --

  • Ошибка polkit pkexec

** Обзор В этом репозитории исследуется ошибка polkit pkexec с помощью CodeQL. Здесь есть

  • инструкции по сборке баз данных
  • результирующие базы данных
  • последовательность запросов, иллюстрирующая подход к поиску этой ошибки

Выполнено:

  • сборка исходников / базы данных polkit
  • codeql-запрос для уязвимого исходного кода
  • иллюстрация CFG

Ещё предстоит сделать:

  • улучшения codeql-запроса для обработки пропатченного исходного кода
  • инструкции для командной строки

** Ошибка Ошибка Polkit pkexec [[https://blog.qualys.com/vulnerabilities-threat-research/2022/01/25/pwnkit-local-privilege-escalation-vulnerability-discovered-in-polkits-pkexec-cve-2021-4034][(CVE-2021-4034)]] начинается с ошибки выхода за границы массива относительно argv и развивается дальше. Выход за границы — это то, что мы можем исследовать с помощью библиотеки анализа диапазонов codeql.

Функция main() в pkexec в polkit/src/programs/pkexec.c имеет структуру #+begin_src text 435 main (int argc, char *argv[]) 436 { ... 534 for (n = 1; n < (guint) argc; n++) 535 { ... 568 } ... 610 path = g_strdup (argv[n]); ... #+end_src

Основные идеи:

  • Использовать простой анализ диапазонов для argc.
  • Ограничить rhs / lhs выражений только теми, что связаны с argc.

Версии для проверки:

  • Все версии Polkit с 2009 года уязвимы; первая версия — май 2009 года (коммит c8c3d83, «Add a pkexec(1) command»).

  • мы можем получить /a/ базу данных [[https://lgtm.com/projects/g/freedesktop/polkit/ci/#ql][с lgtm]], текущая <2022-02-11 Пт> — =...srcVersion_a6bedfd...= но эта версия уже содержит патч polkit: #+BEGIN_SRC text commit a6bedfd09b7bba753de7a107dc471da0db801858 (origin/master, origin/HEAD, master) Author: Xi Ruoyao [email protected] Date: Thu Jan 27 10:16:32 2022 +0000

    root@kitploit:~
      jsauthority: port to mozjs-91
    

    commit a2bf5c9c83b6ae46cbd5c779d3055bff81ded683 Author: Jan Rybar [email protected] Date: Tue Jan 25 17:21:46 2022 +0000

    root@kitploit:~
      pkexec: local privilege escalation (CVE-2021-4034)
    

    #+END_SRC И мы видим, что проблема исправлена: #+BEGIN_SRC text commit a2bf5c9c83b6ae46cbd5c779d3055bff81ded683 Author: Jan Rybar [email protected] Date: Tue Jan 25 17:21:46 2022 +0000

    root@kitploit:~
      pkexec: local privilege escalation (CVE-2021-4034)
    

    diff --git a/src/programs/pkcheck.c b/src/programs/pkcheck.c index f1bb4e1..768525c 100644 --- a/src/programs/pkcheck.c +++ b/src/programs/pkcheck.c @@ -363,6 +363,11 @@ main (int argc, char *argv[]) local_agent_handle = NULL; ret = 126;

    • if (argc < 1)
    • {
    • root@kitploit:~
       exit(126);
      
    • }
    • /* Disable remote file access from GIO. */ setenv ("GIO_USE_VFS", "local", 1); #+END_SRC
  • Поэтому нам нужен [[https://gitlab.freedesktop.org/polkit/polkit.git][исходный код]] и сборка собственных баз данных: одна до патча, одна после.

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

** Сборка polkit и CodeQL DB Нам нужна среда сборки polkit, прежде чем мы сможем получить базу данных codeql.

Варианты операционных систем для сборки:

  • macOS стоит попробовать, но это становится сложным уже в начале. Использование =brew= для получения зависимостей работает до определённого момента, но зависимость =mozjs-78= — это конкретная версия spidermonkey, и собрать /её/ непрактично. #+BEGIN_SRC sh # autoconf... немного сложно на mac brew install autoconf automake libtool gtk-doc export PATH="/usr/local/opt/libtool/libexec/gnubin:$PATH" ./autogen.sh

    root@kitploit:~
    # Использовать meson?
    brew install meson ninja intltool glib gobject-introspection 
    

    #+END_SRC

  • Linux — это родная среда для polkit, но какая именно? Зависимость mozjs-78 — это конкретная версия spidermonkey; кроме того, polkit используется не всеми дистрибутивами:

    • Debian использует PolicyKit, а не polkit.
    • Ubuntu:
      • в 18.04 также отсутствует mozjs78 (только mozjs52)
      • в 22.04 есть mozjs78

Ubuntu 22.04 можно запустить несколькими способами: на оборудовании, в виртуальной машине (vmware, virtualbox, multipass и т. д.) или в docker-контейнере на другом хосте. Для этой задачи мы можем использовать Docker-контейнер и включить в него также инструменты командной строки codeql.

Определение контейнера находится в ./Dockerfiles, вот последовательность сборки: #+BEGIN_SRC shell # Базовый образ для настройки контейнера qlbuild docker pull ubuntu:jammy docker images docker run --cpus 4 -m 8GB -ti ubuntu:jammy

root@kitploit:~
 # Образ, который будет настроен
 docker build -t qlbuild .

#+END_SRC Примечание: при использовании docker desktop на Windows и Mac ограничения памяти и ЦП необходимо увеличить там. После этого последовательность запуска контейнера проста: #+BEGIN_SRC sh # Запуск как демона, чтобы он оставался активным даже при отключении. docker run -d -p 127.0.0.1:2020:22 --cpus 8 -m 16GB qlbuild

root@kitploit:~
 # И подключение
 ssh -p 2020 test@localhost

#+END_SRC

Сборка на Ubuntu 22.04 #+BEGIN_SRC sh # --------------------------------- # Настройка/установка системы, от root: echo "deb-src http://archive.ubuntu.com/ubuntu/ jammy main restricted" >> /etc/apt/sources.list apt-get update apt-get install -y zile build-essential git cmake
meson ninja-build
libmozjs-78-0 libmozjs-78-dev
libdbus-1-3 libdbus-1-dev apt-get build-dep -y policykit-1 apt install unzip

root@kitploit:~
 # Версия polkit a2bf5c9c также требует некоторых дополнительных пакетов
 apt install duktape duktape-dev
 # более старая версия meson в /usr/local/bin
 pip3 install meson==0.60.3
 # Или получить исходники и использовать их:
 #     wget https://github.com/mesonbuild/meson/archive/refs/tags/0.60.3.tar.gz
 #     tar zxf 0.60.3.tar.gz
 #     и т. д.

 # ---------------------------------
 # Настройка codeql -- всё ещё от root

 # grab -- загрузка и извлечение codeql cli и библиотеки
 # Использование: grab version url prefix
 grab() {
     version=$1; shift
     platform=$1; shift
     prefix=$1; shift
     mkdir -p $prefix/codeql-$version &&
         cd $prefix/codeql-$version || return

     # Получить cli
     wget "https://github.com/github/codeql-cli-binaries/releases/download/$version/codeql-$platform.zip"
     # Получить библиотеку
     wget "https://github.com/github/codeql/archive/refs/tags/codeql-cli/$version.zip"
     # Исправить атрибуты
     if [ `uname` = Darwin ] ; then
         xattr -c *.zip
     fi
     # Извлечь
     unzip -q codeql-$platform.zip
     unzip -q $version.zip
     # Переименовать каталог библиотеки для VS Code
     mv codeql-codeql-cli-$version/ ql
     # Удалить архивы
     rm codeql-$platform.zip
     rm $version.zip
 }    

 grab v2.7.6 linux64 /opt
 grab v2.6.3 linux64 /opt

 # ---------------------------------
 # От пользователя test:
 # Получить исходники polkit
 cd /tmp && git clone https://gitlab.freedesktop.org/polkit/polkit.git

 # Собрать версию 0.119
 cd /tmp/polkit
 git checkout 0.119 
 git clean -fxd

 meson setup builddir
 meson compile -C builddir

 find builddir -name pkexec -ls
 : 139269     76 -rwxr-xr-x   1 test     root        76696 Feb 12 03:06 builddir/src/programs/pkexec

 # ---------------------------------
 # Создать базу данных codeql для версии 0.119
 cd /tmp/polkit
 git checkout 0.119 
 git clean -fxd

 # Выполнить шаг настройки как обычно, без codeql
 cd /tmp/polkit && rm -fR builddir
 meson setup builddir

 # Выполнить шаг сборки под codeql
 export CODEQL=/opt/codeql-v2.7.6/codeql/codeql
 $CODEQL --version

 $CODEQL database create  --language=cpp -s . -j 8 -v \
         polkit-0.119.db \
         --command='meson compile -C builddir'

 # Дождаться
 # TRAP import complete (10.2s).
 # Successfully created database at /tmp/polkit/polkit-0.119.db.

 # И быстрая проверка, что pkexec был обнаружен:
 unzip -v polkit-0.119.db/src.zip |grep pkexec
 : 29713  Defl:N     8477  72% 2022-02-14 20:12 bb39f235  tmp/polkit/src/programs/pkexec.c

 # ---------------------------------
 # Создать базу данных codeql для версии a2bf5c9c, пропатченной версии (и всё ещё с
 # mozjs-78)
 cd /tmp/polkit
 git checkout a2bf5c9c 
 git clean -fxd

 # Выполнить шаг настройки как обычно, без codeql
 cd /tmp/polkit && rm -fR builddir
 /usr/local/bin/meson setup builddir

 # С meson 0.61 настройка завершается ошибкой
 #   actions/meson.build:3:5: ERROR: Function does not take positional arguments.
 # быстрый поиск приводит к
 #   https://lore.kernel.org/all/20220111222135.693a88f2@windsurf/T/
 # а оттуда к
 #   [1/1] package/gobject-introspection: bump to version 1.70.0

 # Выполнить шаг сборки под codeql
 export CODEQL=/opt/codeql-v2.7.6/codeql/codeql
 $CODEQL --version

 $CODEQL database create  --language=cpp -s . -j 8 -v \
         polkit-a2bf5c9c.db \
         --command='/usr/local/bin/meson compile -C builddir'

 # Дождаться
 # TRAP import complete (7.2s).
 # Successfully created database at /tmp/polkit/polkit-a2bf5c9c.db.

 # И быстрая проверка, что pkexec был обнаружен:
 unzip -v polkit-a2bf5c9c.db/src.zip |grep pkexec
 :   30136  Defl:N     8647  71% 2022-02-14 21:27 6af18604  tmp/polkit/src/programs/pkexec.c

#+END_SRC

Скопировать базу данных в постоянное место на хосте #+BEGIN_SRC sh # Скопировать из контейнера mkdir -p ~/local/polkit && cd ~/local/polkit scp -rq -P 2020 test@localhost:/tmp/polkit/polkit-0.119.db . scp -rq -P 2020 test@localhost:/tmp/polkit/polkit-a2bf5c9c.db .

root@kitploit:~
 # Сохранить оригиналы
 zip -rq polkit-0.119.zip polkit-0.119.db 
 zip -rq polkit-a2bf5c9c.zip polkit-a2bf5c9c.db

#+END_SRC

TODO

Отправить контейнер для повторного использования, см. [[https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#pushing-container-images][документацию]]

#+BEGIN_SRC sh

docker login ghcr.io -u USERNAME

docker push ghcr.io/OWNER/IMAGE_NAME:latest

docker pull ghcr.io/OWNER/IMAGE_NAME

#+END_SRC

Далее — настройка для разработки запросов.

** Настройка разработки запросов Запросы можно исследовать с помощью codeql cli самостоятельно или с помощью codeql cli + плагина VS Code. В обоих случаях установите cli (см. функцию =grab()= выше) и извлеките базы данных из [[./db]] или соберите их, как описано в [[*Build polkit and codeql db][Сборка polkit и codeql db]].

Далее мы предполагаем следующую структуру каталогов для баз данных: #+BEGIN_SRC text . ├── polkit-0.119.db │   ├── codeql-database.yml │   ├── db-cpp │   ├── log │   └── src.zip ├── polkit-0.119.zip ├── polkit-a2bf5c9c.db │   ├── codeql-database.yml │   ├── db-cpp │   ├── log │   └── src.zip └── polkit-a2bf5c9c.zip #+END_SRC

** Запрос Запрос разрабатывается поэтапно в [[./argv-out-of-bounds-*.ql]].

Первые шаги в [[./argv-out-of-bounds-0.ql]] используют AST и ссылки на переменные, чтобы сузить результаты до известных частей проблемы, как показано ниже.

#+BEGIN_SRC text объявление | 435 main (int argc, char *argv[]) | 436 { | ... инициализация др. переменной; | 534 for (n = 1; сравнение с argc | n < (guint) argc; обновление др. переменной | n++) | 535 { | ... | 568 } | ... чтение по индексу | 610 path = g_strdup (argv[n]); | ... | 629 if (path[0] != '/') | 630 { | ... | 632 s = g_find_program_in_path (path); | ... запись по индексу | 639 argv[n] = path = s; | 640 } #+END_SRC

Исследование значений начинается в [[./argv-out-of-bounds-1.ql]] с попыткой использования библиотеки =SimpleRangeAnalysis= через #+begin_src javascript lowerBound(cmp.getLeftOperand().getFullyConverted()), "left lower bound", lowerBound(cmp.getRightOperand().getFullyConverted()), "right lower bound" #+end_src Границы корректны для типов, но слишком общие — они включают возможные результаты итераций. Нас интересуют только начальные границы, которые статически определимы, то есть те, что существуют до начала любых итераций.

Иными словами, это не общая задача анализа потоков данных; мы хотим проверить только распространение начальных значений по определённым путям выполнения. Цикл =for= усложняет это, как и операции внутри него.

Нам действительно нужно увидеть пути выполнения, которые полностью обходят цикл. Это делается в последних частях [[./argv-out-of-bounds-1.ql]] с использованием =SsaDefinition=.

Запрос [[./argv-out-of-bounds-2.ql]] очищает исследование из [[./argv-out-of-bounds-1.ql]] и корректно определяет все места использования =n= с известным значением индекса =n > 0=.

Этот запрос выдаёт результаты на уязвимой версии кода, =polkit-0.119.db=. Далее его нужно проверить и улучшить, чтобы он не выдавал ничего на пропатченной версии, =polkit-a2bf5c9c.db=.

TODO

** Запуск запроса из командной строки

#+BEGIN_SRC sh

# Запустить запрос против базы данных, сохраняя результаты в подкаталог results/

# каталога базы данных для дальнейшей обработки.

codeql database run-queries -j8 --ram=20000 -- $DB $SRCDIR/example.ql

# Получить общую информацию о доступных результатах

codeql bqrs info --format=text -- $DB/results/cpp-sample/example.bqrs

# Форматировать результаты с помощью bqrs decode.

codeql bqrs decode --output=cpp-simple.csv \

--format=csv --entities=all -- \

$DB/results/cpp-sample/example.bqrs

#+END_SRC

Скачать инструмент