pre { background:#eeeeee; border:1px solid #A6B0BF; font-size:120%; line-height:100%; overflow:auto; padding:10px; color:#000000 } pre:hover { border:1px solid #efefef; } code { font-size:120%; text-align:left; margin:0;padding:0; color: #000000;} .clear { clear:both; overflow:hidden; }

Bienvenido al blog

Bienvenidos al blog de seguridad en sistemas

viernes, 30 de noviembre de 2012

Scapy para Flags TCP

Recientemente he tenido que jugar con la libreria Scapy para Python. Ésta te permite crear cualquier tipo de paquete de red con un par de simples comandos, incluso para protocolos no existente mediante paquetes RAW.

En este caso pondre de ejemplo como solvente la necesidad de tener que enviar paquetes TCP a un puerto determinando usando cualquier combinación de flags TCP, cuyo objetivo era evaluar el comportamiento de la pila TCP al recibir cualquier combinación de flags.

Tenga en cuenta que no estamos hablando de permutaciones, puesto que es lo mismo enviar un paquete con el flags Syn y Ack que enviar un paquete con los flags Ack y Syn. Sí, seguramente habrán recordado la frase "el orden de los factores no altera el producto". Por tanto era necesario generar cualquier combinación teniendo en cuenta que el orden no afecta y que no se desea enviar más paquetes de los estrictamente necesarios.

Con está idea cogí un folio y lo rellene con un par de combinaciones para crear un algoritmo que resolviera el problema dando como resultado "algo", por concederle un nombre, bastante lento y que requería mucha lógica. Tenga en cuenta que no he considerado los flags de congestión y priorización del tráfico. El resultado fue el siguiente:
#!/usr/bin/python
# -*- encoding: utf-8 -*-
 
from scapy.all import *
import sys
 
ip = str(sys.argv[1])
port = int(sys.argv[2])
 
flags = ['S','A','F','R','P']

send(IP(dst=ip)/TCP(dport=port, flags=""))

for i in range(len(flags)):
 send(IP(dst=ip)/TCP(dport=port, flags=str(flags[i])))

vueltag = 2
#Bloque mayor
while(len(flags) >= vueltag):
 vueltap = vueltag
 inib = 0
 while (vueltap <= len(flags)):
  bloque = ""
  aux = inib
  cont = 0
  while (cont < vueltag - 1):
   bloque = bloque + flags[aux] 
   aux = aux + 1
   cont = cont + 1
  finb = inib + cont
  while(len(flags) > finb):
   bandera = (bloque + flags[finb])
   send(IP(dst=ip)/TCP(dport=port, flags=bandera)) 
   finb = finb + 1  
  inib = inib + 1
  vueltap = vueltap + 1
 vueltag = vueltag + 1

Si desea ejecutar el programa, tenga en cuenta que debe indicar como primer argumento la IP del servidor a auditar y como segundo argumento debe indicar un puerto. Recuerde que debe disponer de Python y de Scapy en su máquina, las distribuciones como BackTrack los incluye por defecto. Por ejemplo para auditar el puerto 80 de la ip 127.0.0.1 usted debe introducir lo siguiente: 
# ./programa.py 127.0.0.1 80
Al ejecutarlo contra el puerto 80 de mi máquina local, cuya IP local era 127.0.0.1, pude registrar con la herramienta de auditoría de red Tcpdump que se generaba correctamente el resultado esperado, tal como se muestra en la siguiente imagen:

Monitorización Tcpdump de la ejecución del programa
Pero si se tiene en cuenta como funciona el protocolo TCP/IP y que Scapy permite introducir datos en crudo con valores hexadecimales o binarios, se podría resumir el código anterior con algo tan simple como lo siguiente:
#!/usr/bin/python
# -*- encoding: utf-8 -*- 
 
from scapy.all import *
import sys

ip = str(sys.argv[1])
port = int(sys.argv[2])

num = 0b000000
while(num < 0b1000000):
 send(IP(dst=ip)/TCP(dport=port, flags=num))
 num = num + 0b1
Donde si quisiera ampliar el algoritmo para que se comprobara los flags de congestión de tráfico únicamente deberia modificar la condición while por lo siguiente:
num = 0b00000000
while(num < 0b100000000):
 send(IP(dst=ip)/TCP(dport=port, flags=num))
 num = num + 0b1
Como se aprecia, de forma sencilla podriamos crear un script en Python que permitiera auditar las pilas TCP/IP de muchos dispositivos, añadiendo otras opciones como:
  • Enviar a puerto "0", valores de puertos con valor máximo o mismo puerto origen que destino.
  • Versión TCP distinta a 4 y 6.
  • Número de sesión y de acuse de recibo con valores idénticos, valores máximos o valor "0".
  • Enviar múltiples paquetes con mismo valor de sesión pero ip origen distinta.
  • Misma dirección IP origen que destino o IP reservadas como origen.
  • Fragmentación simple y con superposición. 
  • Tamaño, campos de tamaño, checksum invalido o no múltiplo de 32 bits.
  • Opciones extra TCP no validas.
Para finalizar le recomiendo que en caso que programe las opciones anteriores, tenga especial cuidado con lo que envía y con que velocidad lo hace, puesto que las centralitas telefónicas, entornos SCADA o impresoras suelen comportarse de forma distinta a lo esperado ante estos casos.




Continuar...

martes, 27 de noviembre de 2012

AppSec USA 2012

Los días 23 a 26 de Octubre tuvo lugar la conferencia OWASP AppSec USA 2012 en Texas. En la conferencia se trataron distintos puntos de la seguridad focalizada en la seguridad Web. 

Por desgracia, pese a estar relativamente cerca, me fue imposible acudir a las conferencias debido al desembolso económico que implicaba la estancia en Austin, por lo que decidí reservar el dinero para otra ocasión. 

Hace un par de días me llego un enlace a través de Twitter de que David Hughes había subido una serie de videos de la conferencia, como me imagino que no seré el único que no tuvo la oportunidad de asistir aquí podeis acceder a diez videos de una duración media de 45 minutos.

Como ocurre en todas las conferencias vereís que algunos videos repiten temática con otras conferencias o no son realmente muy interesantes, pero hay un par de videos que me han gustado por lo que he decidido publicar una entrada recomendado la visualización de los mismos. 

Un saludo y hasta la próxima.

Continuar...

domingo, 7 de octubre de 2012

Última actualización OsX y FileVault

Muchos de vosotros direis que última última no, tiene posiblemente un par de semanas, pero es que la última vez que intente actualizar el Os X el sistema no se recuperó y tuve que tirar de Time Machine para restablecer el entorno.

Hoy por fin me he decidido a actualizar, en ella se describe que se trata de un pequeño parche de seguriad para corregir algunos errores, un pequeño parche de unos 1.3 GB...

Bueno dejando esto de lado, cuando he actualizado el entorno me ha solicitado reiniciar el equipo, cosa que he hecho, y como siempre, al arrancar el sistema me ha solicitado la contraseña para acceder al sistema de ficheros puesto que lo tengo cifrado con FileVault, que es el sistema propietario de Apple para cifrar dispositivos.

Lo gracioso ha sido cuando he visto que no me reconocia la contraseña de descifrado del sistema de ficheros, una y otra vez, una y otra vez sin suerte. Como no tienes la posibilidad de ver lo que estas tecleando puesto que en todo momento se muestran "*", cosa que desde el punto de vista de la seguridad es perfecto, pero no estaría de mas poder seleccionar una opción que te permitiera ver lo que estas escribiendo.

Al poco he caido en la cuenta, ¿a que estos hijos de fruta me han puesto el teclado en inglés despúes de actualizar? y efectivamente he probado escribiendo los simbolos no alfanumericos de las contraseñas como si de un teclado americano se tratara y he entrado en el sistema como un campeón.

Pues nada ya lo sabeis por si alguno le pasa, que paseis un buen día ;)

