Tuesday, March 6, 2018

Pragyan CTF 2018 - INTO THE NEXT DIMENSION (250)



This was a very interesting challenge, had a lot of fun stepping through it.
First checking the file format, it looks like we have an FBX file exported from Blender:

$ strings -n 40 way_out.obj
Blender (stable FBX IO) - 2.79 (sub 0) - 3.7.13R
Blender (stable FBX IO) - 2.79 (sub 0) - 3.7.13

Blender is free open-source 3D software, grab a copy here - https://www.blender.org/
This was the challenge description:

Alice is stuck in a two-dimensional world and somehow needs to escape into reality, our three-dimensional world. In order to do so, she must crack a code hidden inside a file(named 'way_out.obj'). The only clues the two-dimensional Gods have given her is this:

clue_begin

0 - P(100, -5, 321), R(0, 90, 0) => pctf{
1 - P(-50, -33, 77), R(90, 0, 0)
2 - P(123, -5, 68), R(60, 30, 0)
3 - P(-89, 90, 0), R(34, 23, 32)
4 - P(-39, 40, 40), R(44, 55, 66)
P(111, 222, 333)
5-10 - Ears, eyes, nose and mouth
11 - Inside the key => 3}

You will never find a way out without colors.

clue_end

Help Alice get back to reality and hence find the flag. Good luck (Y).


Without opening the file yet, the clues look like 3D coordinates which may provide parts of the flag.
The vague "Ears, eyes, nose and mouth" clue is worrisome, but we'll get to that later.

Opening Blender we get a cube in the middle of the scene:


First we need to rename the way_out.obj to way_out.fbx for Blender to recognize it.
Deleting this cube and going to File > Import > FBX (.fbx) we can import our way_out.fbx file.


It looks like we have some nodes entering the scene including multiple Objects, Clues and a Key.

If we press the z key, it will turn off shading and go into wireframe mode.  We can zoom into see the first clue within the Key object:


Converting this to ASCII is simple with some python:

$ python
>>> chr(0b00110011) + chr(0b01111101)
'3}'

Looking back at the challenge description, we see 'Inside the key => 3}', which is now validated.
In the distance we can also see that cone includes some clues in it as well.


Now we have a bunch of coordinates in the description, we need to get around in this scene somehow.
We'll use the camera for that, if we zoom back out we can see the camera object to select:


With the camera selected, we can enable the Objects panel in the bottom right section of the UI:


This will allow us to transform the camera and move around the scene with ease.
We'll have to enable the camera by going to the bottom right View > Camera menu item.




Right now we'll want to enable shading again by hitting the 'z' key (this will become important soon) so we can see material colors.

Let's visit the first coordinate listed in the clues:

0 - P(100, -5, 321), R(0, 90, 0) => pctf{

To do this, we'll enter these coordinates in the Location & Rotation fields of the Object Panel:


We get this..... Not too useful....


If we zoom out slightly we see our first green value P(101.37,-5.31,320.99002), R(69,90,-1.6):



As the clue above hints at this also decodes to 'pctf{'.  Great! We're getting somewhere!

It's also worth noting at this point, the red values do not decode correctly to printable characters.
The hint mentions "You will never find a way out without colors." which in this context means -   green = good; red = ignore.

Next we'll go to #1, entering the coords we land inside a cube with a single character inside the clipping plane (for the remainder of challenges we'll use this plane as a boundary guide):


This decodes to '3'.

On the next one we have to zoom in a little (mouse wheel), also includes a red herring:


This decodes to 'd'.  Hey! we got 3d, maybe the flag spells something ; )

For #3, this was another where the camera is out of view because it landed right on top of the bits:


This is '>'.


With #4 we're placed between two objects, we need to zoom out slightly to check the green bits:


This is '2'.

Now we're at the dreaded monkey!  From the clues with vague descriptions:


Going into wireframe mode ('z') and clicking the clues in the object list we see where they are:



If you press spacebar, type separate, enter > by material, we'll be able to split these meshes into groups based on red & green, this could help soon.  We can also select the monkey and separate 'by loose parts' so we can select the head and use focus to work on that object alone.





We can also press the 'h' key on the monkey mesh to hide it while we work with the bits, that may also help.

The rest will be abbreviated.  We'll just need to travel from right to left for each entity copying the green values:



These decode to 'df0l1f', wrapping up the remaining pieces of the flag.

Adding everything together, we get the full flag:

pctf{3d>2df0l1f3}