elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
25 Mayo 2012, 17:42  


Tema destacado: Suscripción al boletín mensual de elhacker.net

+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Bugs y Exploits (Moderador: berz3k)
| | |-+  SQL Injection
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: SQL Injection  (Leído 6,061 veces)
kfault

Desconectado Desconectado

Mensajes: 88



Ver Perfil
SQL Injection
« en: 18 Abril 2006, 03:51 »

Pues voy a abrir una web y estoy haciendo muchas cosas en php y mysql entre ellas un sistema de miembros. Ahora, tengo una duda.
En el codigo que hice para loguearte hice esto:

Código:
<?php

include("connect.php");

if (isset($_POST['user']))
{
  $user = $_POST['user'];
  $pass = $_POST['pass'];
 
  if ($user == NULL || $pass == NULL)
  {
    echo "Faltan datos en el formulario.";
  }
 
  $pass_enc = md5($pass);
 
  $query = "SELECT * FROM users WHERE user = '$user' AND pass = '$pass_enc'";
  $result = mysql_query($query);
  $count = mysql_num_rows($result);
 
  if ($count > 0)
  {
    echo "Logged in.<br />";
    session_start();
   
    $_SESSION['s_user'] = $user;
    $_SESSION['auth'] = true;
   
    header("Location: index.php");
  }
  else
  {
    echo "Usario/Password Incorrecto.";
    die();
  }
}

?>

Bueno, segun lo que he leido de SQL Injection (quiero hacer mis aplicaciones seguras) la manera en que programe esto es vulnerable a algo como  a' or 'a'='a  creo yo que eso deberia de funcionar pero no funciona, siempre me da el mensaje de Usuario/Password Incorrecto. Quisiera saber si realmente es vulnerable y como lo puedo arreglar pues no quiero llevarme sorpresas despues cuando la web este en el servidor.

Muchas Gracias y haber si alguien me puede ayudar.

P.D. Olvide mencionar que este archivo es login2.php, en login.php tengo una forma con la action puesta en login2.php. Me refiero a que esta pagina procesa la informacion mandada por la forma.
En línea
Ertai
Ex-Staff
*
Desconectado Desconectado

Mensajes: 2.026


Ralph Wiggum


Ver Perfil
Re: SQL Injection
« Respuesta #1 en: 18 Abril 2006, 08:55 »

No limpias la variable 'user', por allí te pueden meter algo.

Te explico rápido.

Si tienes...

Código:
SELECT * FROM users WHERE user = '$user' AND pass = '$pass'

Y supongamos que ahora meto de usuario admin y password ' or 'a'='a.

Fijate como queda la query:

Código:
SELECT * FROM users WHERE user = 'admin' AND pass = '' or 'a'='a'

Lo ves?? Así te saltas la protección, porque inyectas un or de algo que siempre es cierto. Que es cierto? Que a=a.

Espero que lo entiendas y veas la necesidad de limpiar la variable user.

Leete las funciones ereg y eregi de PHP en www.php.net.

Saludos.

En línea

Si la felicidad se comprara, entonces el dinero sería noble.

Código:
void rotar_by_ref(int& a, int& b) {
   /* Quien dijo que no se podia sin una variable temporal? */
   *a = *a ^ *b;
   *b = *a ^ *b;
   *a = *a ^ *b;
}
Rentero
Ex-Staff
*
Desconectado Desconectado

Mensajes: 1.163


La paciencia es la madre de la ciencia.


Ver Perfil
Re: SQL Injection
« Respuesta #2 en: 18 Abril 2006, 18:27 »

Algunas cosas mas:

Citar
  if ($user == NULL || $pass == NULL)
  {
    echo "Faltan datos en el formulario.";
  }
Si el usuario o la contraseña no existen deberias de detener la ejecución del script. Sino no te sirve de nada mostrar un mensaje advirtiendo de eso. Para eso usa exit() o die() que son lo mismo xD.

Citar
  {
    echo "Logged in.<br />";
    session_start();
   
    $_SESSION['s_user'] = $user;
    $_SESSION['auth'] = true;
   
    header("Location: index.php");
  }
Cuando imprimes por pantalla algun mensaje como por ejemplo ese Logged in.<br /> no puedes volver a enviar cabeceras HTML. las funciones session_start() y header() deben de ir antes de que cualquier entidad HTML llegue al navegador. De todas forma no tiene sentido que muestres un mensaje de logueado y acto seguido redirecciones a index.php sin dar tiempo a que el usuario lea este mensaje :P

La parte de la seguridad, como te ha dicho Ertai, en la variable $pass no hay mucho riesgo puesto que usas md5() y da igual que datos maliciosos metan...siempre va a dar un hash como resultado.