Continuar...

viernes, 5 de octubre de 2012

Saltarse un WAF mediante Parameter Pollution

Buenos días a todos, al menos en Boston. Hace un par de días leí en twitter una noticia que apuntaba a una entrada del blog de Daniel Regalado (Danux Mitnick) titulado "Bypassing WAF via HTTP Parameter Pollution". 

La entrada está francamente bien y trata sobre como saltarse en ciertos casos los filtros de un Web Application Firewall o WAF, es decir, un filtro que previene de ciertos ataques Web como SQL-I, XSS, XSRF, etc. 

Daniel emplea para evadir el filtro envenenamiento de parametros o en inglés Parameter Pollution, donde en este caso, trata de saltarse los filtros del WAF cuando este analiza distintos valores para una misma variable de entrada. Un WAF mal programado podría procesar de forma distinta de como es interpretado por el lenguaje de programación empleado para la Web. Se puede ver como un fragmentation overlapping pero en capa de aplicación en vez de capa de red.

Para entenderlo de forma sencilla, si tenemos una variable que es "texto" podemos enviar una petición a la página web auditada introduciendo dos variables "texto" con distinto valor, como se puede ver en la siguiente petición Get:
http://www.paginafictica.com/index.php?texto=hola&texto=adios
El WAF podría tratar el valor del primer texto (hola), el valor del segundo texto (adios), ambos por separado (hola y adios) o el valor resultante de la suma de ambas variables (holaadios). En caso de la entrada de Daniel el se encuentra que el WAF solo procesa el valor del primer texto sin analizar el valor del segundo texto "adios".

Una vez se conoce el funcionamiento del WAF, y por tanto si realmente realiza las cuatro comprobaciones o solo algunas, sabremos si es posible o no saltarse las restricciones e inyectar el parametro deseado. 

Llegado a este punto será necesario saber como funciona la tecnología empleada para el desarrollo de la página. Daniel hace una tabla indicando el funcionamiento de cada una de las tecnologías, la cual la podeis ver en su entrada indicada al principio, pero el resumen básico sería el siguiente:
  • PHP: se queda solo con el valor de la última variable (última ocurrencia).
  • ASP y .NET: se queda con el valor de la suma de todas las variables (todas las ocurrencias).
  • JSP: se queda solo con el valor de la primera variable (primera ocurrencia).
  • Python y Perl: se crea un array.
Por lo que si sabemos que en el ejemplo de Daniel el WAF solo analiza la primera ocurrencia, si la web emplea PHP, ASP o .Net lo único que tendremos que hacer es realizar una solicitud escribiendo dos veces la misma variable y introduciendo el vector de ataque en la segunda ocurrencia. Por descontado habrá que tener cuidado si usamos "ASP" o ".Net" de que el valor de la primera ocurrencia no afecte al funcionamiento del vector de ataque:
http://www.paginafictica.com/index.php?texto=hola&texto=XSS
La verdad que me ha parecido una buena entrada, sencilla, útil y muy bien explicada por parte de Daniel. Recomiendo seguir a esta persona en Twitter y a su blog.

¡Un saludo!

PD: ya tengo asignado a un tutor para el Gold GCIA... y que tutor... ¡un crack!


Continuar...

jueves, 4 de octubre de 2012

¡Gold GCIA aceptado!

Después de un largo fin de semana en Toronto (Canada) visitando a la familia y 2 días sin Internet en casa por fin pude mandar mi correo a SANS preguntando sobre el Gold... contestar, lo que es contestar no me han contestado, pero me ha llegado el correo de confirmación como que han aceptado la propuesta.

Ahora tengo seis meses por delante para desarrollar y redactar la herramienta, que por temas de confidencialidad no puedo hacer pública todavía. Es mi primer Gold por lo que estoy bastante ilusionado al respecto, ya veremos como sale.

Lo que si que me gustaría es solicitar trocitos pequeños de registros o logs de distintos servicios como pueda ser el IIS, WebSphere, Domino, JBoss, etc. Podeis sustituir las IPs por otras ficticias, no es problema, solo me interesa la estructura del log, con un par de entradas me sobra. Toda ayuda será agradecida.

Siento que la entrada sea corta pero mañana me toca levantarme a las 6 am que tengo 5 horas de inglés ¡Woo Hoo!

PD: os dejo una foto de recuerdo del fin de semana en Canada (venga a por los metadatos xDDDD)



Continuar...

domingo, 23 de septiembre de 2012

Auditoría Web - Parte 1

Hoy hace tres semanas justas desde que aterrice en Boston, ya más o menos me conozco la ciudad o al menos los puntos más importantes. Por fin me he podido acomodar y empezar con la rutina de trabajo, aunque todo sea dicho, justo esta semana me marcho 4 días a Toronto (Canada) y me cambio de habitación a una con un escritorio (desk), un colchón limpio (mattress) y con luz natural para poder estudiar en condiciones, sin tener que irme a la biblioteca pública que está a una hora y media de mi casa.


