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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
shiro-cve-2020-17523 — Apache Shiro (CVE-2020-17523) における2つの認証バイパス手法の分析、再現可能なエクスプロイト環境、および根本原因の詳細な調査 | Kitploit
ツール/GitHubGitHub/jweny/shiro-cve-2020-17523
認証と認可脆弱性分析ウェブアプリケーション悪用ペネトレーションテスト学習と教育ラボと実践
GitHubjweny/shiro-cve-2020-17523

shiro-cve-2020-17523

Apache Shiro (CVE-2020-17523) における2つの認証バイパス手法の分析、再現可能なエクスプロイト環境、および根本原因の詳細な調査

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

人気

すべて見る →

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

すべてのツールを探索

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

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

Apache Shiro 二つの方法による認証バイパス分析(CVE-2020-17523)

0x01 脆弱性の説明

Apache Shiroは強力で使いやすいJavaセキュリティフレームワークであり、認証、認可、パスワード、セッション管理を実行します。Shiroの理解しやすいAPIを使用すると、最小のモバイルアプリケーションから最大のネットワークおよびエンタープライズアプリケーションまで、あらゆるアプリケーションを迅速かつ簡単に利用できます。

Springと組み合わせて使用する場合、特定の権限マッチングルールの下で、攻撃者は特別に細工されたHTTPリクエストパケットを構築することで、認証をバイパスできます。

影響範囲:Apache Shiro < 1.7.1

0x02 脆弱性環境の構築

shiro 1.7.0

https://github.com/jweny/shiro-cve-2020-17523 2つの方法に対応した脆弱性環境は既に更新されています。

0x03 pocテスト

方法一:

http://127.0.0.1:8080/admin/%20 または http://127.0.0.1:8080/admin/%20/

スペースなどの空文字を使用することで、shiroの認証をバイパスできます。

image-20210205120522547

方法二:

p0destaさんとの交流を通じて、別の特殊なシナリオでの利用方法が発見されました。

http://127.0.0.1:8080/admin/%2e または http://127.0.0.1:8080/admin/%2e/

しかし、.(および/)はSpringのパスマッチングルールにおいてパス区切り文字として扱われるため、通常の文字としてはマッチングされません。そのため、デフォルトでは/admin/.にアクセスすると404が返されます。

しかし、フルパスが有効なシナリオ(setAlwaysUseFullPath(true))では、正常にマッチングできます。

image-20210205102100797

0x04 脆弱性分析

ShiroにおけるURLの取得とマッチングは、org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChainで行われます。

まず、このgetChainメソッドを簡単に見てみましょう:

carbon (2)

image-20210205103341569

このメソッドはまずrequestURIが/で終わっているかどうかをチェックし、そうであれば最後の/を削除します。

次に、パスをマッチングするループの中で、パスルールpathPatternが/で終わっているかどうかをチェックし、そうであれば削除します。その後、pathMatches()メソッドを呼び出してパスマッチングを行います。

そのため、2つの利用方法において、/で終わるかどうかは関係ありません。なぜなら、getChainメソッドを通過する際に削除されるからです。

4.1 スペースによるバイパス分析

pathMatches()メソッドに注目します:

Evaluateを呼び出して、それぞれpathMatches("/admin/*","/admin/1")とpathMatches("/admin/*","/admin/ ")を計算します。前者は正常にマッチングされ、後者はマッチングに失敗します。

image-20210203134044268

image-20210203134119174

