Skip to content

Latest commit

 

History

History

teleport

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

Teleport

Description

Challenge instance ready at 88.198.219.20:54778.

One of our admins plays a strange game which can be accessed over TCP. He's been playing for a while but can't get the flag! See if you can help him out.

Category: Miscellaneous

Analysis

Let's check out the code first:

import math

x = 0.0
z = 0.0
flag_x = 10000000000000.0
flag_z = 10000000000000.0
print("Your player is at 0,0")
print("The flag is at 10000000000000, 10000000000000")
print("Enter your next position in the form x,y")
print("You can move a maximum of 10 metres at a time")
for _ in range(100):
    print(f"Current position: {x}, {z}")
    try:
        move = input("Enter next position(maximum distance of 10): ").split(",")
        new_x = float(move[0])
        new_z = float(move[1])
    except Exception:
        continue
    diff_x = new_x - x
    diff_z = new_z - z
    dist = math.sqrt(diff_x ** 2 + diff_z ** 2)
    if dist > 10:
        print("You moved too far")
    else:
        x = new_x
        z = new_z
    if x == 10000000000000 and z == 10000000000000:
        print("ractf{#####################}")
        break

The goal is to print the flag, so we need to get down to this block:

    if x == 10000000000000 and z == 10000000000000:
        print("ractf{#####################}")
        break

But we get a max distance of 10 each move.

kali@kali:~/Downloads/ractf$ python3 teleport.py 
Your player is at 0,0
The flag is at 10000000000000, 10000000000000
Enter your next position in the form x,y
You can move a maximum of 10 metres at a time
Current position: 0.0, 0.0
Enter next position(maximum distance of 10): 10,10
You moved too far
Current position: 0.0, 0.0
Enter next position(maximum distance of 10): 4,6
Current position: 4.0, 6.0
Enter next position(maximum distance of 10): 6,4
Current position: 6.0, 4.0
Enter next position(maximum distance of 10): 10,10
Current position: 10.0, 10.0
Enter next position(maximum distance of 10): 14,16
Current position: 14.0, 16.0
Enter next position(maximum distance of 10): 20,20
Current position: 20.0, 20.0

This limit is a problem, because we only get 100 moves.

for _ in range(100):
    print(f"Current position: {x}, {z}")

Look where it takes the input though:

        move = input("Enter next position(maximum distance of 10): ").split(",")
        new_x = float(move[0])
        new_z = float(move[1])

Floats do have some weird corner cases. We need to look up the documentation for float() to find out what special values it accepts.

What happens with inf and nan?

Enter next position(maximum distance of 10): inf,inf
You moved too far
Current position: 20.0, 20.0
Enter next position(maximum distance of 10): nan,nan
Current position: nan, nan
Enter next position(maximum distance of 10): 1000,1000
Current position: 1000.0, 1000.0

Bingo! nan lets us move wherever we want. Apparently anything involving nan is always nan, and comparisons to actual numbers are always False:

>>> float('nan') - 1000
nan
>>> math.sqrt(float('nan') ** 2)
nan
>>> float('nan') > 10
False
>>> float('nan') < 10
False

Solution

Now we just have to use this trick on the challenge server to get the flag.

$ nc 88.198.219.20 54778
Your player is at 0,0
The flag is at 10000000000000, 10000000000000
Enter your next position in the form x,y
You can move a maximum of 10 metres at a time
Current position: 0.0, 0.0
Enter next position(maximum distance of 10): nan,nan
Current position: nan, nan
Enter next position(maximum distance of 10): 10000000000000,10000000000000
ractf{fl0at1ng_p01nt_15_h4rd}

The flag is:

ractf{fl0at1ng_p01nt_15_h4rd}