Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Alex

#501
Presentaciones y cumpleaños / Re:Hola a todos!!
Febrero 01, 2013, 12:31:11 PM
Bienvenido al foro!
espero que te sientas como en casa.

saludos!
#502
Presentaciones y cumpleaños / Re:Hola :)
Febrero 01, 2013, 12:31:05 PM
Bienvenido al foro!
espero que te sientas como en casa.

saludos!
#503
Presentaciones y cumpleaños / Re:saludos al equipo
Febrero 01, 2013, 12:30:52 PM
Bienvenido al foro!
espero que te sientas como en casa.

saludos!
#504
Presentaciones y cumpleaños / Re:Hola Underc0de !!!
Febrero 01, 2013, 12:30:41 PM
Bienvenido al foro!
espero que te sientas como en casa.

saludos!
#505
Presentaciones y cumpleaños / Re:Hola a todos xDDDD
Febrero 01, 2013, 12:30:30 PM
Bienvenido al foro!
espero que te sientas como en casa.

saludos!
#506
Batch - Bash / Pasar .bat a .exe
Enero 31, 2013, 01:15:29 AM
Buenas, mirando mi hdd encontré un viejo code, que tendrá como 2 o 3 años, es un programa que toma el archivo .bat y lo mete dentro de si mismo, generando una copia de si mismo que al abrirla ejecuta el batch, de esta forma pareciera que el .bat es un .exe pero en realidad está metido dentro del .exe y se ejecuta.

You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

opciones:

generar .bat
generar .exe
generar .exe encriptado
probar tu code.

pueden cambiar el color a las letras en menú/formato/estilo
pueden borrar todo con menú/formato/limpiar

pueden guardar su proyecto en .TXT y/o abrir su proyecto tambien guardado en txt

tiene una barra de herramienta con las opciones:
@echo off (agrega con dar click así­ no tenes que escribirlo, o si te olvidaste siempre lo pone al principio)
agrega el title xD
agrega la sentencia echo
la sentencia pause
pause > nul
cls
shutdown
y rem.

genera un ejecutable que se le puede agregar un mensaje cualquiera que deceen, y uno de los tres icono a ese mensaje.

el ejecutable tiene 3 posibles iconos.

errores encontrados hasta ahora:
genera error al maximizar o minimizar
el boton guardar aparece el mensaje open xD (error de tipeado)

pd: aveces algunos antivirus lo tiran como virus, porque durante unos años se le dio el uso de compilar virus aparentemente y además que tiene la lógica de los primeros cripters xD.

pd2: si falta dll descargar de aquí­:

You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

saludos! espero que a alguien le sirva.
#507
Dudas y pedidos generales / Re:.exe .dat
Enero 31, 2013, 01:05:44 AM
You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
alguien sabe como convertir archivo .dat en .exe
cambiándole el formato (osea cambiándole el nombre desde la carpeta no funciona) algún otra idea?

You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

los archivos .dat generalmente contienen datos para un programa, algunas cosas que el mismo necesita.

es una extensión comun.

desde el vamos tienes un error de concepto, las extensiones son simplemente un nombre que identifica el contenido de un archivo, cambiandolas no cambias el contenido de un archivo.

lo que quiero decir es que por ejemplo los ejecutables .exe son archivos con instrucciones que fueron compilados, por más que le cambies el nombre a .mp3 no cambiará su contenido y se transformará en música.

es como agarrar una botella de pepsi y ponerle la etiqueta de acuarius, no será un jugo la pepsi solo por cambiarle la etiqueta.

para cambiar formatos de audio por ejemplo de mp3 a wav, o visceversa necesitas un programa, y los codecs que explican como funcionan esos archivos, de modo que el programa convierta el contenido al otro tipo de contenido.

es poco probable que puedas cambiar el formato de un .dat que fue creado como dato a un ejecutable.

mi pregunta es, por que quieres hacer esto?

saludos!
#508
Otros lenguajes / Paradigmas de Programación
Enero 31, 2013, 12:53:55 AM

Un paradigma de programación es una propuesta tecnológica que es adoptada por una comunidad de programadores cuyo núcleo central es incuestionable en cuanto a que unívocamente trata de resolver uno o varios problemas claramente delimitados. La resolución de estos problemas debe suponer consecuentemente un avance significativo en al menos un parámetro que afecte a la ingeniería de software. Tiene una estrecha relación con la formalización de determinados lenguajes en su momento de definición. Un paradigma de programación está delimitado en el tiempo en cuanto a aceptación y uso ya que nuevos paradigmas aportan nuevas o mejores soluciones que la sustituyen parcial o totalmente.
Ejemplo:
Probablemente el paradigma de programación que actualmente es el más usado a todos los niveles es la orientación a objeto. El nucleo central de este paradigma es la unión de datos y procesamiento en una entidad llamada "objeto", relacionable a su vez con otras entidades "objeto".
Tradicionalmente datos y procesamiento se han separado en areas diferente del diseño y la implementación de software. Esto provocó que grandes desarrollos tuvieran problemas de fiabilidad, mantenimiento, adaptación a los cambios y escalabilidad. Con la orientación a objetos y características como el encapsulado, polimorfismo o la herencia se permitió un avance significativo en el desarrollo de software a cualquier escala de producción.
La orientación a objeto parece estar ligado en sus orígenes con lenguajes como Lisp y Simula aunque el primero que acuño el titulo de programación orientada a objetos fue Smaltalk

Tipos de paradigmas de programación
Programación imperativa

Programación Imperativa
La programación imperativa, en contraposición a la programación declarativa es un paradigma de programación que describe la programación en términos del estado del programa y sentencias que cambian dicho estado. Los programas imperativos son un conjunto de instrucciones que le indican al computador cómo realizar una tarea.
La implementación de hardware de la mayoría de computadores es imperativa; prácticamente todo el hardware de los computadores está diseñado para ejecutar código de máquina, que es nativo al computador, escrito en una forma imperativa. Esto se debe a que el hardware de los computadores implementa el paradigma de las Máquinas de Turing. Desde esta perspectiva de bajo nivel, el estilo del programa está definido por los contenidos de la memoria, y las sentencias son instrucciones en el lenguaje de máquina nativo del computador (por ejemplo el lenguaje ensamblador).
Los lenguajes imperativos de alto nivel usan variables y sentencias más complejas, pero aún siguen el mismo paradigma. Las recetas y las listas de revisión de procesos, a pesar de no ser programas de computadora, son también conceptos familiares similares en estilo a la programación imperativa; cada paso es una instrucción, y el mundo físico guarda el estado (Zoom).
Los primeros lenguajes imperativos fueron los lenguajes de máquina de los computadores originales. En estos lenguajes, las instrucciones fueron muy simples, lo cual hizo la implementación de hardware fácil, pero obstruyendo la creación de programas complejos. Fortran, cuyo desarrollo fue iniciado en 1954 por John Backus en IBM, fue el primer gran lenguaje de programación en superar los obstáculos presentados por el código de máquina en la creación de programas complejos.

Programación lógica

Programación lógica
La programación lógica consiste en la aplicación del corpus de conocimiento sobre lógica para el diseño de lenguajes de programación; no debe confundirse con la disciplina de la lógica computacional.
La programación lógica es un tipo de paradigmas de programación dentro del paradigma de programación declarativa. El resto de los subparadigmas de programación dentro de la programación declarativa son: programación funcional, programación basada en restricciones, programas DSL (de dominio específico) e híbridos. La programación lógica gira en torno al concepto de predicado, o relación entre elementos. La programación funcional se basa en el concepto de función (que no es más que una evolución de los predicados), de corte más matemático.

Programación funcional

Programación funcional


