evasione filtro SQL injection

0

Durante il test manuale dell'iniezione SQL mi sono imbattuto in questo.

C'è un modo per aggirare questi filtri che presumibilmente prevengono un attacco basato su UNION ?

<?php
error_reporting(0);
include('db.inc.php');

$id=strtolower($_GET['id']);

$counter = 0;
if(strpos($id,"union")!=false){
    $counter++;
}
if(strpos($id,"select")!=false){
    $counter++;
}

if($counter==2) {
    echo "Go Away Get a Life";
}else{ 
echo "<font color=green size=4>Query Coming is : ".$id."<br/></font>"; 
$query = "SELECT username,password FROM admin WHERE username='".$id."' ORDER BY 1";

$result = mysql_query($query) or die(mysql_error());

while($row = mysql_fetch_array($result)){
    echo "Username : ".$row['username']."<br/>";
    echo "Password : ".$row['password']."<br/>";
}
}
?>

Inoltre, qual è il modo migliore per prevenire un attacco SQLi basato su UNION ?

    
posta Rummy Khan 28.08.2014 - 13:12
fonte

3 risposte

3

Puoi sfruttare il confronto != del valore di ritorno di strpos e false come 0 != false è falso:

var_dump(0 != false); // bool(false)

Ciò è dovuto a implicita conversione di tipo in booleano , dove 0 è convertito in false .

Quindi devi solo assicurarti che uno dei strpos restituisca 0 , il che significa che $id deve iniziare con union o select , ad esempio:

id=union' union select 'foo', 'bar

Poiché strpos($id,"union") restituisce 0 , strpos($id,"union")!=false è falso, $counter viene incrementato una sola volta e la query viene eseguita con l'SQL iniettato.

    
risposta data 31.08.2014 - 19:27
fonte
2

In teoria, penso che questo possa essere aggirato usando l'HPP (inquinamento dei parametri HTTP), ad esempio

?id=union select&id=union select ...

counter==2 sarà bypassato in questo modo.

Un altro modo in cui penso potrebbe usare commenti come

un/**/ion+se/**/lect 

Un'altra cosa da notare che per aggirare questo problema, possiamo provare il contatore falso usando la selezione unione legittima come in HPP o scrivere unione selezionare in un modo che non conta come nel secondo esempio. Penso che il modo migliore per usare i filtri per parole chiave sia usare espressioni regolari.

Anche la doppia interrogazione dell'iniezione non viene considerata.

    
risposta data 28.08.2014 - 14:45
fonte
1

SQL Injection non richiede l'uso di union o select . SQL injection significa che la struttura della query stessa è stata alterata dall'input dell'utente.

Come su dove $id è ' OR '1'='1 ?

Questo renderà la tua richiesta diventare

SELECT username,password FROM admin WHERE username='' OR '1'='1' ORDER BY 1

che significa che verranno restituiti tutti i record.

La soluzione è utilizzare istruzioni preparate che trattano le variabili come variabili anziché come parte del struttura della query.

    
risposta data 28.08.2014 - 15:12
fonte

Leggi altre domande sui tag