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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2024-27198 — CVE-2024-27198の詳細分析:JetBrains TeamCityにおける認証バイパスがリモートコード実行につながる、コードレベルの説明とエクスプロイトデモを含む | Kitploit
ツール/GitHubGitHub/hpt-intern-task-submission/cve-2024-27198
脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト認証学習と教育
GitHubhpt-intern-task-submission/cve-2024-27198

CVE-2024-27198

CVE-2024-27198の詳細分析:JetBrains TeamCityにおける認証バイパスがリモートコード実行につながる、コードレベルの説明とエクスプロイトデモを含む

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

人気

すべて見る →

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

すべてのツールを探索

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

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

CVE-2024-27198: Jetbrain Teamcityの認証バイパスによりリモートコード実行が可能に

概要

TeamCityは、継続的インテグレーションおよびデプロイメントサーバであり、ビルド問題に関する継続的な単体テスト、コード品質分析、早期レポートを提供します。

この脆弱性は、攻撃者が認証されていない任意のエンドポイントにアクセスできるようにするライブラリに存在します。

コード分析

脆弱なコードは、directory to the lib内のweb-openapi.jarライブラリにあります。

クラスjetbrains.buildServer.controllers.BaseControllerがリクエストとレスポンスの処理を担当しますが、実装が不適切です。コードを見てみましょう:

