SlideShare une entreprise Scribd logo
1  sur  12
Télécharger pour lire hors ligne
Robo de sesiones en PHP

Miguel Angel Lopez Torralba

INtroduccion
Definicion
Session Hijacking (secuestro o robo de sesión) se refiere a que un individuo
(atacante) consigue el identificador de sesión entre una página web y un usuario, de
forma que puede hacerse pasar por este y acceder a su cuenta en esa página.
A continuación veremos algunas de las formas en las que un atacante puede
robar este identificador y técnicas para intentar prevenirlo en esta introducción y que
elaboro un poco más detenidamente en la Seguridad en PHP

Ataque por fuerza bruta
El ataque por fuerza bruta significa probar identificadores aleatoriamente hasta
encontrar uno que esté siendo usado. Es como intentar abrir una caja fuerte sin saber la
combinación, poniendo números al azar.
Como en el caso de la caja fuerte, cuantos más números tenga la combinación
(en este caso el identificador de sesión), más difícil será de adivinar. También ayuda el
hecho de que el número o identificador sea aleatorio, y no algo que se pueda predecir.
El sistema de identificadores de sesión de PHP es aceptable en este sentido.

Robo por sniffing
Este tipo de ataque se da cuando el atacante tiene un programa de sniffing1 en la
red del usuario y puede interceptar el tráfico destinado al mismo, incluido su
identificador de sesión. Es algo que ha dado mucho de que hablar a causa de Firesheep,
una extensión para Firefox que permite robar las sesiones de Facebook, Twitter y otras
páginas web muy conocidas en redes inalámbricas públicas. La única forma de prevenir
estos ataques es utilizando cifrado HTTPS en toda la página web.

Propagacion en URL
Si el identificador de sesión se propaga utilizando la URL en lugar de las cookies,
cualquier atacante puede robarlo desde muchos sitios:
•
•
•

Un enlace que el propio usuario ponga en un lugar público. Los usuarios típicos
no saben para que sirve ese identificador y no le dan importancia.
El historial del navegador.
El referrer, que es un encabezado que envían muchos navegadores a las páginas
web en el que les indican la URL de la que vienen.

La forma de prevenir esto es no utilizar la URL para el identificador de sesión;
utilizar únicamente las cookies. En PHP esto se consigue con la instrucción:
ini_set('session.use_only_cookies', 1);

1

un analizador de paquetes, un programa de captura de las tramas de una red informática
Robo de sesiones en PHP

Miguel Angel Lopez Torralba

Robo en servidor compartido
Si tenemos nuestra página web alojada en un servidor compartido, los archivos
físicos de las sesiones se guardan, por defecto, en un directorio común para todas las
páginas web del servidor. Esto quiere decir que todas las personas que tengan su página
web en ese mismo servidor, tienen acceso a todos los archivos de sesiones. Dado que el
nombre de los archivos es "sess_" más el identificador de sesión, cualquier atacante
tendrá una lista de identificadores de sesión válidos con sólo leer la lista de archivos del
directorio común.
Esta vulnerabilidad se puede combatir de dos formas:
•

Usando la función session_save_path para guardar los archivos de sesión de la
página web en un directorio dentro de su cuenta al que sólo pueda acceder PHP
(ya sea por estar fuera del directorio web o con un .htaccess con la instrucción
deny from all). Este método no es demasiado fiable, ya que el resto de
usuarios seguirá pudiendo leer en ese directorio, sólo tienen que averiguar su
localización.
Robo de sesiones en PHP
•

Miguel Angel Lopez Torralba

Guardando las sesiones en base de datos en lugar de en archivos. Esto se
consigue fácilmente usando la función session_set_save_handler. Esta solución
es la más segura ya que la página web será la única que tendrá acceso a la base
de datos y, por tanto, a las sesiones.

Robo por Cross-Site Scripting
Si la página web es vulnerable a XSS el atacante puede insertar un código
javascript que envíe las cookies de un usuario a su cuenta.
Este tipo de ataque se puede prevenir (además de evitando los ataques XSS)
haciendo que las cookies de sesión tengan el atributo HttpOnly, que evita que puedan
ser manejadas por javascript en la mayoría de navegadores. En PHP esto se consigue
con la instrucción:
ini_set('session.cookie_httponly', 1);

Metodos de prevenci0n generales
Además de los métodos de prevención concretos vistos para cada tipo de ataque, vamos
a ver algunas técnicas de prevención que ayudan a evitar el robo de las sesiones:
•
•

•
•

Limitar tiempo de inactividad: eliminar la sesión si está cierto tiempo sin ser
usada (de 5 a 30 minutos, según el nivel de seguridad de la página web).
Cambiar el identificador de sesión: cada cierto tiempo o después de cada
acción, cambiar el identificador de la sesión por otro distinto y eliminar la sesión
antigua.
Sistema de logout: dar a los usuarios una forma de salir de su cuenta y destruir
la sesión.
Verificación doble: usar un segundo método para intentar reconocer al usuario
de la sesión. Esto puede hacerse guardando cabeceras como HTTP_USER_AGENT
(navegador del usuario) o REMOTE_ADDR (IP del usuario) cuando se crea la
sesión, de esta forma:
$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT']);

La IP del usuario es más significativa que su navegador, pero es más
problemática ya que hay usuarios a los que les cambia la IP habitualmente (IP
dinámica, proxies, ...).
Con este sistema, un atacante tendría que robar la sesión a un usuario y, además,
enviar la misma cabecera de navegador para poder usarla.
Robo de sesiones en PHP

Miguel Angel Lopez Torralba

Seguridad PHP
PHP tiene soporte nativo para trabajar con sesiones. Cada sesión viene
identificada un id aleatorio (32 caracters hexadecimales), que se crea la inicializar dicha
sesión con la función session_start(), y que se almacena en una variable llamada
PHPSESSID. Este id es esencial ya que cuando creamos una sesión, se crea un array
superglobal que almacenará la información de la sesión. Y éste se almacena en el
servidor, en un archivo temporal cuyo nombre está formado por 'sess' + dicho ID de
sesión (depende de la configuración de php.ini).
Ahora necesitamos que el cliente tenga una forma de hacer peticiones al servidor
y que este sepa que se está comunicando en un contexto de sesión determinado. O
dicho de otra forma el servidor tiene que saber que las peticiones del cliente pertenecen
a la sesión.

