Autor Tema: Seguridad en aplicaciones con php ante INYECTION,XSS Y CSRF  (Leído 9251 veces)

Eva

  • Sin experiencia
  • *
  • Mensajes: 23
    • Ver Perfil
Seguridad en aplicaciones con php ante INYECTION,XSS Y CSRF
« en: 03 de Noviembre 2012, 16:17 »
Hola a Todos!!

Me dieron un login de acceso a un sistema el cual tiene distintos niveles de acceso..el codigo es el siguiente:
Código: [Seleccionar]
<?php
if(isset($_SESSION['miUsuario'])){include_once"menuUser.php";}
else{
//me fijo si estan definidos nombre y clave
if(!isset($_POST['nombre'])||!isset($_POST['clave'])){ include_once"login.php";
}else{ 
//Reviso los datos q vienen del formulario x POST
if ($_POST['nombre']!="" || $_POST['clave']!=""){
$user$_POST['nombre'];
$pass=$_POST['clave'];

$sql "SELECT * FROM usuarios WHERE username='$user' AND password='$pass' ";
include_once("conexion.php");
$qry mysql_query($sql);
}
else{
//si hay error de contraseña Informo y vuelve al formulario Login
echo" <h3 class='letras_login'> Contaseña Incorrecta </h3> <br />";
include_once"login.php";
//Si tienen contenido lo comparo con la Base de Datos
$sql="select * from usuarios where username='$_POST[nombre]'and estado='activo'";
include_once"conexion.php";
$rs=mysql_query($sql);
//chequeo si hay un error en $rs (Consulta SQL)
if(!$rs){echo "Error en la Consulta SQL";}
else{
//si es Mayor a cero hay un usuario
if(mysql_num_rows($rs)>0){ 
$passFormulario=$_POST['clave']; //guardo la contraseña q viene del formulario
$passBD=mysql_result($rs,0,2); //guardo la contraseña q esta en la BD
$idUsuario=mysql_result($rs,0,0); //guardo el ID del usuario q esta la BD
$nivelUsuario=mysql_result($rs,0,3); //guardo el nivel q esta en la BD
//$avatar=mysql_result($rs,0,8); //guardo el nivel q esta en la BD

//Comparo las pass, si coinciden INICIO SESION
if($passFormulario==$passBD){
//creo la variable de sesion : usuario y su Nivel
$_SESSION['miUsuario']=$_POST['nombre'];
$_SESSION['miNivel']=$nivelUsuario;
$_SESSION['idCliente']=$idUsuario;
//$_SESSION['miAvatar']=$avatar;
 
/* 
                             $miLog1 = new log('1',$idUsuario,'0');
                             $miLog1->insertarlog ();
 */

                             
                            
mysql_query($sql) or die ("Error en la inserción!");
//incluyo el Modulo q tiene el Menu de Usuario
include_once"menuUser.php";
}else{
//si hay error de contraseña Informo y vuelve al formulario Login
echo" <h3 class='letras_login'> Contaseña Incorrecta </h3> <br />";
include_once"login.php";
}
}else{
//si No hay usuarios con ese nick Informo y vuelve al formulario Login
echo"<h3 class='letras_login'> Usuario y/o Contaseña Incorrecto o inhabilitado </h3> <br />";
include_once"login.php";
}
}
}
else{
//Si el form esta vacio Muestro el Login
include_once"login.php";
}
}
}
?>


En este codigo necesito aplicar ataques de INYECTION,XSS Y CSRF (asumo que quien me brinde su ayuda sabe de que estoy hablando), nos dijeron que podemos hacerle modificaciones al codigo para hacer funcionar nuestros ataques pero probe de varias maneras y no logro resolverlo...

Agradezcco desde ya su colaboracion!!

Saludos!!

Aclaracion: Los include no modifican nada la ideas es trabajar sobre los if, esos archivos son mas referidos al diseño del sitio
« Última modificación: 12 de Septiembre 2014, 17:10 por Alex Rodríguez »

nosferacento

  • Moderador Global
  • Avanzado
  • *******
  • Mensajes: 443
    • Ver Perfil
Re:Seguridad en aplicaciones
« Respuesta #1 en: 04 de Noviembre 2012, 00:05 »
Esto puede tener su complejidad. Para empezar veamos la línea:

$sql = "SELECT * FROM usuarios WHERE username='$user' AND password='$pass' ";

El comportamiento esperado sería que en user y password tengamos un usuario y contraseña normal, como "juan" y "alegria2012" . Al ejecutar la consulta tendríamos:

$sql = "SELECT * FROM usuarios WHERE username='juan' AND password='alegria2012' ";

Un ataque podría venir si se introduce como contraseña:

unacualquiera’  OR PASSWORD LIKE '%

El código de color es la inyección SQL a través de la cual el hacker o quien sea está intentando acceder maliciosamente. Lo que la query quedaría así:

$sql = "SELECT * FROM usuarios WHERE username='juan' AND password='unacualquiera’  OR PASSWORD LIKE '%
 
En este caso trata de entrar sin hacer más daño, pero podría escribir:

unacualquiera; DROP TABLE usuarios

Lo cual sería un intento por borrar la tabla de usuarios de la base de datos.

Una primera validación podría consistir en un condicional que busque caracteres como comas, puntos y comas, signo igual, paréntesis, palabras claves SQL como LIKE, TABLE, DROP, %, etc. y en caso de ser detectado no ejecutar el query.

Eva

  • Sin experiencia
  • *
  • Mensajes: 23
    • Ver Perfil
