The CSCG (Cyber Security Challenge Germany) had the youtuber/hacker LiveOverflow, who also happens to be into game hacking, contribute a game hacking challenge . He created a unity based game from scratch and allowed for some common vulnerabilities to exist in the game similar to the pwnieIslandAdventures game. The description of the challenge reads, "Follow the white rabbit... into the hole." Easy. I went ahead and downloaded it, unpacked the zip, and fired up the .exe.
Upon beginning the game, you are dropped on to a dock from a DeLorean where the white rabbit is in view cleaning itself. Easy enough. I walked up to the rabbit where it took a look at me and began to run up the hill.
I followed it up the hill to where it lead me to a courtyard with a hole. The rabbit then, with no hesitation did a nose dive into the hole. Alright, Alice in Wonderland is dope, so I'm just gonna follow the little guy down. During my long descent, this is what I thought as I fell: "‘Ahhh! Whoa! What’s happening? Who am I? Why am I here? What’s my purpose in life? What do I mean by ‘who am I’? Okay, okay, calm down, calm down, get a grip now. Ooh, this is an interesting sensation. What is it? It’s a sort of a tingling in my… well, I suppose I better start finding names for things. Let’s call it a… tail! Yeah! Tail! And hey, what’s this roaring sound, whooshing past what I’m suddenly gonna call my head? Wind! Is that a good name? It’ll do. Yeah, this is really exciting! I’m dizzy with anticipation! Or is it the wind?" Thank you Douglas Adams. Much like the sperm whale that was randomly called into existence, I too said hello to the ground with my face.
Alright, so it's what we have to do in this challenge. In 3D games, you need to think about how many axes there are happening for which object. We have one set of axes for the camera, one set for the player, and one set for any other moving objects in the virtual world. Lucky for us, there aren't that many objects to take into account for this. With that there is an X, Y, and Z axis where we need to control our descent in the Y access. So there's a few ways we can go about this. Originally, I was going to attempt an internal hack by reverse-engineering the functions that are called in the game, creating a new DLL with the movement function/s, and injecting it into the running process. However, after a quick run through with X64 DBG, it became clear this wasn't the intended approach for this challenge. We have to stay external, which means we're breaking out cheat engine again. After restarting the game, I attached Cheat Engine and began to get to work. Initially, I searched for a range of float values between -20 and 50, which a lot of games use for their Y axis, but this yielded billions of results. We can do this more efficiently. Next, I started the search for unknown float values which gives me all addresses in the game's memory space. From here, I walked up the stairs to increase the value in my Y axis and searched for any values that increased since the last scan. After doing this several times, I was finally left with around 100-150 results. The search hits weren't decreasing anymore, so it was time to grind through the address list. I sorted the list by values to eliminate some values that were like 1.534634E-14 as that's certainly not how most games handle their player positions. This process was also a bit tricky because the camera position values were extremely similar to the player's position. To test out if I had the correct address, I would set an address to active. Changing an address to active in CE keeps the value at this address static and does not allow the value at this location to change. You gotta be careful with doing so as if a function calls on a register and doesn't get an update from the previous value, it may crash the game since the engine may see it as an error. After dealing with a whole lot of game crashes and cursing, I was able to isolate the value.
When active, this address freezes my players Y position and causes the model to snap back to the original position. To much my surprise, I changed the value to 10 and I was now free falling towards an island I couldn't even see. Clearly, this value doesn't take much to move 50 feet in the air. Let's try moving it down from the dock instead. I changed the value by 0.01 and sure enough that was enough to put me under the dock. Now, for most game maps with water or ocean terrain, devs will just make a full layer of the map to be water since it's less work and there usually isn't a need to cut the shape of the land out of the water pattern since you could just place the land on top. After walking up to the hole at the top of the hill, I changed the value by 0.5 and ended up in the water underneath the map. Not bad, at least i'm not dead nor do I have to restart this process. By this point, I had enough going through this process, so we not dying, yo. The process was arduous and redundant, but we carry on. Once under the map, I just began to swim around to see if there are another hidden rooms or what have you. The whole map is visible from here. Around the hole though, the developer had made a drop off in water, so I went for it. I swam off the water fall.
Cool thing about being afraid of dying again is that it let me discover that the waterfall could be used as an elevator. If I swam towards the waterfall it took back to the original location in the base water area. This happens because the dev just sunk the terrain below the hole area in unity without cutting out a hole in the water terrain. Definitely not unusual for smaller devs to do this for time and effort reasons. Using this to slow my decent by going in and out of the water fall, I ended up in the water under the whole.
Alright, I've made to the bottom of the hole, but i'm now below the hole. To get above my current location, I carefully changed the register value by 0.5 incrementally until I was where I really needed to be.
Noice, we made it let's follow the bunny.
Sure enough, at the end of this path was the flag we had set out to get. The next level of this is taking and, like my previous write-up, making this dynamic and allowing for the value to change as I hold a part a particular key. That seems like a bit much for this though and I've got more articles to write, so i'll keep that in my back pocket for this. Til next time fam.