Pero no pasa lo mismo con $user. Tienes que filtrarla, puedes hacer uso de funciones como addslashes() para escapar las comillas y demas. Pero debes de tener cuidado de que magic_quotes_gpc no esté a ON porque sino te los escapará varias veces.

Por ejemplo:
Código:
<?php
$apellido = "O'neil";

//con magic_quotes_gpc OFF
echo addslashes($apellido); //devuelve O\'neil

//con magic_quotes_gpc ON
echo addslashes($apellido); //devuelve O\\\'neil
?>

Para sacarte del apuro puedes usar stripslashes() antes de addslashes() y así mas o menos solucionamos el problema de las magic_quotes.

Después de toda esta tonteria te dejo un ejemplo :P
Código:
<?php
session_start();
include_once("./connect.php");

function escapar($texto)
{
$texto = stripslashes($texto);
$texto = addslashes($texto);

return $texto;
}

if (isset($_POST["user"]))
{
if (empty($_POST["user"]) || empty($_POST["pass"]))
die("Faltan datos en el formulario.");

$query = sprintf("SELECT * FROM users WHERE user = '%s' AND pass = '%s'", escapar($_POST["user"]), md5($_POST["pass"]));
$result = mysql_query($query);

if (mysql_num_rows($result) == 1)
{
$_SESSION['s_user'] = escapar($_POST["user"]);
$_SESSION['auth'] = true;

header("Location: index.php");
}else
die("Ese user/pass no existe en la base de datos.");
}
?>

No creo haberme equivocado, pero aún asi...es un ejemplo para mostrar lo que he dicho y para que te apolles en él xD.

Saludos ;)
« Última modificación: 18 Abril 2006, 18:28 por Rentero » En línea

Firmado.
kfault

Desconectado Desconectado

Mensajes: 88



Ver Perfil
Re: SQL Injection
« Respuesta #3 en: 18 Abril 2006, 18:43 »

Muchas gracias a los dos, ya veo todos los errores que cometi. Buscare informacion de las funciones que me comentan y las agregare a mi codigo.

Ahora, solo una pregunta, en user yo pongo lo que dijo Ertai (' or 'a'='a). Se supone que me podria loguear no es asi? Por lo menos eso es lo que entendi, y cuando lo pongo se va al mensaje de Usuario/Password Incorrecto, entonces no esta haciendo el SQL Injection o si?

Muchas gracias de nuevo.  :)
En línea
kfault

Desconectado Desconectado

Mensajes: 88



Ver Perfil
Re: SQL Injection
« Respuesta #4 en: 18 Abril 2006, 19:18 »

Ertai, busque en el manual de php las funciones ereg() y eregi() y entiendo que hacen pero no mencionan como se usan, me refiero a la sintaxis y demas. Tambien busque en google y para ser sincero no entiendo. Si tienes tiempo, me podrias dar un ejemplo de como se usan?

Muchas Gracias.
En línea
Rentero
Ex-Staff
*
Desconectado Desconectado

Mensajes: 1.163


La paciencia es la madre de la ciencia.


Ver Perfil
Re: SQL Injection
« Respuesta #5 en: 18 Abril 2006, 21:04 »

ereg() y eregi() son funciones para el manejo de expresiones regulares.
Citar
Que son las Expresiones Regulares

Las expresiones regulares son una serie de carácteres que forman un patrón, normalmente representativo de otro grupo de carácteres mayor, de tal forma que podemos comparar el patrón con otro conjunto de carácteres para ver las coincidencias.
Si quieres aprender sobre EERR leete este texto...es muy interesante =)
http://www.ignside.net/man/php/regex.php

No tengo tiempo para responderte lo otro :S, si nadie te lo aclara luego te pongo un ejemplo...aunque te diré que lo que Ertai quiere decir es ponerlo en el password y te da usuario incorrecto puesto que usas md5() con lo cual...pongas lo que pongas siemrpe te va asalir una cadena de 32 bits totalmente distinta ;)

Saludos ;)
En línea

Firmado.
Rey11


Desconectado Desconectado

Mensajes: 3.244



Ver Perfil WWW
Re: SQL Injection
« Respuesta #6 en: 18 Abril 2006, 21:52 »

