Tags: pwn web 

Rating:

## Overview
When opening the page, you are presented the rules of some sort of dice game. You are then tasked to write an algorithm for calculating the winning probability. At the bottom of the page you'll find a text input where you can submit your solution within the body of a C main function. After submitting your code, the server is running some test cases and reports back in an alert how many test cases you passed.

![Place your code here](https://i.ibb.co/5KsdxXk/writeup-1.png)

## Investigation
Inspecting the source code of the page hints us in an html comment that the flag can be found in a text file on the servers root directory. A quick look at the linked javascript also reveals that as soon as an error response is received from the server, we are presented the error details. This is our way to leak information from the server. And indeed, when writing to *stderr* and exiting the program with an error, we are presented with the error output in the alert.

My idea was to just *fopen* the */flag.txt*, read its content, print it to *stderr* and then exit the main function with an error to report the information back. Unfortunately, some source code filter is applied and I got the answer that *the dangerous keyword 'fopen' has been detected* and my code wouldn't run. After trying a few other approaches I quickly realized most of the interesting functions found in *stdio.h* were prohibited.

I then tried to close the main function early with a `}` and `#include "/flag.txt"` after, provoking a compilation error showing me the contents of the file. No luck, `include` as well as the `#`-symbol were considered dangerous, too.

## Solution
My final solution was to trick the filter by inserting the *dangerous* functions at compile time. The key here was to use macros, making the pre-processor concatenating the dangerous function names from two strings with the `##`-directive, overcoming the source code filter. To counter the prohibition of the ` #`-symbol here I used [digraphs](https://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C).

payload:
```
flag();
return 1;
}

%:define OPEN(path, mode) fop%:%:en(path, mode)
%:define SCAN(f, fmt, buf) fsca%:%:nf(f, fmt, buf)

int flag() {
char buf[128];
FILE *f;
f = OPEN("/flag.txt", "r");
SCAN(f, "%s", buf);
fprintf(stderr, buf);
```

flag:
```
SCTF{take-care-when-execute-unknown-code}
```

-- eggthief