root@kitploit:~
public abstract class BaseController extends AbstractController {
//////
public final ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {  
    try {  
        ModelAndView modelAndView = this.doHandle(request, response);  
        if (modelAndView != null) {  
            if (modelAndView.getView() instanceof RedirectView) {  
                modelAndView.getModel().clear();  
            } else {  
                this.updateViewIfRequestHasJspParameter(request, modelAndView);  
            }  
        }

ModelAndViewメソッドの主な目的は、リクエストされたページをUIにレンダリングすることです。ここからバグが始まります。リクエストがリダイレクトされていない場合、updateViewIfRequestHasJspParameterが呼び出されることに注意してください。脆弱性の根本原因を見つけるためには、さらに深く調査する必要があります。

root@kitploit:~
private void updateViewIfRequestHasJspParameter(@NotNull HttpServletRequest request, @NotNull ModelAndView modelAndView) {  
    boolean isControllerRequestWithViewName = modelAndView.getViewName() != null && !request.getServletPath().endsWith(".jsp");  
    String jspFromRequest = this.getJspFromRequest(request);  
    if (isControllerRequestWithViewName && StringUtil.isNotEmpty(jspFromRequest) && !modelAndView.getViewName().equals(jspFromRequest)) {  
        modelAndView.setViewName(jspFromRequest);  
    }  
  
}

このメソッドは、特定の条件を満たした場合にModelAndViewオブジェクトのビュー名を更新するために使用されます。isControllerRequestWithViewNameは、modelAndViewオブジェクトに名前があり、URLのパスが.jspで終わらない場合にTrueになります。例えば、条件を満たすURLはhttp://localhost:8111/random_stringであり、無効なものはhttp://localhost:8111/admin/admin.htmlやhttp://localhost:8111/admin.jspです。前述の通り、リダイレクトを引き起こすもの(通常は認証が必要なページ)にアクセスしてはいけません。プログラムはその後、jspFromRequestという変数にgetJspFromRequest()メソッドの呼び出し結果を代入します。次にそのメソッドに移り、残りのコードを後で説明します。 if文があり、isControllerRequestWithViewNameがtrueで、getJspFromRequest()メソッドの呼び出し結果が空でなく、かつmodelAndViewオブジェクトの名前がリクエストしようとしているページと等しくないことをチェックします。

root@kitploit:~
protected String getJspFromRequest(@NotNull HttpServletRequest request) { String  jspFromRequest  = request.getParameter("jsp"); return  jspFromRequest  == null || jspFromRequest.endsWith(".jsp") && !jspFromRequest.contains("admin/") ? jspFromRequest : null; }

この関数はまず、jspというリクエストパラメータの値を取得します。チェックにより、jspは.jspで終わり、かつ/adminを含んではならないことが保証されます。上記のif文と組み合わせると:

root@kitploit:~
if (isControllerRequestWithViewName && StringUtil.isNotEmpty(jspFromRequest) && !modelAndView.getViewName().equals(jspFromRequest)) {  
        modelAndView.setViewName(jspFromRequest);  
    }  

URLがどのようになるかの全体像が見えてきます:

  1. パスはリダイレクトを引き起こさず、かつ.jspを含んではならない。
  2. jspリクエストパラメータはpathと等しくてはならない。例えば、/random?jsp=/randomは無効。
  3. 最も重要なのは、jspが.jspで終わらなければならないこと。

TeamCityは、外部アプリケーションを統合し、TeamCityサーバとのスクリプトインタラクションを作成するためのREST APIを提供しています。URLパスを介してリソースにアクセスできます。 REST APIの使用を開始するには、ブラウザでhttp://<TeamCity Server host>:<port>/app/rest/server URLを開いてください。このページには、APIを探索するためのいくつかのポインタが表示されます。

TeamCityは、認証をバイパスできれば機密リソースにアクセスできるREST APIを提供しています。この場合、例えば/app/rest/serverにアクセスしてみます。

unauthenticated_request

通常、/app/rest/serverにリクエストすると、サーバは/login.htmlにリダイレクトします。この制限を回避するための完璧なURLを構築しましょう。まず、パスは404ステータスコードまたは200(例:login.html)を返すものなら何でも構いません。次に、jspを使用して/app/rest/serverにリクエストしますが、.jspで終わらなければなりません。この状況では、このチェックをバイパスするために2つのトリックを使用できます。セミコロン;をパラメータ区切り文字として使用する方法:/app/rest/server;.jsp。この場合、.jspは2番目のパラメータとして扱われます。2つ目のバイパスは、URIフラグメント#を使用する方法です:/app/rest/server%23.jsp。URIフラグメントの後ろにあるものはルーティングに使用されず、ページ内のナビゲーションにのみ使用されます。なお、この文字はURLエンコードする必要があります。そうしないと、ブラウザが最初に無視してしまいます。

unauthenticated_request_bypass.png

この手法を使えば、管理者権限を持つ新しいユーザーを作成することもできます。TeamCityのドキュメントによると、エンドポイント/app/rest/usersを介して新しいユーザーを作成できます。

create_new_user

管理者パネルに移動して、新しいユーザーが作成されたか確認しましょう。

confirmed

予想通り、管理者権限を持つ新しいユーザーが作成されました。管理者権限があれば、サーバーを完全に制御できます。しかし、さらにリモートコード実行を獲得することでさらに先に進むことができます。このCVEは2023.11.4より前のすべてのバージョンに影響しますが、このRCEは2023.11より前のバージョンでのみ可能です。管理者権限を持つユーザーが任意のコマンドを実行できる、文書化されていないエンドポイント/app/rest/debug/processesがあります。リクエストURLに2つのリクエストパラメータを付けてPOSTリクエストを送信します。Windowsの場合は?exePath=cmd.exe&params=/c%20[コマンド]、Linuxの場合は?exePath=/bin/sh&params=-c%20[コマンド]です。私はTeamcityをWindowsで実行しているので、完全なパスは/app/rest/debug/processes?exePath=cmd.exe&params=/c%20whoamiになります。

failed_attempt

サーバーはリクエストにcsrfトークンが不足しているという403エラーを返します。TeamCityのドキュメントには、トークンを取得するためのエンドポイント/authenticationTest.html?csrfも記載されています。

トークンを取得したら、リクエストヘッダーX-TC-CSRF-TokenまたはHTTPパラメータtc-csrf-tokenに追加します。ここではX-TC-CSRF-Tokenを選択します。

done

csrfトークンを提供した後、リモートでコマンドを実行することに成功し、サーバーを完全に制御できるようになりました。

このCVEでは、セキュリティの欠陥は入力検証ではなく、コードのロジックにありました。このアプリケーションは非常に複雑で、開発者は何らかのミスを犯してしまいます。また、認証をバイパスする新しいテクニックを学びました。この分析から何か役立つことを学んでいただければ幸いです。Happy hacking!!!

ツールをダウンロード