We want this CTF to be perfect! As we hope you all know this requires us, as good software engineers, to design a specification we can devolop challenges against. So we started meticulously crafting documents for our scope statements and product requirements. Somehow this got a little out of hand (we really don’t know how. We set a timeline and used a strict waterfall model. Theoretically this should have worked out perfectly…) so we need your help to finish the requirements document before it’s to late… Specifically I have a problem with the The root of all evil challenge. I designed a beautiful solve script sequence diagram to prove this challenge is solvable. Since I didn’t want to type the flag out I just shoved a piece of paper into the disk drive and somehow this mess appeared in my diagram… Tragically, before I could save it, my cat ate the original piece of paper with the flag I need. But I have a feeling this weird assortment of symbols contains some info about the flag. Could you please recover it for me? I desperately need it to check the solutions to the challenge. If it helps: I used PlantUML for my diagram Please help me!!!!

Category: misc

Solver: Liekedaeler, MarDN, linaScience, tn1088, abc013

Flag: GPNCTF{its_timezones_not_unicode}

Writeup

We are presented with a website called “Underroot”. It allows us to enter a description which is then rendered into a diagram served as a png. The challenge description gives us the hint that the diagram was generated using PlantUML. So first idea was seeing if we can’t exploit that in some way.

First idea: Injection

We tried injecting some kind of PlantUML to maybe get a file read or something similar. Indeed we could send valid PlantUML and have that rendered, but we couldn’t get a file read. Why exactly that is the case is hard to tell, but PlantUML has a “SANDBOX” mode which could be preventing our file read. We then quickly moved away from this approach as it didn’t seem very promising given the challenge description and the huge blob of symbols we got.

Second idea: What do all these weird symbols mean?

The challenge description says “But I have a feeling this weird assortment of symbols contains some info about the flag”. So, somehow, all these symbols have to be an encoding for the flag. Actually, there are even more symbols than we could see because the diagram is cut off. So the first step is recovering all the missing symbols. To do that, we downloaded the image and wanted to get a better idea of what happened to the image. First choice: exiftool. As it turns out, this was a great choice because PlantUML places the UML used for generation of the image into the metadata. Now we had the UML, which contained all the symbols. (Editor’s note: Getting the symbols this way wasn’t the intended solution. Instead, you could get it using PlantUML debug commands) Armed with this data, we set off to parse it and figure out what kind of encoding this could be. We noticed it only uses four different symbols (which we verified by looking at the hex), so for easier representation we replaced them with the numbers 0,1,2,3 respectively. The result of that looked something like this:

0000020000220200000000200000002000000000000020000202020200220022202000220020222202200222222020020222220022222322232232232323223232323323233233233333333313313133113111311111111111311111111111111311<SNIP>

While that isn’t pretty, it helps with further understanding what kind of encoding it could be. We had a wide range of wild guesses as to what kind of encoding this could be. Those ranged from base4, as there were 4 different characters, to weird Duployan alphabet shenanigans. Unfortunately, none of these actually made any sense. The base4 would only yield garbage because it wasn’t random enough while the Duployan letters used also wouldn’t lead to any kind of flag. But at least we now know how Duployan shorthand works :D We also tried numerous other ideas of course, some of which ended up crashing poor Cyberchef.

Our next guess came back to the name of the challenge, which includes the word “root”. That led us down quite the rabbithole trying to take roots of the numbers this could encode. However, none of this ended up making any sense at all and we went back to the drawing board.

Finally, we turned our attention to a very different idea. Instead of this being a simple encoding, it could also represent directions. Why? Because we only had 4 characters, each corresponding to a direction. Also, we noticed that 1 and 2 as well as 0 and 3 seemed to avoid each other. If we think of them as directions, that would make sense if they’re opposing directions. They’d just cancel each other out.

At this point, the theory seemed quite plausible and we were pretty confident it should be correct. To actually test it, we wrote a little python script that plotted the directions and it indeed greeted us with the flag, written in a blender file:

import bpy

