Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2020-13277 — CVE-2020-13277 標的環境: Gitlab 論理脆弱性 - 任意のユーザーが権限を超えてプライベートリポジトリにアクセス可能 | Kitploit
ツール/GitHubGitHub/exp-docs/cve-2020-13277
脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト学習と教育ラボと実践
GitHubexp-docs/cve-2020-13277

CVE-2020-13277

CVE-2020-13277 標的環境: Gitlab 論理脆弱性 - 任意のユーザーが権限を超えてプライベートリポジトリにアクセス可能

リポジトリを見る
2833年前Kitploit レビュー済み

人気

すべて見る →

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

すべてのツールを探索

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

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

CVE-2020-13277

CVE-2020-13277 学習環境: Gitlab 論理脆弱性 - 任意ユーザーによるプライベートリポジトリへの権限昇格アクセス


0x10 学習環境

0x20 ディレクトリ構成

root@kitploit:~
CVE-2020-13277
├── README.md ............... [この README 説明]
├── imgs .................... [README 説明用画像]
├── gitlab .................. [Gitlab コンテナのマウントディレクトリ]
│   ├── Dockerfile .......... [Gitlab の Docker ビルドファイル]
│   ├── config .............. [Gitlab 設定マウントディレクトリ]
│   ├── data ................ [Gitlab データマウントディレクトリ]
│   ├── logs ................ [Gitlab ログマウントディレクトリ]
│   ├── keys ................ [Gitlab ライセンス解除キー格納ディレクトリ]
│   └── runner .............. [Runner コンテナのマウントディレクトリ]
├── license ................. [ライセンス解除用コンテナビルドディレクトリ]
│   ├── Dockerfile .......... [License の Docker ビルドファイル]
│   └── license.rb .......... [ライセンス解除キー生成 Ruby スクリプト]
├── docker-compose.yml ...... [Docker ビルド設定]
├── keygen.ps1 .............. [Windows: ワンクリックライセンス解除キー生成]
├── keygen.sh ............... [Linux:   ワンクリックライセンス解除キー生成]
├── run.ps1 ................. [Windows: ワンクリック Gitlab 学習環境起動]
├── run.sh .................. [Linux:   ワンクリック Gitlab 学習環境起動]
├── register.ps1 ............ [Windows: ワンクリック Runner 登録]
├── register.sh ............. [Linux:   ワンクリック Runner 登録]
├── stop.ps1 ................ [Windows: ワンクリック Gitlab 学習環境停止]
└── stop.sh ................. [Linux:   ワンクリック Gitlab 学習環境停止]

0x30 事前説明

学習環境 Docker Image バージョン選択の理由

この脆弱性は主に Mirror Repository - リポジトリのミラー同期バックアップ機能を利用します。

Mirror の同期方向には次の2種類があります:

  • Pull:指定した Repository の内容を現在の Repository にプルする
  • Push:現在の Repository の内容を指定した Repository にプッシュする

この脆弱性で利用するのは Pull 方向の Mirror Repository です

Gitlab には CE(コミュニティ無料版)と EE(エンタープライズ有料版)の2種類があり、Gitlab 公式も この脆弱性は CE と EE の以下のバージョンに影響すると発表しています:

  • >=10.6, <12.9.10
  • >=12.10, <12.10.11
  • >=13.0, <13.0.6

しかし、これらのバージョンの Gitlab Docker Image がすべて学習環境の構築に使用できるわけではありません。その理由は:

  • CE 版の Mirror Repository は Push 方向のみ
  • EE 版は Core、Starter、Premium、Ultimate の4つのバージョンに細分化されています。公式の機能比較表によると、Core バージョンだけ Pull 方向が存在しません。そして Gitlab-EE の Docker Image はすべて Core バージョンのみ提供しています

言い換えると、Docker で学習環境を構築するには、Gitlab-EE 版を選択し、それをクラック(お金に余裕があればライセンスを購入しても構いません)して Mirror Repository - Pull 機能を有効化する必要があります。

しかし Gitlab-EE をクラックしても、10.x、12.x、13.x のいずれであっても、Mirror Repository - Pull の URL にローカルパスが含まれていると、Import url is blocked: Requests to localhost are not allowed というエラーが発生します。

0x40 学習環境構築