Re:Seguridad en aplicaciones
« Respuesta #2 en: 04 de Noviembre 2012, 16:07 »
Estuve probando la alternativa que me sugeriste al igual que la mas comun ' OR '1=1
y de todas maneras me figura contraseña incorrecta y si ingreso esa linea en el usuario me aparece error en consulta sql.. Y los DROP y ALTER tampoco me funcionan.. :(

Por las dudas vuelvo a pasar el codigo porque creo que el anterior le habia hecho algunas modificaciones y no se si funciona correctamente(en realidad creo que le falta un if)

Código: [Seleccionar]
<?php
//session_start(); 
//include_once("claseLog.php");
//Si existe una sesion de usuario Lo muestro
if(isset($_SESSION['miUsuario'])){include_once"menuUser.php";}
else{
//me fijo si estan definidos nombre y clave
if(!isset($_POST['nombre'])||!isset($_POST['clave'])){ include_once"login.php";
}else{ 
//Reviso los datos q vienen del formulario x POST
if ($_POST['nombre']!="" || $_POST['clave']!=""){
//Si tienen contenido lo comparo con la Base de Datos
$sql="select * from usuarios where username='$_POST[nombre]'and estado='activo'";
include_once"conexion.php";
$rs=mysql_query($sql);
//chequeo si hay un error en $rs (Consulta SQL)
if(!$rs){echo "Error en la Consulta SQL";}
else{
//si es Mayor a cero hay un usuario
if(mysql_num_rows($rs)>0){ 
$passFormulario=$_POST['clave']; //guardo la contraseña q viene del formulario
$passBD=mysql_result($rs,0,2); //guardo la contraseña q esta en la BD
$idUsuario=mysql_result($rs,0,0); //guardo el ID del usuario q esta la BD
$nivelUsuario=mysql_result($rs,0,3); //guardo el nivel q esta en la BD
//$avatar=mysql_result($rs,0,8); //guardo el nivel q esta en la BD

//Comparo las pass, si coinciden INICIO SESION
if($passFormulario==$passBD){
//creo la variable de sesion : usuario y su Nivel
$_SESSION['miUsuario']=$_POST['nombre'];
$_SESSION['miNivel']=$nivelUsuario;
$_SESSION['idCliente']=$idUsuario;
//$_SESSION['miAvatar']=$avatar;
 
/* 
                             $miLog1 = new log('1',$idUsuario,'0');
                             $miLog1->insertarlog ();
 */

                             
                             
mysql_query($sql) or die ("Error en la inserción!");
//incluyo el Modulo q tiene el Menu de Usuario
include_once"menuUser.php";
}else{
//si hay error de contraseña Informo y vuelve al formulario Login
echo" <h3 class='letras_login'> Contaseña Incorrecta </h3> <br />";
include_once"login.php";
}
}else{
//si No hay usuarios con ese nick Informo y vuelve al formulario Login
echo"<h3 class='letras_login'> Usuario y/o Contaseña Incorrecto o inhabilitado </h3> <br />";
include_once"login.php";
}
}
}else{
//Si el form esta vacio Muestro el Login
include_once"login.php";
}

}
}
?>

« Última modificación: 28 de Septiembre 2014, 10:30 por Ogramar »

nosferacento

  • Moderador Global
  • Avanzado
  • *******
  • Mensajes: 443
    • Ver Perfil
Re:Seguridad en aplicaciones
« Respuesta #3 en: 04 de Noviembre 2012, 19:49 »
Aparentemente la línea donde tienes la vulnerabilidad es esta:

$sql="select * from usuarios where username='$_POST[nombre]'and estado='activo'";

Fíjate que en la consulta que realizas no aparece el password, sino el username y el estado.

Lo primero que tendrás que probar es que te puedas logar con un usuario y contraseña válido, si esto no es posible será porque exista algún fallo en el código, no esté creada la base de datos o cualquier problema similar.

Si es posible logarte con un usuario y password válido, ahora se trataría de lograr que esa consulta sql se ejecute añadiéndole el código de inyección.

Para ello habría que probar a escribir en formulario de acceso en vez de un nombre de usuario algo como:

'unacualquiera' OR ''=';
'unacualquiera’  OR username LIKE '%';
'unacualquiera’  OR username LIKE '%' OR username LIKE '%';

El objetivo sería que se llegara a ejecutar algo como esto:

$sql="select * from usuarios where username='unacualquiera’  OR username LIKE '%' OR username LIKE '%' and estado='activo'";

Tienes que probar con distintas sintaxis.

Una vez logres entrar, establecer la medida para evitar el ataque. Para ello puedes usar condicionales if, o bien funciones propias de sql que sirven para limpiar cadenas de caracteres especiales (con lo que en teoría se evitaría la inyección) como mysql_real_escape_string o mysqli::escape_string, 

Eva

  • Sin experiencia
  • *
  • Mensajes: 23
    • Ver Perfil
Re:Seguridad en aplicaciones
« Respuesta #4 en: 04 de Noviembre 2012, 22:15 »
Te muestro lo que me aparece ingresando la siguiente linea
' OR 1='1';UPDATE usuarios SET password=111 WHERE username='seba

Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in C:\xampp\htdocs\SitioWeb\ModLogin.php on line 22

incluso le saque algunos if y sigue sin reconocer una contraseña distinta a la que se encuentra en la base de datos

El ataque xss ya lo resolvi me falta el csrf pero como este de inyection no me sale aun no se me ocurrio como hacerlo

nosferacento

  • Moderador Global
  • Avanzado
  • *******
  • Mensajes: 443
    • Ver Perfil
Re:Seguridad en aplicaciones
« Respuesta #5 en: 04 de Noviembre 2012, 22:50 »
Solo se me ocurre probar

' OR 1=='1';UPDATE usuarios SET password=111 WHERE username='seba

' OR 1=1;UPDATE usuarios SET password=111 WHERE username='seba

' OR true==true;UPDATE usuarios SET password=111 WHERE username='seba

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".