Random IRC quote :      <ggonzalez> con lo poco que me gusta a mi conocer gente nueva

Bugs in Norman Virus Control driver

super-bug.jpgBuenas noches a todos y todas…

Hace ya algun tiempo que haciendo el tonto descubri dos pequeños errores en el codigo que gestionaba las IOCTL’s de uno de los drivers del Norman. Uno de ellos es un simple despiste a la hora de reservar un buffer para almacenar una cadena de texto. Y el otro un error a la hora de chequear adecuadamente los parametros que que un usuario puede mandar al dispositivo, y que en ultima instancia lleva a tener el control absoluto sobre un parametro en una llamada a una funcion del Kernel.

Dos pequeños despistes que sobre todo nos demuestran lo importante que es ir con pies de plomo en elementos tan sensibles como drivers, servicios, etc. donde un pequeño error puede suponer dejar el sistema en manos de cualquiera.
Y bueno, despues de mucho tiempo, al fin he conseguido sacar un poco de tiempo libre, poner por escrito algo parecido a un advisory, y añadir unos comentarios al exploit que hice a modo de prueba de concepto, todo lo cual os podeis bajar pinchando AQUI

Espero que disfruteis con la lectura, y en cuando al codigo que añado a modo de prueba de concepto, a pesar de estar muy lejos de ser una maravilla, creo que es un ejemplo original.

Sin mas, un saludo
Y por aqui estare esperando vuestro feedback ;o)

Back from DefCon

Finalmente el Martes se me acabaron las vacaciones! 🙁 , y bueno … tocaba poner un post-post-vaca-cional. En general han sido unas vacaciones entretenidas :

El día 1 el «Osu, Tatakae, Sexy Pandas!» Team (si seguís el enlace podeís encontrar algún indicio de la etimología del nombre) , formado por 7 «elementos» de diversos puntos geográficos, tomamos un avion directo hacia el mismísimo corazón del vicio y las construcciones horteras, también conocido como «Las Vegas».

CTF-Team

Nos dirigíamos a la famosa DefCon para competir en la final del conocido «Capture The Flag«, este juego organizado por la gente de Kenshoto es un wargame de seguridad informática donde ocho equipos luchan por la preciada Black Badge que da acceso eterno a la DefCon. Para llegar a la final se realizan unas pruebas clasificatorias en las que, aunque por los pelos y con momento final de película, nos clasificamos entre los siete equipos que la jugarían, siendo el octavo equipo el ganador del año anterior (1@stplace) .

(más…)

Soluciones al reto

Durante la última semana me han llegado varias soluciones al reto de la suma máxima en la lista de números. El primero en enviarla fue erg0t, que escribió este algoritmo en puro y duro C. Pero cansado de este lenguaje tan vulgar, sin glamour, y con tan poca clase (bastante que tiene structs), erg0t nos deleita con otra solución en el exclusivísimo e inescrutable Haskell.

import Data.List

f :: Integer -> Integer -> (Integer, Integer)

f 0 n | n < 0    = (0, n)
      | n >= 0  = (n, n)

f l n = let  a x = if x < 0  then 0 else x;
             b x = if x > l  then x else l
              in (a (l + n),b (l + n))

funcion :: [Integer] -> Integer

funcion lista = (\(x,y) -> maximum y) (mapAccumL f 0 lista)

He de decir que jamás había visto en mi vida ni una línea de código en Haskell, pero como buen jurado que soy he buscado un intérprete de Haskell, unos manuales en internet, y he comprobado que funciona. Incluso he llegado a entenderlo tras unas cuantas horas de investigación. Enhorabuena a erg0t por lo exótico de su solución.

También tenemos la solución de Miguel, que se va haciendo habitual, y que en realidad son dos soluciones: el algoritmo más obvio, de orden cuadrático, y el óptimo, de orden lineal. Además las explicaciones son abundantes y podemos disfrutar de esa notación húngara que delata sus orígenes Windowseros :).

Rodrigo Marcos nos ha envíado también su solución en Python, y yo mismo, después de que erg0t despertara mi interés por los lenguajes no imperativos, he programado mi solución en Prolog.

