SQL injection (SQLi)

sqlinjectionfundamentals SQL Injection sql-injection-payload-list sqlinjectionlm sqlilab validation sql_injection_authentication sql_injection_string sql_injection_numeric sql_injection_routed sql_injection_error

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.


SQLi payloads

NameExpected SQLPayload
Usual PoCSelect [...] where xxx='here' [...]'
The query will fail as there would be 3 quotes,
and that would confirm that an injection is possible.
NoPasswordSelect [...] 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 StringSelect [...] where xxx='here' [...]' code -- -
Input box Non-StringSelect [...] where xxx=here [...]'' code -- -
UpdateUpdate [...] 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.

This section was moved here.


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 of invalid 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'/* and p=*/ OR ''='
  • Routed SQL Injection. Can use "0x" + "-1' union <payload>-- -".encode().hex() then select 0x<...>. sql_injection_routed
  • 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.