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を使って調査する全段階

リポジトリを見る
254年前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

-- coding: utf-8 --

  • polkit pkexec バグ

** 概要 このリポジトリは、CodeQLを使用してpolkit pkexecバグを調査します。 以下が含まれます:

  • データベース構築の手順
  • 生成されたデータベース
  • このバグを見つけるためのアプローチを示す一連のクエリ

完了済み:

  • 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レンジ分析ライブラリで調べることができます。

polkit/src/programs/pkexec.c 内の pkexec の main() 関数は、次の構造を持ちます: #+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を含むものに限定します。

確認するバージョン:

  • 2009年以降のすべてのPolkitバージョンが脆弱です。最初のバージョンは2009年5月 (コミット c8c3d83, "Add a pkexec(1) command") です。

  • [[https://lgtm.com/projects/g/freedesktop/polkit/ci/#ql][lgtmから]] /a/ データベースを取得できます。現在のもの <2022-02-11 Fri> は =...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の構築 codeqlデータベースを取得する前に、polkitのビルド環境が必要です。

ビルド用のオペレーティングシステムのオプション:

  • 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はpolkitではなくPolicyKitを使用します。
    • Ubuntu:
      • 18.04にもmozjs78がありません (mozjs52のみ)
      • 22.04にはmozjs78があります

Ubuntu 22.04は、ハードウェア、VM (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 注: Windowsとmacでdocker desktopを使用する場合、メモリとCPUの制限を そこで引き上げる必要があります。 設定後、コンテナの実行シーケンスは単純です: #+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
 #     etc.

 # ---------------------------------
 # codeqlセットアップ -- まだroot

 # 取得 -- 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

 # ---------------------------------
 # バージョン0.119のcodeqlデータベースをビルド
 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

 # ---------------------------------
 # パッチ適用済みバージョン (そして引き続きmozjs-78を使用) である
 # バージョンa2bf5c9cのcodeqlデータベースをビルド
 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

dbをホスト上の恒久的な場所にコピーします #+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][Build polkit and 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 declaration | 435 main (int argc, char *argv[]) | 436 { | ... init other var; | 534 for (n = 1; compare to argc | n < (guint) argc; update other var | n++) | 535 { | ... | 568 } | ... indexed read | 610 path = g_strdup (argv[n]); | ... | 629 if (path[0] != '/') | 630 { | ... | 632 s = g_find_program_in_path (path); | ... indexed write | 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 > 0= を持つ =n= を使用するすべての場所を正しく識別します。

このクエリは、脆弱なバージョンのコード =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

ツールをダウンロード