Foros del Web » Programando para Internet » PHP »

Problema con Inyección SQL!

Estas en el tema de Problema con Inyección SQL! en el foro de PHP en Foros del Web. Tengo una página la cual hace publicaciones de anuncios, bueno y ayer con un programa para buscar vulnerabilidades (acunetix) encontré que tenia esta grave vulnerabilidad, ...
  #1 (permalink)  
Antiguo 04/03/2011, 11:49
 
Fecha de Ingreso: septiembre-2010
Mensajes: 147
Antigüedad: 13 años, 6 meses
Puntos: 3
Problema con Inyección SQL!

Tengo una página la cual hace publicaciones de anuncios, bueno y ayer con un programa para buscar vulnerabilidades (acunetix) encontré que tenia esta grave vulnerabilidad, la cual puedo publicar a través del mismo programa muchos registros (anuncios).

Bueno desde entonces empecé a buscar formas de corregir este problema y encontré una función que debía aplicar en todas mis sentencias SQL cuando envió parámetros.

Entonces aplique esta función:

Código SQL:
Ver original
  1. INSERT INTO `publicaciones` VALUES(
  2.                                                                                     '',
  3.                                                                                     \"" .mysql_real_escape_string($idCiudad). "\",
  4.                                                                                     $idComuna,
  5.                                                                                     \"" .mysql_real_escape_string($idCategoria). "\",
  6.                                                                                     \"" .mysql_real_escape_string($idSubcategoria). "\",
  7.                                                                                     \"" .mysql_real_escape_string($nombre). "\",
  8.                                                                                     \"" .mysql_real_escape_string($email). "\",
  9.                                                                                     \"" .mysql_real_escape_string($telefono). "\",
  10.                                                                                     \"" .mysql_real_escape_string($titulo). "\",
  11.                                                                                     \"" .mysql_real_escape_string($contenido). "\",
  12.                                                                                     \"" .mysql_real_escape_string($precio). "\",
  13.                                                                                     \"" .mysql_real_escape_string($tipo). "\",
  14.                                                                                     \"" .mysql_real_escape_string($tiempo). "\",
  15.                                                                                     \"" .mysql_real_escape_string($imagen). "\",
  16.                                                                                     \"" .mysql_real_escape_string($random). "\"
  17.                                                                                 )";

Bueno está función no me arroja error y registra normalmente mi anuncio.

Luego volví al programita (acunetix) y aplique Start... Y bueno volvieron aparecer las vulnerabilidades Inyection SQL, y sucedió lo mismo, "puedo hacer inyecciones sql masiva e insertar miles de publicaciones.

No sé cómo puedo arreglar esto, ya que he aplicado lo que encontré sobre los escapes en las comillas, pero no paso nada. =/


Dejo mí un trozo de mi código donde valida un poco, ya que de todas formas en la página donde tengo el formulario valida todos los campos con jquery y además tiene un captcha, aún así se puede hacer estas inyecciones vía POST.

