Translated ['', 'src/pentesting-web/regular-expression-denial-of-service

This commit is contained in:
Translator 2025-10-01 15:17:34 +00:00
parent c4713f10cc
commit 4741b5aa4b

View File

@ -1,41 +1,70 @@
# 正規表現サービス拒否 - ReDoS
# Regular expression Denial of Service - ReDoS
{{#include ../banners/hacktricks-training.md}}
# 正規表現サービス拒否 (ReDoS)
# Regular Expression Denial of Service (ReDoS)
**正規表現サービス拒否 (ReDoS)** は、誰かが正規表現(テキスト内のパターンを検索して一致させる方法)の動作の弱点を利用する場合に発生します。正規表現が使用されると、特に処理するテキストのサイズが大きくなると、非常に遅くなることがあります。この遅さは、テキストサイズがわずかに増加するだけで急速に悪化することがあります。攻撃者はこの問題を利用して、正規表現を使用するプログラムが長時間正常に動作しないようにすることができます。
A **Regular Expression Denial of Service (ReDoS)** は、正規表現(テキスト内のパターンを検索・マッチさせる方法)の挙動の弱点を悪用する攻撃です。正規表現の使い方によっては、処理対象のテキストが大きくなると非常に遅くなり、入力サイズが少し増えるだけで処理時間が急激に増加することがあります。攻撃者はこの問題を利用して、正規表現を使用するプログラムを長時間正しく動作しない状態にすることができます。
## 問題のある正規表現のナイーブアルゴリズム
## 問題のある Regex素朴なアルゴリズム
**詳細は [https://owasp.org/www-community/attacks/Regular*expression_Denial_of_Service*-\_ReDoS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) を確認してください**
**Check the details in [https://owasp.org/www-community/attacks/Regular*expression_Denial_of_Service*-_ReDoS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS)**
## 悪意のある正規表現 <a href="#evil-regexes" id="evil-regexes"></a>
### エンジンの挙動と悪用可能性
悪意のある正規表現パターンとは、**作成された入力に引っかかり、DoSを引き起こす**ことができるものです。悪意のある正規表現パターンは、通常、繰り返しを伴うグループ化や、繰り返しまたは交互の重複を含んでいます。悪意のあるパターンのいくつかの例は次のとおりです:
- ほとんどの主要なエンジン (PCRE, Java `java.util.regex`, Python `re`, JavaScript `RegExp`) は **バックトラッキング** 型の VM を使用します。部分パターンに対して多くの重複するマッチ方法が生じるように細工された入力は、指数関数的または高次数多項式的なバックトラッキングを引き起こします。
- 一部のエンジン/ライブラリは設計上 **ReDoS-resilient**(バックトラッキングなし)となるよう作られており、例えば **RE2** や有限オートマトンに基づくポートは最悪ケースで線形時間を保証します。信頼できない入力に対してそれらを使うことで、バックトラッキングに起因する DoS の原始的手段を排除できます。詳細は末尾の参考文献を参照してください。
## Evil Regexes <a href="#evil-regexes" id="evil-regexes"></a>
悪意ある正規表現パターンとは、細工された入力で **処理がハマり DoS を引き起こす** ものです。悪意ある regex パターンは通常、繰り返しを含むグルーピングや、繰り返し内部で重なり合う繰り返しや選択alternationを含みます。いくつかの例は以下の通りです:
- (a+)+
- ([a-zA-Z]+)\*
- (a|aa)+
- (a|a?)+
- (.\*a){x} for x > 10
- (.*a){x} for x > 10
これらはすべて、入力 `aaaaaaaaaaaaaaaaaaaaaaaa!` に対して脆弱です。
これらはいずれも入力 `aaaaaaaaaaaaaaaaaaaaaaaa!` に対して脆弱です。
### Practical recipe to build PoCs
ほとんどの致命的なケースは次の形をとります:
- 脆弱なサブパターンに入るためのプレフィックス(任意)。
- ネスト/重なり合う量指定子内で曖昧なマッチを生じさせる長い同一文字列(例: 多数の `a``_`、スペース)。
- 最終的に全体を失敗させ、エンジンがすべての可能性をバックトラックするように強制する最後の文字(多くの場合、最後のトークンにマッチしない文字、例: `!`)。
最小の例:
- `(a+)+$` vs input `"a"*N + "!"`
- `\w*_*\w*$` vs input `"v" + "_"*N + "!"`
N を増やして、超線形的な増加を観察してください。
#### クイックタイミングハーネス (Python)
```python
import re, time
pat = re.compile(r'(\w*_)\w*$')
for n in [2**k for k in range(8, 15)]:
s = 'v' + '_'*n + '!'
t0=time.time(); pat.search(s); dt=time.time()-t0
print(n, f"{dt:.3f}s")
```
## ReDoS ペイロード
### ReDoSによる文字列の抽出
### ReDoS による文字列の外部持ち出し
CTFまたはバグバウンティでは、**正規表現が一致する機密情報(フラグ)を制御している**かもしれません。その場合、**正規表現が一致した場合にページをフリーズ(タイムアウトまたは長い処理時間)させる**ことが有用です。そうすることで、**文字を1文字ずつ抽出**することができます:
CTFまたは bug bountyでは、機密情報flagを照合する**Regex をあなたが制御できる**場合があります。そうしたとき、**Regex がマッチした場合にページをフリーズ(タイムアウトや処理時間の延長)**させ、マッチしなかった場合はさせない、という挙動にするのが有用です。こうすることで文字列を**1文字ずつ外部へ持ち出す**ことができます:
- [**この投稿**](https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets) では、このReDoSルールを見つけることができます: `^(?=<flag>)((.*)*)*salt$`
- In [**this post**](https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets) you can find this ReDoS rule: `^(?=<flag>)((.*)*)*salt$`
- 例: `^(?=HTB{sOmE_fl§N§)((.*)*)*salt$`
- [**この解説**](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20%40%20DEKRA%20CTF%202022/solver/solver.html) では、次のものを見つけることができます: `<flag>(((((((.*)*)*)*)*)*)*)!`
- [**この解説**](https://ctftime.org/writeup/25869) では、次のものを使用しました: `^(?=${flag_prefix}).*.*.*.*.*.*.*.*!!!!$`
- In [**this writeup**](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20@%20DEKRA%20CTF%202022/solver/solver.html) you can find this one:`<flag>(((((((.*)*)*)*)*)*)*)!`
- In [**this writeup**](https://ctftime.org/writeup/25869) he used: `^(?=${flag_prefix}).*.*.*.*.*.*.*.*!!!!$`
### ReDoSの入力と正規表現の制御
### ReDoS Controlling Input and Regex
以下は、**入力**と**正規表現**の両方を**制御**する**ReDoS**の例です:
The following are **ReDoS** examples where you **control** both the **input** and the **regex**:
```javascript
function check_time_regexp(regexp, text) {
var t0 = new Date().getTime()
@ -65,16 +94,35 @@ Regexp ([a-zA-Z]+)*$ took 773 milliseconds.
Regexp (a+)*$ took 723 milliseconds.
*/
```
### 攻撃者向けの言語/エンジンに関する注意
- JavaScript (browser/Node): 組み込みの `RegExp` はバックトラッキングエンジンで、regex+input が攻撃者に影響される場合に一般的に悪用されます。
- Python: `re` はバックトラッキングです。長い曖昧な繰り返しと失敗する末尾が組み合わさると、致命的なバックトラッキングを引き起こすことがよくあります。
- Java: `java.util.regex` はバックトラッキングです。もし input のみを制御する場合は複雑なバリデータを使うエンドポイントを探してください。patterns例: stored rulesを制御できる場合、ReDoS は通常簡単です。
- Engines such as **RE2/RE2J/RE2JS** or the **Rust regex** crate are designed to avoid catastrophic backtracking. If you hit these, focus on other bottlenecks (e.g., 巨大なパターン) or find components still using backtracking engines.
## ツール
- [https://github.com/doyensec/regexploit](https://github.com/doyensec/regexploit)
- 脆弱な regex を見つけて悪意ある入力を自動生成します。例:
- `pip install regexploit`
- パターンを対話的に解析する: `regexploit`
- Python/JS コードを regex を探してスキャンする: `regexploit-py path/``regexploit-js path/`
- [https://devina.io/redos-checker](https://devina.io/redos-checker)
- [https://github.com/davisjam/vuln-regex-detector](https://github.com/davisjam/vuln-regex-detector)
- プロジェクトからregexを抽出し、脆弱なものを検出し、ターゲット言語でPoCを検証するエンドツーエンドのパイプライン。大規模なコードベースを探索する際に有用です。
- [https://github.com/tjenkinson/redos-detector](https://github.com/tjenkinson/redos-detector)
- パターンが安全かどうかを報告するため、バックトラッキングを解析するシンプルな CLI/JS ライブラリ。
> ヒント: input のみを制御する場合は、長さが2倍になる文字列例: 2^k 文字)を生成してレイテンシを追跡してください。指数的な増加は ReDoS の有効性を強く示します。
## 参考文献
- [https://owasp.org/www-community/attacks/Regular*expression_Denial_of_Service*-\_ReDoS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS)
- [https://owasp.org/www-community/attacks/Regular*expression_Denial_of_Service*-_ReDoS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS)
- [https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets](https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets)
- [https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20%40%20DEKRA%20CTF%202022/solver/solver.html](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20%40%20DEKRA%20CTF%202022/solver/solver.html)
- [https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20@%20DEKRA%20CTF%202022/solver/solver.html](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20@%20DEKRA%20CTF%202022/solver/solver.html)
- [https://ctftime.org/writeup/25869](https://ctftime.org/writeup/25869)
- SoK (2024): Regular Expression Denial of Service (ReDoS) に関する文献および工学レビュー — [https://arxiv.org/abs/2406.11618](https://arxiv.org/abs/2406.11618)
- Why RE2線形時間のregexエンジン — [https://github.com/google/re2/wiki/WhyRE2](https://github.com/google/re2/wiki/WhyRE2)
{{#include ../banners/hacktricks-training.md}}