Similar to the first iOS challenge, we’re provided with the ARM compiled binary and a simulator version.

Looking through the simulator folders we can see lots of images with ominous names such as “death_01.jpg”, “tunnel_01.jpg”, and “win_01.jpg”. If we load the binary into IDA and look at the strings, we see some interesting messages with “LOSE”, “WIN”, and the start of a URL.

We can also see multiple base64-encoded strings.

The outside air washes over you.
Sunlight beams down and warms you.
You let out a sigh of relief.
You look back and the maze vanishes.
Stepping out of the maze, you live another day.
A tear of joy streams down your face.
There was never any doubt of winning.
You chose...poorly.
Your stomach feels like a pit, the last feeling you'll ever have.
Chills run down your spine as all of the air seeps out of the room.
Mommy?
You knew this was the wrong way...
Gulp..this is the end.
Death awaits you.
You pray for a quick death.
You peek around the right corner, the coast looks clear.
You quickly dive into the right tunnel.
Noises of children echo from the right.
A green mist rises from the tunnel.
This tunnel looks familiar, have you gone this way?
You feel a cold breath on your neck.
This tunnel looks promising...for the dead.
You scurry backwards, only to find a new room.
The sights of this room frieghten you.
Doors begin to shut, but you quickly jump back.
The room fills with fog you think you went back.
You think best before moving forward, best to stay put.
Claustrophobia is setting in.
You have a yearn for your mommy, but her ghost is all that's here.
A light seems to beacon in the left tunnel.
You sprint to the door along the left.
Did a shadow just cross the far door?
Eenie-meenie-minie-moe... giant trolls with no toes.
It feels warm in this direction.
Runes begin to glow as you walk by.
Smells of rotten flesh and fungus greet you.
You move forward to the next tunnel.
A scream bellows from ahead, you run towards it.
Whispers call you near.
Scratched arrows on the wall point forward.
Is this the right way?
You step over corpses on your way.
You step silently ahead, listening to screams in the distance.
dungeon
labyrinth
evil
crystal
hades
bowie
space
treasure
loot
lost
maze
secret

Based on the strings, it sounds like the app is some kind of game so let’s go ahead and boot it up in a simulator and see what it does before we dive in. For quick and simple simulation, you can use the website appetize.io for iOS or APK simulation.

Using the arrow keys, we can navigate around the “Labyrinth” and see some of the base64-decoded strings on each screen.

Eventually we fail and get our “LOSE” message.

Resetting a few times, we eventually make our way out of the maze, which appears random since repeating the same steps would cause us to lose at different points.

When you win, it says you have the “High Score!” and that you can submit your score to http://pansecretloot.com. After clicking submit though, we’re presented with the below message.

The error message states that it was unable to resolve the domain pansecretloot.com, which I validated doesn’t resolve. Playing the game again we see it’s using a different domain this time, http://panlostspace.com, which it states also cannot be resolved.

Playing through a couple of times, this pattern just continues to repeat.

http://pansecretloot.com
http://panlostspace.com
http://panlootdungeon.com
http://panlostlost.com
http://pansecretdungeon.com
http://pandungeonbowie.com

If you recall from our base64 encoded strings, after all of the messages being displayed in the game is a short list of single words.

dungeon
labyrinth
evil
crystal
hades
bowie
space
treasure
loot
lost
maze
secret

You can easily see the correlation. It appears that two of the words are being appended to “http://pan” to build a domain. Smells DGAish to me! If this is the final list of 12 words, and we know they can be next to each other (lostlost), then it’s just 12^2 for the combinations, which is easily generated and checked.

words = ["dungeon", "labyrinth", "evil", "crystal", "hades", "bowie", "space", "treasure", "loot", "lost", "maze", "secret"]

for i in words:
	count = 0
	while count < len(words):
		print "pan" + i + words[count] + ".com"
		count += 1

Iterating through the generated list and performing DNS lookups, we come across this gem.

Host panbowietreasure.com not found: 3(NXDOMAIN)
Host panbowieloot.com not found: 3(NXDOMAIN)
Host panbowielost.com not found: 3(NXDOMAIN)
Host panbowiemaze.com not found: 3(NXDOMAIN)
Host panbowiesecret.com not found: 3(NXDOMAIN)
panspacedungeon.com has address 52.43.46.197
Host panspacelabyrinth.com not found: 3(NXDOMAIN)
Host panspaceevil.com not found: 3(NXDOMAIN)
Host panspacecrystal.com not found: 3(NXDOMAIN)
Host panspacehades.com not found: 3(NXDOMAIN)
Host panspacebowie.com not found: 3(NXDOMAIN)
Host panspacespace.com not found: 3(NXDOMAIN)

Browsing to this domain, it just returns the string “M4z3Cub3”.

So it seems the app is building domains from this wordlist but fails to progress because of resolution errors…What if we simply change modify our host lookup so that all of these domains resolve to the known live site?

Appetize.io is great for quickly looking at an app, but it doesn’t offer us anything in the way of debugging. Since I’m not cool enough to have a physical iOS device that I can load this on, I’ll need to figure out how to load this into a local simulator so that I can affect the domain resolution.

The next part was slightly confusing so I’ll detail it here to make someone’s life easier. Basically, if you create an Xcode project run it on a simulator, it generates a .app file for that simulated device. If you right click on the .app file under Products, you can open the folder that contains your file, then simply move over the .app included with this challenge. The directory path looks like the below:

Where “labyREnth_mobile5-XXX” is the project and then device ID that we created in Xcode. Loading our simulator we see the app we copied over, along with our empty project app.

Now that we have the app running locally, we’ll modify our /etc/hosts file with all of the domains we enumerated and point them all to the IP we resolved for panspacedungeon.com.

Next we’ll run our app and navigate the game until we trigger the win condition.

Success!

PAN{G3t_Sch1f7y}