Por la parte de inglés me ha tocado el nivel esperado, era lógico mi gramática no es buena y no estudie lo que debería para hacer el examen, estoy en Intermediate (PET), es decir el 5º nivel de 9 que hay. Tengo por delante el High, Upper, Advanced y Proficiency. Para antes de navidad me he marcado el objetivo de entrar en el "Upper" que es un nivel entre First avanzado e introducción al Advanced. Respecto a entenderme con la gente bueno… lo de siempre… los profesores me entienden, los compañeros de casa me entienden, las americanos acostumbrados a los españoles me entienden pero los americanos nativos les cuesta un poco entenderme, aunque es curioso que en el banco o en las tiendas me entiendan a la primera :P

En lo que concierne al SANS MSISE ya tengo listo la base de mi primer GOLD que corresponderá al GCIA, estoy esperando la respuesta de SANS para que me lo validen y empezar a escribir puesto que la base del programa ya la hice la semana pasada. Jose Luis Chica, @spankito para los amigos, pudo probar la herramienta y creo que le gusto bastante, es una idea sencilla pero bastante útil.

Respecto al blog voy a aprovechar que por fin tengo algo de tiempo libre para cogerme el libro que compre junto a mi compañero Raúl Rodriguez hace cosa de un año: "The Web Application Hacker's Handbook" en su segunda revisión. Está enfocado a auditoría web y por lo que he podido ver en cuento a nivel técnico es de lo mejorcito que he leído, con un precio más que bueno, aunque si puedo ponerle un pero en mi opinión le falta especificar los pasos adecuados para una auditoria web.

Los auditores Web conoce un montón de distintos posibles vectores pero algunos, entre los que me incluyo, desconocemos adecudamente por donde empezar, ya se sabe, la típica comilla o símbolo de mayor / menor que se suele usar en un formulario de entrada sin ni siquiera comprobar ni la tecnología que emplea la Web. Hay que organizarse, indicar los pasos a realizar y autorealimentarse con los datos obtenidos antes de empezar a explotar distintos vectores de ataque.

Hablando claro estos son los pasos, de cabeza y por tanto puedo haberme dejado alguno, que suelo emplear yo y que creo que estaría bien que el libro hubiera comentado de forma más ordenada y extensa:
  1. Information gathering en Internet.
  2. Arquitectura que tienes en frente (IIS, Apache, Jboss, WebSphere, etc), ¿tiene balanceadores?, ¿WAF?, ¿IPS?, etc
  3. ¿Qué tecnología emplea: servlets, .NET, PHP? ¿Usa un framework? ¿que versión? ¿es vulnerable?
  4. Crawling de lo accesible mediante links usando un proxy para después montarse tu mapita de la Web ya sea en digital o en un folio.
  5. Mediante diccionario y crawlers buscas recursos existentes pero no accesibles desde un enlace de la Web. Comparas con lo obtenido en el punto 4.
  6. Jugar con los dominios, ¿existe más dominios de la web? ¿qué ocurre si pones solo la IP?
  7. Si tiene protocolo cifrado… ¿los algoritmos empleados son adecuados? ¿se puede renegociar empleando algoritmos débiles? ¿el certificado es correcto?
  8. Solicitamos un usuario legítimo y valoramos: como se gestiona la autenticación, como se gestiona la sesión, como se gestiona el cierre de sesión y si los recursos accesibles como usuario autenticado son accesibles de alguna forma sin estar autenticado.
  9. Aquí es cuando suelo usar herramientas automatizadas que me puedan aportar más información a la auditoría, como por ejemplo nikto, w3af, nessus, skipfish, etc.
  10. Ya teniendo un mapa completo de todo, tanto parte pública como privada, accesible desde enlaces y no accesibles es cuando me marco en el mapa los distintos posibles puntos de entrada indicando los posibles vectores de ataque en dicho recurso: XSS, XSRF, LFI, SQL-I, ejecución de comandos, path transversal, etc… algunos incluso solo se pueden aplicar dependiendo de la tecnología. Y es en este punto donde creo que entra en juego el libro.
Para acompañar al libro me he montado un entorno de pruebas con una backtrack 5 y un entorno vulnerable "OWASP Broken Web Applications Project". No tenia conocimientos de este proyecto, si de las distintas aplicaciones vulnerables que lo componen, pero no que existiera un live con todas. Lo leí en una entrada de SBD y me pareció muy interesante de usar durante las próximas entradas del blog.

Un saludo :-)

Continuar...

domingo, 26 de agosto de 2012

SANS MSISE y a Boston

Tal como comente en la anterior entrada hacia mucho tiempo que no escribía nada, un inicio de año donde no he podido apenas invertir tiempo en el blog debido a la carga de trabajo, exámenes y los preparatorios para un cambio de rumbo. Espero que en adelante pueda disponer de más tiempo para el blog. Esta entrada va ser muy distinta a las técnicas que suelo publicar en el blog, más bien es una opinión personal y decisión que he tomado dada la actual situación.

En Agosto dejé mi actual puesto de trabajo como técnico de seguridad para embarcarme en una nueva etapa, en unos días marcho a Boston (EEUU) para afianzar mi inglés y poder realizar los últimos requisitos para obtener el SANS MSISE (Master of Science Degree in Information Security Engineering).

Durante mi estancia en Boston realizaré un curso anual intensivo de inglés (24 lecciones por semana durante 9 meses) más un curso bimensual intensivo de 30 lecciones semanales preparatorio para el TOEFEL. En total son unas 1200 horas de inglés académicas con el objetivo de obtener un nivel C1, ojalá lo consiga :)

En las horas restantes que me deje el inglés quiero realizar una serie de "papers" que me permitan obtener el grado de GOLD en unas certificaciones de GIAC. Los GOLD se pueden realizar una vez se haya superado un certificado SANS/GIAC y deben tratar sobre la temática relacionada con el certificado obtenido. Son los típicos documentos técnicos en inglés de entre 50 y 100 hojas que se publican en SANS por gente externa a la empresa. En caso del MSISE te piden 5 GOLDs en temas tan distintos como análisis forense, gestión de proyectos, detección de intrusos, gestión de incidentes y bastionado.

