# 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](/files/-LwctG_o1746UUolh9hI)

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

![The actual QR code](/files/-LwctG_q0s5gOxgnrC5Q)

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')
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ctf.0xff.re/2019/x-mas_ctf_2019/function_plotter.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
