ez-sql
Category: Web
Description
just your average sql challenge, nothing else to see here (trust)
Attachments: app.js
Write-up
When we access the provided URL, we are presented with the following page:
Upon analyzing the source code, the /search
endpoint catches our attention. It performs a validation check on the name
query parameter before using it in a SQL SELECT
query. This endpoint appears to be vulnerable to SQL injection through the name
parameter, as there is no input sanitization present.
Furthermore, we need to utilize SQL injection to extract the flag, which was inserted into a separate flag table during the server initialization process.
Text Only | |
---|---|
Since the flag table name is concatenated with a random value, we first need to leak the actual flag table name before we can query its contents. Considering that the database used is SQLite, we can employ the following SQL query to extract the database metadata, including table names.
Text Only | |
---|---|
However, there is a length check for the name
query parameter, which must be less than 6 characters. To bypass this limitation, we can employ HTTP parameter pollution by specifying the name
parameter twice. By doing so, the backend will interpret our name
parameter as an array instead of a string, resulting in name.length == 2
. When this array is used in the SQL query, it will used the string representation which are the elements of the array joined by a comma (,
).
Here's an example ExpressJS code snippet to demonstrate the behavior:
When we access /?name=hello
, we get the following output:
However, when we access /?name=hello&name=world
, we get the following output:
Therefore, we can use the following GET request to bypass the length check and retrieve the table names:
Text Only | |
---|---|
From the retrieved table name, we can proceed to extract the contents of the table using:
Text Only | |
---|---|
The corresponding GET request looks like this:
Text Only | |
---|---|
Flag: tjctf{ezpz_l3mon_squ33zy_603f8e08}