Tanto el aprendizaje del inglés como la realización de los Gold tiene como objetivo la preparación del SANS GSE. Esto es posiblemente lo más difícil del MSISE debido al nivel práctico exigido. Ya tengo una lista en cola de libros, retos / CTF y papera pendientes de leer a lo largo de este año. Iré escribiendo en el blog aquellos puntos que me hayan parecido más interesantes.

Lógicamente tener X certificaciones o tal Master no implica que uno sea mejor o peor, pero a mí personalmente me ha permitido aprender, entender y comprender cosas que sin ellos no creo que hubiera podido. Cada persona es un mundo, pero al menos desde mi punto de vista, apostar por la educación e invertir en ella no es nunca una mala decisión. Dejando de lado que estoy de acuerdo que el precio de los cursos son demasiado caros para lo que realmente son, pero por desgracia, no tienen competencia en el rol de seguridad que a mi me interesaba.

Es por esto que tengo bien claro que la obtención del MSISE no implicaría ser un "fucking master", simplemente tendré una base sólida de conocimientos. Sobre esa base deberé construir, y dependiendo de lo que construya, me podrá salir una chabola o un castillo, ya se sabe "la seguridad no es una meta sino un proceso…" aaaahhhh ¿quien eres tú y que haces con mis manos? Fuuuu puto demonio consultor vaporware :P Bueno creo que queda claro lo que quería decir, el objetivo es tener una buena base para empezar a trabajar sobre ella y creo que el MSISE me la proporcionará.

Por si alguien estuviera interesado en cursar el MSISE los requisitos, en su rama de especialidad en análisis forense y gestión de incidentes, son los siguientes:

- GSEC o CISSP (seguridad básica). Es necesario GOLD.
- GCPM o PPM (gestión de proyectos). Es necesario GOLD.
- GCIA (detección de intrusos). Es necesario GOLD.
- GCIH (gestión de incidentes). Es necesario GOLD.
- GCFE (forense en windows).
- GCFA (forense avanzado, APT y demás). Es necesario GOLD.
- GREM (reversing de malware).
- Tres asignaturas que refuerzan la parte de gestión.
- SANS GSE
- Tesina o proyecto de fin de master, esto no es un simple proyecto, sino que son varios, bastante largo la verdad.

Resumiendo: 7 SANS/GIAC, 5 GOLD, 3 asignaturas, el GSE, proyecto comunitario y la tesina de fin de master.

Si se procede de un país de habla no inglesa es necesario el TOEFEL. Los certificados deben haber sido obtenidos con una nota de 8 o más sobre 10 y disponer de al menos 3 años de experiencia en el ámbito de la seguridad. 

Es importante entender que está enfocado a la defensa y no al ataque, por tanto no es válido para gente que busque un rol de pentester. En mi caso para suplir esta carencia curse los certificados de auditoría de redes (GPEN) y de auditoría Web (GWAPT) pero se quedan muy lejos de los conocimientos básicos necesarios para un buen pentester

La próxima entrada ya será técnica y desde Boston :)

Pd: editar una entrada con el Ipad #eshacker ... Cosa más mala no he visto xD

Continuar...

sábado, 25 de agosto de 2012

Informe Software Explotation

Bueno… ya ni me acordaba de como se escribía en el blog :) Antes de nada decir que la explicación de está parada prolongada de varios meses se dará mañana en una entrada específica para dicho propósito, hoy solo escribo para agradecer públicamente a Borja Merino (@BorjaMerino) la oportunidad que me brindo en la redacción del informe de Software Explotation presentado a traves de Inteco-CERT.

Hace unos meses una persona, a la que le estoy muy agradecido, me puso en contacto con Borja porque tenia pensado realizar un informe de Software Explotation y buscaba colaboradores. A mi sinceramente me pareció una idea cojonuda: gente que de forma desinteresada se juntaba para compartir sus conocimientos y hacerlos públicos.

Pero pese a que en un principio pude empezar a colaborar en el proyecto, debido a una serie de problemas ajenos al informe y a Borja (que prefiero dejar pasar), al final prácticamente solo pude ayudar en la corrección evolutiva del documento. Pese a ello, Borja siempre me tuvo en cuenta a lo largo del desarrollo del documento y en los agradecimientos.

Aquí os dejo un enlace al informe por si os interesa leerlo.

Hace unos días tuve la suerte y el placer de conocer a Borja en persona, el tío tiene unos conocimientos que en pocas personas he visto,  eso sí, caro me ha salido conocerle porque me ha convencido para apuntarme al curso de Corelan en Kentucky sobre Software Explotation. Gracias Batman y a ver si nos vemos en el otro lado del charco :P

Mañana la entrada que comento al principio :)

Continuar...

martes, 17 de abril de 2012

Bastionado de Apache Tomcat (II)

Tras la primera parte que vimos el otro día, en esta entrada vamos a ver el uso de Security Manager y la correcta configuración del protocolo SSL sobre un Apache Tomcat.

Respecto al primero, vamos a configurar Security Manager para que restrinja el uso de ciertos métodos y clases que puedan implicar un riesgo para el servidor de aplicaciones. Estas restricciones se definen en el fichero catalina.policy. Para activar Security Manager será necesario añadir las siguientes dos entradas en el arranque de Tomcat:

-Djava.security.manager
-Djava.security.policy=$CATALINA_BASE/conf/catalina.policy
Nota: si se usa el script por defecto de arranque en vez de JSVC se debe añadir el tag -security, que realmente hace lo mismo: añadir las dos entradas anteriores.