En ciencias de la computación, la programación funcional es un paradigma de programación declarativa basado en la utilización de funciones aritméticas que no maneja datos mutables o de estado. Enfatiza la aplicación de funciones, en contraste con el estilo de programación imperativa, que enfatiza los cambios de estado. La programación funcional tiene sus raices en el cálculo lambda, un sistema formal desarrollado en los 1930s para investigar la definición de función, la aplicación de las funciones y la recursión. Muchos lenguajes de programación funcionales pueden ser vistos como elaboraciones del cálculo lambda.

En la práctica, la diferencia entre una función matemática y la noción de una "función" utilizada en la programación imperativa es que las funciones imperativas pueden tener efectos secundarios, al cambiar el valor de calculos realizados previamente. Por esta razón carecen de transparencia referencial, es decir, la misma expresión lingüística puede resultar en valores diferentes en diferentes momentos dependiendo del estado del programa siendo ejecutado. Con código funcional, en contraste, el valor generado por una función depende exclusivamente de los argumentos alimentados a la función. Al eliminar los efectos secundarios se puede entender y predecir el comportamiento de un programa mucho más fácilmente, y esta es una de las principales motivaciones para utilizar la programación funcional.
Los lenguajes de programación funcional, especialmente los que son puramente funcionales, han sido enfatizados en el ambiente académico principalmente y no tanto en el desarrollo de software comercial. Sin embargo, lenguajes de programación importantes tales como Scheme, Erlang, Objective Caml y Haskel, han sido utilizados en aplicaciones comerciales e industriales por muchas organizaciones. La programación funcional también es utilizada en la industria a través de lenguajes de dominio específico como R (estadística), Mathematica (matemáticas simbólicas), J y K (análisis financiero), F# en You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login y XSLT (XML). Lenguajes de uso específico usados comúnmente como SQL y Lex/Yacc, utilizan algunos elementos de programación funcional, especialmente al procesar valores mutables. Las hojas de cálculo también pueden ser consideradas lenguajes de programación funcional.

La programación funcional también puede ser desarrollada en lenguajes que no están diseñados específicamente para la programación funcional. En el caso de Perl, por ejemplo, que es un lenguaje de programación imperativo, existe un libro que describe como aplicar conceptos de programación funcional. JavaScript, uno de los lenguajes más ampliamente utilizados en la actualidad, también incorpora capacidades de programación funcional.

Programación declarativa

Programación declarativa
La Programación Declarativa, es un paradigma de programación que está basado en el desarrollo de programas especificando o "declarando" un conjunto de condiciones, proposiciones, afirmaciones, restricciones, ecuaciones o transformaciones que describen el problema y detallan su solución. La solución es obtenida mediante mecanismos internos de control, sin especificar exactamente cómo encontrarla (tan sólo se le indica a la computadora que es lo que se desea obtener o que es lo que se está buscando). No existen asignaciones destructivas, y las variables son utilizadas con Transparencia referencial

Programación estructurada

Programación estructurada
La programación estructurada es una forma de escribir programas de ordenador (programación de computadora) de manera clara. Para ello utiliza únicamente tres estructuras: secuencia, selección e iteración; siendo innecesario el uso de la instrucción o instrucciones de transferencia incondicional (GOTO, EXIT FUNCTION, EXIT SUB o múltiples RETURN).
Hoy en día las aplicaciones informáticas son mucho más ambiciosas que las necesidades de programación existentes en los años 1960, principalmente debido a las aplicaciones gráficas, por lo que las técnicas de programación estructurada no son suficientes. Ello ha llevado al desarrollo de nuevas técnicas, tales como la programación orientada a objetos y el desarrollo de entornos de programación que facilitan la programación de grandes aplicaciones.

Programación dirigida por eventos

Programación dirigida por eventos
La programación dirigida por eventos es un paradigma de programación en el que tanto la estructura como la ejecución de los programas van determinados por los sucesos que ocurran en el sistema, definidos por el usuario o que ellos mismos provoquen.
Para entender la programación dirigida por eventos, podemos oponerla a lo que no es: mientras en la programación secuencial (o estructurada) es el programador el que define cuál va a ser el flujo del programa, en la programación dirigida por eventos será el propio usuario —o lo que sea que esté accionando el programa— el que dirija el flujo del programa. Aunque en la programación secuencial puede haber intervención de un agente externo al programa, estas intervenciones ocurrirán cuando el programador lo haya determinado, y no en cualquier momento como puede ser en el caso de la programación dirigida por eventos.
El creador de un programa dirigido por eventos debe definir los eventos que manejarán su programa y las acciones que se realizarán al producirse cada uno de ellos, lo que se conoce como el administrador de evento. Los eventos soportados estarán determinados por el lenguaje de programación utilizado, por el sistema operativo e incluso por eventos creados por el mismo programador.
En la programación dirigida por eventos, al comenzar la ejecución del programa se llevarán a cabo las inicializaciones y demás código inicial y a continuación el programa quedará bloqueado hasta que se produzca algún evento. Cuando alguno de los eventos esperados por el programa tenga lugar, el programa pasará a ejecutar el código del correspondiente administrador de evento. Por ejemplo, si el evento consiste en que el usuario ha hecho click en el botón de play de un reproductor de películas, se ejecutará el código del administrador de evento, que será el que haga que la película se muestre por pantalla.
Un ejemplo claro lo tenemos en los sistemas de programación Lexico y Visual Basic, en los que a cada elemento del programa (objetos, controles, etcétera) se le asignan una serie de eventos que generará dicho elemento, como la pulsación de un botón del ratón sobre él o el redibujado del control.
La programación dirigida por eventos es la base de lo que llamamos interfaz de usuario, aunque puede emplearse para desarrollar interfaces entre componentes de Software como módulos del núcleo también.
En los primeros tiempos de la computación, los programas eran secuenciales, también llamados Batch. Un programa secuencial arranca, lee parámetros de entrada, procesa estos parámetros, y produce un resultado, todo de manera lineal y sin intervención del usuario mientras se ejecuta.
Con la aparición y popularización de los pc, el software empezó a ser demandado para usos alejados de los clásicos académicos y empresariales para los cuales era necesitado hasta entonces, y quedó patente que el paradigma clásico de programación no podía responder a las nuevas necesidades de interacción con el usuario que surgieron a raíz de este hecho...

Programación modular

Programación modular
La programación modular es un paradigma de programación que consiste en dividir un programa en módulos o subprogramas con el fin de hacerlo más legible y manejable.
Se presenta históricamente como una evolución de la programación estructurada para solucionar problemas de programación más grandes y complejos de lo que ésta puede resolver.
Al aplicar la programación modular, un problema complejo debe ser dividido en varios subproblemas más simples, y estos a su vez en otros subproblemas más simples. Esto debe hacerse hasta obtener subproblemas lo suficientemente simples como para poder ser resueltos fácilmente con algún lenguaje de programación. Ésta técnica se llama refinamiento sucesivo, divide y vencerás ó análisis descendente (Top-Down).
Un módulo es cada una de las partes de un programa que resuelve uno de los subproblemas en que se divide el problema complejo original. Cada uno de estos módulos tiene una tarea bien definida y algunos necesitan de otros para poder operar. En caso de que un módulo necesite de otro, puede comunicarse con éste mediante una interfaz de comunicación que también debe estar bien definida.
Si bien un modulo puede entenderse como una parte de un programa en cualquiera de sus formas y variados contextos, en la práctica es común representarlos con procedimientos y funciones. Adicionalmente, también pueden considerarse módulos las librerías que pueden incluirse en un programa o, en programación orientada a objetos, la implementación de un tipo de dato abstracto.

Programación orientada a objetos