Pues yo uso esta función de fabricación casera:
Código:
<?php
function limpieza1($valor)
{
$valor = str_replace('"',"//////",$valor);
$valor = str_replace("'","//////",$valor);
$valor = str_replace("@","//////",$valor);
$valor = str_replace("or","//////",$valor);
$valor = str_replace("UNION","//////",$valor);
$valor = str_replace("SELECT","//////",$valor);
$valor = str_replace("%2527","//////",$valor);
$valor = str_replace("%2725","//////",$valor);
$valor = str_replace("%20","//////",$valor);
$valor = str_replace("%27","/////",$valor);
$valor = str_replace("-99","////",$valor);
$valor = str_replace("--","////",$valor);
$valor = str_replace("*/","////",$valor);
$valor = str_replace("null","///////",$valor);
$valor = str_replace("*","///////",$valor);
return $valor;
}
?>
Saludos  ::)
En línea

Rentero
Ex-Staff
*
Desconectado Desconectado

Mensajes: 1.163


La paciencia es la madre de la ciencia.


Ver Perfil
Re: SQL Injection
« Respuesta #7 en: 18 Abril 2006, 22:01 »

Ya estoy aquí :)

Muchas gracias a los dos, ya veo todos los errores que cometi. Buscare informacion de las funciones que me comentan y las agregare a mi codigo.

Ahora, solo una pregunta, en user yo pongo lo que dijo Ertai (' or 'a'='a). Se supone que me podria loguear no es asi? Por lo menos eso es lo que entendi, y cuando lo pongo se va al mensaje de Usuario/Password Incorrecto, entonces no esta haciendo el SQL Injection o si?

Muchas gracias de nuevo.  :)

NO.
Y todo esto contando con que magic_quotes_gpc esté a OFF. Si está a ON escapará las comillas y no podrás hacer la inyección...al menos tan facilmente, ya se escapa de mis conocimientos :P

Sigo...
En tu script inicial...

Si pones ' or 'a'='a como usuario tu consulta quedaría así:
Citar
SELECT * FROM users WHERE user='' or 'a'='a' AND pass='HASH_MD5'
Con lo cual no encontraría ninguna coincidencia y $count no sería mayor de 0(cero) y te mostraría el mensaje de Usuario/Password Incorrecto.

En cualquier caso...ya que no podemos sacar provecho de la variable $pass(porque usas md5()) podemos intentar sacar provecho de la variable $user(que no la filtras con nada).

Podemos probar a insertar lo siguiente como usuario:
Código:
admin' /*
y poner cualquier password(cualquier cosa, por ejemplo: 135654)