デバッグを開始します。デバッグは長いF7の連続の後に始まります。doMatch("/admin/*","/admin/ ")に到達します。tokenizeToStringArrayが返すpathDirsには、もはや2番目のパスがありません。そのため、/admin/*と/adminがマッチングされなくなります。

image-20210203150854085

tokenizeToStringArrayメソッドを追跡すると、tokenizeToStringArrayメソッドを呼び出す際のtrimTokensパラメータがtrueであることがわかります。

image-20210203150959413

そして、tokenizeToStringArrayメソッドは、パラメータtrimTokensがtrueの場合、trim()処理を経由するため、スペースが除去されます。再びgetChainに戻ったとき、最後の/が削除されます。そのため、tokenizeToStringArrayが返すpathDirsには2番目のパスがありません。

image-20210203151053344

まとめ:脆弱性のあるshiroのバージョンでは、tokenizeToStringArrayメソッドを呼び出す際にtrimTokensパラメータがデフォルトでtrueであるため、スペースがtrim()処理で除去されます。これにより、スペースが除去され、getChainに戻ったときに最後の/が削除されるため、/adminと/admin/*のマッチングに失敗し、認証バイパスが発生します。一方、Springが受け取るアクセスパスは/admin/%20であり、通常のロジックでレスポンスを返すため、権限がバイパスされます。

4.2 /./によるバイパス分析

2つ目の方法の/.と/./を見て、あるおなじみのメソッドを思い浮かべませんか?そう、normalize()です。

carbon (3)

簡単に翻訳すると:

条件例
スラッシュをバックスラッシュに変換\ -> /
ダブルスラッシュをスラッシュに変換// -> /
/.または/..で終わる場合、末尾に/を追加/. -> /./ /.. -> /../

そのため、/admin/.は/admin/./に処理された後、/admin/になります。

image-20210205113301788

org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChainで処理される際、/で終わる場合、最後の/が削除され、/adminになります。/adminは/admin/*とマッチしないため、shiroの認証がバイパスされます。

image-20210205113518970

一方、Springが受け取るリクエストは/admin/.です。**フルパスマッチングが有効でない場合、Springでは.と/はパス区切り文字として扱われ、パスマッチングには参加しません。**そのため、マッピングにマッチせず、404が返されます。

image-20210205114350972

フルパスマッチングが有効な場合、URL全体がマッチングされるため、Springは200を返します。

以下に、フルパスマッチングを有効にするコードを示します:

root@kitploit:~
@SpringBootApplication
public class SpringbootShiroApplication extends SpringBootServletInitializer implements BeanPostProcessor {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(SpringbootShiroApplication.class);
    }

    public static void main(String[] args) {

        SpringApplication.run(SpringbootShiroApplication.class, args);
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        if (bean instanceof RequestMappingHandlerMapping) {
            ((RequestMappingHandlerMapping) bean).setAlwaysUseFullPath(true);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        return bean;
    }
}

0x05 公式の修正方法

上記の分析から、shiroの権限バイパスの原因は2つあります:

  1. tokenizeToStringArray関数がスペースを正しく処理していない。
  2. 最後の/を処理するロジックが、パスマッチングループの前にあるべきでない。

そのため、公式の修正方法は次のとおりです:

https://github.com/apache/shiro/commit/0842c27fa72d0da5de0c5723a66d402fe20903df

  1. tokenizeToStringArrayのtrimTokensパラメータをfalseに設定。image-20210203154342100
  2. 最後の/を削除するロジックを調整。元のパスを先にマッチングし、マッチングに失敗した場合のみ最後の/を削除するロジックを実行するように変更。image-20210205115522098

0x06 trimについて

原理的には、trim()は文字列の前後のすべての空白文字を除去します。スペースはその一つに過ぎませんが、テストの結果、スペース以外の空白文字(例:%08、%09、%0a)は、spring+tomcatで処理する際に400が返されることがわかりました。

そのため、方法1ではスペース以外に有効なペイロードはまだ見つかっていません。

0x07 参考

https://github.com/apache/shiro/commit/0842c27fa72d0da5de0c5723a66d402fe20903df

https://www.anquanke.com/post/id/216096

https://www.cnblogs.com/syp172654682/p/9257282.html

ツールをダウンロード
/./を正規化
/./ -> /
パスジャンプ/aaa/../bbb -> /bbb