Programación orientada a objetos
La programación orientada a objetos o POO (OOP según sus siglas en inglés) es un paradigma de programación que usa objetos y sus interacciones, para diseñar aplicaciones y programas informáticos. Está basado en varias técnicas, incluyendo herencia, abstracción, polimorfismo y encapsulamiento. Su uso se popularizó a principios de la década de los años 1990. En la actualidad, existe variedad de lenguajes de programación que soportan la orientación a objetos.

Programación con restricciones

Programación con restricciones
La Programación con restricciones es un paradigma de la programación en informática, donde las relaciones entre las variables son expresadas en términos de restricciones (ecuaciones). Actualmente es usada como una tecnología de software para la descripción y resolución de problemas combinatorios particularmente difíciles, especialmente en las áreas de planificación y programación de tareas (calendarización).
Este paradigma representa uno de los desarrollos más fascinantes en los lenguajes de programación desde 1990 y no es sorprendente que recientemente haya sido identificada por la ACM (Asociación de Maquinaria Computacional) como una dirección estratégica en la investigación en computación.
Se trata de un paradigma de programación basado en la especificación de un conjunto de restricciones, las cuales deben ser satisfechas por cualquier solución del problema planteado, en lugar de especificar los pasos para obtener dicha solución.
La programación con restricciones se relaciona mucho con la programación lógica y con la investigación operativa. De hecho cualquier programa lógico puede ser traducido en un programa con restricciones y viceversa. Muchas veces los programas lógicos son traducidos a programas con restricciones debido a que la solución es más eficiente que su contraparte.
La diferencia entre ambos radica principalmente en sus estilos y enfoques en el modelado del mundo. Para ciertos problemas es más natural (y por ende más simple) escribirlos como programas lógicos, mientras que en otros es más natural escribirlos como programas con restricciones.
El enfoque de la programación con restricciones se basa principalmente en buscar un estado en el cual una gran cantidad de restricciones sean satisfechas simultáneamente. Un problema se define típicamente como un estado de la realidad en el cual existe un número de variables con valor desconocido. Un programa basado en restricciones busca dichos valores para todas las variables.
Algunos dominios de aplicación de este paradigma son:
Dominios booleanos, donde solo existen restricciones del tipo verdadero/falso.
Dominios en variables enteras y racionales.
Dominios lineales, donde sólo se describen y analizan funciones lineales.
Dominios finitos, donde las restricciones son definidas en conjuntos finitos.
Dominios mixtos, los cuales involucran dos o más de los anteriores.
Los lenguajes de programación con restricciones son típicamente ampliaciones de otro lenguaje. El primer lenguaje utilizado a tal efecto fue Prolog. Por esta razón es que este campo fue llamado inicialmente Programación Lógica con Restricciones. Ambos paradigmas comparten características muy similares, tales como las variables lógicas (una vez que una variable es asignada a un valor, no puede ser cambiado), o el backtracking.
La programación con restricciones puede ser implementada como un lenguaje propio o como bibliotecas para ser usadas en algún lenguaje de programación imperativo.

Programación a nivel funcional (John Backus)

Programación a nivel funcional
La programación a nivel funcional es unos de los dos paradigmas contrastantes identificados por John Backus en su trabajo sobre los Programas como objetos matemáticos, siendo el otro la programación a nivel de valores.
En su discurso de aceptación del Premio Turing en 1977, Backus describió lo que considera como la necesidad de un cambio a una filosofía diferente en el diseño de lenguajes de programación:
"Pareciera existir un problema en el diseño de los lenguajes de programación. Cada nuevo lenguaje incorpora, luego de algo de limpieza, todas las características de los lenguajes anteriores más algunas otras. [...] Cada nuevo lenguaje presenta nuevas características de moda... pero el hecho es que pocos lenguajes hacen que la tarea de programar sea más económica, o más segura como para justificar el costo de producirlo y aprender a utilizarlo."
El lenguaje de programación FP fue el primer lenguaje diseñado específicamente para dar soporte al estilo de programación a nivel funcional.
Un programa de nivel funcional no necesita la noción de variable, dado que las variables, que son elemento esencial en las definiciones a nivel de valores no hacen falta en el nivel funcional.
En el estilo de programación de nivel funcional los programas se escriben como combinación de otros programas con la ayuda de las operaciones de construcción de programas o funcionales.
Bajo este enfoque los programas, con los funcionales como operadores, forman un espacio matemático.
Otra ventaja potencial de este enfoque es la posibilidad de restringirse únicamente a las funciones estrictas y asociarles un mecanismo de evaluación por valor. que es el más sencillo de implementar. Otra ventaja es la existencia de definiciones de nivel funcional que no son simplemente el correspondiente de una definición de nivel de valores. Estas definiciones, a veces un poco crípticas por lo concisas representan un estilo de programación muy poderoso.
Si bien la propuesta de Backus data de los años 70 ella ha sido poco adoptada por la comunidad de programación funcional que han preferido basar sus trabajos en el cálculo Lambda.
La programación a nivel funcional en el estilo de FP tiene una fuerte relación con la lógica combinatoria de Haskell Curry, con los lenguajes de combinadores, antecesores de Miranda y Haskell, así como con las categorías cartesianas cerradas, teoría que dio origen al lenguaje CAML (Categorical Abstract Machine Languaje) antecesor del lenguaje Ocaml.

Programación a nivel de valores (John Backus)

Programación a nivel de valores
La programación a nivel de valores es unos de los dos paradigmas contrastantes identificados por John Backus en su trabajo sobre los Programas como objetos matemáticos, siendo el otro la programación a nivel funcional. El término inicialmente utilizado por Backus fue el de programación a nivel de objetos, pero en la actualidad ese término traería confusión con la programación orientada a objetos.
Los programas a nivel de valores describen como combinar diferentes valores (por ejemplo, números, caracteres, etc.) para formar nuevos valores hasta obtener el resultado final. Los nuevos valores se obtienen como resultado de la aplicación de operaciones que transforman valores en otros valores, como por ejemplo, la suma, la concatenación, la inversión de matrices, etc.
Los lenguajes que siguen el estilo de von Neumann son de nivel de valores: las expresiones a la derecha de una asignación tienen por objeto la creación del nuevo valor a asignar.

Programación orientada a componentes

Programación orientada a componentes
La programación orientada a componentes (que también es llamada basada en componentes) es una rama de la ingeniería del software, con énfasis en la descomposición de sistemas ya conformados en componentes funcionales o lógicos con interfaces bien definidas usadas para la comunicación entre componentes.
Se considera que el nivel de abstracción de los componentes es más alto que el de los objetos y por lo tanto no comparten un estado y se comunican intercambiando mensajes que contienen datos.

Programación orientada a aspectos

Programación Orientada a Aspectos
La Programación Orientada a Aspectos (POA) es un paradigma de programación relativamente reciente cuya intención es permitir una adecuada modularización de las aplicaciones y posibilitar una mejor separación de incumbencias. Gracias a la POA se pueden encapsular los diferentes conceptos que componen una aplicación en entidades bien definidas, eliminando las dependencias entre cada uno de los módulos. De esta forma se consigue razonar mejor sobre los conceptos, se elimina la dispersión del código y las implementaciones resultan más comprensibles, adaptables y reusables. Varias tecnologías con nombres diferentes se encaminan a la consecución de los mismos objetivos y así, el término POA es usado para referirse a varias tecnologías relacionadas como los métodos adaptativos, los filtros de composición, la programación orientada a sujetos o la separación multidimensional de competencias.




Este post fue armado con contenido extraido de Wikipedia, todo el material se concidera de libre distribución.
#509
Galería / Re:wallpaper fire by m3x1c0h4ck
Enero 31, 2013, 12:52:25 AM
está bueno, pero yo en lo personal no lo usaré porque choca mucho las letras de fuego, son demaciado grandes.

