Comunidad de diseño web y desarrollo en internet online

Ayuda con SQL Injection

Citar            
MensajeEscrito el 26 Nov 2012 07:32 pm
Buenas tardes,




Estoy tratando de realizar una pequeña aplicación para subir Imágenes(Que ya encontré el código parcialmente en Internet) pero me dado cuenta que es vulnerable a injtecciónes de SQL.

Estructura de la tabla
#
# Estructura de tabla para la tabla `archivos`
#

¡

Código MySQL :

CREATE TABLE archivos (
  id int(10) unsigned NOT NULL auto_increment,
  archivo_binario blob NOT NULL,
  archivo_nombre varchar(255) NOT NULL default '',
  archivo_peso varchar(15) NOT NULL default '',
  archivo_tipo varchar(25) NOT NULL default '',
  PRIMARY KEY  (id)
) TYPE=MyISAM;


Formulario.php:

Código HTML :

?php
if (isset($_GET['proceso'])){
echo $_GET['proceso']."<br>";
}
?>
<FORM enctype="multipart/form-data" method="post" action="insertar.php">
<p><b>Titulo:</b><br /> 
</p> 
<input name="titulo" type="text"  size="40" class="text" id="titulo" /> 
</p> 
<p> <b>Subtitulo:</b><br />
</p>  
<textarea name="subtitulo" id="subtitulo" cols="60" rows="5" tabindex="4"></textarea> 
</p> 
<p><b> Detalles:</b><br /> 
</p> 
<textarea name="detalle" id="detalle" cols="60" rows="10" tabindex="4"></textarea> 
</p> 
<p> 
</p> 

</p> 
<p> 
<b>Categoria:</b><br> 
</p> 
<select name="categoria" id="categoria"> 
<option>Promocion</option> 
<option>Eventos</option> 

</select> 
</p> 
<b>Archivo: </b><br>
</p> 
<INPUT type="file" size="8" name="archivo" size="30"><br>
</p> 
<div style="margin-left:220px; margin-top:20px" ><INPUT type="submit" class="button small blue" name="submit" value="Subir archivo"></div>
</FORM>
</BODY>
</HTML>
<? 
} 



}else{

header("Location: index.php");
   
}
?>


insertar.php

Código PHP :

<?php 
            
                  
//Primero, arranca el bloque PHP y checkea si el archivo tiene nombre.  Si no fue asi, te remite de nuevo al formulario de inserción:
// No se comprueba aqui si se ha subido correctamente.
if (empty($_FILES['archivo']['name'])){
header("location: formulario.php?proceso=falta_indicar_fichero"); //o como se llame el formulario ..
exit;
}


   $conexion=    mysql_connect("******","********","**********") or die ("no se ha podido conectar a la BD");

    mysql_select_db("*********") or die ("no se ha podido seleccionar la BD");


function quitar($mensaje) 
 
 
{ 
   $nopermitidos = array("'",'\\','<','>',"\""); 
   $mensaje = str_replace($nopermitidos, "", $mensaje); 
   return $mensaje; 
} 

$binario_nombre_temporal=$_FILES['archivo']['tmp_name'] ;

$binario_contenido = addslashes(fread(fopen($binario_nombre_temporal, "rb"), filesize($binario_nombre_temporal)));

$binario_nombre=$_FILES['archivo']['name'];
$binario_peso=$_FILES['archivo']['size'];
$binario_tipo=$_FILES['archivo']['type'];

$categoria = $_POST["categoria"]; 
$titulo = (ucfirst($_POST["titulo"])); 
$subtitulo = $_POST["subtitulo"]; 
$detalle = (nl2br(htmlspecialchars(urldecode($_POST["detalle"])))); 

//insertamos los datos en la BD.
$consulta_insertar = "INSERT INTO archivos (id, archivo_binario, archivo_nombre, archivo_peso, archivo_tipo, categoria, titulo, subtitulo, detalle) VALUES ('', '$binario_contenido', '$binario_nombre', '$binario_peso', '$binario_tipo', '$categoria','$titulo', '$subtitulo','$detalle')";
mysql_query($consulta_insertar,$conexion) or die("No se pudo insertar los datos en la base de datos.");
header("location: perfil.php");  // si ha ido todo bien
exit;


?>


listar_imagenes.php


Código PHP :

<?php
     $conexion=    mysql_connect("******","********","**********") or die ("no se ha podido conectar a la BD");

    mysql_select_db("*********") or die ("no se ha podido seleccionar la BD");


$sql = sprintf("SELECT id,archivo_nombre,archivo_tipo,archivo_peso,titulo,subtitulo,detalle FROM archivos",
addcslashes(mysql_real_escape_string($archivosl),'%_'));

    $consulta = mysql_query($sql) or die ("No se pudo ejecutar la consulta");

    While ($registro=mysql_fetch_assoc($consulta)){

echo "<a href=ver.php?id=$registro[id]>"; 
echo $registro['titulo']; 
echo "</a><p></p>";
echo $registro['subtitulo']; 
echo "<p></p>"; 

        echo "<img src=\"ver.php?id=".$registro['id']."\">";
echo "<p></p>";
      
echo $registro['detalle']; 
echo "<p></p>"; 
echo "<p></p>"; 

echo '<hr style="width:80%">';

echo "<p></p>"; 
echo "<p></p>"; 



    }

?>



ver.php


Código PHP :

<?php


function limpiar($contenido)
{
        $contenido = strip_tags($contenido);
        $contenido = mysql_real_escape_string($contenido);
        return $contenido;
}



if(isset($_GET['id'])) {
   
   

   
   



    $conexion=    mysql_connect("******","********","**********") or die ("no se ha podido conectar a la BD");

    mysql_select_db("*********") or die ("no se ha podido seleccionar la BD");

include("proteccion.php") ;


function limpiarcampo($dirty){
if (get_magic_quotes_gpc()) {
$liberate = mysql_real_escape_string(stripslashes($dirty));
}else{
$liberate = mysql_real_escape_string($dirty);
}
return $liberate;
}
$sql = sprintf("SELECT archivo_nombre,archivo_binario,archivo_tipo,archivo_peso,titulo,subtitulo,detalle FROM archivos WHERE id='".mysql_real_escape_string($_GET['id'])."'",

$id = addcslashes(mysql_real_escape_string($id),'%_'));
    $consulta = mysql_query($sql,$conexion);
        

   $datos = mysql_result($consulta,0,"archivo_binario");
    $tipo = mysql_result($consulta,0,"archivo_tipo");
    $nombre = mysql_result($consulta,0,"archivo_nombre");
    $peso = mysql_result($consulta,0,"archivo_peso");
   
  
    header("Content-type: $tipo");
    header("Content-length: $peso"); 
    header("Content-Disposition: inline; filename=$nombre"); 


   echo $datos;


}


?>



Detalles.php


Código PHP :

<?php
    $conexion=    mysql_connect("******","********","**********") or die ("no se ha podido conectar a la BD");

    mysql_select_db("*********") or die ("no se ha podido seleccionar la BD");


$id = (isset($_GET["id"])) ? $_GET["id"] : exit(); 

include("proteccion.php") ;

function strip_all($string)                                            
{
 return addslashes(stripslashes(strip_tags(htmlentities($string))));
}

    
$sql = sprintf("SELECT * FROM archivos WHERE id='$id' ORDER BY id DESC",

$id = addcslashes(mysql_real_escape_string($id),'%_'));

 
    
    
    $consulta = mysql_query($sql) or die ("No se pudo ejecutar la consulta");
    


    While ($registro=mysql_fetch_assoc($consulta)){




echo "<p></p>"; 
echo "<p></p>"; 

echo "<h2>"; 
echo $registro['titulo'];
echo "</h2>";
echo "<p></p>";
echo $registro['subtitulo'];
echo "<p></p>"; 

        echo "<img align='center' width='300' height='300' src=\"ver.php?id=".$registro['id']."\">";
echo "<p></p>";
      
echo $registro['detalle']; 
echo "<p></p>"; 
echo "<p></p>"; 
echo "<p></p>"; 
echo '<b>Publicado:</b> '; echo $registro['fecha']; 
echo "<p></p>";
?> 
 <a href="javascript:history.back(1)">Volver Atrás</a>

<?php
echo "<p></p>";
echo "<p></p>"; 
echo "<p></p>"; 


    }


Pero haciendo pruebas... me dado cuenta...que hay un fallo en el identificador ID=... y se puede entrar hasta el salón!

Pensé que mediante addcslashes(mysql_real_escape_string( iba a solucionarlo... pero veo que no lo debido emplear correctamente.



Código :

[20:26:00] [INFO] testing 'MySQL UNION query (NULL) - 1 to 10 columns'
[20:26:34] [INFO] ORDER BY technique seems to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test
[20:26:35] [INFO] target url appears to have 7 columns in query
[20:26:36] [INFO] GET parameter 'id' is 'MySQL UNION query (NULL) - 1 to 10 columns' injectable
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y
sqlmap identified the following injection points with a total of 125 HTTP(s) requests:
---
[b]Place: GET
Parameter: id
    Type: UNION query
    Title: MySQL UNION query (NULL) - 7 columns
    Payload: id=19%' LIMIT 1,1 UNION ALL SELECT CONCAT(0x3a6a73693a,0x43497141784f7373616b,0x3a7174683a), NULL, NULL, NULL, NULL, NULL, NULL#[/b]



¿Alguien me puede ayudar? Gracias por adelantado.

Un saludo.

Por rokitoh

2 de clabLevel



 

chrome
Citar            
MensajeEscrito el 27 Nov 2012 12:20 pm
Esta línea:

Código PHP :

$id = addcslashes(mysql_real_escape_string($id),'%_'));

Debe estar antes que esta línea:

Código PHP :

$sql = sprintf("SELECT * FROM archivos WHERE id='$id' ORDER BY id DESC",


Por otro lado si $id solo puede ser un número, es mejor verificarlo con is_numeric() en ves de pasarle esas funciones que usaste en el código.

Por DriverOp

Claber

2510 de clabLevel



 

opera
Citar            
MensajeEscrito el 27 Nov 2012 05:40 pm
Muchas gracias DriverOp realizare los cambios que me indicas , y ya comentare una vez finalizado.

Un saludo!

Por rokitoh

2 de clabLevel



 

chrome

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.