tl;dr
- Make a GET request to
/gettoken%3fcreditcard=mmm&promocode=FREEWAF
to get the token. - Using the token make another request with
{"name":"' union select flag, 1, 1, 1 from flag -- -", "name":"x"}
to get the flag.
No. Of Solves: 28
Challenge points: 165
Solved By: Az3z3l, imp3ri0n, 1nt3rc3pt0r, Captain-Kay
Challenge Description
We needed to upgrade this app but no one here can code in Go. Easy fix: just put a custom waf in front of it.
Source Code: here
Analysis
With this challenge, we are given two files in which waf.py
acts as a front-end server, and main.go
is as a back-end server. On opening up the website, we see that in order to use the search function, a token is needed. And, to get the token, a promo code is to be submitted.
We have a promo code in main.go
:
1 | if promo == "FREEWAF"{ |
However, this promo code is blocked by the flask front-end server, and is not passed on to the back-end server.
1 | def catch_all(path): |
There is also a possibility of SQL Injection in the searchWaffle
function in main.go
, as the variable is directly concatenated with the SQL query.
1 | query := "SELECT name, radius, height, img_url FROM waffle " |
Now, our aim is clear. We first need to the front-end server to forward the promocode
to the back-end server and get the token. Then, with the token, we have to exploit the SQL Injection in main.go
.
Solution
Extracting Token
The catch_all
function, uses urllib’s unquote method to replace %xx escapes with their single-character equivalent. It then uses request.args
to get values from the parameters.
1 |
|
To bypass these checks, we urlencode the ?
, and make a get request to /gettoken%3fcreditcard=x&promocode=FREEWAF
. With this, the Flask server does not detect any arguments.
Both promo
and creditcard
variables will beNone
and the variable path
will contain gettoken?creditcard=mmm&promocode=FREEWAF
. This bypasses the checks and forwards the request to the back-end server, and we get the token.
token=LQuKU5ViVGk4fsytWt9C
Now, we have obtained access to search method.
Exploiting SQL Injection
We have already identified that there is a possibility for SQL Injection in searchWaffle
method in main.go
. However, there are some checks implemented in the front-end server for mitigating this.
1 |
|
The search
method in the front-end server uses Flask’s JSON parser whereas the back-end server uses a custom JSON parser.
There can be differences in how different JSON parsers parse data. And this could lead to inconsistency. This is called JSON interoperability (Read more about this here).
1 | { |
The JSON Parser at front-end takes the second value of name
whereas the back-end JSON parser takes the first value for name
. This helps us to bypass the checks and this causes in an SQL Injection in back-end.
Exploit Script
1 | import requests |
Flag
1 | ptm{n3ver_ev3r_tru5t_4_pars3r!} |