En una comunicación bidireccional hay dos posibilidades para la comunicación
de identificador de sesión:
1- Si el cliente tiene las cookies activadas. En él se
crea una cookie con nombre PHPSESSID (modificable en
php.ini) y cuyo valor es el identificador de 32 caracteres
hexadecimales. Recordemos que cada una de las cookies de
un sitio web es una cadena: una lista de parejas "nombre,
valor" separadas por punto y coma. La cookie se crea en el
cliente gracias a que el servidor, tras haber creado la sesión,
envía la primera respuesta con la cookie en su cabecera:
Robo de sesiones en PHP

Miguel Angel Lopez Torralba

HTTP/1.1 200 OK
Date: Sun, 12 Sep 2010 22:46:25 GMT
Server: Apache/2.2.15 (Win32) PHP/5.2.13
X-Powered-By: PHP/5.2.13
Set-Cookie: PHPSESSID=q75n4oq6turdv67uohqkbl7lv5; path=/
Expires: Thu, 5 Sep 2013 08:52:00 GMT
Cache-Control:

no-store,

no-cache,

must-revalidate,

post-check=0,

pre-check=0
Pragma: no-cache
Content-Length: 2031
Content-Type: text/html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es">
<head>
<title>Página 1</title>
...

A partir de aquí y siempre dentro de la duración de la sesión, el navegador
acompañará esta cookie con las solicitudes de páginas que se hagan a ese mismo
servidor. Y este último comprobará que el identificador existe y es válido recuperando
la sesión de entre sus ficheros donde se almacenan las sesiones.

2- Si el cliente (navegador) tiene las cookies desactivadas. PHP dispone de una
opción alternativa que permite la propagación a través de la URL como hemos visto
antes. Para garantizar la propagación de las sesiones aún cuando el navegador esté
configurado para no aceptar cookies. Por lo tanto se tendrá que pasar el PHPSESSID
junto con las llamadas a las páginas siguientes. Y para ello tenemos 2 opciones:
- Añadir el PHPSESSID manualmente cada vez que creamos un enlace:
<a href="page.php?PHPSESSID=<?php
echo htmlspecialchars(session_id()); ?>">haga click</a>

- Dejar que PHP lo añada automáticamente. Si modificamos en el php.ini la
variable session.use_trans_sid a True, PHP añadirá automáticamente el PHPSESSID a
las URI's de tu sitio web de manera transparente al desarrollador. Siempre que la sesión
no haya expirado y que las cookies del cliente estén desactivadas. Y así, cuando el
cliente envíe nuevamente la petición al servidor a través de una URI con PHPSESSID,
se podrá coger mediante el array $_GET para comprobar que no ha habido cambio.
Esta opción viene desactivada por seguridad ya que estamos mostrando dicho id en la
url.

También se puede activar en tiempo de ejecución, en el script evidentemente, mediante
Robo de sesiones en PHP

Miguel Angel Lopez Torralba

ini_set('session.use_trans_sid', true);

Tal y como hemos visto en la introducción.

Problemas de seguridad con PHPSESSID
El mayor problema con el envío del id de la sesión de un lado a otro, ya sea en
las cabeceras o en la url, es que es susceptible a ser interceptado y con ello aumenta la
posibilidad de acceder a un servidor de forma ilegítima.
Podría ser interceptado si alguien escanea o
monitoriza el tráfico de la red. Y debido al fuerte
crecimiento de las redes WIFI con débiles protocolos de
encriptación, hacen que el apropiarse de los datos de
sesión sea más sencillo. Además, la posibilidad
anteriormente comentada de incluir el PHPSESSID en la
url hace que incluso los usuarios despistados revelen ellos
mismos el id. Ya que es posible que al copiar y compartir
un enlace, estén enviando información de su sesión. Y
esto sucede más de lo que uno puede pensar.
Pero no solo es posible interceptar el PHPSESSID mediante un escaneo o
monitorización. También es posible a través de un proxy que actué entre el cliente y el
servidor y capturar la información de la sesión. Y esto podría ocurrir mediante un
mensaje cuyo enlace no lleva al sitio de confianza que se presupone. Si no que lleva a
un servidor (hace de proxy) que se encarga de redirigir al sitio legítimo y capturar la
información de las cabeceras donde puede haber alguna cookie de sesión.

Ataque por fijacion de sesion
Como hemos visto, cuando un usuario se autentica en una aplicación, el valor de
la sesión que se creará no cambiará en toda la sesión (si no lo cambiamos nosotros). Por
tanto, se puede atacar intentando que la víctima se autentique en la aplicación usando un
ID de sesión previamente creada por el atacante. De tal forma que una vez el usuario se
autentique, el atacante pueda acceder a la aplicación con el mismo rol que la víctima
gracias a que conoce la sesión de ésta.
Este ataque es posible gracias a uso de PHPSESSID en las las urls y a programar
el comportamiento de las sesiones de una forma equivocada.
Robo de sesiones en PHP

Miguel Angel Lopez Torralba

Ejemplo
Vamos a ver un ejemplo donde un mal uso de una función puede provocar un
fallo de seguridad.
Con la función PHP session_id() hay que tener
cuidado ya que ofrece la posibilidad de cambiar el
identificador actual de la sesión si se le pasa
como parámetro dicho identificador. Pero para que
funcione este cambio tiene que ir antes de iniciar la
sesión con la llamada a session_start().Y esto puede ser
aprovechado por los atacantes para intentar que un
usuario registrado se identifique y sin saberlo cree un
PHPSESSID conocido por ellos. Y así poder suplantarlo.

Imaginanemos que un atacante, conociendo el uso de id de sesión en la url por
parte del servidor, proporciona este enlace para ver si lo usa algún usuario registrado en
dicho servidor y que tenga desactivado el uso de cookies (recuerda que el servidor que
haga uso de PHPSESSID en url primero comprueba que las cookies están desactivadas
en el cliente):
www.ejemplo.com/index.php?action=login&PHPSESSID=1234

