#sthack : Unity2D, dllimport and Monty Python
On the 14th of march 2014 went on the 4th edition of St’hack, a computer security event in Bordeaux that consists of a whole day of security conferences followed up by a Capture The Flag contest, organized by our very own security guru @agixid. For the 4th year, I’ve been part of the staff, taking care of CTF support at first, then UI design last year. I had the opportunity to create a challenge this year (and hand out pizza and redbull).
Those who know me also know that I really suck at computer security. Idiots would be like “that’s normal, you use MS tech”, but I would be like “I fell more into video games than security these past years”. Yeah, I use Windows as my main OS, deal with it. So I thought about a game concept the powners would have to reverse to find the solution. Here’s what I came up with : a basic hack n’ slash in which the hero has to move from chamber to chamber in the correct direction (much like I don’t remember which zelda) in a limited amount of room changes. If the hero changes too many rooms without finding the correct path, he loses. He can also get killed by cheaty ogres and the level generation is rather buggy (I’ll talk about that in another blog post). There is also no information whatsoever, you are on your own.
So, how do you win? I actually made the game with Unity and used a feature only available for pro versions (I think) : dllimport. The feature itself is something available with C# since the dawn of ages, but Unity has decided you have to pay to use it in your games. That appart, it requires you to understand a bit on how .Net (and Mono + Unity by extension) compile their dynamic libraries : it’s managed code, executed on a virtual machine and totally controlled by it. It means that when you compile your C#, VB.Net or managed c++ in Visual Studio, you create an intermediate language (IL) version of your code that the VM will compile on the run so that the CPU understands it. This is called Just In Time (JIT) compiler and is a rather complex and nasty business. Check out this Telerik blog post if you’d like to know more. As a sidenote, .Net is not the only tech using JIT compiling, it’s rather common these days, so haters go home (unless you just hate JIT, which I can understand).
Back to business : IL code means easy decompiling. And when I say easy, I mean that you can get like 99% of your base .Net code (excluding naming if it is obfuscated of course) in a single click in an app like ILSpy. That’s the same with Mono and Unity, at least for Windows (haven’t checked on other platforms, but it shouldn’t be that different, I suppose). You get a bunch of dlls when you build your game, in particular Assembly-CSharp.dll in your Data/Managed. This includes all your non editor/plugins custom classes, which means “hide yo code, hide yo data, there’s a library intruder”. If you open this dll with ILSpy, you’ll probably find all your code barely touched by Unity (they optimize stuff like loops on build time). From this point, if you want to hide something, there are two solutions:
- hide your data inside gameobjects metadata : this gets compiled into their .assets files at build time and seems like a freaking mess to open. If your data is critical, this is probably where you want to put it.
- hide your methods inside a non managed library and call it via dllimport : this gives another layer of protection to your code, even though it’s not impermeable. We’ll use this.
So the goal is : create a non managed dll that stocks the flag the powners have to find about, call it in our managed code and generate path in game with that data. Want to check out the challenge? Download it here (Windows only, sorry)! Let’s do a step by step on how to solve this:
- Find out this is a Unity game : I’m handing out solution here, but during the ctf, it was not specified. There were a few hints though:
- the exe icon is the default unity icon
- data/Managed/ has UnityEngine.dll
- data/Resources/ files have unity in their name
- Open Data/Managed/Assembly-CSharp.dll with ILSpy.
- Find the class code for HeroMove, decompile it and get the lines of the dllimport.
- Find YeOldeContent.dll in data/Plugins/. You can try to open it in ILSpy, but you’re going to be insulted.
- Two options here:
- the dev way : develop a .Net app that dllimports the non managed library and get the flag
- the hacker way : extract the static strings directly from the non managed library
Now there’s a hiccup : the flag is incomplete, you have to interpret it ingame to get the complete flag (cf. directions). There’s also another hiccup if you use the dev way : I’ve put an extra security on the dll function that requires a passkey to get the flag directly. This passkey is inside the metadata, so if you want to go hardcore, try to open the .asset files and get that passkey. Else, you’ll have to replay a famous scene from Monty Python’s Holy Grail.
That’s it, you can witness my noobitude in computer security. Anyways, it was fun to create and I’m glad that some powners actually were able to break it! Regarding game part, I’m going to have to redo it, because it’s really fucking buggy. I tried to transpose Unity2d components in a full 3d world, and it didn’t go well. I’ll make an article about that later, but it was a pretty stupid idea. I used the Dungeon tileset over at OpenGameArt on a sidenote. Really awesome art!
That being said, have fun, code safe.