Evasión del filtro de inyección SQL

0

Durante las pruebas manuales de inyección de SQL, me topé con esto.

¿Hay alguna forma de evitar estos filtros que supuestamente impiden un ataque basado en 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/>";
}
}
?>

Además, ¿cuál es la mejor manera de prevenir un ataque SQLi basado en UNION ?

    
pregunta Rummy Khan 28.08.2014 - 13:12
fuente

3 respuestas

3

Puede explotar la comparación != del valor de retorno de strpos y false como 0 != false es falso:

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

Esto se debe a la conversión de tipo implícita boolean , donde 0 es convertido a false .

Así que solo necesitas asegurarte de que strpos devuelve 0 , lo que significa que $id debe comenzar con union o select , por ejemplo:

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

Dado que strpos($id,"union") devuelve 0 , strpos($id,"union")!=false es falso, $counter se incrementa solo una vez y la consulta se ejecuta con el SQL inyectado.

    
respondido por el Gumbo 31.08.2014 - 19:27
fuente
2

En teoría, creo que esto se puede evitar usando HPP (contaminación de parámetros HTTP), por ejemplo

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

counter==2 se omitirá de esta manera.

Otra forma en la que creo podría ser usar comentarios como

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

Otra cosa a tener en cuenta es que para evitar esto, podemos probar que el contador es falso usando una selección de unión legítima como en HPP o una selección de escritura por escritura de una manera que no cuenta como en el segundo ejemplo. Creo que la mejor manera de usar filtros de palabras clave es usar expresiones regulares.

Tampoco se considera la inyección de doble consulta.

    
respondido por el Haider Qureshi 28.08.2014 - 14:45
fuente
1

La inyección SQL no requiere el uso de union o select . La inyección de SQL significa que la propia estructura de consulta ha sido modificada por la entrada del usuario.

¿Qué tal si $id es ' OR '1'='1 ?

Esto hará que tu consulta se convierta en

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

lo que significa que todos los registros serán devueltos.

La solución es utilizar declaraciones preparadas que tratan las variables como variables en lugar de parte de estructura de consulta.

    
respondido por el SilverlightFox 28.08.2014 - 15:12
fuente

Lea otras preguntas en las etiquetas