Un ejemplo práctico de Security Manager sería una aplicación con un fallo de seguridad donde un posible atacante ha conseguido subir una Web Shell para intentar ejecutar órdenes en el servidor mediante el método Runtime.getRuntime().exec(). Al intentar ejecutar dicho método Security Manager impedirá su ejecución devolviendo la siguiente excepción:
java.security.AccessControlException: access denied
Donde sí se ha tratado adecuadamente la excepción, tal como se documento en la anterior entrada, únicamente se mostrara la página error.html cuando se intente ejecutar órdenes en el servidor mediante la Web Shell del atacante. Otro punto importante a tener en cuenta es la correcta configuración del registro de sucesos. Para ello se recomienda seguir los siguientes consejos:
  • Aplicar una configuración adecuada para registrar la mayor información posible de los clientes que han realizado una solicitud a una aplicación del servidor Tomcat, añadiendo para ello la siguiente válvula al campo Host del fichero server.xml:
    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
      prefix="localhost_access." suffix=".log"
      resolveHosts="false"
      pattern="%t %h %H %m %s "%r" cookie:%{SESSIONID}c User- Agent:%{User-Agent}i " />
    
  • Crear registros específicos para cada aplicación. Para realizar esta tarea es necesario especificar un fichero de logging.properties por cada aplicación desplegada en el directorio .../aplicacion/WEB-INF/clases/ donde aplicacion es el directorio de la aplicación. Dicho fichero tendrá la siguiente configuración:
    handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
    org.apache.juli.FileHandler.level = FINEST
    org.apache.juli.FileHandler.directory = ${catalina.base}/logs
    org.apache.juli.FileHandler.prefix = aplicacion.
    org.apache.juli.FileHandler.suffix = .log
    org.apache.juli.FileHandler.rotatable = true
    java.util.logging.ConsoleHandler.level = FINEST
    java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
    
  • Emplear LOG4J para aquellas aplicaciones donde las librerías de registros por defectos de Tomcat no cumplan todos nuestros requisitos.