text="0000020000220200000000200000002000000000000020000202020200220022202000220020222202200222222020020222220022222322232232232323223232323323233233233333333313313133113111311111111111311111111111111311111311111111011101101101101101101101101011010110101101010110101010101101010101001010101001001001000100000000000002000200002000022220222202000220220222022222222222223222322322323323333111311111101101101011010110101011010110101101011010110110110110111011111111011111111131111131113113113311313313133313313333332332332323232232232222222022222022220202022202002002020222022022222002222000020222002022022022202220222202222222022222223222222222222222232232222222222223222223222223222232222322232222322232232223222322322322232232232232232322323223232322323323331331311111311311111123232232223222220222020222222020020220020220020020222200220200200002220022020000000000000010010010100101010101011010110110111011110111111111111113113111313313113113331333331111311311133131333333311101111011110111101111011101110111011011011011011101101101101011011010101101010010010000000200002002020202202020000220202022020202202202020202002222022222222222202222222222222222222223223222222322223222222222232322322232222322232223223223222322322322322322322323222323223223223223223223223223232232323232323323233233232333300002000001000010010001001001001010010101010010101010101010101010101011010101011010101011010101101011010110101101101101011011010110110101101010101101010101010101010101010123223232232322323223232232232232223222322223222223222222232222222222222222222222222222222222222222202222222222022222222222223222223222223222232222222232203202222222202220222022022022022020202020202020202020200200222200000002220200002002220002002000202002002020002000002213331331331331331331331313313313133133131313311131311311133131133111311311311311331111331113333111131111113113111011111011110111011101110110110110110110110101101011010101101010101101010101010101010100101010100101010010010000100010000100000001000000000200000022000020020020202220002000002000220020002002202200022200202222022020020220020002202022202022002002000020202200022222220022200200020200220222222222222202222222222222222220222222222202222222222220222223223223223223223223223223232232232232322322322322323223223232232232322322323223223232232232322322323223223232232322322323223233133131311333331331331111313331133333311133311111333133331111111131113313333313133111313020202002000202222200002202000220002022022200222202000022220220222202222220222222002200000020202020220220000022020000220002020220000222002220022000200202000000002002022213111113133111331311333111311331111331331311113133331311331131331111331333330110110110101101101101101101101101011011011011011011011011011010110110110110110101101101101011011010110101101011010101011010101010101010101001010010010001021000000002200200000000000000000022002200202020020202020202020202020202020202020220222020222202002022022222222200202222222333322223322333322233232222222223233233222222222223233222333323222223322223222232223333222222222222333223332232232222322323223223232232322323223232323232323323333333311111111111111110010000000200002020202020202202222220222022202220222200022000222002000022020000200222222202000022200220200222200222000202200022011311311113313313133333133331333331311111133131113311311313113331133313113113113333311131311113133111100100111011001111110010010011111101011010101101010100222002000000200002200202002200202022022202020022022020020202220202022222023133111111333113331331311111133113313311331113311111313311333111133131331331100111010011111111001001111100110000011111011100010110011110010001001011110111101111111100000001101101020220020000000202020020200022022002020220202220022220020222020200020020002202000202022222220220002022200202202222222222223222233222222222222222222222222222222222222322232222322223222232222322232223222322232223222322322232223222322232223222322223222232222232222222222222022220222202202220220220202202020220202020220202020202021313113131311131311311113111111011110111011011011010110101011010101011010101101010110101101010110101101101110111111311313120020202002000000100101010101010110101101010101101010101010101001000100000000020000020020202020020200202022222020002020202220220020022220200222222222022222222222322222222322322232322322322322323223232232322300101011000100110011100100010111101111111010101011010001000000000202020020022022220222222222223222222322222322222222222332332223232232322222232223322222222222222232232233222223222232222222222232322232223221111101011101101011011101101111101100111111010000020200220002022222213133111113311313133113333131131333331331113331333131120020020020022000200000100101010110110111100100011010100110011000011100101000100110011110220222222222223222223222222222222232232222222322222222222222222002000000000000002000000000010001001001010101010111011111131113113133333313133311300000200020002222000202202000200000100101001010101020202020200222020200002000000220202200220222202020200020222020020022220020202232332233232222322232222322232333222222222020222222222002022202222023222223222322232232223223223222322322322322322322322322322322322322322322323110010010101101101111000011110000020202013331313331131133113131111313333313302020202002020000011101111010011110101001001100011001100111110001000100000000002002002000202002220222202222222222222223322222222232232232232232232322323223201001100111111110011001110110001111001010101001010000000000020200202222323222233222222232323223223223232232232232223223222202020020200200202020002000000100101021011110101110110001111011010000011113332222232322222323322232222322322323322232222220220202002020000000101010110101011010110101101011011010110112322322223222322332222333323233222232222222220220220200000001100010110101101101101101011010110101000100002022022000222022020222022222022202222222222223222223223223223233233333313131311311111111111113011101011010100101000100001000000000020002200020002022202002200220220222022222222232222232223222232222322223222222232222022220200222022020202020020000202002200202000222222202201111011110111110011111111111111111111111113111131113113113113313131333022202220002020020020002202002202220022002200200002222000222220002202202222222022223222233222322232232232232223222322222222222022020220202020202020202013131311313111131331111110111010110101010100100100000000000020002020202202220222322222322322323232323232332323332333333330220200020022000000000000000202220002200020002222022222222222222220222022022200020000000101110000010101101101011011011011011011033322333222222322222322332322232222222222202202020000000020000100101101011101101110110110101001000022200220020202022200220222222222220202222022223222232322323323233333131333111111111101101101101101011010101001001000000020200200202022202202220020220222222222222222222223222222222222222222022202220222222222322223222322101011001001010000100000000002000020000001010101010110111011111311131331113131331333100200000022202022022002022020000220202020222022222022000001010101010110110102020202020202020202020202020202020202020202020202020202020202020202023332232222333322322232232233323223232322323232232232232232222322222222222020220202020202000000001001010101011010101101011010110110101101101011322232322223222232323323233222222322222222222022022000220202020012010101001110010111011110110110101010100000000020020022200222022222232322233223232232232232232223222232222222022220202020002220022020233111113131113331111110111011010101010101001001001000010000000020020202202020222223222223223223223232322323323233233323333133331330002000220220000002000022220222202202020200222222220222222222032222322322322322323223223232232232322322322321001011001101110101001111101010000202002111333133111311133331333020200200000111110001001110101011010101011010101010100101000100000000020200002020220222022020220100010101001010101010120200222000022000000022022202022222200200022022322322232222322323223222222222022202232223232322322222222222222232223222322232232223220011111110110111110111110100011010110101011010100101001000000002020202022222222202223323223222323222323223232232322323223232232323223201100111010000110011111101101110010101011001010100101000010000002000202220202222232222322223223222322322322323232323223232222020202200200200100010101010101010110101101011011011101110111022323323232222222222322222323223322322222022022020200020000010010101010110110110110110110100100002020202222222222222223222232223222322322322322301011011100011011111011010110101010010000020020202202022202220222222022220222222232322222223222222223222222222220202002022002222020202002020033313113113113313311311311311113111111110110110101010101001001000100000000200000022222022022220222222222222223222222223222222222220222202220220220220202020202020023113131111331333113311131111113311111111011110110101010101001001000000020002002022002022222220222222223222322232322322323233232323323020000000212022020220000020200220222022022202222222222220222220200022020002020020000200000000333333313333311333131313131311311111111330011111111101100101010100100100010000000000202002020202202222023223222223222232232222222222222223323333222232333323223232232232322322322323223223232232232322323223200011011110011011111111101111001010010001111110001101011110110101101101101011011011010110110101010101001000000200202020220222222220202202000202202222220022020222202222220222220222322222223332223232333233333233133133133111311111111111101111011101101101101101010110101010010010010000020000200020020022220200020022000202220202202220222202002202200020020222202000020000000000000000020000200200202200202222223232232322323232323232332323233233233233233233232332323232322322322222322222222220220220200202020200231111131331311333313331333333333333233232332323232323232322323223223223223223223232232322322323232323232323323323333313313131313311111133111131333"

vertices=[]

px = 0.0
py = 0.0
for c in text:
    if c == '0':
        px = px + 1
    elif c == '1':
        py = py + 1
    elif c == '2':
        py = py - 1
    else:
        px = px - 1
    vertices.append((px, py, 0.0))

new_mesh = bpy.data.meshes.new('new_mesh')
new_mesh.from_pydata(vertices, [], [])
new_mesh.update()
new_object = bpy.data.objects.new('new_object', new_mesh)
bpy.context.collection.objects.link(new_object)

flag image

This was much to the amusement of some other team members whom we had asked for ideas earlier. They had proposed this exact idea long ago but we had ignored it. As this was still a first blood we couldn’t really complain though.