Código PHP:
Ver original
  1. if(isset($_SESSION['Random']) == isset($_POST['math']) && isset($_POST['idCiudad']) && isset($_POST['idCategoria'])){
  2.  
  3.     $idCiudad                           = $_POST['idCiudad'];
  4.     $idComuna                           = $_POST['idComuna'];
  5.     $idCategoria                        = $_POST['idCategoria'];
  6.     $idSubcategoria                     = $_POST['idSubcategoria'];
  7.        
  8.     $nombre                             = strip_tags(str_replace(array( '@', '¬', '/', '&', '%' ), '',$_POST['nombre']));
  9.     $email                              = strtolower(strip_tags($_POST['email']));
  10.     $telefono                           = $_POST['telefono'];
  11.     $titulo                             = strip_tags(str_replace(array( '@', '¬', '/', '&', '%' ), '',$_POST['titulo']));
  12.     $contenido                          = $_POST['contenido'];
  13.     $precio                             = $_POST['precio'];
  14.     $tipo                               = $_POST['tipo'];
  15.     $tiempo                             = date("Y-m-d H:i:s",time());
  16.     $random                             = rand(123456789,987654321);
  17.     $archivo                            = $_FILES['file']['tmp_name'];


Una Foto del programa, donde marco el boton Start y me realiza las miles de Inyecciones SQL a mi Base de datos...



Espero que alguién sepa como corregir esto y me ayuda, saludos!!
  #2 (permalink)  
Antiguo 04/03/2011, 18:55
Avatar de s00rk  
Fecha de Ingreso: octubre-2010
Ubicación: Mexico
Mensajes: 238
Antigüedad: 13 años, 5 meses
Puntos: 48
Respuesta: Problema con Inyección SQL!

Mira aqui ya explique un poco sobre esto y mostre un codigo que ayudaria en ello bastante, espero te sirva

http://www.forosdelweb.com/f18/inyec...5/#post3766702
  #3 (permalink)  
Antiguo 04/03/2011, 22:07
 
Fecha de Ingreso: septiembre-2010
Mensajes: 147
Antigüedad: 13 años, 6 meses
Puntos: 3
Respuesta: Problema con Inyección SQL!

Hola s00rk, aplique la función ! pero no me ha funcionado, las inyecciones siguen teniendo efecto.

Aquí puse la función cuando recibe los $_POST[] :

Código PHP:
Ver original
  1. <?php
  2. error_reporting(E_ALL & ~E_NOTICE);
  3. date_default_timezone_set("America/Santiago");
  4.  
  5.     include_once('../modelo/Publicar.php');
  6.    
  7.     if(isset($_SESSION['Random']) == isset($_POST['math']) && isset($_POST['idCiudad']) && isset($_POST['idCategoria'])){
  8.    
  9.     /*function seguridad($value){
  10.         return mysql_real_escape_string($value);
  11.     }*/
  12.    
  13.     /*  function escape($str){
  14.           $search=array("\\","\0","\n","\r","\x1a","'",'"');
  15.           $replace=array("\\\\","\\0","\\n","\\r","\Z","\'",'\"');
  16.             return str_replace($search,$replace,$str);
  17.       }*/
  18.        function clean($value)
  19.        {
  20.             $check = $value;
  21.             $value = preg_replace(sql_regcase("/(from|select|insert|delete|where|drop table|show tables|#|\*|--|\\\\)/"),"",$value);
  22.             $value = trim($value);
  23.             $value = strip_tags($value);
  24.             $value = addslashes($value);
  25.             $value = str_replace("'", "''", $value);
  26.  
  27.             if( $check != $value )
  28.             {
  29.                 $logf = fopen("logs/injection.txt", "a+");
  30.                 fprintf($logf, "Fecha: %s IP: %s Valor: %s, Corregido: %s\r\n", date("d-m-Y h:i:s A"), $_SERVER['REMOTE_ADDR'], $check, $value );
  31.                 fclose($logf);
  32.                 alertbox("Que intentas hacer? (: , Mejor mira esto xD", "http://www.google.com/");
  33.             }
  34.  
  35.             return( $value );
  36.         }
  37.  
  38.         if(!function_exists("alertbox")){
  39.             function alertbox($text, $url)
  40.             {
  41.                 echo "<body  bgcolor='#000000'><script>alert('$text');document.location = '$url'</script></body>";
  42.                 die("Javascript disabled");
  43.             }
  44.         }
  45.    
  46.  
  47.         $idCiudad                           = strip_tags(clean($_POST['idCiudad']));
  48.         $idComuna                           = strip_tags(clean($_POST['idComuna']));
  49.         $idCategoria                        = strip_tags(clean($_POST['idCategoria']));
  50.         $idSubcategoria                     = strip_tags(clean($_POST['idSubcategoria']));
  51.        
  52.         $nombre                             = strip_tags(str_replace(array( '@', '¬', '/', '&', '%' ), '', clean($_POST['nombre'])));
  53.         $email                              = strtolower(strip_tags(clean($_POST['email'])));
  54.         $telefono                           = strip_tags(clean($_POST['telefono']));
  55.         $titulo                             = strip_tags(str_replace(array( '@', '¬', '/', '&', '%' ), '', clean($_POST['titulo'])));
  56.         $contenido                          = clean($_POST['contenido']);
  57.         $precio                             = strip_tags(clean($_POST['precio']));
  58.         $tipo                               = strip_tags(clean($_POST['tipo']));
  59.         $tiempo                             = date("Y-m-d H:i:s",time());
  60.         $random                             = rand(123456789,987654321);
  61.         $archivo                            = $_FILES['file']['tmp_name'];

Al volver a inicar el programita (acunetix)



Luego :



Se aprecia que el metodo sql_regcase() dice que esta obsoleta :S
http://php.net/manual/es/function.sql-regcase.php

Bueno y al final con presionar Start y hacer las inyecciones, voy a la página y :





------------
Muestro mi método donde inserto a MySQL, el cual también he colocado la función: mysql_real_escape_string()

Código PHP:
Ver original
  1. // Método que hace inserción de una publicacion.
  2.         public function setPublicaciones($idCiudad,$idComuna,$idCategoria,$idSubcategoria,$nombre,$email,$telefono,$titulo,$contenido,$precio,$tipo,$tiempo,$imagen,$random){
  3.            
  4.             try{
  5.                 //Instanciamos la Clase Conexion para MySQL.
  6.                 $dbConectar     = new Conexion;
  7.                 $dbCon          = $dbConectar->conectarClasico();
  8.                
  9.                 if($idComuna == 0) $idComuna = 'NULL';
  10.            
  11.                
  12.                 $this->SQL      = "INSERT INTO `publicaciones` VALUES(
  13.                                                                         '',
  14.                                                                         \"" .mysql_real_escape_string($idCiudad). "\",
  15.                                                                         $idComuna,
  16.                                                                         \"" .mysql_real_escape_string($idCategoria). "\",
  17.                                                                         \"" .mysql_real_escape_string($idSubcategoria). "\",
  18.                                                                         \"" .mysql_real_escape_string($nombre). "\",
  19.                                                                         \"" .mysql_real_escape_string($email). "\",
  20.                                                                         \"" .mysql_real_escape_string($telefono). "\",
  21.                                                                         \"" .mysql_real_escape_string($titulo). "\",
  22.                                                                         \"" .mysql_real_escape_string($contenido). "\",
  23.                                                                         \"" .mysql_real_escape_string($precio). "\",
  24.                                                                         \"" .mysql_real_escape_string($tipo). "\",
  25.                                                                         \"" .mysql_real_escape_string($tiempo). "\",
  26.                                                                         \"" .mysql_real_escape_string($imagen). "\",
  27.                                                                         \"" .mysql_real_escape_string($random). "\"
  28.                                                                     )";
  29.                                                        
  30.                 mysql_query($this->SQL,$dbCon) or die(mysql_error());
  31.            
  32.                 //Cerramos conexion.
  33.                 mysql_close($dbCon);
  34.                
  35.             }catch(Exception $e){
  36.                 //Cerramos conexion.
  37.                 mysql_close($dbCon);
  38.                
  39.                 return $e;
  40.             }
  41.         }


Las Inyecciones SQL aún afectan a mi página :(

Ayuda!!!!! SOS

Última edición por ZeThito; 04/03/2011 a las 22:25
  #4 (permalink)  
Antiguo 04/03/2011, 23:53
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 2 meses
Puntos: 260
Sonrisa Respuesta: Problema con Inyección SQL!

Hola,

Cita:
Iniciado por ZeThito Ver Mensaje
if(isset($_SESSION['Random']) == isset($_POST['math'])
¿Que se supone que es eso? ¿Tu validación del captcha?

Saludos,
  #5 (permalink)  
Antiguo 05/03/2011, 00:05
 
Fecha de Ingreso: septiembre-2010
Mensajes: 147
Antigüedad: 13 años, 6 meses
Puntos: 3
Respuesta: Problema con Inyección SQL!

Hola =)

La validacíón del captcha esta con jQuery.

Cita:
if(isset($_SESSION['Random']) == isset($_POST['math'])
Esto es solo una validación para que el usuario no ingrese por Url a esta página,

Al final tengo:

Cita:
}else{header('refresh: 0; url = /web/'); }
  #6 (permalink)  
Antiguo 05/03/2011, 00:55
 
Fecha de Ingreso: septiembre-2010
Mensajes: 147
Antigüedad: 13 años, 6 meses
Puntos: 3
Respuesta: Problema con Inyección SQL!

Dejaré mi código, haber si alguien descubre mi problema =(

Recibo los Datos :

Código PHP:
Ver original
  1. <?php
  2. error_reporting(E_ALL & ~E_NOTICE);
  3. date_default_timezone_set("America/Santiago");
  4.  
  5.     include_once('../modelo/Publicar.php');
  6.    
  7.     if(isset($_SESSION['Random']) == isset($_POST['math']) && isset($_POST['idCiudad']) && isset($_POST['idCategoria'])){
  8.  
  9.     $idCiudad                           = strip_tags((int)$_POST['idCiudad']);
  10.     $idComuna                           = strip_tags((int)$_POST['idComuna']);
  11.     $idCategoria                        = strip_tags((int)$_POST['idCategoria']);
  12.     $idSubcategoria                     = strip_tags((int)$_POST['idSubcategoria']);
  13.        
  14.     $nombre                             = strip_tags(str_replace(array( '@', '¬', '/', '&', '%' ), '', $_POST['nombre']));
  15.     $email                              = strtolower(strip_tags($_POST['email']));
  16.     $telefono                           = strip_tags((int)$_POST['telefono']);
  17.     $titulo                             = strip_tags(str_replace(array( '@', '¬', '/', '&', '%' ), '',$_POST['titulo']));
  18.     $contenido                          = $_POST['contenido'];
  19.     $precio                             = strip_tags(floatval($_POST['precio']));
  20.     $tipo                               = strip_tags((int)$_POST['tipo']);
  21.     $tiempo                             = date("Y-m-d H:i:s",time());
  22.     $imagen                             = 'QsXzxcCsDvfD.png'
  23.     $random                             = rand(123456789,987654321);
  24.  
  25.    
  26.        
  27.         // Metodo para registrar una publicación.
  28.         $metodo = new Publicar;
  29.         $metodo->setPublicaciones(
  30.                                     $idCiudad,
  31.                                     $idComuna,
  32.                                     $idCategoria,
  33.                                     $idSubcategoria,
  34.                                     $nombre,
  35.                                     $email,
  36.                                     $telefono,
  37.                                     $titulo,
  38.                                     $contenido,
  39.                                     $precio,
  40.                                     $tipo,
  41.                                     $tiempo,
  42.                                     $imagen,
  43.                                     $random
  44.                                 );
  45.        
  46.         session_unset();
  47.         session_destroy();
  48.        
  49.  
  50.            
  51.     }else{
  52.             header('refresh: 0; url = /web/');
  53.     }
  54. ?>



Metodo para hacer el INSERT en MySQL.

Código PHP:
Ver original
  1. // Método que hace inserción de una publicacion.
  2.         public function setPublicaciones($idCiudad,$idComuna,$idCategoria,$idSubcategoria,$nombre,$email,$telefono,$titulo,$contenido,$precio,$tipo,$tiempo,$imagen,$random){
  3.            
  4.             try{
  5.                 //Instanciamos la Clase Conexion para MySQL.
  6.                 $dbConectar     = new Conexion;
  7.                 $dbCon          = $dbConectar->conectarClasico();
  8.                
  9.                 if($idComuna == 0) $idComuna = 'NULL';
  10.            
  11.                
  12.                 $this->SQL      = "INSERT INTO `publicaciones` VALUES(
  13.                                                                         '',
  14.                                                                         \"" .mysql_real_escape_string($idCiudad). "\",
  15.                                                                         $idComuna,
  16.                                                                         \"" .mysql_real_escape_string($idCategoria). "\",
  17.                                                                         \"" .mysql_real_escape_string($idSubcategoria). "\",
  18.                                                                         \"" .mysql_real_escape_string($nombre). "\",
  19.                                                                         \"" .mysql_real_escape_string($email). "\",
  20.                                                                         \"" .mysql_real_escape_string($telefono). "\",
  21.                                                                         \"" .mysql_real_escape_string($titulo). "\",
  22.                                                                         \"" .mysql_real_escape_string($contenido). "\",
  23.                                                                         \"" .mysql_real_escape_string($precio). "\",
  24.                                                                         \"" .mysql_real_escape_string($tipo). "\",
  25.                                                                         \"" .mysql_real_escape_string($tiempo). "\",
  26.                                                                         \"" .mysql_real_escape_string($imagen). "\",
  27.                                                                         \"" .mysql_real_escape_string($random). "\"
  28.                                                                     )";
  29.                                                        
  30.                 mysql_query($this->SQL,$dbCon) or die(mysql_error());
  31.            
  32.                 //Cerramos conexion.
  33.                 mysql_close($dbCon);
  34.                
  35.             }catch(Exception $e){
  36.                 //Cerramos conexion.
  37.                 mysql_close($dbCon);
  38.                
  39.                 return $e;
  40.             }
  41.         }
  #7 (permalink)  
Antiguo 05/03/2011, 01:05
 
Fecha de Ingreso: enero-2011
Ubicación: DF
Mensajes: 898
Antigüedad: 13 años, 2 meses
Puntos: 155
Respuesta: Problema con Inyección SQL!

y asi?


Código PHP:
$this->SQL=sprintf("INSERT INTO `publicaciones` VALUES('',%d,%d,%d,%d,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",mysql_real_escape_string($idCiudad),mysql_real_escape_string($idCategoria),mysql_real_escape_string($idSubcategoria),mysql_real_escape_string($nombre),mysql_real_escape_string($email),mysql_real_escape_string($telefono),mysql_real_escape_string($titulo),mysql_real_escape_string($contenido),mysql_real_escape_string($precio),mysql_real_escape_string($tipo),mysql_real_escape_string($tiempo),mysql_real_escape_string($imagen),mysql_real_escape_string($random)); 
  #8 (permalink)  
Antiguo 05/03/2011, 17:58
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 2 meses
Puntos: 260
Sonrisa Respuesta: Problema con Inyección SQL!

Cita:
Iniciado por ZeThito Ver Mensaje
Hola =)

La validacíón del captcha esta con jQuery.

Código PHP:
Ver original
  1. if(isset($_SESSION['Random']) == isset($_POST['math'])

Esto es solo una validación para que el usuario no ingrese por Url a esta página,

Al final tengo:
Eso que pusiste allí se traduce en :

if (true == true ...
o false == false

No está comparando que Random == Math. Aunque Random se cree en otra página, puedes llamar a la otra página antes y después a esta.



Mmmm ... ¿y que se supone que tiene que ver JQuery con una validación del lado del servidor? Evidentemente el problema no es de inyección de SQL, pero por supuesto a mi no me creas nada de lo que escribo, porque el programa que usas ya te dijo que era inyección de SQL y por supuesto tienes que creer en lo que te dijo el programa.

El problema realmente es que no validas el captcha del lado del servidor, así que si hago un post manualmente con cualquier herramienta automatizada, el programa acepta la secuencia de insert's sin chistar. Es decir, si hago un programa que llame a la página donde está el insert y que mande datos por post y repito la operación miles de veces, entonces se insertan miles de veces, porque el la lógica está mal escrita isset() == isset() de una variable que está en SESSION y por eso crees que no se puede crear fácilmente, y porque no validas el capta sino con JQuery (que es javascript y corre del lado del cliente, cualquier validación del lado del cliente se puede falsificar fácilmente).

Como seguramente yo estoy equivocado, posiblemente alguien mas te sea de mayor ayuda,

Saludos,
  #9 (permalink)  
Antiguo 05/03/2011, 23:32
 
Fecha de Ingreso: septiembre-2010
Mensajes: 147
Antigüedad: 13 años, 6 meses
Puntos: 3
Respuesta: Problema con Inyección SQL!

HackmanC , Muchas Gracias !!!!!

Tienes toda la razón, el isset() era el problema!

También agregue esto a mi código :

Código PHP:
Ver original
  1. function output_safe($string) {
  2.                     $chars = str_split($string);
  3.                     $out_str = "";
  4.                     foreach ($chars as $char){
  5.                         if ($char == "a" || $char == "b" || $char == "c" || $char == "d" || $char == "e" || $char == "f" || $char == "g" || $char == "h" || $char == "i" || $char == "j" || $char == "k" || $char == "l" || $char == "m" || $char == "n" || $char == "o" || $char == "p" || $char == "q" || $char == "r" || $char == "s" || $char == "t" || $char == "u" || $char == "v" || $char == "w" || $char == "x" || $char == "y" || $char == "z" || $char == "A" || $char == "B" || $char == "C" || $char == "D" || $char == "E" || $char == "F" || $char == "G" || $char == "H" || $char == "I" || $char == "J" || $char == "K" || $char == "L" || $char == "M" || $char == "N" || $char == "O" || $char == "P" || $char == "Q" || $char == "R" || $char == "S" || $char == "T" || $char == "U" || $char == "V" || $char == "W" || $char == "X" || $char == "Y" || $char == "Z" || $char == "1" || $char == "2" || $char == "3" || $char == "4" || $char == "5" || $char == "6" || $char == "7" || $char == "8" || $char == "9" || $char == "0" || $char == "." || $char == "," || $char == "!" || $char == ":" || $char == "<" || $char == ">" || $char == "=" || $char == "'" || $char == "/" || $char == "?" || $char == "@" || $char == "%" || $char == "*" || $char == ";" || $char == "?" || $char == '"' || $char == "&" || $char == '\\' || $char == "#" || $char == "(" || $char == ")" || $char == "[" || $char == "]" || $char == "{" || $char == "}")
  6.                         {
  7.                             $out_str = $out_str.$char;
  8.                         }
  9.                     }
  10.                    
  11.                     $out_str = trim($out_str);
  12.                     $out_str = strip_tags($out_str); // Quitar las Etiquetas HTML y PHP.
  13.                     $out_str = htmlentities($out_str);
  14.                     $out_str = mysql_real_escape_string($out_str);
  15.                     $out_str = stripslashes($out_str);
  16.                     return $out_str;
  17.                 }

He sacado los isset(), ahora el programa no detecta inyecciones sql.

Gracias!!!!!!
  #10 (permalink)  
Antiguo 07/03/2011, 20:33
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 2 meses
Puntos: 260
Sonrisa Respuesta: Problema con Inyección SQL!

Hola,

Perdón por todo el párrafo que me disparé, pero es que muchas veces me contestan: no ... estás equivocado y siguen con lo mismo de la inyección SQL,

Cita:
Iniciado por ZeThito Ver Mensaje
$out_str = mysql_real_escape_string($out_str);
Me alegro que hayas solventado tu duda, y solamente voy a agregar un último detalle, la inyección SQL se logra insertando caracteres que tienen un significado especial para el motor de base de datos, como las comillas, el punto y coma, el doble guión, etc.

La única instrucción necesaria en MySQL para evitar inyección SQL es mysql_real_escape_string, todo lo demás de strip_tags, htmlentities, etc., sirve para evitar otro tipo de mal uso de las páginas web, que también es inyección pero no inyección SQL, porque modifica otro tipo de contexto.

Como por el ejemplo, el caso de inyección de javascript dentro de un comentario de un post; pero lo que se conoce como inyección SQL es la modificación de una instrucción SQL para que realice actividades indeseadas en la base de datos y se evita en 'casi' todos los casos solamente con mysql_real_escape_string.

Saludos,

Última edición por HackmanC; 07/03/2011 a las 20:39 Razón: edicion
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:10.