web exploitation

gekyuel

Compfest

12 August 2020

Points: 50

Problem :lock:

We have an api endpoint, judging from the title, it might be a graphql api.

Solution :key:

First off is to google about graphql and learn the basics about it, and after that, we can try to give it a simple “introspection query”, which acts like a kind of fuzzing query.

?query={__schema{types{name fields{name}}}}

Now we have some idea about the structure of the database, we got some things that look like tables: game, developers, games. Let’s try looking into game.

query={games{id, name, genre, developer{name,id,games{name}}}}

We found an interesting game! Also an interesting developer, looks like the name is caesar ciphered (the dev name isn’t actually a clue) and the id is mocking us. Let’s try to search through the developers table.

?query={developer{id,name,games{id,name,genre}}}

Wierd, it doesn’t just dump the data of all developers like it did with games. I checked around to see if the query was wrong, but looks like it wasn’t so I tried to google some more. After googling, I tried to query for the devs but be more specific, let’s use that wierd name from before.

?query={developer(name:"dlyrddru_uqzbir_dlqrbz"){id,name,games{id,name,genre}}}

Wooot we got the flag! But I’m now confused and not satisfied. How is it possible that when we accessed the {developer{id}} from game we got “Do you think it would be that easy?” but if we accessed {developer{id}} from developer we got a different value?

So I went and did some more googling, I also found out about graphql voyager, I took their introspection query, changed all newlines into spaces (with tr) so that the query would be HTTP friendly, threw it at the api, gave the output back to gqlvoyager, and it showed me this mapping.

Well that just made me even more confused now, it clearly shows that the 2 tables are linked, which means that I was indeed accessing the same resource, right? First one, I accessed game table, and went to developers “sub table” and retrieved the id field. Second one, I accessed developers table directly, and retrieved the id field.

All I can think of is that

  1. we aren’t actually allowed to query the developers table, and so instead,
  2. if we put developers in the HTTP GET query, it’s calling a function which is also named developers,

which explains why it didn’t output anything when we didn’t specify any parameters, but when we did, it gave us an output.

But that’s just a guess, until now I still don’t know what’s really happening here, if you do, please tell me!

Flag :checkered_flag:

COMPFEST12{c0nv3n1Ence_i5_A_d0ubL3_eDged_SwoRD!}

Takeaway :books: