Vexcited's Logo

Times Square

Let’s try to connect over SSH!

We’re given the following ssh -o StrictHostKeyChecking=no -p 2051 challenges.fcsc.fr

Once connected, it shows a TUI asking if our TTY is too small.

┌ FCSC ACCESS TERMINAL ─────────────────────────────────────────┐
│ You've been waiting 67 seconds for a flag to appear...        │
│ Maybe your TTY is too small? 🦕                               │
│                                                               │
│ uint16_t X = 130, Y = 47, t = 67                              │
└ Press q to exit ──────────────────────────────────────────────┘

When we resize our terminal window, the X and Y values are updated in real time and t is the seconds elapsed since we connected.

Let’s uh- play with the TTY?

It told me my TTY was too small, and I took it personally so I tried to zoom out my terminal window as much as possible and extend it over all my screens to get the largest terminal window I’ve ever seen.

Once done, I finally got an interesting message.

So much screen space, you seem serious about getting the flag!
Pass the following C condition to print the flag:
X + Y + t == 42 && X > 300 && Y > 200

We’re cooked, how can X + Y + t be 42 when I have to stretch all my window (X or Y) over 42?

Integer Overflow

You probably saw it earlier but the TUI tells us that X, Y and t are of type uint16_t, we might be able to overflow if we somehow give an X or Y over 65536!

We’re looking for the following values.

(X + Y + t) mod 65536 == 42
X > 300
Y > 200

Let’s define t = 0 because we’re too lazy to wait duh…

X ≡ Y (mod 65536)
X = Y + k . 65536 for some integer k
X + Y = 42 + k . 65536

We have to find the value of k.

X + Y > 500

42 is too smol though so we must take k = 1. We end up with X + Y = 42 + 65536 = 65578.

Y > 200 so we can pick Y = 201, Y > 300 so we can pick the rest!X = 65578 - 201 = 65377

Exploit!

After a bit of googling, I found pexpect that could help us emulate TTY dimensions.

import pexpect
import time

child = pexpect.spawn(
    'ssh -o StrictHostKeyChecking=no -p 2051 challenges.fcsc.fr',
    dimensions=(201, 65377)
)

# let it run until t=0 is over
time.sleep(1)

data = child.read_nonblocking(size=4096)
print(data)

We get a bunch of garbage but in the middle of all that mess we can find the flag!

you did the impossible and got the flag!
FCSC{2b1150bfd7ad93f72a184764bcae0f51521fcaf796b0997288}