Tags: rce exploitation 

Rating: 0

First, we need to get enough gold to perform the save and load operations.

Looking at the source code (in particular these lines):
```perl
if( ($subm) <= $gold and int($subm)>=0){
$gold -= ($subm);
$points += ($subm)*1000;
}
```

We see that we must enter a value less than the amount of gold we have, but greater than zero. Notice that the first condition checks the entire value of `$subm` against `$gold`, while the second condition only checks the integer part of `$subm`. Thus, we can actually enter a value of `-0.99` gold and get `0.99` gold. If we do this 253 times, we can get enough gold to save and load.

It turns out perl has a very interesting, "feature" that is very useful (for us) when we can modify the "file name" used in `open()`. [According to the perl docs](https://perldoc.perl.org/functions/open.html#Opening-a-filehandle-into-a-command), you can open a file handle to a command.

If we try a payload like `|ls|`, then try to load a save, we see that our gold becomes
```
* u hav run.sh gold
```
Thus, we can execute arbitrary commands.

We need some way to `grep` across the entire system for `3k{` to find the flag. Unfortunately, the characters `/`, `.` and ` ` are removed from the name, so we must find another way to get to the root and perform a `grep`.

It turns out, a space can be substituted by `${IFS%??}`. With this replacement, we can run almost any command. However, we need a way to `grep` from the root, since we are in a the user's home directory (can be checked with `|pwd|`). We can abuse environment variables to accomplish this. In particular, `dirname${IFS%??}$(dirname${IFS%??}$HOME)` will get us to `/`.

We have all the tools to find a file. Entering the name as
```
|grep${IFS%??}-r${IFS%??}"3k"${IFS%??}$(dirname${IFS%??}$(dirname${IFS%??}$HOME))${IFS%??}1>&2|
```

will get you the flag. Note that we are redirecting `grep`'s standard output to standard error, since only the first line of standard output is loaded into `u hav ... gold`, and the flag is not the first file. On the other hand, all of standard error is visible.

The final step is to find all the `Permission Denied` (among other things) standard error junk, which can be done trivially with another `grep` locally.

**Flag:** `3k{p333rl_aInt_7hat_deAd_Y3t}`