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):
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, 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}