saludos!
#510
Hola! bueno verán hoy tengo una duda, desde hace mucho me han sugerido cifrar los datos de un formulario antes de enviarlo al servidor, para evitar que un snifer cuando capte el paquete vea el contenido así nada más, y hacersela un poco más complicado.

como harían ustedes esto?

se me ocurre que por javascript se cifre, pero que tipos de cifrados son recomendados, existe una funcion md5 en javascript como la de php?

saludos!
#511
Hacking ShowOff / Re:Xss peliculas21
Enero 31, 2013, 12:36:30 AM
estas con todo amigo! sigue así ;)

saludos!
#512
Hacking / Re:Brute Force V.1 (TEU)
Enero 31, 2013, 12:35:46 AM
You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
buenas amigo! estoy entrando al mundo de la informata! y no tengo mucho conocimiento sobre como ejecutar o correr esos scrip .php me podrían recomendar una guía o algún sitio que pueda leer para informarme sobre esto! gracias ;)

los php son ejecutados (interpretados mejor dicho) por el interprete php.exe, se puede descargar desde You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

pero normalmente es para un servidorweb.

la próxima por favor haz un tema en dudas generales si no sabes donde va, no respondas un tema desviandolo.

saludos!
#513
Back-end / Re:Sesiones
Enero 31, 2013, 12:29:25 AM
Secuestro de sessión (session hijacking)

Si la fijación de sesión es más díficil de entender que de solucionar, para el secuestro el problema se invierte. Secuestrar una sesión es suplantar a un usuario que ya ha entrado al sistema y por lo tanto existe una sesión activa. Las formas de "robar" su identificador de sesión se expusieron en el primer apartado de este tema. El problema es que si un atacante conoce el identificador después de ser regenerado tras la autenticación del usuario, nada le impide realizar una petición haciéndose pasar por el usuario legítimo.

En el ejemplo anterior usábamos propagación por URL que sabemos que tiene riesgos como cuando las páginas se almacenan en cachés con el parámetro del identificador. Si aún tenemos el ejemplo abierto con una sesión autenticada en autentica1.php, podemos pasar a la página protegida autentica2.php y copiar la URL de la barra de direcciones:
Código: text

http://localhost/temas/php-sesion/ejemplos/sesion-registrada/⇒
    autentica2.php?aseguraSesion=r96ol6v2ecorf76gf72d0ne135


Luego la trasladamos a otro navegador diferente y observará que podemos acceder también a esa página protegida, como hemos experimentado con el navegador Safari:


De igual forma podría hacer cualquiera si encuentra esa dirección almacenada en una caché, como la que usan los buscadores. Esto se mitiga usando propagación con sólo cookies, pues el identificador únicamente viaja en una cookie y no se expone en la URL. Pero usar sólo cookies no evita este secuestro, pues el atacante puede aún robar una cookie de sesión en el navegador del usuario o en su fluir por la red.

Para verificar que es posible el secuestro de sesiones con cookies, podemos realizar esta suplantación en nuestro localhost. Para ello ponemos las variables de control del ejemplo de esta forma:

Código: text
$solo_cookies = true; (en las 3 páginas php)
$evita_fijacion = true; (en autentica1.php)
$evita_secuestro = false; (en autentica1.php y autentica2.php)


Luego vamos a un navegador, por ejemplo Internet Explorer y, desde una sesión finalizada, iniciamos autentica0.php, luego seguimos el enlace a autentica1.php para autenticarnos y pasar a la página protegida autentica2.php. Copiamos la dirección de la barra

Código: text
http://localhost/temas/php-sesion/ejemplos/⇒
    sesion-registrada/autentica2.php

y los datos de la sesión que aparece en los resultados:

Código: text
session_name(): aseguraSesion 
session_id(): i6p1b3ujomn9vqj4738t7nbta0


Hemos de imaginar que el atacante logró este SID de alguna otra forma, pero sea cual sea ahora podrá acceder a esa página en su navegador, supongamos el Google Chrome. Para ello puede usar una aplicación telnet con php y enviar esta petición al servidor:

Código: text
GET /temas/php-sesion/ejemplos/sesion-registrada/⇒
    autentica2.php HTTP/1.1
Host: localhost
cookie: aseguraSesion=i6p1b3ujomn9vqj4738t7nbta0
Connection: Close


El servidor le responderá con el HTML de la página protegida autentica2.php, cuyo código verá en ese telnet-php:

Código: text
HTTP/1.1 200 OK
Date: Sun, 07 Nov 2010 11:59:56 GMT
Server: Apache/2.2.15 (Win32) PHP/5.2.13
X-Powered-By: PHP/5.2.13
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 4869
Connection: close
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>autentica2.php</title>

    <p>Ha entrado en este sitio <big><big>PROTEGIDO</big></big>
    con su nombre usuario: <big style="color: green">user</big>.
    </p>

    <li><code>$_COOKIE["aseguraSesion"]</code>:<code class="verde">
    i6p1b3ujomn9vqj4738t7nbta0</code></li>
    ...


Se observa que el atacante puede acceder a la página protegida enviando la cookie de sesión desde el telnet-php. Es importante observar el encabezado de la respuesta, con un valor 200 que significa en el protocolo HTTP que la respuesta ha finalizado con éxito. Por otro lado hemos ejecutado ese telnet-php en el navegador Chrome pero la cookie se envió desde telnet-php, no desde el navegador, por lo que no está almacenada ahí. Podemos comprobar en el navegador Chrome que no hay ninguna cookie de localhost almacenada. De hecho el PHP en el servidor la recibe pensando que proviene de un navegador que la tiene almacenada y que se generó en algún momento anterior al iniciar una sesión. En la repuesta no vuelve a enviar la cookie de sesión pues en la petición comprobó que el identificador coincidía con la que tenía almacenada en una sesión.

En cambio si volvemos a repetir el experimento pero antes poniendo la variable $evita_secuestro a true en las páginas correspondientes veremos que se puede intentar evitar. El procedimiento en este caso es almacenar una variable que identifique al usuario:

Código: text
$_SESSION["identifica-usuario"] = md5($_SERVER["HTTP_USER_AGENT"])


Se trata de guardar la cabecera que envían los navegadores con su información, el User-Agent que viene a ser el agente de usuario que envío la petición. Esto lo hacemos en el inicio de sesión y con cada petición del usuario comprobamos que el navegador es el mismo. Hay otras cabeceras como Accept o incluso almacenar la IP del usuario, pero parece ser que no son tan fiables pues el usuario puede estarse conectando mediante mecanismos que modifican estas cabeceras, como los proxys, o incluso cuando las IP son dinámicas y pueden ser modificadas durante el transcurso de varias peticiones. Parece que incluso el User-Agent podría verse alterado en ciertos casos, no sirviendo tampoco para este cometido.

El tema no lo tengo muy claro en este aspecto. Sea como fuere vamos a utilizar el User-Agent como identificador de usuario. Probamos esta posibilidad finalizando la sesión actual en el Explorer (navegador del usuario) y volviendo a autenticarnos para llegar luego a la página protegida. Esta sesión ha generado el identificador o9o496qi2oo6abedgti31gedb3. En el telnet-php que tenemos abierto en el Chrome (navegador del atacante) modificamos la petición con el nuevo identificador que aparece en la nueva sesión del usuario en el Explorer:

Código: text
GET /temas/php-sesion/ejemplos/sesion-registrada/⇒
    autentica2.php HTTP/1.1
Host: localhost
cookie: aseguraSesion=o9o496qi2oo6abedgti31gedb3
Connection: Close


obteniéndose la siguiente respuesta en el telnet-php:

