Tags: javascript level0 data.unity3d unityinstance build.data.unityweb global-metadata.dat unity webgl 

Rating: 5.0

# 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`




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.




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:


## 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).




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 :

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


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