Para finalizar trataremos de configurar adecuadamente los conectores que empleen protocolos cifrados (conectores SSL) definidos en nuestro servidor de aplicaciones Tomcat siguiendo para ello los siguientes puntos:
  • Forzar a los conectores que no cifran las comunicaciones a usar SSL mediante los siguientes pasos, llamado también redirección a conector SSL:

    1. En los conectores definidos en el fichero server.xml que no se empleen protocolo SSL se debe aplicar una redireccionan hacia un conector que emplee el puerto SSL:
    <Connector port="80" protocol="HTTP/1.1"
                    redirectPort="443"
    ...
    />
    <Connector port="443" protocol="HTTP/1.1"
                    scheme="https"
    ...
    />
    
  • 2. Indicar que los métodos GET, POST y HEAD sean confidenciales añadiendo la siguiente entrada al fichero web.xml:
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" …>
    ...
        <security-constraint>
                <web-resource-collection>
                        <web-resource-name>Servidor Aplicaciones</web-resource-name>
                        <url-pattern>/*</url-pattern>
                        <http-method>GET</http-method>
                        <http-method>POST</http-method>
                        <http-method>HEAD</http-method>
               </web-resource-collection>
                <user-data-constraint>
                        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
                </user-data-constraint>
        </security-constraint>
    </web-app>
    
  • Impedir el uso de algoritmos y protocolos débiles. Para ello en la configuración de los conectores cifrados, definidos en el fichero server.xml, se deberá indicar que se desea usar TLS mediante la variable sslProtocol="TLS". Hay que tener en cuenta que el valor “TLS” en las últimas versiones de Tomcat identifica a la versión 1.1, y por tanto, acepta tanto TLS como SSL v3 pero no SSL versión 2, tal y como se especifica en la documentación del protocolo TLS v1.1.

    Será necesario definir que ciphers suite de los soportados por Java (ver enlace) se deben emplear. Estos presentan la siguiente forma:
    Proto_AlgClaveAsimetrica_WITH_AlgClaveSimetrica_tamClaveSim_AlgCompendio
    
  • Para esta restricción se pueden aplicar listas negras: aceptamos todos los algoritmos menos unos cuantos, como se recomienda en la entrada de SecurityByDefault, o se pueden aplicar listas blancas: solo permito los estrictamente indicados. Para gustos colores, pero en mi opinión prefiero aplicar listas blancas, es decir, indicar solo los que puedo usar. 
    En mi opinión, sin ser ni mucho menos un experto en algoritmos de cifrado, recomendaría usar TLS, algoritmos de curva elíptica o RSA como clave asimétrica, AES de 128 bits mínimo para clave simétrica y SHA como algoritmo de compendio:
    TLS_RSA_WITH_AES_128_CBC_SHA
    TLS_RSA_WITH_AES_256_CBC_SHA
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
    
    Por ello se definirán los cipher suite indicados con anterioridad en cada conector SSL creado en el fichero server.xml mediante la variable ciphers separados por comas:
    <Connector port="443" protocol="HTTP/1.1"
    scheme="https"
    ...
    ciphers="TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"
    ...
     />
    
    Hay que tener en cuenta que para que pueda emplear algoritmos de curvas elípticas y algoritmos simétricos de más de 128 bits será necesario sustituir las librerías por defecto del Java JDK local_policy.jar y US_export_policy.jar por las suministradas en el paquete Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. Esto es debido a que por defecto el JDK está restringido a las leyes de EEUU donde no se permite más de 128 bits ni algoritmos de curva elíptica. 
    Una vez sustituidas las librerías y reiniciado Tomcat ya se permitirá emplear dichos algoritmos, tal como se muestra a continuación:
    $ openssl s_client -host localhost -port  443 -tls1 -cipher AES256-SHA
    …
    New, TLSv1/SSLv3, Cipher is AES256-SHA
    Server public key is 1024 bit
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    SSL-Session:
        Protocol  : TLSv1
        Cipher    : AES256-SHA
    ...
    
Con este par de pasos ya se dispondrá de un servidor Tomcat con una configuración de seguridad más o menos correcta ya que se han omitido una serie de configuraciones adicionales que se deberían aplicar para mejorar la seguridad del entorno, aspecto que queda fuera del contexto de esta entrada. 

PD: entrada publicada para el blog de securityartwork.
PD2: veo que se sale el texto de algunas casillas, siento las molestias :(


Continuar...

jueves, 12 de abril de 2012

Bastionado de Apache Tomcat (I)

A raíz de la entrada de Guillermo Mir sobre el bastionado de Apache (parte I y parte II) y una entrada en el blog SecurityByDefault sobre cómo trabajar con SSL en Tomcat me he decidido a escribir una entrada sobre el bastionado de Tomcat que debía desde hace mucho tiempo a Manolo, quien no se olvidaba de recordármelo.

En primer lugar indicar que la entrada se centrará en un correcto bastionado de Tomcat sobre un entorno Linux, puesto que sinceramente Tomcat en Windows no ofrece las mismas opciones, por muy Java que sea, que en un entorno Linux. Como documentar una guía de bastionado de Tomcat ocuparía muchas páginas, esta y la siguiente entrada tratará los principales puntos a tener en cuenta durante un bastionado adecuado. Para más información os remito a la documentación de Tomcat.

Durante la instalación se deben tener en cuenta los siguientes puntos:
  • En primer lugar se debe emplear un usuario administrador de tomcat al que llamaremos “tomcatadm” y un grupo tomcat al que llamaremos “tomcat”. Los ficheros de configuración tendrán permisos de lectura para el grupo “tomcat” y permisos de lectura más escritura para el usuario “tomcatadm”.
  • A su vez se debe diferenciar entre el Home y el Base de Catalina. El base CATALINA_HOME debe tener únicamente el motor de Tomcat mientras que CATALINA_BASE debe tener la parte dinámica constituida por: webapps, logs, temporales y ficheros de configuración, de forma que para actualizar el motor solo sea necesario cambiar el enlace dinámico donde apunta CATALINA_HOME.
  • La ejecución del servicio Tomcat se debe realizar a través del demonio programado en C JSVC, el cual permite que Tomcat escuche en puertos inferiores al 1024 para posteriormente cambiar a rol de usuario sin privilegios, sin ser necesario el uso de redirecciones a nivel de red o proxys frontales.
Durante el bastionado inicial se deben tener en cuenta los siguientes puntos:
  • Solo habilitar los conectores estrictamente necesarios. Si vamos a usar Tomcat en alta disponibilidad mediante clusters o vamos a usar un proxy frontal se deberá usar el conector AJP. Si se va a emplear un único Tomcat donde los usuarios se conecten directamente desde su navegador Web a Tomcat se deberá emplear un conector HTTP/HTTPS. Lo que no tiene sentido en un entorno de producción es que se empleé los dos conectores a la vez.
  • Ajustar las variables proporcionadas por Tomcat para dada una infraestructura y unos recursos, evitar dentro de los límites posibles, una denegaciones de servicio de los recursos del servidor. Recomendando los siguientes valores para cada conector configurado en el fichero server.xml:
    maxPostSize=”2097152”
    maxSavePostSize=”4096”
    maxHttpHeaderSize="8192"
    maxParameterCount="15"
    keepAliveTimeout="300000"
    maxThreads="150"
    maxPostSize="2097152"
    maxSavePostSize="4096"
    compression="on"
    compressableMimeType="text/html,text/xml,text/plain,application/xml"
  • Se deben ocultar las cabeceras HTTP server y xpoweredBy que proporciona por defecto el servidor como respuesta ante una solicitud. Para ello es necesario añadir las siguientes dos variables al fichero “server.xml”:
    server="Nombre Inventado"
    xpoweredBy="false"
  • Importante, muy importante, realizar el tratamiento adecuado de las excepciones. Si un desarrollador no trata correctamente las excepciones de su aplicación, nuestro servidor Tomcat no debe permitir que estas se visualicen en el cliente Web. Para tratar las excepciones hay que añadir al final del fichero web.xml, antes de cerrar el tag web-app la siguiente entrada:
    <web-app ... >
    ...
       <error-page>
           <exception-type>java.lang.Throwable</exception-type>
           <location>/error.html</location>
       </error-page>
    </web-app>
    Donde será necesario crear un fichero error.html en el directorio base de cada aplicación, de forma que, ante una excepción de Tomcat se mostrará dicha página en lugar de la traza de la excepción.

    De la misma forma que se tratan las excepciones, se puede gestionar los códigos de error HTTP, tanto del servidor (5XX) como del cliente (4XX). Para ello será necesario añadir al final del fichero web.xml, antes de cerrar el tag web-app, una entrada por cada error a gestionar, donde XXX es el código de error de respuesta (401, 403, 404, 414, 500, etc):
    <web-app ... >
    ...
        <error-page>
            <error-code>XXX</error-code>
            <location>/error.html</location>
        </error-page>
    </web-app>
    De esta forma cuando se origine un error de tipo “XXX” se redireccionará a la página error.html indicada y no a la de por defecto de Tomcat que muestra, entre otras cosas, la información de la versión. Si se quiere evitar que se muestre el mensaje por defecto de error para cualquier código de error es necesario modificar el código de Tomcat: desempaquetar, modificar un par de líneas y empaquetar, pero esto ya queda fuera del contexto de esta entrada.
  • Se debe desactivar el puerto de apagado del servicio. Esto es algo curioso y no acabo de entender el motivo por el cual este activado por defecto en distribuciones como Debian, donde se habilita el conector Shutdown en el puerto 8005 con contraseña por defecto SHUTDOWN, de forma que un usuario local del sistema puede detener el servicio Tomcat:
    $ netstat -putan | grep LISTEN | grep java
    tcp6     0    0 127.0.0.1:8005      :::*        LISTEN      7437/java
    tcp6     0    0 :::8080             :::*        LISTEN      7437/java
    $ telnet localhost 8005
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    SHUTDOWN
    Connection closed by foreign host.
    $ netstat -putan | grep LISTEN | grep java
    $
    Por ello se debe desactivar el conector en el fichero server.xml indicando que el puerto es “-1” y adicionalmente cambiando la contraseña:
    <Server port="-1" shutdown="QUiENnnQu1er3J4v4Cuand0TIENeCee">
    Por defecto se debe restringir el despliegue de aplicaciones de forma automatizada. Para ello se debe configurar adecuadamente el fichero server.xml impidiendo que se desplieguen aplicaciones automáticamente cuando se deposita la aplicación en el directorio de aplicaciones (webapps), indicándolo con el tag autoDeploy="false". A su vez se debe impedir que las aplicaciones depositadas en el directorio de aplicaciones (webapps) se desplieguen al reiniciar el servicio mediante el tag deployOnStartup="false”.

    Si ya se quiere ser muy tiquismiquis se puede indicar que solo las aplicaciones documentadas en el fichero server.xml se puedan desplegar. Para ello se debe definir la variable deployXML=”false” y emplear los tag Context path que identificaran las aplicaciones que se desean desplegar, tal y como se muestra a continuación:
    <Server ...>
     <Service name="Catalina">
        <Engine name="Catalina" ...>
          <Host ... autoDeploy="false" deployOnStartup="false" deployXML="false"
              ...
               <Context path="/aplicacion"/>
              ...
          </Host>
        </Engine>
      </Service>
    </Server>
  • Desactivar el método HTTP Trace añadiendo el siguiente tag al fichero server.xml:
    allowTrace=”false”
Con estas recomendaciones damos por finalizada la primera entrada de bastionado en Apache Tomcat. En la siguiente entrada trataremos el uso de Security Manager y la correcta configuración del protocolo SSL sobre un Apache Tomcat. Esperamos que os resulte útil.

PD: entrada publicada para SecurityArtWork.

Continuar...

miércoles, 29 de febrero de 2012

Parcheando código con GDB

Hace un par de días, durante un reto de seguridad, nos encontramos con la situación de tener que modificar con GDB el código de un binario para que realizara las acciones que nos interesaban y no para las que había sido programado; esto suele usarse en los retos tipo “crack me” o “patch me”. Todo sea dicho, al final no era la solución al reto, pero como todo reto, se suelen probar distintas opciones.

De forma resumida tenemos un programa con la función principal y dos funciones adicionales declaradas. En la función principal se llama solo a una de las dos funciones, en este caso a la función que llamaremos “malo”, pero nosotros necesitábamos que en vez de llamar a esa función llame a la otra función, la que llamaremos “bueno”.

Un ejemplo del código en C sería el siguiente, al que denominaremos “prueba.c”:

#include
#include
//Funciones auxiliares
void bueno(void) { printf("SIIII");}
void malo(void) { printf("Noooo");}
//Función principal que llama a la funcion malo
void main(void){malo();}

Nuestro objetivo era que el programa, en lugar de llamar a la función malo en el main, llamara a la función bueno. Para el reto teníamos únicamente GDB como debugger. Para la entrada usaremos el código anterior por estar más simplificado y resultar más claro.

Teniendo en cuenta que el código anterior se ha escrito en el fichero “prueba.c”, hay que seguir los siguientes pasos para compilar y cargar el binario en GDB:

$ gcc -o prueba prueba.c
$ gdb prueba
 
Una vez accedido a GDB le indicaremos que queremos usar el formato Intel en vez del AT&T seleccionado por defecto (me gusta más, para gustos colores o sabores):


$ set disassembly-flavor intel

El siguiente paso consistirá en ver el código del programa, teniendo encuenta que las pruebas se hacen sobre un entorno de 64 bits (por eso las direcciones son tan largas):

(gdb) disas main
Dump of assembler code for function main:
0x0000000000400514 < +0>: push rbp
0x0000000000400515 < +1>: mov rbp,rsp
0x0000000000400518 < +4>: call 0x4004fc <malo>
0x000000000040051d < +9>: pop rbp
0x000000000040051e < +10>: ret
End of assembler dump.

NOTA: “disas” viene de la orden “disassemble” pero se puede usar de esta forma porque no hay órdenes que empiecen por “disas” y no es necesario escribir la orden completa… es igual que ocurre en los cacharritos CISCO :)

Como vemos la llamada a la función malo, mediante CALL, está en posición “0×400518″, la cual apunta a la dirección “0×4004fc” donde se encuentra la primera instrucción de la función malo, tal como se muestra a continuación:

(gdb) disas malo
Dump of assembler code for function malo:
0x00000000004004fc < +0>: push rbp

...
0x0000000000400512 < +22>: pop rbp
0x0000000000400513 < +23>: ret
End of assembler dump.

El siguiente paso es analizar el tipo de CALL de la función principal (main), identificando el tipo de OP Code de la función; en nuestro caso se mostrarán los 8 bytes a partir del CALL:


(gdb) x/8xb 0x400518
0x400518 : 0xe8 0xdf 0xff 0xff 0xff 0x5d 0xc3 0x90

Vemos que el primer byte es 0xe8, que corresponde con el OP Code del CALL a dirección relativa Call32(). Dicha llamada consta de 5 bytes; el primero es el OPCode representado como “0xe8″ identificativo de la llamada y los siguientes 4 bytes es la dirección donde se encuentra la función que se desea llamar. Por tanto para ver correctamente esta instrucción será necesario visualizar solo los 5 primeros bytes:


(gdb) x/5xb 0x400518
0x400518 : 0xe8 0xdf 0xff 0xff 0xff

Donde tenemos el Op Code 0xe8 y la dirección “0xdf 0xff 0xf 0xff”. Como este ordenador es un LE hay que darle la vuelta: es decir, la dirección real es ” 0xff 0xff 0xff 0xdf”. Esto se puede realizar cambiando el carácter “b” de byte por el de word “w” e indicando la posición de memoria donde empieza la dirección que se quiere tratar, es decir, la dirección del CALL + 1 (quitamos el OP Code 0xe8):


(gdb) x/xw 0x400519
0x400519 : 0xffffffdf

Y la pregunta que se estarán realizando, ¿de dónde sale ese dato? Pues ese dato es el valor negado de la diferencia (offset) entre el final de la llamada del CALL y la función que se quiere llamar:

Not (OFFSET) = pos pre CALL + tam instrucción call - F(x) a saltar

¿Lioso? Veámoslo por partes. Tenemos de offset este valor “0xffffffdf”, con lo que la operación NOT sería:

0xdf -> 1101 1111 (el not de esto) -> 0010 0000 -> 0x20


Por tanto el NOT de “0xffffffdf” es “0×00000020″. Si sabemos que el Call se llama en la posición “0×400518″ y el tamaño de la instrucción CALL son 5 bytes, entonces sabemos que la f(x) termina en la posición “0×40051c”; cuidado porque el byte “518” ya es el primer byte del CALL:


F(x) a saltar = pos pre CALL + tam instrucción call - Not (OFFSET)
F(x) a saltar = 0x400518 + 0x4 - 0x20 = 0x40051c - 0x20 = 0x4004FC

Es decir, la posición donde está la función malo que hemos identificado con anterioridad.

Ahora queremos modificar el CALL para que apunte a bueno. Para ello es necesario obtener la posición de la función bueno:


(gdb) disas bueno
Dump of assembler code for function bueno:
0x00000000004004e4 < +0>: push rbp

Ya sabemos que el último byte de CALL está en la posición “0×40051c”, por tanto:


0x40051c - 0x4004e4 = 0x38

Not de 0×38 = 0xFFFFFFC7, y como es necesario ponerlo en LE -> 0xC7 0xff 0xff 0xff

Si recordamos, en el CALL de la función principal teníamos la siguiente entrada “0xe8 0xdf 0xff 0xff 0xff” la cual apuntaba a malo, y ahora queremos sustituirla por 0xc7 0xff 0xff 0xff: solo necesitamos cambiar el segundo byte del call, es decir 0xdf por 0xc7. O sea, indicarle que el byte “0×400519″ valga 0xC7:


(gdb) x/xb 0x400519
0x400519 : 0xdf

Para realizar dicha operación es necesario usar “set” indicando que lo que se quiere sustiruir es un byte en la posición indicada:


(gdb) set *(unsigned char*) 0x400519 = 0xc7
Cannot access memory at address 0x400519

Como vemos ha fallado, no tenemos acceso a dicha posición de memoria, hagamos una triquimechuela poniendo un breakpoint en la instrucción previa al call y ejecutando el programa:


(gdb) break 0x0000000000400515
Function "0x0000000000400515" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (0x0000000000400515) pending.

Ejecutamos ahora el programa esperando a que se detenga en el break indicado, una instrucción antes del call:


(gdb) start
Temporary breakpoint 2 at 0x400518
Starting program: /home/moxilo/prueba

Temporary breakpoint 2, 0x0000000000400518 in main ()
(gdb) disas main
Dump of assembler code for function main:
0x0000000000400514 < +0>: push rbp
0x0000000000400515 < +1>: mov rbp,rsp
=> 0x0000000000400518 < +4>: call 0x4004fc <malo>
0x000000000040051d < +9>: pop rbp
0x000000000040051e < +10>: ret
End of assembler dump.

Ahora ya podemos aplicar el cambio y comprobar que la modificación se ha llevado a cabo al apuntar el call a la función bueno en vez de a la función malo:

(gdb) set *(unsigned char*) 0x400519 = 0xc7
(gdb) disas main
Dump of assembler code for function main:
0x0000000000400514 < +0>: push rbp
0x0000000000400515 < +1>: mov rbp,rsp
=> 0x0000000000400518 < +4>: call 0x4004e4 <bueno>
0x000000000040051d < +9>: pop rbp
0x000000000040051e < +10>: ret
End of assembler dump.

Como vemos ya apuntamos a la función bueno, por lo que si le decimos que “continue” mostrará el texto de la función buena (“SIIII”) y no el de la función mala:


(gdb) continue
Continuing.
SIIII[Inferior 1 (process 3897) exited with code 05]

Por tanto hemos parcheado el programa en ejecución con GDB, de tal forma que hemos obtenido la dirección de memoria de otra función, sustituyendo posteriormente la dirección de la llamada CALL por la de la función que nos ha interesado. Esto también se puede usar para sustituir instrucciones de códio que realizan ciertas comprobaciones que no nos interesa por NOPs (0×90), es decir, por “nada”.

PD: soy consciente de la poca actividad del foro, pero los 4 tomos de canción de hielo y fuego, el nombre del viento, el temblor de un hombre sabio, las 7 horas de inglés semanales y el GREM que lo tengo en dos semanas son los culpables.

Continuar...

lunes, 23 de enero de 2012

¿Realmente importa la seguridad?

Hace unos meses estuve investigando un producto de software que te permite detectar posibles fugas de información mediante compendios de ciertos ficheros. Este programa tiene su parte comercial y su parte gratuita o comunitaria. Quería probar la parte gratuita para ver un poco el funcionamiento del mismos para decidir si el producto valía la pena. 

Lógicamente como todo producto nuevo quise documentarme de su funcionamiento, para validar si el producto cumplía todos los requisitos que necesitaba. Solo encontré enlace a la documentación para la parte comunitaria y no para la de pago. Para ello seguí los siguientes pasos:
  1. Voy a la web oficial del producto: http://www.XXXX.com/
  2. Desde la barra superior selecciono Products -> XXXX Comunity Edition llevándome al enlace siguiente: http://www.XXXX.com/XXXX-community-edition
  3. En dicha web se muestra en el primer párrafo el siguiente texto:
    "You can checkout documentations from XXXX Documentation or from other sites."
  4. Dicho enlace apunta a http://www.XXXX.com/documents ... bueno pues navego a dicho enlace y me veo que me redirecciona al siguiente enlace:
    http://www.XXXX.com/?controller=..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fenviron_


Y yo, ¡vale! parece ser que se han cargado la Web o  la gente que mantiene la parte comunitaria les ha gastado una broma o cualquier cosa de ese tipo. Pues bueno, voy a notificar a un CERT español, CSIRT-cv, para que les informe, ya que, siendo un producto de seguridad no da una buna imagen... 

Pues bien, de eso hace dos meses, no he recibido noticia alguna, ni el CERT tampoco y llevan con ese enlace en su propia Web al menos 2 meses que fue cuando lo notifique. En cambio el blog sigue en marcha, ya que hay una noticia del 12 de Diciembre del 2011...

¿Como está el panorama de la seguridad, si los propios fabricantes de seguridad les importa un huevo la propia seguridad? Creo que me tendría que haber dedicado a programar Java, te hacen más caso, hay más trabajo, está mejor visto y te pagan mejor. Masajaker con la bara les tenia que crujir a todos. 

PD: he sustituido el producto por "XXXX" para evitar cualquier cosa, que tal como está el panorama ya ni una SOPA te puedes tomar sin que te siente mal.

-----


Madre, ¡cuanto tiempo ha pasado desde mi última entrada! siento la tardanza pero voy bastante liado con tema de papeleos, trabajo, los cuatro tomos de "canción de hielo y fuego" y el GREM. Sí, sí al final me decidi por el de reversing de malware en vez de por el de bastionado en entornos Windows.

¿Por qué? uiii como diría Guardiola que palabra más peligrosa. Pues la razón es simple, muchas veces cuando realizas un forense te encuentras con un bicho. Debes analizar ese bicho y comprobar su comportamiento a nivel de ingeniería inversa del código, pero mis conocimientos para realizar tal tarea no eran ni de lejos los adecuados. Por ahora tengo que decir que el GREM me está gustanto bastante. A ver si un día tengo tiempo y voy contando un poco sobre los certificados que estoy realizando ;)

Continuar...