Cheat sheet

Databases

Name
Description

mysql

Requires root privileges

information_schema

Availalble from version 5 and higher

Commentaires

Type
Description

#

Hash comment

/* MYSQL Comment */

C-style comment

/*! MYSQL Special SQL */

Special SQL

/*!32302 10*/

Comment for MYSQL version 3.23.02

-- -

SQL comment

;%00

Nullbyte

`

Backtick

Test

  • Strings: Requête du type SELECT * FROM Table WHERE id = 'FUZZ';

    '       # Faux - Une seule apostrophe casse la requête, provoquant une erreur.
    ''      # Vrai - Deux apostrophes ferment correctement la chaîne, indiquant une injection réussie.
    "       # Faux - Un seul guillemet double, casse la requête.
    ""      # Vrai - Deux guillemets doubles ferment correctement la chaîne.
    \       # Faux - Un seul antislash casse la requête.
    \\      # Vrai - Deux antislashs s'échappent correctement, indiquant une injection réussie.
  • Numeric: Requête du typeSELECT * FROM Table WHERE id = 5;

    AND 1        Vrai   # Toujours vrai, pas d'erreur ; confirme une injection réussie.
    AND 0        Faux   # Toujours faux, provoque l'échec de la requête.
    AND true     Vrai   # Logiquement vrai, confirmant une injection réussie.
    AND false    Faux   # Logiquement faux, provoque l'échec de la requête.
    1-false      Renvoie 1 si vulnérable  
    1-true       Renvoie 0 si vulnérable 
    1*56         Renvoie 56 si vulnérable 
    1*56         Renvoie 1 si non vulnérable 
  • Login: Requête du type SELECT * FROM Users WHERE username = 'FUZZ1' AND password = 'FUZZ2';

    ' OR '1         # Contourne l'authentification en renvoyant toujours vrai.
    ' OR 1 -- -     # Termine la requête prématurément, permettant l'accès.
    " OR "" = "     # Semblable à ci-dessus mais avec des guillemets doubles.
    " OR 1 = 1 -- - # Termine la requête prématurément, toujours vrai, contourne l'authentification.
    '='             # Peut contourner l'authentification selon l'implémentation.
    'LIKE'          # Souvent utilisé dans des requêtes où une correspondance est faite ; peut contourner les filtres.
    '=0--+          # Termine la requête prématurément avec une condition fausse.

Déterminer le nombre de colonnes

ORDER BY

GROUP BY

ERROR BASED

Utilisation de ORDER BY

Testez avec un grand nombre de colonnes dans la clause ORDER BY pour identifier combien sont utilisées :

  • Erreur Possible: Unknown column '4' in 'order clause'

  • Interprétation: Indique que la requête utilise seulement 3 colonnes.

circle-info

Pareil avec GROUP BY

Utilisation de UNION SELECT

Lorsque les erreurs sont activées, utilisez UNION SELECT pour déterminer le nombre de colonnes :

Utilisation de LIMIT INTO

Si l'injection se fait après une clause LIMIT, utilisez cette méthode pour vérifier le nombre de colonnes :

  • Erreur Possible: The used SELECT statements have a different number of columns

  • Interprétation: Si aucune erreur n'apparaît avec 3 colonnes, la requête utilise 3 colonnes.

Extraction - information_schema

Extraction sans information_schema

MySQL >= 4.1.

Extraire le Nombre de Colonnes

Extraire les Noms des Colonnes

Method for MySQL 5

Extraction - sans Nom de Colonne

  • Extraire la 4ème Colonne

  • Explication : La requête UNION combine des colonnes fictives (1 à 6) avec les colonnes de la table users. On sélectionne ensuite la 4ème colonne de ce résultat combiné. Si la table users a moins de 6 colonnes, les colonnes fictives ajouteront des valeurs NULL pour les colonnes manquantes

Exemple d'Injection SQL

Si vous avez une requête comme :

Injectez cette valeur :

  • Explication : L'injection UNION combine les résultats de la table posts avec une sous-requête qui extrait les données de la 3ème et 4ème colonnes des résultats combinés.

  • 0x3a = :

MYSQL Error Based

Méthode de Base

Cette méthode fonctionne avec MySQL >= 4.1. Elle exploite les erreurs pour obtenir des informations

Explication : Cette requête exploite les erreurs pour vérifier si la version de MySQL est affichée en utilisant des calculs et des concaténations.

Fonction updatexml

Versions Simplifiées

Extractvalue function

Works with MySQL >= 5.1

NAME_CONST function (only for constants)

Works with MySQL >= 5.0

MYSQL Blind

MYSQL Blind with substring equivalent

MYSQL Blind using a conditional statement

TRUE : Si la version de MySQL commence par 5 :

Réponse : HTTP/1.1 500 Internal Server Error

FALSE : Si la version de MySQL commence par 4 :

Réponse : HTTP/1.1 200 OK

MAKE_SET

LIKE

  • Le caractère _ dans LIKE fonctionne comme le caractère . en regex. Il représente un seul caractère.

Trouver un code client avec un nom spécifique :

Ici, k__l recherche des noms de clients commençant par k, suivis de deux caractères quelconques, et se terminant par l.

Rechercher un produit avec un nom contenant une entrée utilisateur :SELECT * FROM products WHERE product_name LIKE '%user_input%';

Remplacez user_input par l'entrée recherchée pour trouver les produits dont le nom contient cette chaîne.

MYSQL Time Based

The following SQL codes will delay the output from MySQL.

  • MySQL 4/5 : BENCHMARK()

  • MySQL 5: SLEEP()

Using SLEEP in a subselect

Using conditional statements

MYSQL DIOS - Dump in One Shot

MYSQL Current queries

This table can list all operations that DB is performing at the moment.

MYSQL Read content of a file

Need the filepriv, otherwise you will get the error : ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

If you are root on the database, you can re-enable the LOAD_FILE using the following query

MYSQL Write a shell

Into outfile method

Into dumpfile method

MYSQL Truncation

In MYSQL "admin " and "admin" are the same. If the username column in the database has a character-limit the rest of the characters are truncated. So if the database has a column-limit of 20 characters and we input a string with 21 characters the last 1 character will be removed.

Payload: username = "admin a"

MYSQL Fast Exploitation

Requirement: MySQL >= 5.7.22

Use json_arrayagg() instead of group_concat() which allows less symbols to be displayed

  • group_concat() = 1024 symbols

  • json_arrayagg() > 16,000,000 symbols

MYSQL UDF command execution

First you need to check if the UDF are installed on the server.

Then you can use functions such as sys_exec and sys_eval.

MYSQL Out of band

DNS exfiltration

UNC Path - NTLM hash stealing

MYSQL WAF Bypass

Alternative to information schema

information_schema.tables alternative

Alternative to version

Scientific Notation

In MySQL, the e notation is used to represent numbers in scientific notation. It's a way to express very large or very small numbers in a concise format. The e notation consists of a number followed by the letter e and an exponent. The format is: base 'e' exponent.

For example:

  • 1e3 represents 1 x 10^3 which is 1000.

  • 1.5e3 represents 1.5 x 10^3 which is 1500.

  • 2e-3 represents 2 x 10^-3 which is 0.002.

The following queries are equivalent:

  • SELECT table_name FROM information_schema 1.e.tables

  • SELECT table_name FROM information_schema .tables

In the same way, the common payload to bypass authentication ' or ''=' is equivalent to ' or 1.e('')=' and 1' or 1.e(1) or '1'='1. This technique can be used to obfuscate queries to bypass WAF, for example: 1.e(ascii 1.e(substring(1.e(select password from users limit 1 1.e,1 1.e) 1.e,1 1.e,1 1.e)1.e)1.e) = 70 or'1'='2

Conditional Comments

  • /*! ... */: This is a conditional MySQL comment. The code inside this comment will be executed only if the MySQL version is greater than or equal to the number immediately following the /*!. If the MySQL version is less than the specified number, the code inside the comment will be ignored.

    • /*!12345UNION*/: This means that the word UNION will be executed as part of the SQL statement if the MySQL version is 12.345 or higher.

    • /*!31337SELECT*/: Similarly, the word SELECT will be executed if the MySQL version is 31.337 or higher. Examples: /*!12345UNION*/, /*!31337SELECT*/

Wide byte injection

Wide byte injection is a specific type of SQL injection attack that targets applications using multi-byte character sets, like GBK or SJIS. The term "wide byte" refers to character encodings where one character can be represented by more than one byte. This type of injection is particularly relevant when the application and the database interpret multi-byte sequences differently.

The SET NAMES gbk query can be exploited in a charset-based SQL injection attack. When the character set is set to GBK, certain multibyte characters can be used to bypass the escaping mechanism and inject malicious SQL code.

Several characters can be used to triger the injection.

  • %bf%27: This is a URL-encoded representation of the byte sequence 0xbf27. In the GBK character set, 0xbf27 decodes to a valid multibyte character followed by a single quote ('). When MySQL encounters this sequence, it interprets it as a single valid GBK character followed by a single quote, effectively ending the string.

  • %bf%5c: Represents the byte sequence 0xbf5c. In GBK, this decodes to a valid multi-byte character followed by a backslash (\). This can be used to escape the next character in the sequence.

  • %a1%27: Represents the byte sequence 0xa127. In GBK, this decodes to a valid multi-byte character followed by a single quote (').

A lot of payloads can be created such as:

Here is a PHP example using GBK encoding and filtering the user input to escape backslash, single and double quote.

Here's a breakdown of how the wide byte injection works:

For instance, if the input is ?id=1', PHP will add a backslash, resulting in the SQL query: SELECT * FROM users WHERE id='1\'' LIMIT 0,1.

However, when the sequence %df is introduced before the single quote, as in ?id=1%df', PHP still adds the backslash. This results in the SQL query: SELECT * FROM users WHERE id='1%df\'' LIMIT 0,1.

In the GBK character set, the sequence %df%5c translates to the character . So, the SQL query becomes: SELECT * FROM users WHERE id='1連'' LIMIT 0,1. Here, the wide byte character effectively "eating" the added escape charactr, allowing for SQL injection.

Therefore, by using the payload ?id=1%df' and 1=1 --+, after PHP adds the backslash, the SQL query transforms into: SELECT * FROM users WHERE id='1連' and 1=1 --+' LIMIT 0,1. This altered query can be successfully injected, bypassing the intended SQL logic.

References

Last updated