0x41 ビルド

  • ホストマシンに docker と docker-compose を事前にインストール
  • このリポジトリをクローン: git clone https://github.com/lyy289065406/CVE-2020-13277
  • クラック用鍵ペアを生成: ./keygen.sh または ./keygen.ps1
  • Gitlab をビルドして実行(80 ポートが占有されていないことを確認): ./run.sh または ./run.ps1
  • 約5分後、ブラウザから Gitlab にログイン:http://127.0.0.1 (初回ログイン時は管理者アカウント root のパスワードを再設定する必要があります)

0x42 クラック

鍵ペア生成時に公開鍵はすでに Gitlab コンテナのバックグラウンドに書き込まれていますが、秘密鍵をフロントエンドから Gitlab にアップロードしてクラックを完了する必要があります:

  • 鍵ペアは ./gitlab/keys/ ディレクトリに生成されます。その中の .gitlab-license の内容(秘密鍵)をコピーします
  • root ユーザーで http://127.0.0.1/admin/license/new ページを開きます
  • Enter license key を選択し、秘密鍵を貼り付け、Upload license ボタンをクリックするとクラック完了です

これで Mirror Repository - Pull 機能が有効になりました

0x43 発信設定

  • root ユーザーで http://127.0.0.1/admin/application_settings ページを開きます
  • 一番下の Outbound requests を見つけ、Allow requests to the local network from hooks and services にチェックを入れて保存します

これで Mirror Repository - Pull がローカル Repository のプルをサポートするようになりました

0x44 Runner の設定

  • root ユーザーで http://127.0.0.1/admin/runners ページを開きます
  • registration token を見つけてコピーします
  • Runner を登録: ./register.sh $TOKEN または ./register.ps1 $TOKEN

これで全ての Repository がこの Runner を使用して CI スクリプト(Pipeline Jobs)を実行できるようになりました

0x50 学習環境検証

検証手順は公式の Issue を参考にできますが、以下の検証手順ではこの学習環境に合わせて一部の手順を微調整しています

0x51 検証用アカウントの事前作成

root ユーザーで http://127.0.0.1/admin/users ページを開き、3つのアカウントを作成します:

  • victim: 被害者アカウント
  • attacker1: 攻撃者アカウント1
  • attacker2: 攻撃者アカウント2

アカウント作成時に初期パスワードは設定できません。Gitlab はデフォルトで設定された Email に初期パスワードを送信します。便宜上、Email は適当に入力し、まずアカウントを作成し、その後すぐにそのアカウントを編集して、root でそのアカウントの初期パスワードを設定できます(Email 経由は不要)

0x52 被害者リポジトリの事前作成

  • victim アカウントで Gitlab にログインします
  • 新しいリポジトリ New Project を作成:
    • Name: target
    • Visibility Level: Private
  • リポジトリ内に README.md ファイルを作成し、内容を mykey is abcxyz など適当に設定します

明らかに target は victim のプライベートリポジトリであり、我々の目標は脆弱性を利用してこのリポジトリの内容を取得することです

0x53 攻撃者の poc リポジトリ作成

  • attacker1 アカウントで Gitlab にログインします
  • 新しいリポジトリ New Project を作成:
    • Name: poc
    • Visibility Level: Public
  • リポジトリ内に .gitlab-ci.yml ファイルを作成し、内容は以下の通り:
root@kitploit:~
image: "ruby:2.6"

rspec:  
  script:  
    - git clone http://gitlab-ci-token:[email protected]/victim/target.git
    - cd target
    - ls -lah .  
    - cat README.md

【目的】 以降の操作で、victim が知らないうちに、自分の権限でこの CI スクリプトを実行させるため。

現在の学習環境では証明書が設定されていないため、http プロトコルを使用する必要があります。また 172.168.30.2 は docker-compose.yml で Gitlab コンテナに割り当てられた IP です。この CI スクリプトは最終的に Runner 経由で実行されるため、現在の学習環境では Runner と Gitlab は同じコンテナではないため、Docker が割り当てた IP アドレスを使用する必要があります

0x53 攻撃者の poc ミラーリポジトリ作成

  • attacker2 アカウントで Gitlab にログインします
  • 新しいグループ New Group を作成:
    • Name: test
    • Visibility Level: Public
  • test グループ内に完全に空のリポジトリ New Project を作成:
    • Name: poc
    • Visibility Level: Public