Código: text
HTTP/1.1 302 Found
Date: Sun, 07 Nov 2010 12:02:06 GMT
Server: Apache/2.2.15 (Win32) PHP/5.2.13
X-Powered-By: PHP/5.2.13
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: aseguraSesion=deleted; expires=Sat, 07-Nov-2009 12:02:05 GMT; path=/
Location: http://localhost/como-se-hace/php-sesion/ejemplos/⇒
    sesion-registrada/acceso-indebido.html
Content-Length: 0
Connection: close
Content-Type: text/html


En este caso el servidor envía una cabecera 302, lo que supone una redirección que se ha ejecutado debido a que hemos incluído un control para evitar secuestro, obligando a redireccionar a la página acceso-indebido.html en lugar de ofrecer la del recurso protegido solicitada autentica2.php. Además se observa que envió un borrado de la cookie de sesión tal como dispusimos en el script para destruir la sesión, que por supuesto no tendrá efecto pues no está en el navegador. En un navegador se redireccionaría a la página acceso-indebido.html, pero en este telnet-php que he escrito no se previsto la posibilidad de redirección. Aunque el propósito está conseguido, verificar que podemos evitar el secuestro de sesión.

Pero, por supuesto, el atacante podría enviar una cabecera User-Agent con el telnet usando la misma cabecera que el usuario (podría probar los User-Agent más frecuentes):

Código: text
GET /temas/php-sesion/ejemplos/sesion-registrada/⇒
    autentica2.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; ...)
Cookie: aseguraSesion=o9o496qi2oo6abedgti31gedb3
Connection: Close


Con el mismo User-Agent que tiene el usuario que se autenticó, el de Internet Explorer que hemos acortado por comodidad, podría llevar a cabo el ataque pues el servidor le devolvería la página protegida:

Código: text
HTTP/1.1 200 OK
Date: Sat, 13 Nov 2010 19:47:06 GMT
Server: Apache/2.2.15 (Win32) PHP/5.2.13
X-Powered-By: PHP/5.2.13
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 4997
Connection: close
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>
    ...
    <p>Ha entrado en este sitio <big><big>PROTEGIDO</big></big> con su nombre
    usuario: <big style="color: green">user</big>.
    ...


El problema aquí es que estamos usando dos cosas para identificar al usuario: el SID de la cookie, que el atacante nos ha robado, y el User-Agent que es un dato que el atacante también puede conocer. Al fin y al cabo cualesquiera otros identificadores que ideemos no dejan de ser otra cosa que sinónimos del SID. Si éste puede robarse, los otros también, pues ambos viajan por el mismo canal HTTP de comunicación a efectos de que el usuario se identifique. Una solución parece que pasa por HTTPS, donde toda la información fluye cifrada.
#514
Back-end / Re:Sesiones
Enero 31, 2013, 12:27:34 AM
La fijación de sesión (session fixation)

Si ejecuta este ejemplo en su localhost, recuerde poner las variables de control así para poder ver el efecto:

Código: text
$solo_cookies = false; (en las 3 páginas php)
$evita_fijacion = false; (en autentica1.php)
$evita_secuestro = false; (en autentica1.php y autentica2.php)


La fijación de sesión (session fixation) podemos definirla como la suplantación de usuario antes de que éste inicie sesión. El primer paso del atacante sería iniciar una sesión en el conjunto de páginas. Supongamos que esto lo hago en local con uno de los navegadores que tengo instalado en mi ordenador, como el Google Chrome. Después de ir a la página de entrada sigo el vínculo a la primera página autentica1.php y obtengo una pantalla con un formulario para autenticar:


En primer lugar el atacante necesita mantener una sesión viva en el servidor. Además debe obtener el identificador de sesión lo que puede hacer de varias formas. Puede ver el código fuente HTML en el navegador para comprobar si está embebido en los vínculos. En nuestro ejemplo lo va a encontrar como campo oculto de los formularios. Recuerde que estamos en localhost usando el valor false para la variable $solo_cookies, por lo que los formularios se envían por GET con campos ocultos para el identificador de sesión, pues la propagación es por URL:

Código: text
<form action="/como-se-hace/php-sesion/ejemplos/⇒
    sesion-registrada/autentica1.php"
method="get" style="border: gray solid 1px">
<input type="hidden" name="aseguraSesion"
value="r96ol6v2ecorf76gf72d0ne135" />
</form>


También podría enviar el botón de autenticar con el formulario vacío y el servidor le responde otra vez con el formulario, acompañando el SID en la ruta que se expone en la barra de direcciones del navegador Chrome, donde podría copiar el identificador:


Decíamos que debe mantener la sesión viva hasta conseguir el ataque. Recordemos que las sesiones tienen una duración de vida, por defecto de 24 minutos (ver tema II en el apartado de vida de una sesión). Si el usuario no interactúa con la sesión, esta se borra de la carpeta Temp si ya ha cumplido su vida útil desde la última interacción. El atacante puede mantenerla viva presionado periódicamente el botón de autenticar, aunque supuestamente usará algún programa que le permita esta acción de forma automática.

Mientras la sesión se mantiene viva, el atacante intentará que un usuario legítimo entre en el sistema usando su identificador. Debe entonces trasladarlo al navegador del usuario. Esta es la parte más compleja y caben varios métodos, incluso si se está usando propagación por cookies. En este caso estamos propagando por URL y es más sencillo presentar un ejemplo de traslado de identificador. Por ejemplo, supongamos que el atacante conoce de alguna forma el email del usuario. Podría enviarle uno con un mensaje HTML con este vínculo:

Tenemos una oferta atractiva para Usted. Si está interesado, por favor,
Código: text
<a href="http://localhost/como-se-hace/php-sesion/ejemplos/⇒
    sesion-registrada/autentica1.php?aseguraSesion=r96ol6v2ecorf76gf72d0ne135">
entre en el sistema</a>


El atacante presentaría el mensaje con lo necesario para engañar al cliente quién podría ya estar acostumbrado a recibir correos electrónicos del sitio donde esta registrado. Para emular en nuestro servidor local el acto del usuario pulsando sobre ese vínculo recibido en su email, copiamos el URL y lo trasladamos a la barra de direcciones de otro navegador, en este caso el Internet Explorer (este será supuestamente el navegador del usuario):

Esto le conduce al usuario a entrar en una sesión iniciada previamente por el atacante, comprobándose que el identificador de sesión es el mismo que inició el atacante:


El usuario no piensa que está siendo engañado, pues realmente está en la página del sitio. Así que se autenticará introduciendo su nombre de usuario y contraseña, tras lo cual el script le devolverá el vínculo con la página de recursos protegidos:


CitarEs evidente que por mucho que hagamos para protegernos la fijación de sesión, no estaremos conseguiendo nada si el atacante es capaz de robar el nombre de usuario y la contraseña que viaja sin cifrar por la red. Para evitarlo se usan protocolos seguros, pero aún así es necesario protegerse de la fijación.

A partir de ese momento, en algúno de los procesos automáticos que realiza el atacante pulsando el botón de autenticar, si el usuario ya se autenticó, entonces el atacante podrá entrar. Esto es lo que vemos si ahora pulsamos ese botón en el navegador Chrome, permitiéndole pasar a la página de recursos protegidos autentica2.php sin necesidad de conocer la contraseña de acceso:


Si en lugar de propagar por URL usáramos sólo cookies podríamos mitigar el problema pero no desaparecería. El atacante tendría que llevar una cookie con su identificador hasta el navegador del usuario, pero es factible usando diversas técnicas, entre ellas y sólo a título informativo:

    Usando JavaScript en el navegador del usuario para emitir la cookie. Para ello puede servirse de cross-site scripting (XSS) que consiste en aprovechar vulnerabilidades del código HTML del sitio para incrustar JavaScript y hacer un document.cookie="aseguraSesion=r96ol...".
    Inyectando la etiqueta HTML <meta http-equiv=Set-Cookie content="aseguraSesion=r96ol..."> con alguna vulnerabilidad del servidor.