Pues si ese usuario se identifica en el servidor y resulta que el servidor ejecuta
algo parecido a session_id($_GET['PHPSESSID']) antes de una llamada a
session_start(), se acaba de crear una sesión con el id 1234. Y como ese ID lo conoce el
atacante, se puede apropiar de la sesión. Y utilizarla para identificarse en el servidor y
suplantar al usuario legítimo.
La utilización de $_GET['PHPSESSID'] solo tiene sentido si se transportan
PHPSESSID por la url. Si el servidor solo utilizará cookies no tendría sentido que en
algún momento se capturase de variable anterior.
Por lo tanto este ataque (el del ejemplo) no podría llevarse a cabo si solo se transmite el
PHPSESSID por cookies. Pero aún está el problema de la interceptación de la
comunicaciones (proxy o escaneo) y utilizar la cookie de sesión para identificarse.

Opciones para prevenir ataques
Aunque hemos visto anteriormente algunas formas de evitar ataques, en este
caso vamos a hacerlo de forma más tecnica y enfocada a PHP
SSL
Muchos sitios web usan SSL únicamente para encriptar contenido de
formularios, como podría ser el de login. Sin embargo también sería muy aconsejable
usar SSL para encriptar toda la información que se transmite entre las partes de la
comunicación (cliente-servidor). Ya que encriptando la PHPSESSID podríamos
protegernos de dos de los tipos de ataques comentados en el apartado anterior:
Robo de sesiones en PHP

Miguel Angel Lopez Torralba

-Por un lado nos protegeríamos gracias a la encriptación de posible atacantes que
escaneando o monitorizando el tráfico de la red buscan datos de sesión.
-Y por otro lado nos protegeríamos de posibles redirecciones a proxys
inesperados. Ya que al establecerse la comunicación entre el cliente y el
servidor fraudulento (autofirmado con su certificado fraudulento), el navegador (cliente)
nos avisaría que el certificado de dicho servidor es desconocido.
Evidentemente el problema de este mecanismo de
seguridad es su coste económico (certificados de clave pública
firmados por entidad certificadora). Por lo que se van a presentar
otros mecanismos para proporcionar una seguridad decente sin
coste adicional. Pero que no es completa al cien por cien. Ya que el
la seguridad completa ante proxies y escaneos solo la proporciona
el uso correcto de SSL.

Tiempo de expiracion en la sesion
Esto tiene poca historia. Si definimos un tiempo de expiración de sesión muy
alto estamos dando más tiempo al usuario 'malicioso' a que pruebe y desarrolle sus
ataques.
El tiempo de vida de la 'cookie de sesión' lo podemos especificar mediante la
siguiente función:
ini_set("session.cookie_lifetime",120);

//El

tiempo

viene

dado

en

segundos

Es posible que intentéis modificar el tiempo de
vida de una cookie y no funcione. Hay que tener en
cuenta que es posible que vuestro equipo siga teniendo
una cookie activa, por lo que hasta que no caduque la
anterior no se guardará la nueva con el tiempo de vida
modificado.
Pero este cambio sólo afecta la vida de la cookie y
la sesión puede ser todavía válida. Es tarea del servidor
invalidar una sesión, no del cliente. Así que como lo que
queremos es que expire la sesión en el servidor tenemos
que buscar una alternativa mejor.
Una buena solución sería utilizar marcas de tiempo. En el siguiente ejemplo
destruiremos las sesión si han pasado mas de 30 minutos desde la identificación del
usuario.
Tras hacer login y al crear la sesión nos guardariamos la tiempo Unix del último acceso:
$_SESSION['LAST_LOGIN'] = time(); // última identificación

Y podríamos introducir la siguiente función para saber si tenemos que cancelar
la sesión o no por haber pasado el tiempo límite.
Robo de sesiones en PHP

Miguel Angel Lopez Torralba

function tiempo() {
if

(isset($_SESSION['LAST_LOGIN'])

&&

(time()

-

$_SESSION['LAST_LOGIN'] > 1800)) {
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), "", time() - 3600, "/");
//limpiamos completamente el array superglobal
session_unset();
//Eliminamos la sesión (archivo) del servidor
session_destroy();
}
header(...) //redirigir al punto de partida para identificarse
exit;
}
//...
}

Afortunadamente dependiendo de la versión de PHP que estemos utilizando, así
como de la configuración de nuestro php.ini, las sesiones desaparecen por si solas en
periodos que van desde los 30 a 180 minutos, claro que este puede ser tiempo más que
necesario para que nos suplanten la sesión.
Cookies vs PHPSESSID en la URL
A partir de PHP 4.2, la variable session.use_trans_sid en el php.ini esta a false
por lo que por defecto el uso de PHPSESSID automático en las urls, por parte de php,
esta desactivado. Y únicamente se usarán cookies para la comunicación del PHPSSID.
Tambien podemos usar este código en entornos donde session.use_trans_sid este activo
y queramos desactivarlo.
ini_set('session.use_only_cookies', true);
ini_set('session.use_trans_sid', false);

Hay que recordar que usar cookies no evita ataque mediante proxies o escaneos.

Regenerar ID de sesion
Una manera facíl de proteger contra ataques provocados por el posible robo del
identificador de sesión es mediante una simple regeneración de dicho id. De está forma
un atacante no podría utilizar el id apropiado ya que no sería el mismo que el generado
por el servidor.
Hay que pensar que el robo de id de sesión solo es útil para el atacante después
de que el usuario se haya logeado y se haya creado la sesión. Por lo tanto es un buen
momento para regenerar dicho id. en tiempo de ejecución:
Robo de sesiones en PHP

Miguel Angel Lopez Torralba

Por ejemplo:
<?php
session_start();
if (!isset($_SESSION['inicializada']))
{
session_regenerate_id();
$_SESSION['inicializada'] = true;
}
?>

