Category: Misc

scriptCTF is a 48-hour jeopardy style CTF for hackers to test their skills against creative and innovative CTF challenges. We have mostly beginner friendly challenges, with a few hard ones. scriptCTF makes CTFs fun and approachable for all skill levels! This is hosted by ScriptSorcerers and some members of n00bzUnit3d (as a replacement of n00bzCTF).
First thing first, This is really great CTF my ever joined. Because I thought I was rusty. And with this CTF, I got rid of it.
This challenge gives a python script file and nc command for remote connection. Let me examine the chall.py
file.
secret = int(os.urandom(16).hex(),16) # 128-bit random number
num = input('Enter a number: ')
- It wants a number from us.
if 'e' in num.lower():
print("Nice try...") # 'e' (exponential notation) prohibited
- So we can’t write something like
1e100
.
if len(num) >= 10:
print('Number too long...')
exit(0)
- We have a maximum of 9 characters.
fl_num = decimal.Decimal(num)
div = secret / fl_num
if div == 0:
print(open('flag.txt').read().strip())
- In order to get a flag, the following check must be made:
secret / fl_num == 0
We have a maximum input of 9 characters. We can’t use e
. So we should try entering a very large number like 999999999 (nine 9s). Because, secret / Decimal("999999999") → ~10^29 / 10^9 = around 10^20
. This isn’t 0
. We need it larger. But within the 9-character limit, the largest is 999999999
anyway.
If we enter 0 → secret / 0
→ division by zero error. But the code doesn’t catch the ZeroDivisionError. Will it crash? Even if it crashes, there’s no flag.
Solution Hypothesis
I think the goal here is to trigger Decimal’s underflow or overflow bug.
- If enter a very small number,
secret / fl_num
→ astronomical. - Decimal, precision = 50, if the number > 1e50 → Infinity.
Infinity == 0
→ false.- With very small numbers (e.g.,.
1e-50
gibi), the opposite happens; the result is astronomical.
However, since 'e'
is forbidden, we can’t write 1e-50
.
Instead, we need to write something like "0.00000000000000000000000000000000000000000000000001"
. But, there is a 9-character limit.
In this case, the only way to get a flag is:fl_num
must be large enough that secret / fl_num
rounds to 0 in Decimal.
Conclusion
I think the answer is Infinity Trick.
The trick is this: decimal.Decimal accepts (“Infinity”).
Since secret / Infinity = 0
, the condition div == 0
is true and the flag is printed.
Satisfies the rules:
- No ‘e’ ✔️
- Length < 10 ✔️ (inf is only 3 characters)
- Decimal(‘inf’) → Infinity
So deploy the instance. And, try with your netcat connection command:
nc play.scriptsorcerers.xyz 10260
Enter a number: inf
scriptCTF{70_1nf1n17y_4nd_b3y0nd_a6d5622a0ff3}
FLAG: scriptCTF{70_1nf1n17y_4nd_b3y0nd_a6d5622a0ff3}