# FUNction Plotter

## Misc, 50 points

### Description

*One of Santa's elves found this weird service on the internet. He doesn't like maths, so he asked you to check if there's anything hidden behind it.*

*Remote Server: `nc challs.xmas.htsp.ro 13005`* *Author: yakuhito*

### Solution

Let's connect to the server and see what's going on.

```
╭─face0xff@aniesu-chan /den/ctf/xmas  
╰─$ nc challs.xmas.htsp.ro 13005
Welcome to my guessing service!
Can you guess all 961 values?


f(27, 5)=0
Pretty close, but wrong!

f(26, 6)=1
Pretty close, but wrong!

f(4, 20)=0
Good!

f(17, 13)=1
Pretty close, but wrong!
```

After enough retries, we can infer several important points:

* The server asks us for a value of f(x, y), with x and y in {0, ... 30}
* The only answers that can (sometimes) give "Good!" answers are "0" and "1"
* Our goal is certainly to determine f over \[\[0, 31]]^2.

At this point I was thinking about what we would get once we fully recovered f. It could not be a binary text because of the length, so I thought of a QR Code because of the square shape.

It happened I had the correct intuition; here's an animation of the script recovering the square:

![Retrieving the QR code](https://3789372156-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LdJcrhckZrBeFeRnySu%2F-LwctG4MjFNu9ZLkayUa%2F-LwctG_o1746UUolh9hI%2Ffun.gif?generation=1576939102491996\&alt=media)

What was only left to do was to make an image out of it:

![The actual QR code](https://3789372156-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LdJcrhckZrBeFeRnySu%2F-LwctG4MjFNu9ZLkayUa%2F-LwctG_q0s5gOxgnrC5Q%2Fout.png?generation=1576939101549099\&alt=media)

which decodes as the flag : `X-MAS{Th@t's_4_w31rD_fUnCt10n!!!_8082838205}`.

Enjoy!

### Script

```python
import socket, itertools

def display(S):
    for j in range(31):
        print(''.join(str(u) if u >= 0 else ' ' for u in S[j]))
    print('\n')

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('challs.xmas.htsp.ro', 13005))

square = [[-1] * 31 for i in range(31)]

d = s.recv(4096)

while -1 in list(itertools.chain(*square)):
    coords = d.split(b'\n')[-1].replace(b'f(', b'').replace(b')=', b'')
    x, y = map(int, coords.decode('utf-8').split(', '))
    s.send(b'0\n')
    d = s.recv(4096)
    square[y][x] = 1 if b'wrong' in d else 0
    display(square)

s.close()

from PIL import Image

BLOCK = 10
img = Image.new('RGB', (31 * BLOCK, 31 * BLOCK))

for y in range(31):
    for x in range(31):
        color = (0,) * 3 if square[y][x] else (255,) * 3
        for i in range(BLOCK):
            for j in range(BLOCK):
                img.putpixel((x * BLOCK + i, y * BLOCK + j), color)

img.save('out.png')
```