También quiero hacer una mención especial a Ángel Alonso que se curró una solución de última hora en Perl, pero no pudo terminar de ponerla a punto por falta de tiempo. Habrá más retos en el futuro para una revancha Ángel.

Y el que se lleva la estatuilla esta vez es… tara tatá tatá… erg0t! Por la solución más curiosa y eficiente al mismo tiempo.

Siguen los retos

Para no perder el ritmo seguimos proponiendo nuevos retos en 48bits, y esta vez no se trata de ingeniería inversa, se trata de un reto de programación, porque un buen reverser tiene que ser además un buen programador. Para este reto haremos lo mismo que antes, las soluciones me las envían por correo a plusvic[at]yahoo[dot]com, y dentro de una semana más o menos publicaremos las soluciones recibidas y eligiremos la mejor. Se admite cualquier lenguaje de programación razonablemente usado en el siglo XXI, ya sabéis: C y familia, incluyendo al primo sharp, Java, Python, Perl — que sé que hay algún fan de Perl por ahí 😉 — , Pascal, Ruby, ensamblador si hay algún valiente –pero nada de MASM que Mario se pone de mala leche–, y que hostias…. el que les de la gana, a ver si hay huevos y alguien manda el programa para la máquina de Turing. Pero al grano, el problema es este:

Dada una lista de N números enteros (positivos y negativos), encontrar el mayor valor que es posible obtener sumando cualquier grupo de números consecutivos dentro de la lista. Por ejemplo, si la lista fuera: 1,-2,5,3,-4,5,0,2,-2,3,-7,5,1. La mayor suma que se puede obtener es 12, resultado de sumar los valores 5,3,-4,5,0,2,-2,3. No hay otra suma de números consecutivos dentro de la lista que sea mayor que 12. El programa naturalmente recibirá como entrada una lista con una cantidad arbitraria de números (en un fichero, por teclado, o como se prefiera) y retornará el valor de la suma máxima, y si es posible, también la secuencia de números que forman parte de la suma. Se valorará la eficiencia en cuanto a tiempo de ejecución para valores grandes de N.

And the Oscar goes to…. Miguel!

Pues sí, el ganador en la categoría de mejor reverser de la segunda edición de los 48bits Academy Awards ha sido nuestro amigo Miguel, con esta solución.

En efecto, como se puede ver en la solución de Miguel, el fichero de licencia comienza con un byte de control, seguido de un entero de 32 bits, y a continuación un array de 511 bytes. Estos 511 bytes son los nodos de un árbol binario perfecto de profundidad 8. Recordemos que un árbol binario es aquel en el que cada nodo puede tener 0, 1 o 2 dos hijos, y es perfecto cuando no hay ningún nodo que tenga un solo hijo, y todas las hojas están en el mismo nivel de profundidad. Los 511 nodos están dispuestos según el recorrido inorder del árbol, que consiste en hacer el recorrido del subárbol izquierdo, procesar el nodo actual, y luego recorrer el subárbol derecho. El array resultante parece ser una representación aplastada del árbol, como se muestra en la figura. Además, al tratarse de un árbol perfecto, la raíz del árbol cae justo en el centro del array.

arbolbinario.JPG

El algoritmo de verficación consiste en recorrer el árbol comenzando por la raíz, hasta una de sus hojas, usando los bits del byte de control para decidir en cada nivel si descendemos por la rama izquierda o derecha del nodo actual. Si el bit es 0 vamos por la izquierda, si es 1 por la derecha. Naturalmente el árbol tiene 8 niveles (o 9 se cuenta la raíz) porque el byte de control tiene 8 bits, y se usa un bit para tomar la decisión «izquierda o derecha» en cada nivel. Al hacer el recorrido se van sumando los valores de los nodos por lo que se pasa, y al final este valor tiene que ser igual al entero de 32 bits que sigue al byte de control.

Como ven el algoritmo es muy sencillo, pero es un buen ejercicio para refrescar algunos conceptos básicos relacionados con la recursividad y los recorridos de árboles. Además vale la pena echarle una ojeada a la solución de Miguel, que aprovecha las características del árbol y su recorrido para hacer una implementación iterativa del algoritmo.