# CSAdventure  

The goal of this challenge is to kill 1.000.000 mobs to get a flag, knowing
that killing one mob will make two mobs spawn. The only way to kill mobs is by
making them step on spikes. Of course, killing 1.000.000 mobs by hand will
take too much time.

The game is coded using **WebGL / Unity**.

Only one team (FluxFingers) was able to flag this challenge during the CTF,
but I was able to flag it after the CTF using another way.

Two solutions exist to solve this challenge :

\- finding the base64 encoded flag inside the game files  
\- using JavaScript to interact with the game, to decrease the mob counter and
beat the game

I'll present both.

## Recovering and analyzing Unity files  

Using the Network tab of any modern browser (or by looking at the
[Build.json](http://chal.cybersecurityrumble.de:6543/Build/Build.json) file),
you could recover three files :

\- `Build.wasm.code.unityweb`  
\- `Build.wasm.framework.unityweb`  
\- `Build.data.unityweb`

![screenshotgamefiles](http://imgshare.io/images/2020/11/03/screenshotgamefiles.png)

We will focus on `Build.data.unityweb`, which is a packed Unity file,
containing all the resources for this game.

First of all, let's open this file using
[AssetStudio](https://github.com/Perfare/AssetStudio), which will allow us to
see tiles, shaders, etc.

![asset_studio](http://imgshare.io/images/2020/11/03/asset_studio.png)

This allows us to get a little bit more precise view of the structure of the
project. We identify `GameManager` and `FlagScreen` as being promising.  
However, the flag was not found (it could have been if the flag was an image
or a tile, but it was a Text dynamically loaded).

We then use the "Extract file" option from AssetStudio to unpack the files of
the project. This will unpack the following files :  
\- `boot.config` -> some booting configuration for the game  
\- `data.unity3d` -> Unity file, which contains game resources and can be
viewed with AssetStudio  
\- `global-metadata.dat` -> This file contains all the strings used in the
game's source code. They can be extracted using
[unity_metadata_loader](https://github.com/nevermoe/unity_metadata_loader) but
this wasn't required here  
\- `machine.config` -> some configuration  
\- `sharedassets0.resource` -> game resources  
\- `unity_default_resources` -> game resources

## Solution 1 : Looking at strings

The first solution was pretty straightforward : have a look at `global-
metadata.dat`.

A simple `strings global-metadata.dat` would reveal a base64 encoded string,
at the very end.

You then just had to decode it to get the flag : `echo "TmljZSwgeW91IGVhcm5lZCB5b3Vyc2VsZiBhIGZsYWc6CkNTUntkMHkwdTYzNzcwN2gzY2wwdWRkMTU3cjFjN3YzcnkwZjczbn0=" | base64 -d`  
  
**Nice, you earned yourself a flag:  
CSR{d0y0u637707h3cl0udd157r1c7v3ry0f73n}**

## Solution 2 : Beat the game

The goal was to decrement the Mob Counter / change the game so that killing
one mob will decrement the counter by a lot / make myself invicible and then
use a Speedhack to kill the mobs.

The first thing I tried was to use [Cetus](https://github.com/Qwokka/Cetus),
which is a browser extension made for hacking WebAssembly games. ([DefCon 27
Conference](https://www.youtube.com/watch?v=Sa1QzhPNHTc)).

However :  
\- Patching WebAssembly with Cetus is not easy.,  
\- The MobCounter variable is protected (confirmed by the challenge's author)

Therefore, I was only able to find with an incremental search and freeze my
health value, which made me invicible (and allowed me to get out of bounds,
but this was not useful).

![invicible](http://imgshare.io/images/2020/11/03/invicible.png)

At this point, I was invicible and could benefit from the SpeedHack. I just
had to wait for the mobs to die from the spikes.

However, this was still too slow and as each time you kill a mob two mobs will
spawn, the game would crash at around 500 mobs killed.

### Call Unity scripts from JavaScript

I then looked at the possibility to call Unity scripts from JavaScript. [Unity
Documentation](https://docs.unity3d.com/Manual/webgl-
interactingwithbrowserscripting.html)

The calls are made from the Web Console :
`unityInstance.SendMessage('MyGameObject', 'MyFunction');`, where
`MyGameObject` is a [GameObject](https://docs.unity3d.com/Manual/class-
GameObject.html) and `MyFunction` is a method from this class.

To find the right classes and method, I used [Unity Assets Bundle
Extractor](https://github.com/DerPopo/UABE) on `data.unity3d`, and I extracted
`level0.assets`.

Looking at this file, I was able to find interesting objects and methods, and
by combining it with information we had from AssetStudio, I was able to
decrement the mob counter artificially by calling
`unityInstance.Module.SendMessage("GameManager","EnemyDied");`.

This would decrement the Mob Counter by 1, and make two mobs spawn.

Using all of this, I could almost beat the challenge. The only issue left was
that too many mobs were spawned, and the game would eventually crash.

The method to kill all ennemies, which I did not find during the CTF, was
`KillAllEnemies` and was only mentionned in `global-metadata.dat`.

The final solution goes like this :  
\- Using Cetus, freeze address `0x01075d2c` to be invicible  
\- Using Cetus, Speedhack x10  
\- In the Web Console :

```js  
for (let i = 0; i < 100; i++) {  
setInterval(function()
{unityInstance.Module.SendMessage("GameManager","EnemyDied")}, 1);  
setInterval(function()
{unityInstance.Module.SendMessage("GameManager","KillAllEnemies")}, 100)  
}  
```  
\- Wait for a few hours  
\- Flag

![flag](http://imgshare.io/images/2020/11/03/flag.png)

*Thanks to [Moritz Thomas](https://de.linkedin.com/in/moritz-thomas-34992718a) @ [NVISO](https://nviso.eu) for the challenge*