ミラーリポジトリを設定 Settings => Repository => Pull from a remote repository:

  • Mirror repository: チェック
  • Git repository URL: http://GITLAB/attacker1/poc と入力
  • Password: (空欄のまま。Pull 元のリポジトリは Public なのでパスワード不要)
  • Trigger pipelines for mirror updates: チェック(ミラー同期時に CI スクリプトを実行)

設定が成功すると、30分ごとにソースリポジトリに変更がないかチェックし、変更があれば強制同期されます。

Git repository URL は先ほど作成した poc リポジトリを指しています。127.0.0.1 を使用しないのは、Pull がローカルリポジトリのプルを禁止しているためですが、DNS バイパスが可能です: GITLAB は docker-compose.yml で Gitlab コンテナに割り当てられた hostname で、デフォルトで /etc/hosts に設定されます。ホストマシンでは GITLAB を解決できませんが、コンテナ内では http://127.0.0.1/attacker1/poc にアクセスすることと同等です

0x54 ミラーリポジトリ poc の所有者を強制的に被害者に移す

  • 引き続き attacker2 アカウントを使用
  • http://127.0.0.1/groups/test/-/group_members ページを開き、test グループのユーザー管理
  • victim ユーザーをグループに追加:
    • Add new member to test: victim
    • Permissions: Owner
    • Expiration date: (空欄、無期限)
  • 右上のアカウントアイコンをクリック => Setting => Account => Delete account で現在のアカウント(attacker2)を削除

【目的】 test グループ内には victim と attacker2 の2人の Owner しかいません。attacker2 ユーザーが削除されると、test グループとその下のすべてのリポジトリの所有権は強制的に victim に移ります。現在 test グループには attacker1/poc からミラー同期された test/poc リポジトリがあるため、test/poc リポジトリが強制的に victim ユーザーに「養子縁組」されたことになります。

0x55 攻撃の実行

まず、現在の状況を整理します:

  • 攻撃者は強制的かつ密かに被害者 victim のために test/poc リポジトリを作成した
  • test/poc リポジトリの内容は attacker1/poc リポジトリからミラー同期されている(30分ごとに変更をチェックし、必要に応じて同期)
  • attacker1/poc リポジトリの内容は攻撃者が制御しており、CI スクリプト .gitlab-ci.yml も含む
  • test/poc リポジトリに Trigger pipelines for mirror updates が設定されているため、同期のたびに CI スクリプトが実行される
  • test/poc リポジトリの Owner は victim であるため、CI スクリプトは victim の権限で実行される

先ほど設定した CI スクリプト .gitlab-ci.yml の内容を振り返ると、この poc は Runner 内で victim の権限を使用して、その Private リポジトリ target のディレクトリ構造と README.md にアクセスしています:

root@kitploit:~
image: "ruby:2.6"

rspec:  
  script:  
    - git clone http://gitlab-ci-token:[email protected]/victim/target.git
    - cd target
    - ls -lah .  
    - cat README.md

その後、攻撃者は attacker1/poc リポジトリ内の重要でない内容を適宜変更するだけで、最悪の場合30分待てば、victim の権限で設定した CI スクリプトを実行させることができます。

攻撃者は Pipeline Jobs の実行結果に直接アクセスする権限はありませんが、スクリプトの出力先を調整する(例えば、リポジトリの内容を指定の Email や FTP サーバーに送信する)ことで、リポジトリコードを盗むことができます。

ツールをダウンロード

Admin area => Settings => Network => Outbound requests で Allow requests to the local network from hooks and services を設定するとローカル URL を構成できるようになりますが、ミラー同期時に 2:Fetching remote upstream failed: fatal: unable to access http://127.0.0.1/xxxx/: The requested URL returned error: 301 というエラーが発生します。つまり、Pull Remote Repository のみが利用可能です。

しかし幸いなことに、12.x と 13.x ではローカル URL の判定が非常に厳格ですが、10.x バージョンには回避策があります:Pull URL を構成するときに、ローカルで設定した DNS サービス名を指定することでバイパスできます。

以上から、最終的に gitlab-ee:10.6.0-ee.0 バージョンの Docker Image を使用してこの学習環境を構築する必要があります。

前述の説明からもわかるように、この脆弱性の利用条件はかなり厳しく、基本的に貧乏な人がこの脆弱性の影響を受けることはほとんどありません