Esto nos protegería ante la fijación de la sesión ya que el id que pretendía usar el
atacante, forzando al usuario a crear una sesión con él, habrá cambiado.
Aunque evidentemente, no solucionará nada si intercepta todas las comunicaciónes. Ya
que todos los cambios de cookies de sesión viajan por las cabeceras de la peticiones y
respuestas.
User-Agent
Una forma de incrementar la seguridad es mediante el uso
del user-agent. En las cabeceras de cada mensaje entre cliente y
servidor, además de la cookie con el PHPSESSID también se
especifica el user-agent. Que incluye información como la
versión del navegador del cliente que está haciendo las
peticiones. Pues podemos utilizar esta información para que
aunque se apropien del PHPSESSID, los atacantes necesiten las
mismas condiciones que indica el user-agent. Por lo
que podríamos guardarlo tras identificar al usuario y
posteriormente hacer comprobaciones para cada para cada script.
<?php
/*login.php*/
...
if($existeUsuario){
session_start( );
$_SESSION['user_id']

=

$data['user_id'];

$_SESSION['first_name']
=
$data['first_name'];
$_SESSION['agent'] = sha1($_SERV['HTTP_USER_AGENT']);
header("location:home.php");
}
...
Robo de sesiones en PHP

Miguel Angel Lopez Torralba

<?php
/*home.php*/
session_start();
if (isset($_SESSION['agent']))
{
if ($_SESSION['agent'] != sha1($_SERVER['HTTP_USER_AGENT']))
{
exit;
}
}
...
?>

Sin embargo hay que tener cuidado ya que por ejemplo Internet Explorer, al usar el
modo compatibilidad, puede cambiar su usar-agent.

Conclusion
La forma eficaz de combatir el robo de sesiones es mediante la combinación de
las técnicas explicadas.
- Usar SSL para evitar que les sirva de algo la información interceptada por lo
atacantes.
- Tener el servidor configurado correctamente (no permitir PHPSESSID en url,
expirar sesiones ....).
- Regenerar sesiones para que si alguien ha obtenido en algún momento un
identificador de sesión no pueda utilizarlo. Ya que el identificador habrá cambiado con
la regeneración y el que tiene el atacante no es válido.

Contenu connexe

Tendances

Cuáles son los navegadores de internet más seguros
Cuáles son los navegadores de internet más segurosCuáles son los navegadores de internet más seguros
Cuáles son los navegadores de internet más seguros
jmatheus74
 
Manual de squid creado por juanextk
Manual de squid creado por juanextkManual de squid creado por juanextk
Manual de squid creado por juanextk
juanextk
 

Tendances (14)

Tema 3 - Seguridad en Internet
Tema 3 - Seguridad en InternetTema 3 - Seguridad en Internet
Tema 3 - Seguridad en Internet
 
2.6 implementacion de ssh
2.6 implementacion de ssh2.6 implementacion de ssh
2.6 implementacion de ssh
 
MAITAINING ACCESS
MAITAINING ACCESSMAITAINING ACCESS
MAITAINING ACCESS
 
Concientización de Riesgos de Ciberseguridad En Wordpress.
Concientización de Riesgos de Ciberseguridad En Wordpress.Concientización de Riesgos de Ciberseguridad En Wordpress.
Concientización de Riesgos de Ciberseguridad En Wordpress.
 
Maitaining access
Maitaining accessMaitaining access
Maitaining access
 
[Flisol2011] Seguridad en el Desarrollo de Aplicaciones Web PHP
[Flisol2011] Seguridad en el Desarrollo de Aplicaciones Web PHP[Flisol2011] Seguridad en el Desarrollo de Aplicaciones Web PHP
[Flisol2011] Seguridad en el Desarrollo de Aplicaciones Web PHP
 
Seguridad en Aplicaciones Web y Comercio Electrónico
Seguridad en Aplicaciones Web y Comercio ElectrónicoSeguridad en Aplicaciones Web y Comercio Electrónico
Seguridad en Aplicaciones Web y Comercio Electrónico
 
Cuáles son los navegadores de internet más seguros
Cuáles son los navegadores de internet más segurosCuáles son los navegadores de internet más seguros
Cuáles son los navegadores de internet más seguros
 
Ethical hacking 03
Ethical hacking 03Ethical hacking 03
Ethical hacking 03
 
Mitm (Man in the middle) part II
Mitm (Man in the middle) part IIMitm (Man in the middle) part II
Mitm (Man in the middle) part II
 
Hablemos ransomware
Hablemos ransomwareHablemos ransomware
Hablemos ransomware
 
Clvesppwinpt
ClvesppwinptClvesppwinpt
Clvesppwinpt
 
Lord Epsylon - XSSer: the cross site scripting framework [RootedCON 2012]
Lord Epsylon - XSSer: the cross site scripting framework [RootedCON 2012]Lord Epsylon - XSSer: the cross site scripting framework [RootedCON 2012]
Lord Epsylon - XSSer: the cross site scripting framework [RootedCON 2012]
 
Manual de squid creado por juanextk
Manual de squid creado por juanextkManual de squid creado por juanextk
Manual de squid creado por juanextk
 

En vedette (8)

Presentación de Rocío Pérez en AULAGARDEN
Presentación de Rocío Pérez en AULAGARDENPresentación de Rocío Pérez en AULAGARDEN
Presentación de Rocío Pérez en AULAGARDEN
 
Contribuiren el proceso de regeneracion y transformacion de los niños niñas y...
Contribuiren el proceso de regeneracion y transformacion de los niños niñas y...Contribuiren el proceso de regeneracion y transformacion de los niños niñas y...
Contribuiren el proceso de regeneracion y transformacion de los niños niñas y...
 
06practica servidorseguro
06practica servidorseguro06practica servidorseguro
06practica servidorseguro
 
Tomcat
TomcatTomcat
Tomcat
 
Glassfish
GlassfishGlassfish
Glassfish
 
Manual express de git
Manual express de gitManual express de git
Manual express de git
 
Instalación de Apache Tomcat 8
Instalación de Apache Tomcat 8Instalación de Apache Tomcat 8
Instalación de Apache Tomcat 8
 
12 fundamental liberties 6 10 (8)
12 fundamental liberties 6 10 (8)12 fundamental liberties 6 10 (8)
12 fundamental liberties 6 10 (8)
 