Afortunadamente PHP dispone de un mecanismo para evitar la fijación de sesión en cualquiera de las dos formas de propagación del identificador. En nuestro ejemplo, cuando el usuario engañado por el email entra en la página autentica1.php ya hay un identificador previo creado por el atacante. De hecho es una sesión completamente válida, con su archivo de sesión almacenado en Temp. Pero PHP no sabe que proviene de un ataque. Lo que podemos hacer es cambiar de identificador cuando el usuario sea autenticado. Eso se hace con la la función session_regenerate_id(true). Entonces PHP cambia el identificador y traspasa el contenido de las variables de esa sesión al nuevo, eliminando el archivo de sesión anterior. Ahora el usuario ya autenticado tiene un nuevo identificador, de hecho una nueva sesión, por lo que el atacante no podrá usarla. Si realiza el mismo proceso que antes, verá que tras la autenticación del usuario se genera un nuevo identificador. Luego en el otro navegador del atacante ya no será válido el identificador anterior, de hecho, no existirá y se le generará uno nuevo cuando pulse "autenticar".

Cuando con PHP hacemos session_start() y de alguna forma esa página ya porta un identificador de sesión entonces PHP lo adopta, independientemente de que lo haya generado anteriormente. Es lo que se llama un sistema permisivo, pues adopta cualquier identificador si no hay uno creado previamente. En oposición están los sistemas estrictos que sólo aceptan identificadores conocidos que fueron generados por el sistema en algún momento del pasado (como hace IIS de Microsoft). En los sistemas permisivos también existe la posibilidad de enviar un falso identificador con sesiones no inicidas. El atacante puede iniciar una sesión con un identificador como "1234" por ejemplo. Poniendo en la barra de direcciones del Chrome (navegador del atacante) esto:

Código: text
http://localhost/temas/php-sesion/ejemplos/⇒
    sesion-registrada/autentica1.php?aseguraSesion=1234


PHP genera una nueva sesión con ese identificador. El resto del proceso es igual que antes, enviarlo al usuario y esperar que este se autentique para tener luego acceso a esta sesión (siempre que no se regenere el identificador después de la autenticación).

Podemos evitar los falsos identificadores con sesiones no iniciadas si asociamos cada inicio de sesión con una variable de sesión que nos sirva para controlar el estado de la misma. Así usando una variable como $_SESSION["estado"], cuando el atacante entre por primera vez para registrar su falso identificador esta variable no existirá para ese identificador. Esto lo podemos ver en el diagrama de flujo, donde preguntamos si "¿Hay sesión iniciada?", que equivale a observar si la variable de sesión ha sido establecida: isset($_SESSION["estado"]). Entonces podemos hacer que PHP regenere el identificador. A partir de este momento el atacante se verá obligado a usar un identificador generado por PHP, que junto al método de regeneración tras la autenticación podrá evitar el ataque de fijación.

La norma general es que cuando se pase de un nivel de seguridad o otro más restrictivo, como puede ser una autenticación, se aconseja regenerar el identificador. No es bueno regenerarlo con excesiva frecuencia, por ejemplo con cada petición de una página, pues PHP estará ejecutando esa función y con muchos usuarios podrá recargar el sistema.
#515
Back-end / Re:Sesiones
Enero 31, 2013, 12:25:38 AM
Ejemplo de sesión con autenticación

Es obvio que un ataque de sesión se llevará a cabo si el atacante obtiene algún beneficio. Un caso típico es poder acceder a recursos protegidos en el sitio sin que quede huella de su paso. El acceso a estos recursos suele requerir que el usuario canalizado por medio de una sesión sea también autenticado, es decir, sea identificado por medio de la comparación con una información de usuario que previamente tendremos almacenada en nuestro sitio. Por lo tanto hemos de evitar que el atacante suplante una sesión con autenticación, pues le permitirá acceder a esos recursos haciéndose pasar por el usuario legítimo.

El proceso de autenticación o autentificación en un sistema web podemos resumirlo como el modo de asegurar que el usuario que se conecta es quién realmente dice ser. Para ello debemos disponer en nuestro sitio de una copia de la contraseña para compararla con la que el usuario nos envía. Porque partimos de la base de que esa contraseña sólo será conocida por el servidor y el cliente. La autenticación no sustituye a la sesión, pues con una sesión abrimos un canal de comunicación con un único cliente, aspecto necesario para saber que sólo le estamos sirviendo a este usuario que inició la sesión y no a otro. Pero no podemos saber quién es ese usuario, para lo cuál necesitamos la autenticación.
En inglés se usa el término "login" (de "log in") traducido como "entrar o registrarse en un sistema" en un contexto informático, pues el verbo "log" significa registrar. De la misma forma "logout" para la acción de "salir de un sistema". He visto que se usa el verbo en español "loguear" como "autenticar", pero no está admitido en el R.A.E., al menos por ahora. Probablemente el clásico botón de "login" será más asequible para los usuarios no expertos que uno con la leyenda "autenticar" o "autentificar".

Además la autenticación da lugar dos figuras necesarias en un proceso de comunicación. Por una lado la autorización, proceso por el cual el servidor autoriza al usuario autenticado a acceder a ciertos recursos y luego tenemos la auditoría, con lo que el servidor registra los accesos de un usuario autenticado para resolver posibles incidencias.

El proceso de autorización se entiende mejor si tenemos planificado el acceso a los recursos en grupos según niveles de protección de esos recursos. Entonces el usuario de un cierto grupo que se autentique será autorizado a acceder sólo a los recursos a que tenga derecho. Cuando todos los recursos están al mismo nivel, no hay diferencia entre autenticación y autorización, pudiéndose prescindir de este último pero entendiendo que el proceso está implícito. Por otro lado, la auditoría nos permite realizar una investigación posterior de las incidencias que se hayan ocasionado en los accesos.

Para exponer un ejemplo lo más cercano a un caso real y luego aplicar los conceptos anteriores de fijación y secuestro de sesión, elaboramos un conjunto de 3 páginas con sesión y autenticación:

    autentica0.php: es una página de entrada sin sesión, donde se ofrece al usuario la posibilidad de entrar en una página con sesión, para autenticarse y acceder a recursos protegidos.
    autentica1.php: en esta página se inicia una sesión, ofreciendo al usuario un formulario de autenticación (nombre+contraseña), datos que de validarse le permitirán pasar a la siguiente página. También damos posibilidad para registrarse si no lo estuviera antes.
    autentica2.php: en esta página tenemos los recursos o activos de valor, es decir, la información protegida que sólo podrán ver los usuarios registrados.

También se dispone de una página con sólo html (acceso-indebido.html) para redirigir a un usuario cuando indebidamente intente acceder a la página protegida autentica2.php sin estar autenticado. En principio no es necesario conocer en profundidad el mecanismo de este conjunto de páginas para los apartados siguientes, pero si lo desea puede ampliar la información en el siguiente epígrafe (desplegable oculto) o bien ver todo el código completo del conjunto de páginas.

