Utilizzo manuale di SQL injection cieco nell'istruzione SELECT nell'intestazione X-Forwarded-For

3

Sto facendo fatica a sfruttare questa vulnerabilità nel seguente codice:

<?php
ini_set('display_errors', 0);

define("INDEX", 1);
include '../db.php';

if(isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  $query = "SELECT * FROM banned_ip WHERE ip='$ip'";

  $res = mysql_query($query);

  if(mysql_num_rows($res) > 0) {
      die('<h2>Banned!</h2>');
  }
}
?>

C'è un'iniezione sql cieca nell'intestazione X-Forwarded-For nel codice sopra. Ho provato diversi payload da Guida ai test OWASP e ho letto questo corso su Pentesterlab ma trovo ancora impossibile sfruttarlo.

Le mie ipotesi:

  • la tabella banned_ip è vuota, quindi questo controllo: if(mysql_num_rows($res) > 0) restituisce false. Ci deve essere un modo per inserire in questa tabella o eseguire la selezione da un'altra tabella per restituire una risposta diversa da zero.
  • Il database di backend sembra essere MySQL $res = mysql_query($query); quindi potrebbero esserci alcuni comandi che non sono a conoscenza di specifici di MySql che possono aiutare
posta jpiechowka 26.05.2017 - 10:52
fonte

2 risposte

2

Approcci non lavorativi (multi-query, inserimento / eliminazione / aggiornamento)

mysql_query non supporta la multi-query:

multiple queries are not supported

Ciò significa che l'aggiunta di un'altra query tramite ; per eliminare, modificare o inserire dati non funzionerà. Sei bloccato con la query di selezione che hai.

Possiamo anche vedere che i dati selezionati non sono visualizzati, quindi hai effettivamente un'iniezione cieca.

Approccio improbabile: scrivere un file di shell

In teoria, potresti provare a scrivere dati su un file, ad esempio per ottenere una shell PHP. Potrebbe assomigliare a questo:

' UNION SELECT '<?php passthru($_GET['x']);' INTO OUTFILE '/var/www/404.php' -- -

È tuttavia improbabile che tu disponga di autorizzazioni sufficienti per questo. Non avresti solo bisogno di un utente SQL che abbia il permesso di scrivere su un file e su una directory a cui l'utente mysql può effettivamente scrivere, ma il server mysql dovrebbe anche essere eseguito senza l'opzione --secure-file-priv , che non è il caso per impostazione predefinita nei sistemi moderni.

Leggi dati ciechi: basato su errori

Quanto sopra significa che l'unico vettore di attacco sta leggendo i dati dal database. Se sei fortunato, gli errori ti verranno mostrati.

Se vengono visualizzati degli errori, dovrai semplicemente creare un errore che contenga le informazioni che vuoi leggere. Un modo è utilizzare extractvalue :

' or extractvalue(1,version()) -- -

Invece di chiedere semplicemente la versione, puoi selezionare i nomi di tabella e colonna da INFORMATION_SCHEMA . Una volta trovate le tabelle interessanti, leggi i dati.

Leggi dati ciechi: basato sul contenuto

Forse eri sfortunato e gli errori non sono mostrati. Puoi ancora estrarre i dati chiedendo sì / no domande:

' AND substring(version(),1,1)='5

Come puoi vedere, l'intera query compresa l'iniezione restituirà true se la versione di MySQL è 5 e false altrimenti. Quindi, a seconda di cosa succede - lo script muore o non lo è - conosci la versione di MySQL.

Invece di chiedere la versione, puoi chiedere altri dati, ad esempio il primo carattere dell'hash della password del primo utente nella tabella utenti mysql.

Puoi ottimizzare l'approccio usando ASCII e chiedendo se il valore è più grande o più piccolo di un certo numero, e quindi restringi la finestra del possibile carattere.

Probabilmente vorrai utilizzare uno strumento o uno script personalizzato per lo sfruttamento effettivo, dato che avrai bisogno di molte richieste.

Leggi dati ciechi: basati sul tempo

Solo per completezza: se non ricevi alcun feedback (nessun messaggio vietato), puoi ancora sfruttare le iniezioni in selezione in base al tempo necessario per completare una richiesta.

L'idea è la stessa dello sfruttamento basato sul contenuto, ma invece di ottenere una risposta diversa, eseguirai un'attività lenta o meno:

' AND IF(SUBSTRING(version(), 1, 1)='5',BENCHMARK(50000000,ENCODE('MSG','by 5 seconds')),null) %23
    
risposta data 26.05.2017 - 14:20
fonte
0

Che cosa ti aspetti di essere restituito dalla query? È cieco quindi non puoi probabilmente vedere nulla.

Se lo hai distribuito nel tuo ambiente di test, puoi verificare se sei in grado di manipolare i record nel db. Da quello che posso vedere puoi sicuramente.

In questo caso, puoi:

X-Forwarded-For: '; DELETE * FROM banned_ip; '

durante la prossima richiesta l'IP non sarà più bannato se DELETE è permesso all'utente che collega il DB.

È difficile fare qualsiasi altra cosa se non si conosce la struttura della tabella / database. Se vuoi saperlo, puoi inserire l'IP lì e poi controllare se è vietato.

Puoi utilizzare un qualche tipo di strumento automatico che proverà a sondare varie tabelle e colonne sul valore da inserire (il cosiddetto attacco brute force ovviamente), quindi controlla se l'IP è stato bannato.

Inoltre, utilizzando questa vulnerabilità avrai accesso a tutto il database. Se c'è una tabella con gli utenti nominati (che è il 99,9% dei casi) con nome utente e password delle colonne, puoi provare a inserire un utente con pass hash con MD5, quindi SHA, poi SHA2 ... Ci sono così tante opportunità. ..

Ma non aspettarti che sarai in grado di vedere nulla. Ecco perché è chiamato "cieco".

Modifica: A proposito, posso vedere nell'esempio quello che devi ottenere. È esattamente scritto lì. E inoltre, è esattamente scritto lì come raggiungerlo. Fondamentalmente, dovresti ottenere l'accesso alla tabella degli amministratori e prelevare un hash della password da lì. Di conseguenza, devi attaccare l'applicazione utilizzando le credenziali di amministratore.

    
risposta data 26.05.2017 - 13:42
fonte

Leggi altre domande sui tag