Similaire à Robo desesionesfinal

Curso php dia5
Curso php dia5Curso php dia5
Curso php dia5
cognos_uie
 
Curso php dia5
Curso php dia5Curso php dia5
Curso php dia5
cognos_uie
 
Seguridad En Base De Datos
Seguridad En Base De DatosSeguridad En Base De Datos
Seguridad En Base De Datos
William Suárez
 
Seguridad En Base De Datos
Seguridad En Base De DatosSeguridad En Base De Datos
Seguridad En Base De Datos
guestb40a1b0
 

Similaire à Robo desesionesfinal (20)

Manual php completo by_ desarrolloweb
Manual php completo by_ desarrollowebManual php completo by_ desarrolloweb
Manual php completo by_ desarrolloweb
 
Seminario Seguridad con PHP
Seminario Seguridad con PHPSeminario Seguridad con PHP
Seminario Seguridad con PHP
 
Hx c20
Hx c20Hx c20
Hx c20
 
Desarrollo seguro en NodeJS (OWASP top ten y JWT)
Desarrollo seguro en NodeJS (OWASP top ten y JWT)Desarrollo seguro en NodeJS (OWASP top ten y JWT)
Desarrollo seguro en NodeJS (OWASP top ten y JWT)
 
Webinar - Seguridad en WordPress
Webinar - Seguridad en WordPressWebinar - Seguridad en WordPress
Webinar - Seguridad en WordPress
 
Sesiones
SesionesSesiones
Sesiones
 
WHITEPAPER ESET ESPAÑA – AUMENTADO LA SEGURIDAD DE WORDPRESS
WHITEPAPER ESET ESPAÑA – AUMENTADO LA SEGURIDAD DE WORDPRESSWHITEPAPER ESET ESPAÑA – AUMENTADO LA SEGURIDAD DE WORDPRESS
WHITEPAPER ESET ESPAÑA – AUMENTADO LA SEGURIDAD DE WORDPRESS
 
tema.pptx
tema.pptxtema.pptx
tema.pptx
 
Seguridad WEB - Principios básicos.
Seguridad WEB - Principios básicos.Seguridad WEB - Principios básicos.
Seguridad WEB - Principios básicos.
 
Xss a fondo
Xss a fondoXss a fondo
Xss a fondo
 
Open ID
Open IDOpen ID
Open ID
 
PHP Tema 5 - Sesiones
PHP Tema 5 - SesionesPHP Tema 5 - Sesiones
PHP Tema 5 - Sesiones
 
Tips de Seguridad para Administradores
Tips de Seguridad para AdministradoresTips de Seguridad para Administradores
Tips de Seguridad para Administradores
 
Curso php dia5
Curso php dia5Curso php dia5
Curso php dia5
 
Curso php dia5
Curso php dia5Curso php dia5
Curso php dia5
 
Seguridad en las apis desde un punto de vista de developer
Seguridad en las apis desde un punto de vista de developerSeguridad en las apis desde un punto de vista de developer
Seguridad en las apis desde un punto de vista de developer
 
Seguridad en aplicaciones web
Seguridad en aplicaciones webSeguridad en aplicaciones web
Seguridad en aplicaciones web
 
Hack like a pro with custom VPS - Najava Negra 2019
Hack like a pro with custom VPS - Najava Negra 2019Hack like a pro with custom VPS - Najava Negra 2019
Hack like a pro with custom VPS - Najava Negra 2019
 
Seguridad En Base De Datos
Seguridad En Base De DatosSeguridad En Base De Datos
Seguridad En Base De Datos
 
Seguridad En Base De Datos
Seguridad En Base De DatosSeguridad En Base De Datos
Seguridad En Base De Datos
 

Plus de Miguel Angel Lopez Torralba (13)

Ftpsegurocompleta
FtpsegurocompletaFtpsegurocompleta
Ftpsegurocompleta
 
13proftpd
13proftpd13proftpd
13proftpd
 
12integracion de tomcat con apache
12integracion de tomcat con apache12integracion de tomcat con apache
12integracion de tomcat con apache
 
11practicafinal
11practicafinal11practicafinal
11practicafinal
 
10practicafinal
10practicafinal10practicafinal
10practicafinal
 
09practicafinal
09practicafinal09practicafinal
09practicafinal
 
08practica monitorizacion
08practica monitorizacion08practica monitorizacion
08practica monitorizacion
 
07practica multilenguaje
07practica multilenguaje07practica multilenguaje
07practica multilenguaje
 
Depuradores Guía rapida de uso
Depuradores Guía rapida de usoDepuradores Guía rapida de uso
Depuradores Guía rapida de uso
 
03practica puertosip
03practica puertosip03practica puertosip
03practica puertosip
 
02practica completa
02practica completa02practica completa
02practica completa
 
01intalacion de apache
01intalacion de apache01intalacion de apache
01intalacion de apache
 
04practicalog404
04practicalog40404practicalog404
04practicalog404
 

