Tags: programming polyglot 

Rating: 0

**Description**

> solve cats first
>
> http://cats.2018.teamrois.cn:1337

**Solution**

Using the hint from the solution to `cats`, we need another list of 15 commands, but they must include at least 4 of `python3`, `bash`, `php`, `node`, `ruby`.

Script interpreters like these are generally happy to just do nothing when given an empty input file, but our `food` file must be at least 2 bytes in size! This immediately meant one thing: polyglot quine, or polyquine for short.

A "polyglot" in a programming context is a piece of code that is valid (and preferably does the same thing) in multiple languages. A lot of simple Python scripts are technically polyglots, since they work in both Python 2 and Python 3. The less similar the syntax of two languages is, the more difficult it is to make a polyglot with them, naturally.

And a "quine" in a programming context is a program which produces its own source code when executed. Generally, if this is accomplished by actually opening and reading the source file the program is considered a "cheating quine", since a lot of the difficulty of this problem is in crafting a string which somehow expands into the full program when formatted in a particular way. Fortunately, there is no restriction in this challenge, and a cheating quine is completely fine.

At first I looked online for similar challenges, and [this answer](https://codegolf.stackexchange.com/a/163371) seemed the closest to what I needed. Unfortunately, `perl` was not on the list of possible languages, and the challenge asked for Python 3, not Python 2. I spent some time trying to adapt this to work better, but I could only ever make it work for 3 languages at a time.

Then I decided to write my own polyquine, and solve the challenge the hard way. There was no particular method to my development, just writing some code and seeing which interpreter complains about the changes and why, then fixing it and so on. Of the 5 languages I chose `python3`, `bash`, `php`, and `node`, since I knew their syntax well enough. `ruby` not so much.

The script I came up with during the CTF was:

a=0;food=1;exit=0;cat=2;echo=3;x=5;int=6
cat <food
echo
exit <food
int; 1//5 # <?php die(substr(file_get_contents("food"),79)."\n"); ?>
int; 2//5 or __import__("sys").stdout.write(open("food").read() + "\n") and quit() and """
x ;console.log(require("fs").readFileSync("food", "utf8"));
x//"""

I made no effort to clean it up (mostly a waste of time if it works), but for this write-up I will describe a smaller version. The core functionality is the same.

a=0;cat=0;echo=0;exit=0;food=0;i=0
cat<food
echo;exit
i//1#<?die(substr(file_get_contents("food"),59)."\n");?>
i//2;print(open("food").read());quit();"""
x =0;console.log(require("fs").readFileSync("food","utf8"))
x//"""

Some things could still be removed, but I kept them to make sure `sort` prints the file out as-is, i.e. the lines need to be sorted already. Let's see how each language interprets this code.

### PHP ###

PHP is the simplest to understand. By default, PHP just copies file contents to standard output. Any actual scripting capability is possible only in PHP mode, which is entered when a ` Wew, you've found 15 cats! Here is your flag: RCTF{you_love_cats_dont_you}. You are so lihai! RCTF{did_you_make_a_polyglot}

I did indeed.