Random IRC quote :       <@matalaz> yo me voy a poner

x-ray con xaray

Seguramente después de haber leido el título muchos estareís pensando «¿que narices será eso de x-ray?», quizá ya lo hayaís usado, aún sin saberlo, dado que es una técnica con una base muy sencilla e intuitiva y la cual nos Probando xaray con homerpuede ser útil en más de una ocasión tal y como demostró Rubén hace unos días con el crackme de erg0t.

En general, x-ray, es una técnica comunmente usada en labores de ingeniería inversa para atacar algoritmos de cifrado muy simple y es aplicable cuando conocemos parte de los datos que se encuentran debajo de la capa cifrada. En su tiempo fue un gran descubrimiento para los analístas de virus, ya que permitió evitar en algunos casos la costosa emulación de código máquina que de otra manera hubiera tenido que realizarse para poder descifrar algunos motores polimórficos. Actualmente se sigue utilizando para detectar algunos virus polimórficos, shellcodes, etc… teneís un excelente paper de Peter Ferrie y Frédéric Perriot en el cual podreís profundizar más en el fundamento de x-raying y en su historia.

Por otro lado os presento xaray, un cutre-programa, con el cual espero que los que lo deseeís podaís practicar con esta técnica para ver su funcionamiento y utilidad … y además os dejo un pequeño reto para el que tenga ganas 😉

La idea de xaray, más que la de tener un programa que te haga de todo, es la de tener una pequeña plantilla, sobre la que poder hacer modificaciones cuando necesitas usar alguna de las técnicas derivadas de x-ray, os explico un poco como funciona, es muy sencillo 🙂

En el código de ejemplo que encontrareís en el paquete de xaray, vereís algo como esto :

int main (int argc, char **argv)
{
 unsigned char buffer[]      = "bpqaqafizigbpmlqzbgfzigbmuxtibmmvrwgqb";
 unsigned char plainText  [] = "secret";
 unsigned char plainText2 [] = "dirty";
 unsigned char plainText3 [] = "password";

 add_string(plainText,sizeof(plainText)-1);
 add_string(plainText2,sizeof(plainText2)-1);
 add_string(plainText3,sizeof(plainText3)-1);

 set_xcallback(lpcallback);
 x_ray(buffer,sizeof(buffer));
 free_strings();

}

Aunque en este ejemplo usamos xaray con cadenas de texto, xaray está preparado para manejar datos en raw, así que podeís utilizarlo sobre vuestros binarios favoritos ;-). El código creo que es bastante sencillo, en este caso lo que se hace es agregar una serie de palabras, las cuales creemos que podrían encontrarse bajo el texto cifrado, establecer una rutina callback que será llamada cada vez que se encuentre algo y llamar al motor de x-ray para que analice, posteriormente se libera la memoria usada por las palabras en texto plano.

La rutina callback debe devolver un valor al engine de xaray, existen dos opciones X_BREAK y X_CONTINUE, si devolvemos el primero el motor parará el análisis y si devolvemos el segundo continuará con él, por otro lado la estructura que recibe la función callback es la siguiente :

typedef struct _plain_string
{
 char             *lpString;     // Puntero a los bytes de la cadena en raw
 size_t                size;       // Tamaño de la cadena
 struct _plain_string *next;  // Aunque es una lista enlazada este campo no es usado externamente.
}plain_string,*pplain_string;

typedef struct _x_ray_key
{
 unsigned int keysize;  // Tamaño de la clave
 void            *key;    // Puntero a la clave
}x_ray_key,*px_ray_key;

typedef struct _x_ray_info
{
 unsigned char  *lpbuffer;  // Buffer original
 size_t         buffsize;       // Tamaño del buffer
 unsigned int   offset;       // Desplazamiento sobre el buffer en el que se ha encontrado la palabra
 unsigned int   method_id; // Identificador del algoritmo que ha sido usado, recordad que están implementados varios
 pplain_string  pstring;      // Puntero a una estructura que describe la cadena de la detección
 x_ray_key      xkey;        // Puntero a una estructura que describe los datos de la clave encontrada
}x_ray_info,*px_ray_info;

Como veís podemos obtener a partir de ella todos los datos necesarios para trabajar con la detección, actualmente solo están implementados unos pocos algoritmos básicos:

– xor simple (byte a byte)
– xor incremental, la clave se va incrementando según se avanza por el buffer byte a byte
– add/sub (byte a byte)
– caesar

Aunque las claves que almacenamos con estos algoritmos son de tamaño 1 byte, como veís en la estructura x_ray_key, se soportaría la implementación de un algoritmo que tenga una clave de cualquier tamaño.

Implementar un nuevo algoritmo es muy sencillo también, para ello debereís escribir dos rutinas, una de ellas tiene que implementar el descifrado normal y la otra la detección usando x-ray, los prototipos de estas funciones son los siguientes:

typedef int (*xmethod_i)   ( unsigned char *lpxbuff, size_t buffsize, pplain_string pstring, unsigned int method_id );
typedef int (*decryptproc) ( unsigned char *lpdst, unsigned char *lpbuff, size_t buffsize, px_ray_info  xinfo );

Además debemos agregar a la tabla de métodos las nuevas funciones :

typedef struct _xmethod
{
 xmethod_i   x_ray;
 decryptproc dproc;
  char        method_desc[MAX_METHOD_NAME_LENGTH];
}xmethod,*pxmethod;

Y eso es todo, os dejo por un lado el paquete de xaray con su codigo fuente, y un fichero cifrado, como pista os diré que es una imagen, a ver quien es el primero en sacarla 😉

Un saludo!,

Mario

Un comentario para “x-ray con xaray”

  1. Comment por ruben | 06/20/07 at 9:43 am

    Sí señor, has gozao con la lib. Y además ya tenemos nuevo crackme, uuuuuuuu venga que alguien se anime!!!

Se han cerrado los comentarios