Robo desesionesfinal

  • 1.
  • 2. Robo de sesiones en PHP Miguel Angel Lopez Torralba INtroduccion Definicion Session Hijacking (secuestro o robo de sesión) se refiere a que un individuo (atacante) consigue el identificador de sesión entre una página web y un usuario, de forma que puede hacerse pasar por este y acceder a su cuenta en esa página. A continuación veremos algunas de las formas en las que un atacante puede robar este identificador y técnicas para intentar prevenirlo en esta introducción y que elaboro un poco más detenidamente en la Seguridad en PHP Ataque por fuerza bruta El ataque por fuerza bruta significa probar identificadores aleatoriamente hasta encontrar uno que esté siendo usado. Es como intentar abrir una caja fuerte sin saber la combinación, poniendo números al azar. Como en el caso de la caja fuerte, cuantos más números tenga la combinación (en este caso el identificador de sesión), más difícil será de adivinar. También ayuda el hecho de que el número o identificador sea aleatorio, y no algo que se pueda predecir. El sistema de identificadores de sesión de PHP es aceptable en este sentido. Robo por sniffing Este tipo de ataque se da cuando el atacante tiene un programa de sniffing1 en la red del usuario y puede interceptar el tráfico destinado al mismo, incluido su identificador de sesión. Es algo que ha dado mucho de que hablar a causa de Firesheep, una extensión para Firefox que permite robar las sesiones de Facebook, Twitter y otras páginas web muy conocidas en redes inalámbricas públicas. La única forma de prevenir estos ataques es utilizando cifrado HTTPS en toda la página web. Propagacion en URL Si el identificador de sesión se propaga utilizando la URL en lugar de las cookies, cualquier atacante puede robarlo desde muchos sitios: • • • Un enlace que el propio usuario ponga en un lugar público. Los usuarios típicos no saben para que sirve ese identificador y no le dan importancia. El historial del navegador. El referrer, que es un encabezado que envían muchos navegadores a las páginas web en el que les indican la URL de la que vienen. La forma de prevenir esto es no utilizar la URL para el identificador de sesión; utilizar únicamente las cookies. En PHP esto se consigue con la instrucción: ini_set('session.use_only_cookies', 1); 1 un analizador de paquetes, un programa de captura de las tramas de una red informática
  • 3. Robo de sesiones en PHP Miguel Angel Lopez Torralba Robo en servidor compartido Si tenemos nuestra página web alojada en un servidor compartido, los archivos físicos de las sesiones se guardan, por defecto, en un directorio común para todas las páginas web del servidor. Esto quiere decir que todas las personas que tengan su página web en ese mismo servidor, tienen acceso a todos los archivos de sesiones. Dado que el nombre de los archivos es "sess_" más el identificador de sesión, cualquier atacante tendrá una lista de identificadores de sesión válidos con sólo leer la lista de archivos del directorio común. Esta vulnerabilidad se puede combatir de dos formas: • Usando la función session_save_path para guardar los archivos de sesión de la página web en un directorio dentro de su cuenta al que sólo pueda acceder PHP (ya sea por estar fuera del directorio web o con un .htaccess con la instrucción deny from all). Este método no es demasiado fiable, ya que el resto de usuarios seguirá pudiendo leer en ese directorio, sólo tienen que averiguar su localización.
  • 4. Robo de sesiones en PHP • Miguel Angel Lopez Torralba Guardando las sesiones en base de datos en lugar de en archivos. Esto se consigue fácilmente usando la función session_set_save_handler. Esta solución es la más segura ya que la página web será la única que tendrá acceso a la base de datos y, por tanto, a las sesiones. Robo por Cross-Site Scripting Si la página web es vulnerable a XSS el atacante puede insertar un código javascript que envíe las cookies de un usuario a su cuenta. Este tipo de ataque se puede prevenir (además de evitando los ataques XSS) haciendo que las cookies de sesión tengan el atributo HttpOnly, que evita que puedan ser manejadas por javascript en la mayoría de navegadores. En PHP esto se consigue con la instrucción: ini_set('session.cookie_httponly', 1); Metodos de prevenci0n generales Además de los métodos de prevención concretos vistos para cada tipo de ataque, vamos a ver algunas técnicas de prevención que ayudan a evitar el robo de las sesiones: • • • • Limitar tiempo de inactividad: eliminar la sesión si está cierto tiempo sin ser usada (de 5 a 30 minutos, según el nivel de seguridad de la página web). Cambiar el identificador de sesión: cada cierto tiempo o después de cada acción, cambiar el identificador de la sesión por otro distinto y eliminar la sesión antigua. Sistema de logout: dar a los usuarios una forma de salir de su cuenta y destruir la sesión. Verificación doble: usar un segundo método para intentar reconocer al usuario de la sesión. Esto puede hacerse guardando cabeceras como HTTP_USER_AGENT (navegador del usuario) o REMOTE_ADDR (IP del usuario) cuando se crea la sesión, de esta forma: $_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT']); La IP del usuario es más significativa que su navegador, pero es más problemática ya que hay usuarios a los que les cambia la IP habitualmente (IP dinámica, proxies, ...). Con este sistema, un atacante tendría que robar la sesión a un usuario y, además, enviar la misma cabecera de navegador para poder usarla.
  • 5. Robo de sesiones en PHP Miguel Angel Lopez Torralba Seguridad PHP PHP tiene soporte nativo para trabajar con sesiones. Cada sesión viene identificada un id aleatorio (32 caracters hexadecimales), que se crea la inicializar dicha sesión con la función session_start(), y que se almacena en una variable llamada PHPSESSID. Este id es esencial ya que cuando creamos una sesión, se crea un array superglobal que almacenará la información de la sesión. Y éste se almacena en el servidor, en un archivo temporal cuyo nombre está formado por 'sess' + dicho ID de sesión (depende de la configuración de php.ini). Ahora necesitamos que el cliente tenga una forma de hacer peticiones al servidor y que este sepa que se está comunicando en un contexto de sesión determinado. O dicho de otra forma el servidor tiene que saber que las peticiones del cliente pertenecen a la sesión. En una comunicación bidireccional hay dos posibilidades para la comunicación de identificador de sesión: 1- Si el cliente tiene las cookies activadas. En él se crea una cookie con nombre PHPSESSID (modificable en php.ini) y cuyo valor es el identificador de 32 caracteres hexadecimales. Recordemos que cada una de las cookies de un sitio web es una cadena: una lista de parejas "nombre, valor" separadas por punto y coma. La cookie se crea en el cliente gracias a que el servidor, tras haber creado la sesión, envía la primera respuesta con la cookie en su cabecera:
  • 6. Robo de sesiones en PHP Miguel Angel Lopez Torralba HTTP/1.1 200 OK Date: Sun, 12 Sep 2010 22:46:25 GMT Server: Apache/2.2.15 (Win32) PHP/5.2.13 X-Powered-By: PHP/5.2.13 Set-Cookie: PHPSESSID=q75n4oq6turdv67uohqkbl7lv5; path=/ Expires: Thu, 5 Sep 2013 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 2031 Content-Type: text/html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"> <head> <title>Página 1</title> ... A partir de aquí y siempre dentro de la duración de la sesión, el navegador acompañará esta cookie con las solicitudes de páginas que se hagan a ese mismo servidor. Y este último comprobará que el identificador existe y es válido recuperando la sesión de entre sus ficheros donde se almacenan las sesiones. 2- Si el cliente (navegador) tiene las cookies desactivadas. PHP dispone de una opción alternativa que permite la propagación a través de la URL como hemos visto antes. Para garantizar la propagación de las sesiones aún cuando el navegador esté configurado para no aceptar cookies. Por lo tanto se tendrá que pasar el PHPSESSID junto con las llamadas a las páginas siguientes. Y para ello tenemos 2 opciones: - Añadir el PHPSESSID manualmente cada vez que creamos un enlace: <a href="page.php?PHPSESSID=<?php echo htmlspecialchars(session_id()); ?>">haga click</a> - Dejar que PHP lo añada automáticamente. Si modificamos en el php.ini la variable session.use_trans_sid a True, PHP añadirá automáticamente el PHPSESSID a las URI's de tu sitio web de manera transparente al desarrollador. Siempre que la sesión no haya expirado y que las cookies del cliente estén desactivadas. Y así, cuando el cliente envíe nuevamente la petición al servidor a través de una URI con PHPSESSID, se podrá coger mediante el array $_GET para comprobar que no ha habido cambio. Esta opción viene desactivada por seguridad ya que estamos mostrando dicho id en la url. También se puede activar en tiempo de ejecución, en el script evidentemente, mediante
  • 7. Robo de sesiones en PHP Miguel Angel Lopez Torralba ini_set('session.use_trans_sid', true); Tal y como hemos visto en la introducción. Problemas de seguridad con PHPSESSID El mayor problema con el envío del id de la sesión de un lado a otro, ya sea en las cabeceras o en la url, es que es susceptible a ser interceptado y con ello aumenta la posibilidad de acceder a un servidor de forma ilegítima. Podría ser interceptado si alguien escanea o monitoriza el tráfico de la red. Y debido al fuerte crecimiento de las redes WIFI con débiles protocolos de encriptación, hacen que el apropiarse de los datos de sesión sea más sencillo. Además, la posibilidad anteriormente comentada de incluir el PHPSESSID en la url hace que incluso los usuarios despistados revelen ellos mismos el id. Ya que es posible que al copiar y compartir un enlace, estén enviando información de su sesión. Y esto sucede más de lo que uno puede pensar. Pero no solo es posible interceptar el PHPSESSID mediante un escaneo o monitorización. También es posible a través de un proxy que actué entre el cliente y el servidor y capturar la información de la sesión. Y esto podría ocurrir mediante un mensaje cuyo enlace no lleva al sitio de confianza que se presupone. Si no que lleva a un servidor (hace de proxy) que se encarga de redirigir al sitio legítimo y capturar la información de las cabeceras donde puede haber alguna cookie de sesión. Ataque por fijacion de sesion Como hemos visto, cuando un usuario se autentica en una aplicación, el valor de la sesión que se creará no cambiará en toda la sesión (si no lo cambiamos nosotros). Por tanto, se puede atacar intentando que la víctima se autentique en la aplicación usando un ID de sesión previamente creada por el atacante. De tal forma que una vez el usuario se autentique, el atacante pueda acceder a la aplicación con el mismo rol que la víctima gracias a que conoce la sesión de ésta. Este ataque es posible gracias a uso de PHPSESSID en las las urls y a programar el comportamiento de las sesiones de una forma equivocada.
  • 8. Robo de sesiones en PHP Miguel Angel Lopez Torralba Ejemplo Vamos a ver un ejemplo donde un mal uso de una función puede provocar un fallo de seguridad. Con la función PHP session_id() hay que tener cuidado ya que ofrece la posibilidad de cambiar el identificador actual de la sesión si se le pasa como parámetro dicho identificador. Pero para que funcione este cambio tiene que ir antes de iniciar la sesión con la llamada a session_start().Y esto puede ser aprovechado por los atacantes para intentar que un usuario registrado se identifique y sin saberlo cree un PHPSESSID conocido por ellos. Y así poder suplantarlo. Imaginanemos que un atacante, conociendo el uso de id de sesión en la url por parte del servidor, proporciona este enlace para ver si lo usa algún usuario registrado en dicho servidor y que tenga desactivado el uso de cookies (recuerda que el servidor que haga uso de PHPSESSID en url primero comprueba que las cookies están desactivadas en el cliente): www.ejemplo.com/index.php?action=login&PHPSESSID=1234 Pues si ese usuario se identifica en el servidor y resulta que el servidor ejecuta algo parecido a session_id($_GET['PHPSESSID']) antes de una llamada a session_start(), se acaba de crear una sesión con el id 1234. Y como ese ID lo conoce el atacante, se puede apropiar de la sesión. Y utilizarla para identificarse en el servidor y suplantar al usuario legítimo. La utilización de $_GET['PHPSESSID'] solo tiene sentido si se transportan PHPSESSID por la url. Si el servidor solo utilizará cookies no tendría sentido que en algún momento se capturase de variable anterior. Por lo tanto este ataque (el del ejemplo) no podría llevarse a cabo si solo se transmite el PHPSESSID por cookies. Pero aún está el problema de la interceptación de la comunicaciones (proxy o escaneo) y utilizar la cookie de sesión para identificarse. Opciones para prevenir ataques Aunque hemos visto anteriormente algunas formas de evitar ataques, en este caso vamos a hacerlo de forma más tecnica y enfocada a PHP SSL Muchos sitios web usan SSL únicamente para encriptar contenido de formularios, como podría ser el de login. Sin embargo también sería muy aconsejable usar SSL para encriptar toda la información que se transmite entre las partes de la comunicación (cliente-servidor). Ya que encriptando la PHPSESSID podríamos protegernos de dos de los tipos de ataques comentados en el apartado anterior:
  • 9. Robo de sesiones en PHP Miguel Angel Lopez Torralba -Por un lado nos protegeríamos gracias a la encriptación de posible atacantes que escaneando o monitorizando el tráfico de la red buscan datos de sesión. -Y por otro lado nos protegeríamos de posibles redirecciones a proxys inesperados. Ya que al establecerse la comunicación entre el cliente y el servidor fraudulento (autofirmado con su certificado fraudulento), el navegador (cliente) nos avisaría que el certificado de dicho servidor es desconocido. Evidentemente el problema de este mecanismo de seguridad es su coste económico (certificados de clave pública firmados por entidad certificadora). Por lo que se van a presentar otros mecanismos para proporcionar una seguridad decente sin coste adicional. Pero que no es completa al cien por cien. Ya que el la seguridad completa ante proxies y escaneos solo la proporciona el uso correcto de SSL. Tiempo de expiracion en la sesion Esto tiene poca historia. Si definimos un tiempo de expiración de sesión muy alto estamos dando más tiempo al usuario 'malicioso' a que pruebe y desarrolle sus ataques. El tiempo de vida de la 'cookie de sesión' lo podemos especificar mediante la siguiente función: ini_set("session.cookie_lifetime",120); //El tiempo viene dado en segundos Es posible que intentéis modificar el tiempo de vida de una cookie y no funcione. Hay que tener en cuenta que es posible que vuestro equipo siga teniendo una cookie activa, por lo que hasta que no caduque la anterior no se guardará la nueva con el tiempo de vida modificado. Pero este cambio sólo afecta la vida de la cookie y la sesión puede ser todavía válida. Es tarea del servidor invalidar una sesión, no del cliente. Así que como lo que queremos es que expire la sesión en el servidor tenemos que buscar una alternativa mejor. Una buena solución sería utilizar marcas de tiempo. En el siguiente ejemplo destruiremos las sesión si han pasado mas de 30 minutos desde la identificación del usuario. Tras hacer login y al crear la sesión nos guardariamos la tiempo Unix del último acceso: $_SESSION['LAST_LOGIN'] = time(); // última identificación Y podríamos introducir la siguiente función para saber si tenemos que cancelar la sesión o no por haber pasado el tiempo límite.
  • 10. Robo de sesiones en PHP Miguel Angel Lopez Torralba function tiempo() { if (isset($_SESSION['LAST_LOGIN']) && (time() - $_SESSION['LAST_LOGIN'] > 1800)) { if (isset($_COOKIE[session_name()])) { setcookie(session_name(), "", time() - 3600, "/"); //limpiamos completamente el array superglobal session_unset(); //Eliminamos la sesión (archivo) del servidor session_destroy(); } header(...) //redirigir al punto de partida para identificarse exit; } //... } Afortunadamente dependiendo de la versión de PHP que estemos utilizando, así como de la configuración de nuestro php.ini, las sesiones desaparecen por si solas en periodos que van desde los 30 a 180 minutos, claro que este puede ser tiempo más que necesario para que nos suplanten la sesión. Cookies vs PHPSESSID en la URL A partir de PHP 4.2, la variable session.use_trans_sid en el php.ini esta a false por lo que por defecto el uso de PHPSESSID automático en las urls, por parte de php, esta desactivado. Y únicamente se usarán cookies para la comunicación del PHPSSID. Tambien podemos usar este código en entornos donde session.use_trans_sid este activo y queramos desactivarlo. ini_set('session.use_only_cookies', true); ini_set('session.use_trans_sid', false); Hay que recordar que usar cookies no evita ataque mediante proxies o escaneos. Regenerar ID de sesion Una manera facíl de proteger contra ataques provocados por el posible robo del identificador de sesión es mediante una simple regeneración de dicho id. De está forma un atacante no podría utilizar el id apropiado ya que no sería el mismo que el generado por el servidor. Hay que pensar que el robo de id de sesión solo es útil para el atacante después de que el usuario se haya logeado y se haya creado la sesión. Por lo tanto es un buen momento para regenerar dicho id. en tiempo de ejecución:
  • 11. Robo de sesiones en PHP Miguel Angel Lopez Torralba Por ejemplo: <?php session_start(); if (!isset($_SESSION['inicializada'])) { session_regenerate_id(); $_SESSION['inicializada'] = true; } ?> Esto nos protegería ante la fijación de la sesión ya que el id que pretendía usar el atacante, forzando al usuario a crear una sesión con él, habrá cambiado. Aunque evidentemente, no solucionará nada si intercepta todas las comunicaciónes. Ya que todos los cambios de cookies de sesión viajan por las cabeceras de la peticiones y respuestas. User-Agent Una forma de incrementar la seguridad es mediante el uso del user-agent. En las cabeceras de cada mensaje entre cliente y servidor, además de la cookie con el PHPSESSID también se especifica el user-agent. Que incluye información como la versión del navegador del cliente que está haciendo las peticiones. Pues podemos utilizar esta información para que aunque se apropien del PHPSESSID, los atacantes necesiten las mismas condiciones que indica el user-agent. Por lo que podríamos guardarlo tras identificar al usuario y posteriormente hacer comprobaciones para cada para cada script. <?php /*login.php*/ ... if($existeUsuario){ session_start( ); $_SESSION['user_id'] = $data['user_id']; $_SESSION['first_name'] = $data['first_name']; $_SESSION['agent'] = sha1($_SERV['HTTP_USER_AGENT']); header("location:home.php"); } ...
  • 12. Robo de sesiones en PHP Miguel Angel Lopez Torralba <?php /*home.php*/ session_start(); if (isset($_SESSION['agent'])) { if ($_SESSION['agent'] != sha1($_SERVER['HTTP_USER_AGENT'])) { exit; } } ... ?> Sin embargo hay que tener cuidado ya que por ejemplo Internet Explorer, al usar el modo compatibilidad, puede cambiar su usar-agent. Conclusion La forma eficaz de combatir el robo de sesiones es mediante la combinación de las técnicas explicadas. - Usar SSL para evitar que les sirva de algo la información interceptada por lo atacantes. - Tener el servidor configurado correctamente (no permitir PHPSESSID en url, expirar sesiones ....). - Regenerar sesiones para que si alguien ha obtenido en algún momento un identificador de sesión no pueda utilizarlo. Ya que el identificador habrá cambiado con la regeneración y el que tiene el atacante no es válido.