
Trova espressioni regolari vulnerabili a ReDoS (Negazione del Servizio tramite Espressioni Regolari)

Trova regex vulnerabili a Regular Expression Denial of Service (ReDoS).
Maggiori informazioni sul blog di Doyensec
Molti parser di espressioni regolari predefiniti hanno una complessità del caso peggiore illimitata. Il matching delle regex può essere rapido quando viene presentata una stringa di input corrispondente. Tuttavia, alcune stringhe di input non corrispondenti possono far impazzire il matcher di espressioni regolari con cicli di backtracking e richiedere molto tempo per l'elaborazione. Ciò può causare un denial of service, poiché la CPU rimarrà bloccata nel tentativo di far corrispondere la regex.
Questo strumento è progettato per:
Questo riflette la complessità della procedura di backtracking del matcher di espressioni regolari rispetto alla lunghezza della stringa inserita.
La complessità cubica qui significa che se la parte vulnerabile della stringa viene raddoppiata in lunghezza, il tempo di esecuzione dovrebbe essere circa 8 volte più lungo (2^3).
Per ReDoS esponenziale con stelle annidate, ad esempio (a*)*$, viene utilizzato un fattore di correzione e la complessità sarà maggiore di 10.
Per l'exploitabilità, in genere è richiesta una complessità cubica o superiore, a meno che non siano consentite stringhe veramente enormi come input.
Esegui regexploit e inserisci l'espressione regolare v\w*_\w*_\w*$ al prompt.
$ regexploit
v\w*_\w*_\w*$
Pattern: v\w*_\w*_\w*$
---
Worst-case complexity: 3 ⭐⭐⭐ (cubic)
Repeated character: [5f:_]
Final character to cause backtracking: [^WORD]
Example: 'v' + '_' * 3456 + '!'
La parte \w*_\w*_\w* contiene tre gruppi ripetuti sovrapposti (\w corrisponde a lettere, cifre e trattini bassi). Come mostrato nella riga Repeated character: [5f:_], una lunga stringa di _ (0x5f) corrisponderà a questa sezione in molti modi diversi. La complessità del caso peggiore è 3 poiché ci sono 3 gruppi infinitamente ripetuti. Viene fornito un esempio per causare ReDoS: consiste nel prefisso richiesto v, una lunga stringa di _ e poi un ! (carattere non di parola) per causare backtracking. Non tutti i ReDoS richiedono un carattere particolare alla fine, ma in questo caso una lunga stringa di _ corrisponderà alla regex con successo e non farà backtracking. La riga Final character to cause backtracking: [^WORD] mostra che è richiesto un carattere non corrispondente (non un carattere di parola) alla fine per prevenire la corrispondenza e causare ReDoS.
Come altro esempio, installa una versione di un modulo vulnerabile a ReDoS come pip install ua-parser==0.9.0. Per scansionare i moduli Python installati, esegui regexploit-python-env.
Importing ua_parser.user_agent_parser
Vulnerable regex in /somewhere/.env/lib/python3.9/site-packages/ua_parser/user_agent_parser.py #183
Pattern: \bSmartWatch *\( *([^;]+) *; *([^;]+) *;
Context: self.user_agent_re = re.compile(self.pattern)
---
Worst-case complexity: 3 ⭐⭐⭐
Repeated character: [20]
Example: 'SmartWatch(' + ' ' * 3456
Worst-case complexity: 3 ⭐⭐⭐
Repeated character: [20]
Example: 'SmartWatch(0;' + ' ' * 3456
Vulnerable regex in /somewhere/.env/lib/python3.9/site-packages/ua_parser/user_agent_parser.py #183
Pattern: ; *([^;/]+) Build[/ ]Huawei(MT1-U06|[A-Z]+\d+[^\);]+)[^\);]*\)
Context: self.user_agent_re = re.compile(self.pattern)
---
Worst-case complexity: 3 ⭐⭐⭐
Repeated character: [[0-9]]
Example: ';0 Build/HuaweiA' + '0' * 3456
...
Per ogni espressione regolare vulnerabile stampa una o più stringhe malevole per innescare ReDoS. Impostando il tuo user agent a ;0 Build/HuaweiA000000000000000... e navigando un sito che utilizza una vecchia versione di ua-parser, potrebbe far sì che il server impieghi molto tempo per elaborare la richiesta, probabilmente terminando con stato 502.
È richiesto Python 3.8+. Per estrarre regex da codice JavaScript/TypeScript, è richiesto anche NodeJS 12+.
Opzionalmente crea un ambiente virtuale
python3 -m venv .env
source .env/bin/activate
Ora installa effettivamente con pip
pip install regexploit
Inserisci espressioni regolari tramite stdin (una per riga) in regexploit.
regexploit
o tramite un file
cat myregexes.txt | regexploit
C'è supporto integrato per l'analisi di regex da Python, JavaScript, TypeScript, C#, YAML e JSON.
Analizza il codice Python (senza eseguirlo) tramite AST per trovare regex.
regexploit-py my-project/
regexploit-py "my-project/**/*.py" --glob
Questo utilizzerà il pacchetto NodeJS in bundle in regexploit/bin/javascript che analizza il tuo JavaScript come AST con eslint e stampa tutte le regex.
regexploit-js my-module/my-file.js another/file.js some/folder/
regexploit-js "my-project/node_modules/**/*.js" --glob
N.B. ci sono differenze tra l'analisi regex di javascript e python, quindi potrebbero esserci alcuni errori. Non sono sicuro di voler scrivere un AST regex JS!
Cerca regex in tutti i moduli python attualmente installati nel tuo path/environment. Significa che puoi pip install qualsiasi modulo ti interessi e verranno analizzati. Il codice Cpython è incluso.
regexploit-python-env
N.B. questo non analizza il codice python in un AST e troverà solo le regex compilate automaticamente all'importazione del modulo. I moduli vengono effettivamente importati, quindi il codice nei moduli verrà eseguito. Questo è utile per trovare regex costruite da stringhe più piccole al caricamento, ad esempio CVE-2021-25292 in Pillow
Il supporto YAML richiede pyyaml, che può essere installato con pip install regexploit[yaml].
regexploit-json *.json
regexploit-yaml *.yaml
regexploit-csharp something.cs
Questo strumento è stato creato da Ben Caller di Doyensec LLC durante il tempo di ricerca.