Las páginas PHP de este ejemplo disponen al inicio del script de unas variables específicas de control para poder usar los ejemplos de suplantación de sesiones:

    $solo_cookies (en todas las páginas PHP). Con valor true se realizará una propagación de SID con sólo cookies (ver propagar SID con sólo cookies). Con valor false propagaremos el SID con sólo URL (ver propagar SID con sólo URL sin trans_sid). Así se tratará de evidenciar el riesgo que tiene este método en las suplantaciones de sesión.
    $evita_fijacion (en autentica1.php). Con valor true se regenerará el identificador de sesión para evitar la fijación de sesiones, efecto que podrá comprobar con valor false.
    $evita_secuestro (en autentica1.php y autentica2.php). Con valor true realizará una identificación del usuario comprobando si su navegador es el mismo que usó cuando se inició la sesión. Con valor false podrá comprobarse el efecto del secuestro de sesión.

Ejecutando este ejemplo en línea desde este sitio estarán con valor true de forma permanente. Pero si queremos ver los efectos de la suplantación, hemos de ejecutar estas páginas en un dominio localhost para usar con un servidor Apache+PHP montado como local. Para ello puede descargar el conjunto de páginas comprimidas en You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login. Las extensiones de los archivos ".php" las he modificado por ".txt", por lo que una vez descargado y descomprimido hay que hacer el proceso inverso, aparte de también poner aquellas variables a false para ver el efecto de la suplantación.
#516
Back-end / Re:Sesiones
Enero 31, 2013, 12:25:10 AM
Asegurar sesiones

Suplantación de sesiones

El tema de seguridad en la web es muy extenso y complejo. Requiere un profundo conocimiento del funcionamiento de todos los aspectos relacionados: servidores, navegadores, protocolos de comunicaciones, redes, etc. En esta página no pretendo mostrar un estudio exhaustivo, sino lo básico para empezar a enfrentarnos con este problema en relación con las sesiones. Veremos dos conceptos que se repiten mucho en lo que he leído: session hijacking y session fixation.

En los temas anteriores hemos visto para que sirve una sesión y cómo trabaja. Hemos indicado algunas cuestiones relacionadas con la seguridad de las sesiones. Es obvio que las sesiones sirven para algo más que lo que vimos en los ejemplos de los temas anteriores. Son especialmente útiles en el control de accesos a ciertos recursos protegidos de nuestro sitio, estableciendo un "canal" único entre el servidor y un determinado cliente.

Las sesiones se basan en la existencia del identificador de sesión que emplea el servidor para establecer la comunicación. Ese identificador está presente en el servidor y en el navegador, viajando por la red en uno y otro sentido con las peticiones y respuestas. Si en un momento dado hay una sesión abierta, un atacante que pueda hacerse con su identificador podría acceder al servidor sin que éste o el cliente se apercibieran, a no ser que hagamos algo para evitarlo.

El uso no deseado de un identificador válido de otro usuario es lo que se conoce como secuestro de sesión (session hijacking). Podemos decir que un indentificador válido es aquel que fue generado por un usuario legítimo mediante un script PHP y que identifica su sesión activa. Las sesiones siguen activas mientras no se eliminen de la carpeta Temp, por lo que incluso después de finalizar su vida podrían seguir activas si aún no han sido eliminadas por el mecanismo de control se sesiones. Hay tres formas de obtener un identificador de sesión válido:

    Interceptando un identificador donde se almacene o fluya. Ya hemos visto que en un alojamiento compartido hay un riesgo de que otros sitios alojados puedan leer nuestros identificadores de sesión. En la propia red se pueden interceptar aunque para evitarlo se usan comunicaciones cifradas con el protocolo HTTPS. E incluso pueden leerse identificadores en el navegador del usuario.
    Prediciendo cuál será el identificador de sesión para un usuario determinado. En PHP el identificador de sesión es un valor aleatorio que, según parece, no es fácil de predecir.
    Usando la "fuerza-bruta" para iterar por todos los identificadores posibles hasta que demos con uno igual que alguno que se esté usando en ese momento. Como la longitud de los identificadores es mucho mayor que el número de sesiones simultáneas, parece poco probable que esto tenga éxito.

El objetivo final del atacante es suplantar al usuario, pues una vez que obtenga una sesión válida, podrá acceder a los mismos recursos del servidor que ese usuario. Hay otra forma de suplantar sesiones sin necesidad de conocer un identificador válido. Se trata en este caso de que el atacante emita un identificador previamente a que el usuario haya entrado en el sitio. El atacante entonces intentará que el usuario entre en el sistema con este identificador. Esto se le denomina fijación de sesión (session fixation), pues de alguna forma el atacante fija la sesión antes de que el usuario entre, a diferencia del secuestro, donde el atacante "roba" la sesión después de que el usuario haya entrado. En sentido general a veces decimos suplantación de sesión cuando en realidad queremos referirnos al hecho de suplantar a un usuario en el uso de una sesión, ataques que pueden conseguirse con las técnicas descritas del secuestro y la fijación.

Para realizar un ejemplo de suplantación y exponer los conceptos señalados de fijación y secuestro de sesión, realizamos en el siguiente apartado unas páginas de ejemplo de sesión con autenticación.
#517
Back-end / Re:Sesiones
Enero 31, 2013, 12:24:09 AM
Propagar SID: sólo POST

También es posible no enviar el SID por URL ni mediante cookies, sino únicamente usando campos ocultos en formularios POST. Toda petición que se haga al servidor, incluso la de vínculos <a>, se realizará con formularios POST. De esta forma no dependemos de que el usuario tenga activadas las cookies y, por otro lado, no exponemos el SID en las URL. Sin embargo sería necesario que el navegador tenga activado JavaScript. La ejecución se inicia en este enlace solo-post/propaga0.php. El ejemplo es igual que el del apartado sólo URL sin trans_sid, con las mismas configuraciones iniciales:

Código: text
ini_set("session.use_cookies", 0);
ini_set("session.use_only_cookies", 0);
ini_set("session.use_trans_sid", 0);
define("SESION", "sesionPost");
session_name(SESION);
session_start();


Entonces la propagación de SID hemos de realizarla manualmente en el código. Pero nos obligaremos a que toda clase de vínculos se realice mediante un formulario POST. Así sólo tendremos formularios con method="post" y en ningún caso usaremos el method="get". En cada formulario agregaremos el campo oculto con el SID.

Para todos los vínculos <a> de una página usaremos un único formulario que podemos disponer antes de la aparición del primero de los vínculos. Lo completaremos con el campo oculto que porta el SID:

Código: text
<form action="" method="post" id="form-vinculos">
    <input type="hidden" name="<?php echo SESION; ?>"
    value="<?php echo session_id(); ?>" />   
</form>


Note que el atributo action es una cadena vacía. Al no contener elementos visibles, este formulario no aparecerá en pantalla, aunque en el ejemplo en ejecución le agregamos un borde rojo para poder apreciarlo. Luego todos los vínculos de la páginas los escribiremos de esta forma:

Código: text
<a href="javascript:irA('propaga2.php');">propaga2.php</a>


El destino del vínculo será el argumento de la función irA(), que se ejecutará mediante script de JavaScript que ubicaremos en el encabezado de cada página:

Código: text
<script>
    function irA(destino){
        var formulario = document.getElementById("form-vinculos");
        formulario.action = destino;
        formulario.submit();
    }
</script>


Este script identifica el formulario de vínculos y le dota del destino al atributo action. Luego el método submit() de JavaScript permite remitir el formulario como si hubiésemos pulsado un botón con tipo submit.

Las ventajas de este ejemplo es que no dependemos de las cookies y no exponemos el SID en la URL. Por contra se basa en que el usuario tenga activado JavaScript. Otro problema es que cuando el usuario se sitúa sobre un vínculo no verá el destino en la barra de estado del navegador, sino el literal javascript:irA('un_destino');. Esto puede condicionar al usuario pues no se le está ofreciendo una cadena URL clásica, aunque en ese texto aún puede ver el destino al que se dirige.
#518
Back-end / Re:Sesiones
Enero 31, 2013, 12:22:49 AM
Propagar SID: Cookies o URL sin trans_sid y usando constante SID