En este caso la consulta quedaría así:
Citar
SELECT * FROM users WHERE user='admin' /*' AND pass='HASH_MD5'
En este caso...entrariamos como el usuario admin directamente ya que al poner /* hacemos que el resto de la consulta sea un comentario :)

Bueno, no tengo tiempo para estenderme más...pero aquí tienes información para entretenerte un rato xDD

Saludos ;)
En línea

Firmado.
kfault

Desconectado Desconectado

Mensajes: 88



Ver Perfil
Re: SQL Injection
« Respuesta #8 en: 18 Abril 2006, 22:06 »

Muchas gracias, ya entiendo. Pues leere el texto que me diste y ya entiendo por que no funcionaba el sql injection. Ahora corregire mi script para hacerlo seguro.  :)

Gracias de nuevo a todos.
En línea
kfault

Desconectado Desconectado

Mensajes: 88



Ver Perfil
Re: SQL Injection
« Respuesta #9 en: 18 Abril 2006, 22:10 »

Jaja, no me lo vas a creer rentero pero el sql injection que pusiste, el de admin' /* tampoco funciona. Bueno sera por que magic_quotes_gpc tal vez este on. Bueno de todos modos corregire mi script.
En línea
Rentero
Ex-Staff
*
Desconectado Desconectado

Mensajes: 1.163


La paciencia es la madre de la ciencia.


Ver Perfil
Re: SQL Injection
« Respuesta #10 en: 18 Abril 2006, 22:17 »

Código:
<?php
echo get_magic_quotes_gpc();
?>
Si te devuelve 1 es que lo tienes ON, si te devuelve 0(cero) es que lo tienes OFF.

  • Si lo tienes ON ahí está la respuesta de porque no puedes "inyectar"...
  • Si lo tienes OFF el problema puede ser que:
1.- No estas conectando a la base de datos(en tu script no se ve ninguna conexión..supongoq ue conectarás en connect.php jeje)
2.- Estas probando con admin' /* y en la base de datos que lo haces no existe ningún usuario llamado admin. Tienes que probar con un usuario que exista...sino...no estás haciendo nada.
3.- Algo que se escapa de mi escasa sabiduría xD

[Añado]
Si lo tienes ON y quieres probar para ver como es una inyección de código sql, solo por probar...puedes añadir esto a tu script.

Pero recuerda eliminarlo de tu script final, o será vulnerable indudablemente ;)
Código:
<?php
//...
//despues de $user = $_POST["user"];
$user = stripslashes($user);
//...
?>

Saludos ;)
« Última modificación: 18 Abril 2006, 22:20 por Rentero » En línea

Firmado.
kfault

Desconectado Desconectado

Mensajes: 88



Ver Perfil
Re: SQL Injection
« Respuesta #11 en: 18 Abril 2006, 22:27 »

Si esta on, era por eso. Y si conecto en connect.php  ;D y estaba probando con un usuario que yo tenia creado.

Bueno probare con poner eso en el script para ver como es la inyeccion.

Gracias, un saludo.
En línea
kfault

Desconectado Desconectado

Mensajes: 88



Ver Perfil
Re: SQL Injection
« Respuesta #12 en: 18 Abril 2006, 22:31 »

Oye rentero y crees que con solo poner el addslashes() y antes el stripslashes() (por si el servidor tiene magic_quotes_gpc = on) sea suficiente para que el script sea seguro? O filtro mas cosas?

Gracias.  :)
En línea
Rentero
Ex-Staff
*
Desconectado Desconectado

Mensajes: 1.163


La paciencia es la madre de la ciencia.


Ver Perfil
Re: SQL Injection
« Respuesta #13 en: 18 Abril 2006, 23:18 »

Oye rentero y crees que con solo poner el addslashes() y antes el stripslashes() (por si el servidor tiene magic_quotes_gpc = on) sea suficiente para que el script sea seguro? O filtro mas cosas?

Gracias. :)

NO.

Eso solo te sirve en gran parte para la base de datos.
Pero no solo existen ataques de ese tipo. Por ejemplo.

Ataques XSS mediante los cuales puedes insertar codigo HTML en tu pagina o incluso javascript. Para esto existen funciones como htmlentities() o htmlspecialchars(). Debes usarlas en todos aquellos lugares donde vallas a imprimir valores(ya sean recojidos desde bases de datos, cookies, variables de URL, etc) que el usuario pueda manipular. Ya tenga acceso directo a ellas o no.

Por ejemplo: Imagina que tiene sun sistema de descargas...
Código:
<?php
//...
$id = $_GET["id"];
echo "La ID de esta descarga es: $id";
//...
?>

Si el usuario modifica la URL de esta forma: pagina.php?id=<script>alert('peligro!!')</script>

Al entrar en ese página saltaría una alerta. Eso en principio no tiene peligro...pero podría hacer muchisimas cosas peligrosas coo por ejemplo: guardarse las cookies de los visitantes de esa pagina en una archivo, podría crear bucles infinitos para fastidiar, y muchas mas chorradas...

En ese caso, podríamos usar cualquiera de los dos funciones anterior mente citadas para arreglar el error sobre la variable $id.
Pero si nos paramos a pensar...vemos que $id queremos que reciba valores UNICA Y EXCLUSIVAMENTE numéricos...en ese caso, la mejor opción sería coprobar si $id es un número con is_int() o mejor aún...podríamos cambiar el tipo de valor de la variable a INT(numero entero) silenciosamente con settype() o intval().

Bueno, que me enroyo...
Como he dicho...existen muchisimos tipos de ataques web. En lo que consiste basicamente es en comprobar que las variables que queremos usar contengan lo que nosotros queremos que contengan y en caso de que esto no ocurra tenemos que modificarlas silenciosamente o detener la ejecucion del script.

Tengo que irme de nuevo...luego sigo :P

Saludos ;)
En línea

Firmado.
Ertai
Ex-Staff
*
Desconectado Desconectado

Mensajes: 2.026


Ralph Wiggum


Ver Perfil
Re: SQL Injection
« Respuesta #14 en: 18 Abril 2006, 23:37 »

Otra vez yo.

Te explico mi experiencia programando con PHP.

Casi siempre puedes verificar datos usando la siguiente línea:

Código:
if(!is_numeric($var)){ die(); }

Esto lo uso siempre para el tema de los IDs que te comenta Rentero, ya que sobretodo programo sistemas de noticias, y sistemas de administración de contenido.

Eso solo es interesante cuando la variable debe ser numérica.

Si no lo es, tienes a tu disposición muchísimas funciones que ya se han comentado, pero sigo opinando que la mejor es ereg o eregi  ;)

Saludos.



En línea

Si la felicidad se comprara, entonces el dinero sería noble.

Código:
void rotar_by_ref(int& a, int& b) {
   /* Quien dijo que no se podia sin una variable temporal? */
   *a = *a ^ *b;
   *b = *a ^ *b;
   *a = *a ^ *b;
}
Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines