Category Archives: C y C++

Análisis y solución de un wargame de Criptografia

Bueno no se si sera exactamente criptografia x’D (mas bien es como resolver el acertijo), les comento lectores, ayer sábado estaba terminando algunos pendientes del trabajo y quise hechar un vistazo a ver como iba la comunidad de diosdelared, para los que no lo saben diosdelared es una comunidad de seguridad informatica con la característica de que tiene incluido un sistema de rangos y wargames, conforme vas solucionando mas retos vas avanzando de rango :).

Tengo mi cuenta ahi desde algunos meses o años ya.

Recordando la sección de retos informáticos (wargames) me apeteció ponerme a resolver uno antes de salir al cine a ver capitan america :p, como tenia algo de ganas de pensar en logica elegi el que se llama Valid Token, hasta aqui quiero comentarles que mostrare paso por paso como se soluciona el reto, así que si eres miembro ya de la comunidad o te gustaría serlo y pasar los retos intelectuales te recomiendo que lo intentes por ti mismo en un principio :).

Como ya es característico, el reto comienza con un texto que te hace sentir como si fueras algún ciber agente de la NSA o de la CIA xD (Murder siempre tan dramático).

Ok las instrucciones dicen lo siguiente:

Tenemos acceso al E-Mail de un administrador de SafePoint. Hemos podido recuperar su usuario y contraseña y una serie de Tokens.
El problema es que estas tokens se caducan tras ser usadas y según hemos confirmado, el algoritmo de generación cambia mensualmente.
Por si te sirve, hemos encontrado lo siguiente.
Ayudanos a generar un token valido y recibirás tu recompensa.
El usuario y contraseña que conseguimos es:
$email == ‘[email protected]’ && $password == ‘one2one’

Suerte en tu misión.

mas abajo hay un link que nos dirige al siguiente panel de login:

En las instrucciones se nos proporciona un usuario y una contraseña, pero nos falta un token (como sacamos el maldito token x’D?), entonces procedemos a descargar el archivo, que se supone es un archivo robado del generador de tokens :p

<?php
class Crypt0reto
  {
  private $prefix_token = 'ddlr-';
  private $valid_algorithm = '56-101-52-51-56';
  private function TokenCalculate($string)
    {
    $md5_1 = md5($string[0]);
    $md5_2 = md5($string[1]);
    $md5_3 = md5($string[2]);
    $md5_4 = md5($string[3]);
    $md5_5 = md5($string[4]);
    $token = ord($md5_1).'-'.ord($md5_2).'-'.ord($md5_3).'-'.ord($md5_4).'-'.ord($md5_5);
    return $token;
    }
  private function DebugToken($token)
    {
    $string_explode_array = explode($this->prefix_token, $token);
    $string = $string_explode_array[1];
    return $string;
    }
  public function CheckToken($token)
    {
    $test_token = $this->TokenCalculate($this->DebugToken($token));
    if($test_token == $this->valid_algorithm)
      {
      echo "verdadero";
      return true;
      }
    else
      {
      echo "falso";
      return false;
      }
    }
  }

Y comenzamos el análisis del código.

Vemos que tenemos 3 metodos en la clase, 2 privados (DebugToken, TokenCalculate ) y el otro publico (CheckToken), partimos del hecho de que como es publica sera la función que nos diga si nuestro token es valido o no (ademas el nombre es muy obvio no xd?).

public function CheckToken($token)
    {
    $test_token = $this->TokenCalculate($this->DebugToken($token));
    if($test_token == $this->valid_algorithm)
      {
      echo "verdadero";
      return true;
      }
    else
      {
      echo "falso";
      return false;
      }
    }

La función recibe un parametro que después es pasado al metodo privado DebugToken, veamos su código entonces.

private function DebugToken($token)
    {
    $string_explode_array = explode($this->prefix_token, $token);
    $string = $string_explode_array[1];
    return $string;
    }

Al igual que el primer metodo este tambien recibe un parametro solamente, comenzando tenemos una variable que recibe el valor resultante aplicar la función explode, para los que no saben explode te permite cortar una cadena en varias partes utilizando una expresion como delimitador, en este caso $this->prefix_token, al inicio de la clase esta declarada esta variable:

 private $prefix_token = 'ddlr-'; 

Llegados a este punto sabemos que el token contiene si o si la sub cadena ddlr- :p, ¿por que? pues por que en la función DebugToken después de utilizar explode se le asigna a la variable $string el contenido del arreglo $string_explode_array en la posición 1, la posición 0 quedo vacía puesto que no había nada antes de ddlr- al final $string es devuelto un nivel mas arriba, ósea a la función CheckToken.

Recordemos que teníamos algo así como

$test_token = $this->TokenCalculate($this->DebugToken($token));

Entonces el resultado de DebugToken ($string) es pasado directamente a TokenCalculate, veamos el metodo.

private function TokenCalculate($string)
    {
    $md5_1 = md5($string[0]);
    $md5_2 = md5($string[1]);
    $md5_3 = md5($string[2]);
    $md5_4 = md5($string[3]);
    $md5_5 = md5($string[4]);
    $token = ord($md5_1).'-'.ord($md5_2).'-'.ord($md5_3).'-'.ord($md5_4).'-'.ord($md5_5);
    return $token;
    }

Al igual que los 2 metodos anteriores recibe solo un parámetros, del cual extra los caracteres individualmente y obtiene su hash en md5, después de eso guarda el resultado de todos las variable que contiene el md5 de cada caracter en la variable $token y les asigna un ‘-‘ entre cada valor.

Hay vemos algo interesante, mientras se hace la concatenación se le aplica el metodo ord, lo que hace ord es tomar el primer caracter de una cadena y regresar su equivalente en ascii, al final la cadena $token es regresada.

Regresando a nuestro metodo original (CheckTone), ya ven que esto es como inception x’D, el resultado de todo eso es asignado en $test_token y abajo hay una comparación interesante

if($test_token == $this->valid_algorithm)

Nos esta diciendo que si nuestra cadena resultante es $this->valid_algorithm, que al inicio es declarado

private $valid_algorithm = '56-101-52-51-56';

Entonces nuestro token es valido, de lo contrario es invalido :).

Ahora, después de este análisis ¿por donde comenzamos?, ¿nuestro $test_token tiene que ser igual a $this->valid_algoritm verdad?, una vez que sabemos como se construye la cadena y como funciona el algoritmo procedemos a aplicar ingeniería inversa o resolver el acertijo … vaya :).

Lo primero que tenemos que hacer es ver cual es el valor de los números ascii, ¿por que?, pues como ya habíamos dicho arriba, si no recuerdas regresa a leer xd, el ultimo paso era aplicar la función ord que devuelve el ascii del primer caracter de una cadena, en este caso los hash en md5.

Los valores son:

  /*

  56-101-52-51-56

  56 = 8
  101 = e
  52 = 4
  51 = 3
  56 = 8

  8-e-4-3-8

  */

¿Ahora que hacemos? tenemos que confiar en que el creador del wargame no se paso mucho de listo y generar todos los md5 que comiencen con dichos caracteres (8-e-4-3-8), usando las letras del abecedario y los números del 0-9 (por eso dije que no se haya pasado de listo y haya utilizando caracteres raros jaj)

Tengo un arreglo ya preparado

$abc = array('@','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[',']','^','`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','{','|','}','~');

Imprimo las cadenas hash resultantes que coincidan con nuestro patron de búsqueda.

for($i = 0; $i < count($abc); $i++)
  {
    switch(substr(md5($abc[$i]),0,1))
    {
      case '8':
      echo $abc[$i]." : ".md5($abc[$i])."<br/>";
      break;
      
      case 'e':
      echo $abc[$i]." : ".md5($abc[$i])."<br/>";
      break;
      
      case '4':
      echo $abc[$i]." : ".md5($abc[$i])."<br/>";
      break;
      
      case '3':
      echo $abc[$i]." : ".md5($abc[$i])."<br/>";
      break;
    }

Y el resultado es (ya organizados)

/*
8-e-4-3-8

= 8 = 

F : 800618943025315f869e4e1f09471012
N : 8d9c307cb7f3c4a32822a51922d1ceaa
[ : 815417267f76f6f460a4a61f9db75fdb
` : 833344d5e1432da82ef02e1301477ce8
d : 8277e0910d750195b448797616e091ad
f : 8fa14cdd754f91cc6554c9e71929cce7
i : 865c0c0b4ab0e063e5caa3387c1a8741
k : 8ce4b16b22b58894aa86c421e8759df3
p : 83878c91171338902e0fe0fb97a8c47a

= e =

R : e1e1d3d40573127e9ee0480caf1283d6
e : e1671797c52e15f763380b45e841ec32
t : e358efa489f58062f10dd7316b65649e

= 4 =

P : 44c29edb103a2872f519ad0c9a0fdaaa
U : 4c614360da93c0a041b22e537de151eb
c : 4a8a08f09d37b73795649038408b5f33
r : 4b43b0aee35624cd95b910189b3dc231
y : 415290769594460e2e485922904f345d
~ : 4c761f170e016836ff84498202b99827

= 3 =

E : 3a3ea00cfc35332cedf6e5e9a32e94da
j : 363b122c528f54df4a0446b6bab05515
*/

Hagamos cuentas para ver cuantas contraseñas posibles podríamos generar x’D, 9 * 3 * 6 * 2 = 324 contraseñas posibles xD, no podemos utilizar fuerza bruta por que el server nos banearia así que, una vez mas una prueba de fe, armamos nuestra cadena que corresponda a 8-e-4-3-8 tomando los primeros resultados y queda

/*
8 = F
e = R
4 = P
3 = E
8 = N (la segunda letra correspondiente a los hash que comienzan con 8)

FRPEN
*/

Por ultimo le agregamos el ‘ddlr-‘ quedando ‘ddlr-FRPEN‘.

Ahora probamos, tan solo le pasamos el token que creemos es el correcto al metodo de la clase.

 $testing = new Crypt0reto();
 $testing->CheckToken("ddlr-FRPEN");

Y voilà el metodo nos regresa verdadero :), lo probamos en el formulario junto con el correo y la contraseña y efectivamente nos deja entrar al panel y superamos el reto :).

salu2

PD
Este tipo de retos me gustan mucho, me tomo 12 minutos entenderle y hacer la ing inversa, tal vez algunos lo hicieron mas rapido y mas lento, eso no importa lo importantes es tener algo para ejercitar la mente x’D

PD 2
Cada reto dice el numero de personas que lo han superado, este wargames han sido alrededor de 40 personas los que lo han pasado, quiero pensar que es por que no saben programar jeje

Mi nuevo proyecto con Android

Se podrían decir que ayer a las 8 de la noche comenzaron mis vacaciones jeje, fue la hora en que me desocupe del trabajo y de varias cosas que tenia pendiente, sin embargo aun me queda mucho trabajo de la universidad por hacer x’D (bonitas vacaciones -.-“), pero bueno no nos lamentemos xD.

Les quiero mostrar un proyecto (uno de tantos jaja) en el que estoy trabajando y ya casi termino, se trata de una calculadora científica desarrollada para la plataforma de android. para los que piensen que realizar una calculadora es algo sencillo … puede ser, pero hay que tener varias cosas en cuenta, por ejemplo ¿como le haces para que tu calculadora resuelva una expresión algebraica tipo ((a+b)*((c/d)-e)^f)/g xD? en algún post anterior les hable sobre un código que realice en C++ donde tu le dabas una expresión de ese tipo y te regresaba su equivalente en orden postfijo o notación polaca inversa :D, si bien en C++ necesite del uso de pilas y listas creándolas desde cero usando apuntadores x’D, migrar el código a Java fue un juego de niños x’D, claro que en Java ya existen todas esas estructuras de datos, en C++ también pero creo el crear las listas desde 0 me sirvió mucho para dominar el uso de los apuntadores :).

A continuación les dejo una captura de como luce el software:

Cuando el proyecto este terminado (2 semanas mas o menos) planeamos subir nuestra aplicacion al android market (un lugar donde hay muchas aplicaciones android, algo así como la app store) y ponerle un módico precio de 1 usd 🙂 ya que el objetivo no es lucrar con este proyecto sino que la gente conozca y use esta plataforma para teléfonos mobiles.

No he utilizado nada del otro mundo para este proyecto, solamente cosas básicas que ya trae incluida la api de android y algunos componentes custom que tuve que realizar :), ahora lo siguiente que tengo en mente es que mi nuevo proyecto haga uso de una tecnología que cada vez es mas común en la actualidad, gps para android, xD.

Aun que me gusta mucho Java yo sigo siendo un C/C++ fan x’D, lo he comprobado por mi mismo, sabiendo C y C++ los demás lenguajes de programación son muy fáciles :p.

PD lo mas probable es que en mi siguiente post les haga un tutorial acerca de como instalar la api de android en eclipse y el android manager para que tengan su emulador y comiencen a desarrollar xD

salu2

C++ conversion a notacion polaca inversa

Hola, tengo ganas de hacer un post sobre programación :). acabo de terminar mi segundo parcial de la materia de Programación y Estructura de datos y uno de los programas que tuve que entregar esta vez era la famosa conversión a notación polaca inversa o también llamado post orden.

Esa donde tu les das una expresión como a+b y te devuelve ab+, obviamente esta expresión es muy sencilla pero también podemos darle expresiones mas complejas como ((((a+b)*(c/d))^e)*f/g)) y otra razón por lo que realice este programa es debido a que voy a implementarlo para una calculadora cientifica / algebraica / etc que voy a desarrollar para android … pero eso ya sera en java :p

A continuación les dejo el código, decidí ponerlo en copypastecode.com por que si lo pegaba aquí quedaría muy largo el post :p

http://www.copypastecode.com/65845/
http://www.copypastecode.com/65849/
http://www.copypastecode.com/65853/

salu2

Emular comando WC en C


Hola de nuevo, aquí les traigo un código que nos dejaron en la clase de Sistemas Operativos.
Básicamente tenemos que emular la salida del comando wc de linux (el que cuenta el numero de lineas, caracteres o palabras de un archivo).

Pero con unas pequeñas diferencias

  • Recibe n archivos (parámetros)
  • Cuenta el numero de lineas, caracteres y palabras de cada archivo
  • Muestra la suma total de lineas, caracteres y palabras de todos los archivos
  • Cada archivo es manipulado por un thread

#include<sys/types.h>   // fork
#include<unistd.h>      // getpid, getppid
#include<stdio.h>       // printf
#include<sys/wait.h>  // wait
#include<string.h>  // strcat
#include<pthread.h>

//Constantes
#define TIEMPO 1
//Variables globales
int total_lineas = 0;
int total_palabras = 0;
int total_caracteres = 0;

void* manejoArchivo (char* archivo)
{  
  int *a,*b,*c;
  a = &total_lineas;
  b = &total_palabras;
  c = &total_caracteres;
  char x;

  int nlineas = 0, npalabras = 1, ncaracteres = 0;
  
  
  //printf("%s\n",archivo);
  
  FILE *file;
  file = fopen(archivo, "rt");
  if (file == NULL)
  {
    puts("Error al abrir el archivo");
  }
  else
  {
    puts("Accediendo al archivo");
    while (feof(file) == 0)
    {
            //fgets(caracteres,100,archivo);
            //printf("%s",caracteres);
      x = getc(file); // Obtiene un caracter del archivo
      //putchar(x); // Lo despliega en pantalla y continua..
      if(x == 32)
      {
        npalabras++;

      }
      if(x == '\n') 
      {
        nlineas++;
      }
      if(x != '\n' && x != ' ')
      {
        ncaracteres++;
      }
    }
    ncaracteres = ncaracteres - 1;
    if(npalabras > 1){npalabras = npalabras + (nlineas - 1);}
  
    *a = *a + nlineas;
    *b = *b + npalabras;
    *c = *c + ncaracteres;
    
    printf("El numero de lineas del archivo %s es %d\n",archivo,nlineas);
    printf("El numero de caracteres del archivo %s es %d\n",archivo,ncaracteres);
    printf("El numero de palabras del archivo %s es %d\n",archivo,npalabras);
  }
}

int main(int argc, char *argv[])
{
  int n_ficheros = 0;
  int i = 0;
  char *puntero;
  
      if(argc < 2)
      {
          printf("Debes teclear el nombre de almenos 1 fichero, ej:\n");
    printf("./wc_emulado archivo.txt archivo2.txt archivo3.txt\n");
          exit(1);
      }

  n_ficheros = argc - 1; //Numero de ficheros a leer

  //creo tantos threads como ficheros haya pasado por argumentos
  pthread_t ficheros_t[n_ficheros];
  
  for (i=0;i<=n_ficheros;i++)
  {
    sleep(TIEMPO);    
    pthread_create(&ficheros_t[i],NULL,&manejoArchivo,argv[i+1]);
  }

  printf("EL numero total de lineas es: %d\n",total_lineas);
  printf("EL numero total de caracteres es: %d\n",total_caracteres);
  printf("EL numero total de palabras es: %d\n",total_palabras);
  return -1;
  
}

Aquí les dejo el código mas legible listo para que lo compilen.

salu2

Programacion: Threads en C

3GUGFVCXPCUB

De Wikipedia:

[code]]czo4NTA6XCJJbiBjb21wdXRlciBzY2llbmNlLCBhIHRocmVhZCBvZiBleGVjdXRpb24gaXMgdGhlIHNtYWxsZXN0IHVuaXQgb2YgcHJ7WyYqJl19b2Nlc3NpbmcgdGhhdCBjYW4gYmUgc2NoZWR1bGVkIGJ5IGFuIG9wZXJhdGluZyBzeXN0ZW0uIEl0IGdlbmVyYWxseSByZXN1bHRzIHtbJiomXX1mcm9tIGEgZm9yayBvZiBhIGNvbXB1dGVyIHByb2dyYW0gaW50byB0d28gb3IgbW9yZSBjb25jdXJyZW50bHkgcnVubmluZyB0YXNre1smKiZdfXMuIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aHJlYWRzIGFuZCBwcm9jZXNzZXMgZGlmZmVycyBmcm9tIG9uZSBvcGVyYXRpbmcgc3l7WyYqJl19c3RlbSB0byBhbm90aGVyLCBidXQgaW4gbW9zdCBjYXNlcywgYSB0aHJlYWQgaXMgY29udGFpbmVkIGluc2lkZSBhIHByb2Nlc3MuIHtbJiomXX1NdWx0aXBsZSB0aHJlYWRzIGNhbiBleGlzdCB3aXRoaW4gdGhlIHNhbWUgcHJvY2VzcyBhbmQgc2hhcmUgcmVzb3VyY2VzIHN1Y2gge1smKiZdfWFzIG1lbW9yeSwgd2hpbGUgZGlmZmVyZW50IHByb2Nlc3NlcyBkbyBub3Qgc2hhcmUgdGhlc2UgcmVzb3VyY2VzLiBJbiBwYXJ0aWN7WyYqJl19dWxhciwgdGhlIHRocmVhZHMgb2YgYSBwcm9jZXNzIHNoYXJlIHRoZSBsYXR0ZXJcJ3MgaW5zdHJ1Y3Rpb25zIChpdHMgY29kZSkgYW57WyYqJl19ZCBpdHMgY29udGV4dCAodGhlIHZhbHVlcyB0aGF0IGl0cyB2YXJpYWJsZXMgcmVmZXJlbmNlIGF0IGFueSBnaXZlbiBtb21lbnQpLntbJiomXX0gVG8gZ2l2ZSBhbiBhbmFsb2d5LCBtdWx0aXBsZSB0aHJlYWRzIGluIGEgcHJvY2VzcyBhcmUgbGlrZSBtdWx0aXBsZSBjb29rcyBye1smKiZdfWVhZGluZyBvZmYgdGhlIHNhbWUgY29vayBib29rIGFuZCBmb2xsb3dpbmcgaXRzIGluc3RydWN0aW9ucywgbm90IG5lY2Vzc2FyaWx7WyYqJl19eSBmcm9tIHRoZSBzYW1lIHBhZ2UuXCI7e1smKiZdfQ==[[/code]

En resumen

Un thread es un subproceso que corre en paralelo y que comparte la memoria y los recursos con su proceso padre (el proceso padre puede tener varios threads), esto nos permite resolver el problema de la ejecución lineal, y podemos lograr que por ejemplo 2 procesos modifiquen el valor de una misma variable (esto también se puede hacer usando forks u apuntadores :p).

A continuación ejemplifico en un código el rol de un productor y un consumidor, el productor genera Items y el consumidor los consume xD.

Funciona de la siguiente forma, cada thread apunta a una misma localidad de memoria donde va modificando los valores, pero en orden, ya que si no fuera así el valor actual podría ser modificado varias veces por un proceso (el consumidor podría consumir 2 veces seguidas o el productor producir 2 items seguidos).

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
/* Parameters to print_function.
*/

#define BUFFER_SIZE 10
//PRODUCTOS EN EXISTENCIA (memoria que compartiran los threads)
int j = 0; //in
//PRODUCTOS CONSUMIDOS (memoria que compartiran los threads)
int k = 0; //out

//TIPO DE DATO ITEM
typedef struct
{
  int dato;
}item;

//ARGUMENTOS DEL THREAD PRODUCTOR
struct propiedades_prod
{
  item buffer[BUFFER_SIZE];
  //numero de thread creado
  int n;
  int nextProduced;
};
//ARGUMENTOS DEL THREAD CONSUMIDOS
struct propiedades_cons
{
  item buffer[BUFFER_SIZE];
  int nextConsumed;
};

void* productor (void* parameters)
{
  struct propiedades_prod* p = (struct propiedades_prod*) parameters;

  int *creados;
  creados = &j;

  int *consumidos;
  consumidos = &k;
  
  while(1)
  {
    //while((*creados + 1) % BUFFER_SIZE == *consumidos) ;
    while((*creados + 1) == *consumidos) ;
    p->buffer[*creados].dato = p->nextProduced++;
    //printf("Productor: %d creo el producto: %d, %d %d \n",p->n,*creados,p->buffer[*creados].dato,*consumidos);
    printf("Productor: %d creo el producto: %d\n",p->n,*creados);
    *creados = (*creados + 1) % BUFFER_SIZE;
    //*creados = *creados + 1;    
    sleep(1);
  }
}
void* consumidor (void* parameters)
{ 
  struct propiedades_cons* p = (struct propiedades_cons*) parameters;

  int *creados;
  creados = &j;

  int *consumidos;
  consumidos = &k;
  
  while(1)
  {
    while(*creados == *consumidos) ;
    p->nextConsumed = p->buffer[*consumidos].dato;
    //printf("Consumio %d, %d %d \n",*consumidos,p->nextConsumed,*creados);
    printf("Consumio %d \n",*consumidos);
    *consumidos = (*consumidos + 1) % BUFFER_SIZE;
    //*consumidos = *consumidos + 1;    
    sleep(1);
  }
}
/* The main program.
*/
int main ()
{
  pthread_t thread1_id;//productores
  pthread_t thread2_id;//productores
  pthread_t thread3_id;//consumidor

  struct propiedades_prod thread1_prop;
  struct propiedades_prod thread2_prop;
  struct propiedades_cons thread3_prop;

  /* Creamos el 1 thread */
  thread1_prop.n = 1;
  thread1_prop.nextProduced = 0;
  pthread_create (&thread1_id, NULL, &productor, &thread1_prop);
  
  /* Creamos el 2 thread */
  thread2_prop.n = 2;
  thread2_prop.nextProduced = 0;
  pthread_create (&thread2_id, NULL, &productor, &thread2_prop);

  /* Creamos el 3 thread que sera el consumidor */
  thread3_prop.nextConsumed = 0;
  pthread_create (&thread3_id, NULL, &consumidor, &thread3_prop);

  pthread_join (thread1_id, NULL);
  pthread_join (thread2_id, NULL);
  pthread_join (thread3_id, NULL);
  return 0;
}

Para compilar el programa lo pueden guardar por ejemplo como thread.c y desde la shell de linux escriben:

gcc -lpthread thread.c -o thread

salu2