La ejecución se inicia en este enlace cookies-url-sid/propaga0.php. El ejemplo es igual que el del apartado anterior cookies o url, pero ahora sin utilizar trans_sid. Las configuraciones iniciales son:

Código: text
ini_set("session.use_cookies", 1);
ini_set("session.use_only_cookies", 0);
ini_set("session.use_trans_sid", 0);
define("SESION", "sesionCookieUrlSid");
session_name(SESION);
session_start();


La constante SID es construida por PHP concatenando session_name()."=".session_id(). La única ventaja es que usando un modo de configuración con propagación por cookies-url como el de este ejemplo, si PHP detecta que recibe sesión por cookie entonces esa constante será una cadena vacía. En otro caso se construye como hemos dicho. Así podemos incorporar la constante en nuestro código y no preocuparnos cuando la propagación sea por cookies pues no se agregará el parámetro de sesión en la URL. Por ejemplo, la página propaga2.php, la parte de vínculos y formularios sería escrita como sigue:

Código: text
...    
<a href="propaga1.php?<?php echo SID; ?>">propaga1.php</a></li>   
...
<a href="propaga3.php?<?php echo SID; ?>">propaga3.php</a></li>
...
<!--  En el caso de un form GET no podemos agregar el SID en el
action, pues en el envío el navegador lo sustituye por los campos
que va a enviar -->
<form action="propaga3.php" method="get">
    <input type="hidden" name="<?php echo SESION; ?>"
    value="<?php echo session_id(); ?>" />
    <label>campo-get:
    <input type="text" name="campo-get" value="Valor del input get" />
    </label>
    <input type="submit" value="enviar" />
</form>
...
<form action="propaga3.php?<?php echo SID; ?>" method="post">
    <label>campo-post:
    <input type="text" name="campo-post" value="Valor del input post" />
    </label>
    <input type="submit" value="enviar" />
</form>   
...


Cuando las cookies esten activadas, entonces los vínculos no contienen los parámetros pues la constante SID será una cadena vacía (""). Cuando estén desactivadas esa constante será el SID que se agregará como parámetro. Puede probar el ejemplo activando y desactivando cookies y observando el código fuente generado en su navegador.

El comentario HTML hace referencia a que si agregamos el parámetro en el formulario GET, en el envío del mismo parece sustituirlo por lo parámetros que se remiten. Por eso ahí se incluye como campo oculto.

Debe observarse que este ejemplo tiene el mismo problema que comentamos en los párrafos finales del apartado anterior, pues usando cookies, en el primer inicio de sesión agrega el SID en la URL dado que aún no ha recibido cookie de sesión.
#519
Back-end / Re:Sesiones
Enero 31, 2013, 12:22:18 AM
Propagar SID: Cookies o URL con trans_sid

La ejecución se inicia en este enlace cookies-url/propaga0.php. En este ejemplo PHP usará cookies si están activadas y en otro caso agregará el SID a los vínculos. El inicio del PHP de las páginas de sesión es:

Código: text
ini_set("session.use_cookies", 1);
ini_set("session.use_only_cookies", 0);
ini_set("session.use_trans_sid", 1);
ini_set("url_rewriter.tags", "a=href,form=fakeentry");
define("SESION", "sesionCookieUrl");
session_name(SESION);
session_start();   
...


El ejemplo es exactamente igual que el del primer apartado con sólo cookies, pero cambiando este inicio de configuraciones. El use_trans_sid se encarga de agregar los SID a los vínculos de forma transparente. Así parece que este ejemplo consigue evitar la desactivación de las cookies por parte del usuario, asegurando la propagación de la sesión en todos los casos.

Cuando se propaga por cookies sucederá que en la página de inicio de sesión propaga1.php, sólo la primera vez que se inicia una sesión, los vínculos de esa página propagarán por URL, aparte de que también envíe la cookie. Esto sucede porque PHP no ha recibido aún alguna cookie de sesión y decide enviar el SID también por URL. Esto lo podemos ver en el código fuente generado en nuestro navegador en esa primera entrada a la página:

Código: text
...
Vínculo a otra página
<a href="propaga2.php?sesionCookieUrl=fttcg55uddc4oi0qvshqc27bs6">
propaga2.php</a>
...


Mientras que si volvemos a esa misma página propaga1.php después de haber estado en otra, o bien simplemente la recargamos, entonces ya no aparecerá el parámetro del vínculo, pues PHP ya habrá recibido la cookie de sesión del navegador.
#520
Back-end / Re:Sesiones
Enero 31, 2013, 12:21:41 AM
Propagar SID: Sólo URL sin trans_sid

La ejecución se inicia en este enlace solo-url-no-transsid/propaga0.php. Las configuraciones iniciales son:

Código: text
ini_set("session.use_cookies", 0);
ini_set("session.use_only_cookies", 0);
ini_set("session.use_trans_sid", 0);
define("SESION", "sesionUrlNoTranssid");
session_name(SESION);
session_start();


Ahora el programador debe incluir los SID manualmente en cada vínculo. Por ejemplo, la página propaga2.php tiene los elementos con vínculos con el SID de esta forma antes de que el script se procese, donde en amarillo aparece resaltado lo que hemos tenido que agregar en el código:

Código: text
...
<a href="propaga1.php?<?php echo SESION."=".session_id(); ?>">
propaga1.php</a></li>   
...
<form action="propaga3.php" method="get">
<input type="hidden" name="<?php echo SESION; ?>"
value="<?php echo session_id(); ?>" />
<label>campo-get:
<input type="text" name="campo-get" value="Valor del input get" />
</label>
<input type="submit" value="enviar" />
</form>
...
<form action="propaga3.php" method="post">
<input type="hidden" name="<?php echo SESION; ?>"
value="<?php echo session_id(); ?>" />
<label>campo-post:
<input type="text" name="campo-post" value="Valor del input post" />
</label>
<input type="submit" value="enviar" />
</form>
...


Como hemos mencionado en comentarios anteriores, PHP dispone de la constante SID que se actualiza después de hacer un session_start() con el mismo resultado que la cadena session_name()."=".session_id(). La ventaja es que si estamos propagando por cookies, esta constante será una cadena vacía, por lo que podemos usar este método con un ejemplo que soporte propagación por cookies o URL sin trans_sid, como veremos en un apartado más abajo. En el ejemplo actual podríamos usar esa constante para no tener que estar escribiendo nombre e identificador, pero esto sólo nos sirve para los vínculos URL, pues en los campos ocultos de formulario tenemos que ponerlo por separado.

En el código resultante en el navegador veremos esto para una sesión en ejecución:

Código: text
...
<a href="propaga1.php?sesionUrlNoTranssid=4uuunt9u3jtebkr9afscpkrvp1">
propaga1.php</a>
...
<form action="propaga3.php" method="get">
<input type="hidden" name="sesionUrlNoTranssid"
value="4uuunt9u3jtebkr9afscpkrvp1" />
...
</form>
...
<form action="propaga3.php" method="post">
<input type="hidden" name="sesionUrlNoTranssid"
value="4uuunt9u3jtebkr9afscpkrvp1" />
...
</form>
...


Cuando veamos los temas de seguridad, comprenderemos que no es conveniente propagar el SID por URL, es decir, vía GET. Así en este ejemplo se propaga por POST sólo para el formulario con method="post", pues para los que tienen method="get" y para los vínculos <a> lo hará por GET. Podemos obligarnos sólo a incluir formularios POST, pero los vínculos <a> sólo podrán propagar la sesión como un parámetro URL (aunque al final del tema veremos una forma de evitarlo).