SQL injection (SQLi)
Most websites are using a relational database to store data, and the SQL query language to query the database.
When making a SQL request, a programmer may use the user input. For instance, a product name for a query to search a product.
A vulnerable PHP code use the user input directly in the SQL request:
$name = $_GET['name']; // filled by the user
$sql = "Select name from product where name LIKE '%$name%'";
There is a SQL injection when a user inputs SQL code, and the request interpret the user input as SQL code.
β
If the user enters the product name "yummy
"
Select name from product where name LIKE '%yummy%'";
β But, with the product name "' UNION SELECT "hacked"-- -
", the injected SQL code is executed just fine.
Select name from product where name LIKE '%' UNION SELECT "hacked"-- -%'
β‘οΈ A hacker may be able to fetch/create/update/delete records!
π₯ While SQL injections are known since 1998, they are still a frequent vulnerability found in applications. They are found in every language.
Tools π€
- sqlmap (discovery+exploitation)
SQLi categories
In-band SQLi πΈ is a category of SQLi attacks for those using the same channel to attack and to gather results.
Blind/inferential SQLi πΊοΈ is a category of SQLi attacks for which we observe the application response to infer results.
- Boolean-based
- Time-based
- Out-of-band-based
- Voice-based
- Stacked queries-based (
req1 ; req2
)
SQLi payloads
Name | Expected SQL | Payload |
---|---|---|
Usual PoC | Select [...] where xxx='here' [...] | ' The query will fail as there would be 3 quotes, and that would confirm that an injection is possible. |
NoPassword | Select [...] where username='here' AND password='...' [...] | ' OR 1=1 -- - The query will bypass the check of the password, if it was made in the query. We use 1=1 for maximum compatibility. |
Input box String | Select [...] where xxx='here' [...] | ' code -- - |
Input box Non-String | Select [...] where xxx=here [...] | '' code -- - |
Update | Update [...] set x='here',y=[...] | ',x=(code),y=' |
Other characters such as "
, )
, #
, ;
, and their URL-encoded versions can be used to detect a SQL injection.
π As Union-based are used in most other techniques, many payloads are here too.
SQLi Filesystem Attacks
SQL injections can be used to read/write files if the user as sufficient permissions. Aside from root, it's not common.
SQLi mitigations π‘οΈ
-
Use prepared requests (statements), they are ensuring that the parameters of your queries are not interpreted as SQL code
-
Input validation or escaping user input: You can filter and validate input, but you CAN'T rely on it, as your filter will most likely be bypassed. Front-end validations are not enough.
-
Do not trust anyone π. SQL injections may be delayed. For instance, one may have protected the login queries, but if someone submitted SQL code as their username, then any other request using the username may interpret it.
-
Keep quiet about errors πͺ². Do not display SQL/DBMS errors. Do not be too specific either. For instance, some use
invalid credentials
instead ofinvalid password
to prevent mappings.
- Apply the least privilege principle π«. Use accounts with the least permission. Restrict/Revoke file permissions.
Some network security devices such as a WAF may be configured to detect/block SQLi attacks and other common attacks.
Pentester By-pass/notes π
-
You can by-pass client side verifications by manually sending the form or directly interacting with the API (if any).
-
For manual SQLi, you may use the HTML tags "names" in the form first, as they may be the name of the attributes in the database.
π» To-do π»
Stuff that I found, but never read/used yet.
- sqlinjection.net
- Inline queries: a query in a query
-
/* */
is not often used in injections. Foolish example:u=admin'/*
andp=*/ OR ''='
- Routed SQL Injection. Can use
"0x" + "-1' union <payload>-- -".encode().hex()
thenselect 0x<...>
. -
select xxx,yyy,zzz [...] where [...] union select 'xxx','yyy','zzz'
: auth by-pass by hard-coded user creation - A program creating a file then deleting it =>
Disable inheritance, Convert to explicit, Select user > Edit > Show advanced permissions, uncheck both 'delete'
to prevent them from removing the file and allow us to read it.