jueves, 31 de diciembre de 2009

Criptograma 30/07/09: Solución

Viendo que acaba el año y el criptograma continúa inexpugnable, aquí os dejo la solución.

CIFRADO:
BPJTALUJBPUPRFBIISASIYRTJTMSAKGMCPCRRPPBALC
AAKTPSOCUPFAPKIFKRNOPRSKABPUPSMDFSOKETCPFCP

CLAVE:
CRISIS

MENSAJE:
EN LOS MOMENTOS DE CRISIS SOLO LA IMAGINACION
ES MAS IMPORTANTE QUE EL CONOCIMIENTO
ALBERT EINSTEIN


Aprovecho para desearos un feliz comienzo de año!

domingo, 25 de octubre de 2009

Criptograma 30/07/09: Pista

Dado que se resiste, y ni el increible Altair consigue dar con la solución, ahí va una pista.

Se trata de un cifrado Playfair.

Criptograma 30/07/09

Criptograma 16/07/09: Solución

Cada par de letras del criptograma correspondía a una letra del mensaje en claro. Tomando esto como hipótesis se podía recurrir a un análisis de frecuencias tradicional.

Enhorabuena Altair.

HO LA BU HO DE MI MA HO LA SI TU MA
E S M E J O R E S T A R

CE TU NA NA TU BI MI CI RU TU MA HO
C A L L A D O Y P A R E

CE HO MA SI MI RU SI MI RE FA HO DO
C E R T O N T O Q U E H

TU BL NA TU MA CI BI HO LA RU HO SS
A B L A R Y D E S P E J

TU MA NA TU LA BI FA BI TU LA BI HO
A R L A S D U D A S D E

GR UX RU UX SI UX GU TU BU HO RU SI
F I N I T I V A M E N T

HO RR MA MI FA YY MI BU TU MA YY
E G R O U X O M A R X

viernes, 4 de septiembre de 2009

ssh en batch sin expect

Ssh y scp no permiten pasar la contraseña como parámetro, lo que complica las cosas a la hora de automatizar tareas. Normalmente se suele recurrir a dos tipos de soluciones: distribuir claves sin password y/o usar expect. La primera no siempre es posible, pues a veces no se tiene el control del servidor. La segunda es más habitual, aunque en ocasiones no se dispone de 'expect', problema con el que me he encontrado recientemente en el proyecto OpenDomo.

 
Como consecuencia he desarrollado la herramienta sshbatch, que permite realizar comandos ssh y scp pasando la passwd como parámetro.

 
Dejo aquí una copia del programa en C y un enlace al grupo de OpenDomo donde expliqué como funciona.


 

domingo, 16 de agosto de 2009

Cómo funciona el exploit sock_sendpage()

 
Tavis Ormandy y Julien Tinnes, del equipo de seguridad de Google, han descubierto un bug en el kernel Linux que nadie ha sido capaz de ver en los últimos ocho años. Este bug, que afecta a todas las versiones del kernel desde la 2.4.4 a la 2.4.37.4 y desde la 2.6.0 a la 2.6.30.4 permite escalar privilegios en el sistema. En este artículo vamos a analizar su funcionamiento.


Primer error:
Todo comienza en la función sock_sendpage() situada en net/socket.c. El problema reside en la llamada a sendpage() pues no se ha verificado que el puntero esté inicializado.


static ssize_t sock_sendpage(struct file *file, struct page *page,
              int offset, size_t size, loff_t *ppos, int more)
{
   struct socket *sock;
   int flags;

   sock = file->private_data;

   flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
   if (more)
      flags |= MSG_MORE;

   return sock->ops->sendpage(sock, page, offset, size, flags);
}


A continuación, dejo una copia de la función sock_splice_read() que no tiene nada que ver ni con el bug ni con el exploit, pero nos sirve para ver como se podría haber evitado la vulnerabilidad.  En esta función se verifica el puntero a la función mediante unlikely() antes su llamada.


static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
                 struct pipe_inode_info *pipe, size_t len,
            unsigned int flags)
{
   struct socket *sock = file->private_data;

   if (unlikely(!sock->ops->splice_read))
      return -EINVAL;

   return sock->ops->splice_read(sock, ppos, pipe, len, flags);
}


Segundo error:
Hemos visto que no se verifica si el puntero a sendpage() esta correctamente inicializado. Sera necesario ahora, encontrar situaciones en las que el puntero a la función sendpage() no se haya inicialiado.

Tavis Ormandy y Julien Tinnes en su investigación localizaron deficiencias en la incialización del puntero para la macro SOCKOPS_WRAP, definida en include/linux/net.h, que incluye PF_APPLETALK, PF_IPX, PF_IRDA, PF_X25 y PF_AX25. Tambien encontraron deficiencias en otros protocolos  como  PF_BLUETOOTH, PF_IUCV, PF_INET6 (con IPPROTO_SCTP), PF_PPPOX y PF_ISDN.


Veamos por ejemplo el caso del protocolo bluetooth. En net/bluetooth/bnep/sock.c nos encontramos con la estructura bnet_sock_ops en la que vemos que no se inicializa sendpage con sock_no_sendpage(), por lo que quedará apuntando a NULL.

static const struct proto_ops bnep_sock_ops = { 
        .family         = PF_BLUETOOTH,
        .owner          = THIS_MODULE,
        .release        = bnep_sock_release,
        .ioctl          = bnep_sock_ioctl,
#ifdef CONFIG_COMPAT
        .compat_ioctl   = bnep_sock_compat_ioctl,
#endif
        .bind           = sock_no_bind,
        .getname        = sock_no_getname,
        .sendmsg        = sock_no_sendmsg,
        .recvmsg        = sock_no_recvmsg,
        .poll           = sock_no_poll,
        .listen         = sock_no_listen,
        .shutdown       = sock_no_shutdown,
        .setsockopt     = sock_no_setsockopt,
        .getsockopt     = sock_no_getsockopt,
        .connect        = sock_no_connect,
        .socketpair     = sock_no_socketpair,
        .accept         = sock_no_accept,
        .mmap           = sock_no_mmap
};



El caso de SOCKOPS_WRAP es mas sutil, pues en net/ipx/af_ipx.c todo parece correcto. Podemos ver la inicialización en la última linea.


static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
        .family         = PF_IPX,
        .owner          = THIS_MODULE,
        .release        = ipx_release,
        .bind           = ipx_bind,
        .connect        = ipx_connect,
        .socketpair     = sock_no_socketpair,
        .accept         = sock_no_accept,
        .getname        = ipx_getname,
        .poll           = datagram_poll,
        .ioctl          = ipx_ioctl,
#ifdef CONFIG_COMPAT
        .compat_ioctl   = ipx_compat_ioctl,
#endif
        .listen         = sock_no_listen,
        .shutdown       = sock_no_shutdown, /* FIXME: support shutdown */
        .setsockopt     = ipx_setsockopt,
        .getsockopt     = ipx_getsockopt,
        .sendmsg        = ipx_sendmsg,
        .recvmsg        = ipx_recvmsg,
        .mmap           = sock_no_mmap,
        .sendpage       = sock_no_sendpage,
};


Sin embargo, si estudiamos con detenimiento la macro SOCKOPS_WRAP en include/linux/net.h vemos que mietras otras llamadas se inicializan correctamente, no se realiza la inicialización de sendpage.
No pego el código por que es demasiado largo, consultar en include/linux/net.h y ver que la última inicialización es la de mmap(), olvidando sendpage().



Cómo explotarlo?
Lo primero que necesitaremos para explotar esta vulnerabilidad es una función que podamos ejecutar en espacio de usuario que use sock_sendpage(). Hay muchas funciones que lo hacen, una de ellas es sendfile().



Tavis Ormandy y Julien Tinnes y proponen como secuencia válida de llamadas para forzar el uso de sendpage(), la siguiente:

/* ... */
int fdin = mkstemp(template);
int fdout = socket(PF_PPPOX, SOCK_DGRAM, 0);

unlink(template);

ftruncate(fdin, PAGE_SIZE);

sendfile(fdout, fdin, NULL, PAGE_SIZE);
/* ... */



Cuando se ejecute la función sendpage(), si esta no está inicializada y apunta a NULL, el kernel intentará ejecutar las instrucciones que hay en la dirección 0. Podemos aprovechar esto mapeando la dirección 0 y almacenando allí las instrucciones que queremos que ejecute el kernel. Así, cuando se intente ejecutar sendpage() realmente se ejecutará nuestro código en espacio de kernel. Podremos escalar privilegios haciendo que el código almecando en la dirección 0 ponga nuestros uid a cero (root).

Este tipo de bugs son muy comunes en el kernel Linux y se conocen como bugs por 'NULL pointer dereference'. Ya vimos aquí uno de estos con el exploit vmsplice.


En las referencias dejo un ejemplo de exploit.




referencias:
- http://www.securityfocus.com/archive/1/505751
- http://blog.cr0.org/2009/08/linux-null-pointer-dereference-due-to.html
- exploit: http://www.frasunek.com/proto_ops.tgz

 

miércoles, 5 de agosto de 2009

Criptograma Principiantes 05/08/09


RJ BZR KWPSJHLMHZR CJMJLRLG LAJVJMJZR AL BK NJRNK VZWNK LG PSL BZR UWZOWKNKAZWLR LRMWJTLG UWZOWKNKR, LB UWJNLW UKQKWZ MKWUJGHLWZ PSL UKRKRL UZW KPSJ ALRHWSJWJK BK MJXJBJFKMJZG.

OLWKBA ILJNTLWO

jueves, 30 de julio de 2009

Criptograma 30/07/09

BPJTALUJBPUPRFBIISASIYRTJTMSAKGMCPCRRPPBALC
AAKTPSOCUPFAPKIFKRNOPRSKABPUPSMDFSOKETCPFCP
  

viernes, 24 de julio de 2009

El impresionante Robot Asimo de Honda

 
Empezó siendo un robot torpón que a duras penas andaba. Después nos sorprendió subiendo escalareas... e incluso corriendo. Increible lo que estan consiguiendo los ingenieros de Honda.
 

jueves, 16 de julio de 2009

Criptograma 16/07/09

 

HOLAB UHODE MIMAH OLASI TUMAC ETUNA NATUB IMICI RUTUM
AHOCE HOMAS IMIRU SIMIR EFAHO DOTUB LNATU MACIB IHOLA
RUHOS STUMA NATUL ABIFA BITUL ABIHO GRUXR UUXSI UXGUT
UBUHO RUSIH ORRMA MIFAY YMIBU TUMAY YXXXX
  

 

jueves, 9 de julio de 2009

Comandos útiles para Vim

 
" las funciones de autocompletado buscan en los directorios indicados
: set path=/usr/include,/usr/local/include

" Habilita el coloreado de sintaxis
: syntax on

" habilita el auto indentado
: set autoindent

" habilita el auto indentado inteligente
: set smartindent

" Define 3 espacios para el indentado
:set shiftwidth=3

" Convierte tabulados en espacios. Deshabilitar con :set noexpandtab
: set expandtab     

" Hace que los tabuladores sean de tres espacios
: set tabstop=3 

" Plega bloques delimitados por {{{ }}}. Usando fdm=syntax no se necesitan marcas
: set fdm=marker   

" Establece los nivels de anidamiento para plegar código.
: set foldnestmax=1

" Marca el parentesis/llave que abre y el que cierra al situarse encima.
: set showmatch 

" La marca habilitada con 'showmatch' dura un segundo.
: set matchtime=1 

" Aparecen indicadores con el numero de linea, de columna, etc.
: set ruler 

" Cuando se abre un archivo coloca el cursor en su posicion del ultimo cierre
if has("autocmd")
  au BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$")
    \| exe "normal! g'\"" | endif
endif

" Pinta los resultados de la busqueda
: set hlsearch

" Cierra un bloque delimitado por {{{ }}}. 
" Se abre pulsando el espacio sobre el bloque.
: foldclose        

" Entra en modo insercion a continuacion de la posicion actual


" Entra en modo insercion en la posicion actual


" Deshace los cambios


" Rehace los cambios
:redo 

" Guarda los cambios
:w! 

" Guarda los cambios en el fiechero 'file'
:w! file

" Sale sin guardar
:q!  

" Mueve el cursor al final del fichero
G 

" Mueve el cursor al principio del fichero
gg

" Mueve el cursor a la linea N
N G  

" Entra en modo visual. Seleccion a nivel de columnas.
ctrl + v 

" Entra en modo visual. Seleccion de todo el texto.
ctrl + v v 

" Corta/borra el texto seleccionado
dd 

" Copia el texto seleccionado

" Pega el texto del portapapeles

" Sustituye from por to, pidiendo confirmacion
:%s/from/to/gc 

" Sustituye from por to, pidiendo confirmacion de un texto seleccionado.
:'<,'>s/from/to/gc

" Ir al principio de la linea
0

" Ir al final de la linea
$

" Ir a la palabra siguiente
w
" Busca palabras como la situada debajo del cursor
#

" Abre la pagina man de la función sobre la que se encuentra el cursor
K

" Salta a la definición/declaración de la variable sobre la que se encuentra el cursor
gd

" Salta al parentesis/llave asociado al parentesis/llave sobre el que se encuentra el cursor
%

" Abre una pestaña con el fichero 'file'
: tabnew file

# Salta de una pestaña a otra
gt


" Divide la ventana en dos abriendo el fichero 'file'
: split file

" Salta de una ventana a otra
Ctrl+w w

" Autocompleta la palabra
Ctrl + p
Ctrl + n




lunes, 6 de julio de 2009

Estamos dentro de VMWare?

A continuacion dejo un programa que permite detectar si nuestro servidor se encuentra dentro de una maquina virtual VMWare. Utiliza una tecnica descubierta por Ken Kato que consiste en encontrar el Backdoor I/O port. Este puerto es el que utiliza VMWare para comunicarse con la maquina virtual. Como dicho puerto no existe en un servidor normal su deteccion indica que nos encontramos bajo VMWare.


/*
 * 4tphi-vmchk.c
 * Detects if you are in a VMWare virtual machine.
 *
 * Written by Andrew Hintz 
 * and AAron Walters
 * Fortify Research Laboratories 
 *
 * "Oft at the hives of his tame bees
 * They would their sugary thirst appease."
 *
 * This program is based on info and code from:
 * http://chitchat.tripod.co.jp/vmware/
 * by chitchat_at_lycos.jp
 *
 * Notes:
 * The program can be run as a normal user.
 * We tested the program only in x86 Linux.
 * The m4dn3ss lives on!
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/signal.h>

#if __INTSIZE == 2 /* 16 bit environment */
typedef unsigned int uint16;
typedef unsigned long uint32;
#else /* 32 bit environment */
typedef unsigned short uint16;
typedef unsigned int uint32;
#endif /* __INTSIZE */

void segfault()
{
  printf("Not running inside VMware.\n");
  exit(1);
}

int main()
{
  uint32 verMajor, verMinor, magic, dout;

  signal(SIGSEGV, segfault);

  __asm__ __volatile__ 
   (
   "mov $0x564D5868, %%eax; /* magic number */"
   "mov $0x3c6cf712, %%ebx; /* random number */"
   "mov $0x0000000A, %%ecx; /* specifies command */"
   "mov $0x5658, %%edx; /* VMware I/O port */"
   "in %%dx, %%eax;"
   "mov %%eax, %0;"
   "mov %%ebx, %1;"
   "mov %%ecx, %2;"
   "mov %%edx, %3;"
    : "=r"(verMajor), "=r"(magic), "=r"(verMinor), "=r"(dout)
    );

  if (magic == 0x564D5868) 
  {
    printf("Running inside VMware. ");
    printf("(Version %lu,%lu)\n", verMajor, verMinor);
    /* I'm not really sure what the versions mean. */
  }

  return 0;

}

miércoles, 17 de junio de 2009

OpenDomo visto desde un iPod touch

Dejo una foto de un sistema OpenDomo controlado desde un iPod Touch, en el se accede al sistema de videovigilancia.
Cortesía de Isidro, uno de los desarrolladores principales de OpenDomo.




Enlace original:
http://www.opendomo.com/drupal/node/55

Control de sensores e interruptores con OpenDomo

 
Recientemente he publicado un manual en OpenDomo que explica como controlar sensores e interruptores.
Por fin opendomo puede usarse en sistemas reales, aunque esté todavía en fase alpha.

Dejop un enlace al manual:

¿Cómo controlar sensores e interruptores con OpenDomo y Micropik PS3X8?

 

viernes, 12 de junio de 2009

Criptograma 11/04/09: Solución

   
Se trataba de un autocifrado, cuya clave era nada más y nada menos que "AUTOCIFRADO" ;)

Aquí tenéis un ejemplo de como se hace el cifrado:


SIHEVISTOMASLEJOSESPORQUEESTOYSENTADOSOBREHOMBROSDEGIGANTESISAACNEWTON

AUTOCIFRADOSIHEVISTOMASLEJOSESPORQUEESTOYSENTADOSOBREHOMBROSDEGIGANTES

======================================================================

SCASXQXKOPOKTLNJAWLDARIFINGLSQHSEJUHSKHPPWLBFBUCKRFXMNOZUVGAVEGKTEJMSF


 y un ejemplo de como se descifra:

SCASXQXKOPOKTLNJAWLDARIFINGLSQHSEJUHSKHPPWLBFBUCKRFXMNOZUVGAVEGKTEJMSF

AUTOCIFRADO

===========

SIHEVISTOMA

           SIHEVISTOMA

           ===========

           SLEJOSESPOR

                      SLEJOSESPOR

                      ===========

                      QUEESTOYSEN

                                 QUEESTOYSEN

                                 ===========

                                 TADOSOBREHO

                                            TADOSOBREHO

                                            ===========

                                            MBROSDEGIGA

                                                       MBROSDEGIGA

                                                       ===========

                                                       NTESISAACNE

                                                                  NTES

                                                                  ====

                                                                  WTON




Habéis perdido el interés o es que era muy difícil?! :)

  

domingo, 7 de junio de 2009

Librerías para Visión Artificial

   
Excelente colección de código que implementa diferentes técnicas de visión artificial. Desde algoritmos 'sueltos' hasta librerías completas.

http://www.cs.cmu.edu/~cil/v-source.html

   

miércoles, 13 de mayo de 2009

OpenBSD en el escritorio

 
OpenBSD es un Sistema Operativo centrado en la seguridad. Es muy apreciado en el mundo de los servidores no tan solo por su seguridad, si no por su gran estabilidad y su política de 'corrección' del código.

Desde hace algún tiempo he ido viendo posts de gente que lo usaba como entorno de escritorio. lo que me ha llevado a hacer mis propias pruebas. Esta no es su mejor baza, ni mucho menos. Pero si se quiere una roca como Sistema Operativo, hay que tenerla en cuenta.
 
En este post explico el procedimiento para instalar OpenBSD en el escritorio. No es Ubuntu, así que no esperéis nada parecido, pero tampoco resulta excesivamente complicado. Usaré OpenBSD 4.5 (la última en el momento de escribir el post) en una arquitectura AMD64. El que tenga otra arquitectura solo tendrá que sustituir en las URL amd64.


Instalación del sistema base

Descargamos la imagen y la quemamos en un CD:
Arrancamos desde el CD y seguimos los pasos que se nos indican. En general, aunque es unainstalación en modo texto, no supone mucho problema: configuración de teclado, red, etc.

Lo que sí puede resultar difícil si no se está acostumbrado es el particionado de disco. Si no se sabe lo que se esta haciendo lo mejor es usar el disco entero para OpenBSD, o la pérdida de datos estará garantizada.

Esta parte está explicada en detalle en el siguiente enlace, en el punto 4.5.2:

 

Selección de paquetes
Durante la instalación se nos solicitarán los paquetes que queremos instalar. Los seleccionaremos todos, o como mínimo, los paquetes relacionados con las X.

 

Ejecutando las X
En estos momentos tenemos un sistema base con las X, las cuales podemos ejecutar mediante el comando startx. Si no funcionan correctamente tendremos que revisar /etc/X11/xorg.conf y adaptarlo a nuestro sistema.

 

Instalando GNOME

Habrá quien quiera instalar KDE. Googlead un poco, no creo que sea muy diferente. Aquí instalaremos GNOME

Para poder instalar binarios de forma cómoda tendremos que establecer la variable de entorno  PKG_PATH. Lo haremos añadiendo:

export PKG_PATH=ftp://ftp.openbsd.org/pub/OpenBSD/4.5/packages/amd64/

en el fichero ~/.profile. Así quedara configurada al reiniciar.

Ahora, para instalar GNOME haremos:
$ pkg_add gnome-session
 
Y para que GNOME arranque al iniciar el sistema pondremos en /etc/rc.local
/usr/local/bin/gdm -nodaemon


Creación de usuarios


Ejecutaremos:
$ adduser
Este nos irá preguntando lo típico: nombre de usario, shell a usar, contraseña, etc.
Si queremos que el usuario se pueda convertir en root con el comando 'su' necesitaremos añadirlo al grupo wheel. Lo haremos con:

$ moduser -G wheel usuario



Y con esto, ya tenemos un espléndido OpenBSD en nuestro escritorio.

Solo faltará instalar los paquetes que creamos necesarios como:

$ pkg_add openoffice-3.0.1p2
$ pkg_add firefox-i18n-es-ES-3.0.6

etc.

martes, 12 de mayo de 2009

Factorización en tiempo polinómico!?

  
Claus P. Schnorr ha presentado en el Eurocrypt 2009 "Average Time Fast SVP and CVP Algorithms: Factoring Integers in Polynomial Time".

Habría que ver el impacto que puede tener este documento en la criptografía de clave pública. Pero si es correcto, podría representar el fin de RSA.

Se ha iniciado un hilo de discusión en sci.crypt.research.

  

sábado, 9 de mayo de 2009

Free Mathematics Books

Estupenda colección de libros de matemáticas distribuidos gratuitamente:

http://www.e-booksdirectory.com/mathematics.php

jueves, 7 de mayo de 2009

The P-versus-NP page

Dejo un enlace a una página estupenda que recopila todos los intentos de demostrar el problema P?=NP.

http://www.win.tue.nl/~gwoegi/P-versus-NP.htm

Después de todo, hay un suculento premio para el que lo consiga.

martes, 5 de mayo de 2009

Criptograma 11/04/09

Pista: Autocifrado


 SCASXQX KOPOKTL NJAWLDA RIFINGL SQHSEJU 
HSKHPPW LBFBUCK RFXMNOZ UVGAVEG KTEJMSF

 

jueves, 23 de abril de 2009

Criptograma 07/04/09: Solución

Una combinación de transposición y sustitución. Primero había que transponer las letras del criptograma:


TRJVMFPTTFIEPFNCCFSFFTTDIVBDOIOBBSDZJNEJPSDBPSOEEPPTTWPFKDP
FTTEBPOTUPFSTFEKFBITBZCVMOBBSTNPBMEBBMNFFOEHFVTBFFWTJQHPOSF


Cogiendolas con un periodo de dos: una si, una no, ... Obteníamos:


TJMPTIPNCSFTIBOOBDJEPDPOEPTPKPTEPTPSFKBTZVOBTPMBMFOHVBFTQPS
RVFTFEFCFFTDVDIBSZNJSBSEPTWFDFTBOUFTEFIBCMBSNBEBNFEFTFWJHOF


Finalmente con un desplazamiento de una letra en el abecedario inglés:


SILOSHOMBRESHANNACIDOCONDOSOJOSDOSOREJASYUNASOLALENGUAESPOR
QUESEDEBEESCUCHARYMIRARDOSVECESANTESDEHABLARMADAMEDESEVIGNE

miércoles, 22 de abril de 2009

Evitar timeouts en conexiones ssh

 
echo "ServerAliveInterval 60" >> ~/.ssh/config

Y se acabaron los timeouts por inactividad.

Gracias Jordi!

martes, 21 de abril de 2009

Criptograma 05/04/09: Solución

Observando los números con atención se veía que 'todos' se podían descomponer en, únicamente, dos números primos. Dado que había un total de 26 números primos, se podía deducir que había un primo por letra del abecedario inglés.

La asignación era la siguiente:

A: 002, B: 003, C: 005, D: 007, E: 011, F: 013, G: 017, 
H: 019, I: 023, J: 029, K: 031, L: 037, M: 041, N: 043, 
O: 047, P: 053, Q: 059, R: 061, S: 067, T: 071, U: 073, 
V: 079, W: 083, X: 089, Y: 097, Z: 101

El problema añadido del criptograma, era que al asignar cada letra a su número primo correspondiente las letras podían quedar desordenadas, pues dependía del orden en que se colocaban los dos factores. Aun así, después de la sustitución, no ser dificil finalizar el criptograma.

Despues de factorizar los números originales quedaba como:

37  2  5  23  11  43  5  23  2  43  47  43  47  67  19  2
11  43  67  11  43  2  7  47  2  73  43  67  23  37  2  37
47  5  73  61  2  11  67  47  43  47  37  47  41  2  67  67
73  3  37  23  41  11  7  11  37  2  23  43  71  11  37  23
17  11  43  5  23  2  11  7  17  2  61  2  37  37  2  43
53  47  11 101

Y finalmente, después de sustituir:

LACIENCIANONOSHAENSENADOAUNSILALOCURAESONO
LOMASSUBLIMEDELAINTELIGENCIAEDGARALLANPOEX

lunes, 20 de abril de 2009

Catástrofe!!

Oracle compra Sun Microsystems, y con ella MySQL, Java, OpenOffice, OpenSolaris, VirtualBox, ...

Esta noche voy a tener pesadillas.

domingo, 19 de abril de 2009

Criptograma 26/03/09: Solución

 
Volvíamos con Kasiski, esta vez con una clave un poquito más larga...

VRBCI UGJZB JMCJK EVMBF ZSCNX
NIWAN CEGYI UVIQV FRWUZ ANWEH
VLPAT EUQUH RPIIW ONWQB EWXXX
RCVAN CCDHH PKMBF FTJYL HCKSE
EMCAN NFIBB HYTLB EPLCI ZZXLY
UGZOQ VPGYU APWBB RPPAX NVMBB
XYHNT QWMIA FXTHZ AUCDE FTXUY
EPWOY RKTHM EPWUH JXPKN EWVCG
VRVUL URZCC ZEUYM OFWGG FHDMF
EOQFN EQPFL ANDCY FWRCX GQASF
EEIOK ANIPP UIUAA ILSZZ FTFLL


CLAVE: REPUTACION



ENMIP UEBLO SINPR ETENS IONTE
NGOMA LAREP UTACI ONHAG ALOQU
EHAGA ESIGU ALTOD OLOCO NSIDE
RANMA LYONO PIENS OPUES HACER
NINGU NDANO QUERI ENDOV IVIRF
UERAD ELREB ANONO ALAGE NTENO
GUSTA QUEUN OTENG ASUPR OPIAF
ENOAL AGENT ENOGU STAQU EUNOT
ENGAS UPROP IAFET ODOST ODOSM
EMIRA NMALS ALVOL OSCIE GOSES
NATUR ALABC DEFGH IJKLM OPQRS




 

viernes, 17 de abril de 2009

Criptograma 20/03/09: Solución

Como ya se decía en la pista del criptograma se trataba de un cifrado Vigenere susceptible al ataque Kasiski.



BEAOSERIPMXAQUTLXTDMTLDDTCXABIEAEABEAOSIYEGOCMJCWAHVTCTS
NLDOAVXDPBPMJCWAHMPSIRPBPJPNXNDNDTTPXECSTSFUTSXNSICEGOKI
KIGAHJJNIATLTSUUTROONEAAWOGRDAQRTTTPPSDYPVTRPSROBOAAKISA
IESEEAGAQUTNDSBOBECTDSIEPLOAGAHSDBGEAOHPDBGEHYBEOQJICOHQ
JECOWACSPBXDDDTSROALPRBEAOSERIPMXAQUTLXTDMTLDDTCXABIEAEA
BEAOSIYEGOCMJCWAHVTCTSNLDOAVXDPBPMJCWAHMPSAAKISATSAURHPD
TSEIPDPDPNPDXEIEPYJDPAHICOBAHYHIIUHOAOCOPDTLPNIAHTTIGACD
TJPNSOPTGAHAIRPSPNSABURHPCWOSAAESUGOAAIITRGAIOSATLHOAITL
BAGSDNEAGAPQJEALDSFUTHPNHAQISOHECTPRHEHOQRTLDSSEBAHMTLDD
TCXABIPBJEAIIOBEAOSERIPMXPPPPMTLDDXJTRDNBURHPSKEREHYAOWE
DLKISASOHITMERTMPSYOHEPGJSIICGDYIIHOAOPBRDTFVHXJZLBNDPFR



CLAVE : PAPA

MELODECIAMIABUELITOMELODECIAMIPAPAMELODIJERONMUCHASVECES
YLOOLVIDABAMUCHASMASTRABAJANINONOTEPIENSESQUESINDINEROVI
VIRASJUNTAELESFUERZOYELAHORROABRETEPASOYAVERASCOMOLAVIDA
TEDEPARABUENOSMOMENTOSTEALZARASSOBRELOSPOBRESYMEZQUINOSQ
UENOHANSABIDODESCOLLARMELODECIAMIABUELITOMELODECIAMIPAPA
MELODIJERONMUCHASVECESYLOOLVIDABAMUCHASMASLAVIDAESLUCHAD
ESPIADADANADIETEAYUDAASINOMASYSITUSOLONOADELANTASTEIRAND
EJANDOATRASATRASANDAMUCHACHODALEDUROLATIERRATODAELSOLIEL
MARSONPARAAQUELLOSQUEHANSABIDOSENTARSESOBRELOSDEMASMELOD
ECIAMIABUELITOMELODECIAMIPAPAMELODIJERONMUCHASVECESYLOHE
OLVIDADOSIEMPREMASJOSEAGUSTINGOYTISOLOABCDEFGHIJKLMNOPQR

lunes, 13 de abril de 2009

Vectores Dinámicos en C

Si queremos usar vectores dinámicos en C necesitamos recurrir a funciones de manejo de memoria de la familia *alloc(). En este post explico cómo hacerlo de forma sencilla y añado algunas macros que facilitan la tarea.


Para empezar necesitaremos declarar el vector. Lo haremos como apuntador a NULL, creando así, un vector vacío. Necesitaremos también una variable que almacene el tamaño del vector, es decir, la cantidad de elementos que contiene.

Como ejemplo crearemos un vector de números enteros.

int *v = NULL;
size_t v_size = 0;



Tenemos un vector vacío, por lo que el siguiente paso no puede ser otro que añadir elementos. Lo haremos mediante realloc(), función que permite reasignar el tamaño reservado en memoria.



v_size++;
v = realloc(v, sizeof(int)*v_size);
v[v_size-1] = 5;


De esta manera podemos añadir tantos elementos como creamos oportuno. El acceso a ellos se realizará mediante la tradicional indexación de vectores v[i], donde i es el índice del vector. Así podremos acceder al contenido de las diferentes posiciones del vector tanto para leerlas como para escribir en ellas.

Finalmente, tendremos que liberar la memoria asignada al vector mediante la función free().


free(v);



A continuación pego un ejemplo completo del uso de vectores dinámicos con las sentencias comentadas anterioremente. Añado tambien un ejemplo de uso de la función qsort() que permite ordenar el vector.

#include <stdio.h>
#include <stdlib.h>


int cmp(const void *a, const void *b)
{
   int *ia, *ib;

   ia = (int *) a;
   ib = (int *) b;

   return (*ia - *ib);
}

int main()
{
   /* Declaracion del vector y de su tamaño */
   int *v = NULL;
   size_t v_size = 0;


   /* Añade un elemento al vector con valor 5 */
   v_size++;
   v = realloc(v, sizeof(int)*v_size);
   v[v_size-1] = 5;

   /* Añade un elemento al vector con valor 3 */
   v_size++;
   v = realloc(v, sizeof(int)*v_size);
   v[v_size-1] = 3;

   /* Añade un elemento al vector con valor 1 */
   v_size++;
   v = realloc(v, sizeof(int)*v_size);
   v[v_size-1] = 1;

   /* Mofifica el valor del primer elemento del vector */
   v[0] = 2;

   /* Ordena el contenido del vector */
   qsort(v, v_size, sizeof(int), cmp);

   /* Muestra los elementos del vector */
   int i;
   for(i=0; i<v_size; i++)
      printf("%d ", v[i]);
   printf("\n");

   /* Libera la memoria asignada */
   free(v);

   return 0;
}




La sintaxis usada es un poco engorrosa, principalmente cuando se trata de añadir elementos a un vector. Esto puede solucionarse mediante el uso de macros. A continuación pego un ejemplo usando macros. En el puede verse también cómo pasar un vector como parámetro a una función.


#define VECTOR(v_var,v_size_var,type) \
   type *v_var = NULL; \
   size_t v_size_var = 0;

#define VECTOR_ADD(v_var,v_size_var,type,value) \
   (v_size_var)++; \
   v_var = realloc(v_var, sizeof(type)*(v_size_var)); \
   v_var[v_size_var-1] = value;
   
#define VECTOR_FREE(v_var) if(v_var) free(v_var);


void add_elements(int *v, size_t *v_size)
{
   VECTOR_ADD(v, *v_size, int, 3);
   VECTOR_ADD(v, *v_size, int, 5);
   VECTOR_ADD(v, *v_size, int, 7);
}  

int main()
{
   VECTOR(v, v_size, int);
   VECTOR_ADD(v, v_size, int, 2);
   
   add_elements(v, &v_size);

   int i;
   for(i=0; i<v_size; i++)
      printf("%d ", v[i]);
   printf("\n");
   
   VECTOR_FREE(v);

   return 0;
}




Para finalizar, solo recordar que el punto fuerte de los vectores es el acceso directo a los elementos (solo es necesaria una operación - O(1) ). Esto permite por ejemplo ordenar los elementos del vector a gran velocidad.

Por el contrario son costosas las inserciones de elementos. Pueden añadirse con facilidad al final, pero insertar un elemento en el medio, obliga a recolocar todos los demás elementos. Si se requiere una estructura de datos que permita estas operaciones es mejor recurrir a las listas dinámicas.


viernes, 10 de abril de 2009

Criptograma 01/04/09: Solución

Se trataba de un cifrado de sustitución homofónica que usaba dos valores para cada letra. A contnuación, la solución propuesta por Izzec.
Mis felicitaciones, Izzec!
dEbo decir que soy un priNcipiante en esto, y que a pesar de Haberme informadO sobRe Algunos aspectos de la criptografía tengo que decir que no tengo aún una haBilidad adqUirida. aún así mE gusta, y con coNstancia, en mi tiempo libre le dedico lo suficiente pAra intentar saber semana tras semana (aunque siemPre se nOs adelante altaiR) que nos escondes en los cripTogramas, daniel.
    bUeno el método que seguí fue Bastante sencilLo la verdad. en primera instancia hice una lectura rápida de los númerOs, y me di cuenta que todos eran curiosamente impares. alGo me Hizo pensar en esE momento que serían números impares sustituidos por letras. así que me puse a contar caDa númEro impar las veces que aparecía en dicho criptograma (esto no me serviría de mucho más adelante). hecho esto los clasifique por orden ascendente 002 (el único que no era impar) -003-005, etc. y me di cuenta que eran primos.así que los reordené todos de forma ascendente de tal forma que quedasen cuadrados con el alfabeto (sin utilizar la ñ). adjunto eJemplo;

    002   A     003   b    005   c     007   D   011   e     013   f     017   g    019   h    023   i      029   j      ¿? k         037   l

    041   m    043   n    047  O     053   p    059   q    061   r     067  s      071   t     073   U    ¿? v         ¿? w        089  x

    097  y     ¿? z         103  a      107  b     109  c      113  d     127  e      ¿?   f        ¿?  g        139 h      149  i       ¿?   j

    ¿?   k      163 l        167 m      173 N      179 o      ¿?  p        191  q     193  r      197  s      199  t      211  u     ¿?   v

    ¿?  w      ¿?  x       233  y     ¿?   z      241  a      ¿?   b     257  C     263  d     269  e      ¿?  f       ¿?  g      ¿?  h

    283  i       ¿?   j       ¿?  k       311  l       313  m     317  n     331  o     ¿?  p        ¿?  q       349  R      353  s      359  t

    367  u
    Y luego lo demás fue cambiar las cifras Por las leTras. El texto queda así:

    l a d i f e r e N c
    i a q u e e x i s t

    e e n t r e l o s h

    o M b r e s n e c I

    o s y l o s h o m B

    r e s d e t a L e n

    t O s u e l e s e r

    q u e l o s p r i m

    e r o s d i c e n n

    e c e d a d e s y l

    o s s e G u n d o s

    l a s c o m e t e n

    m a r i a n o j o s

    e d e l a r r a


Lo habéis leído con atención? ;)

miércoles, 8 de abril de 2009

Búsqueda de Patrones en Cifrados de Sustitución

Cuando se realiza el criptoanálisis de un cifrado de sustitución monoalfabética, suele ser necesario encontrar palabras que encajen en ciertos patrones de letras. Por ejemplo, en un patroón como AACBBDA encajarían palabras como arrollar, guerrilleroencarrillar. Muchas veces, para encontrar estas palabras no es suficiente con nuestra imaginación y conocimiento de la lengua, por lo que suele ser útil recurrir al ordenador.
A continuación, pego un programa que permite realizar este tipo de búsquedas de forma muy sencilla.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void remove_nl(char *str)
{
   if(str[strlen(str)-1]=='\n')
      str[strlen(str)-1]=0;
}

int match_pattern(char *match, const char *pattern, size_t pattern_len)
{
   int i,j;

   for(i=0; i<pattern_len; i++)
   {
      for(j=i; j<pattern_len; j++)
      {
         if(pattern[i]==pattern[j])
            if(match[i]!=match[j])
               return 0;

         if(pattern[i]!=pattern[j])
            if(match[i]==match[j])
               return 0;
      }
   }

   return 1;
}

int main(int argc, char *argv[])
{
   char word[64];
   char *pattern = NULL;
   int pattern_len = 0;

   if(argc!=3)
   {
      printf("Usage: %s [word list] [crypto-pattern]\n\n", argv[0]);
      return 0;
   }

   pattern = argv[2];
   pattern_len = strlen(pattern);

   FILE *file = fopen(argv[1], "r");
   if(!file)
   {
      perror("fopen()");
      exit(0);
   }

   while(!feof(file))
   {
      fgets(word, sizeof(word), file);
      remove_nl(word);

      char *substr = word;

      while(strlen(substr)>=pattern_len)
      {
         if(strlen(substr)<pattern_len)
            break;

         char match[pattern_len];
         strncpy(match, substr, pattern_len);
         match[pattern_len]=0;

         if(match_pattern(match, pattern, pattern_len))
            printf("%s\n", word);

         substr++;
      }
   }


   fclose(file);

   return 0;
}




Para el patrón del ejemplo bastarí con compilar el programa con:

$ gcc pattern.c -o pattern

Y ejecutarlo con:

$  ./pattern ../dict/spanish AACBBDA
acurrullar
aporrillarse
arrollar
arrullar
aturrullar
barrillar
barrillera
barrillero
carrillera
cerrillar
churrillera
churrillero
churrullera
churrullero
corrillera
corrillero
desarrollar
descarrillar
emborrullarse
emparrillar
encarrillar
guerrillero
marrullera
marrulleria
marrullero
pantorrillera
zarzaparrillar

Espero que os sirva para vuestros cripoanalisis!

martes, 7 de abril de 2009

Criptograma 07/04/09

TRJVMFPTTFIEPFNCCFSFFTTDIVBDOIOBBSDZJNEJPSDBPSOEEPPTTWPFKDP
FTTEBPOTUPFSTFEKFBITBZCVMOBBSTNPBMEBBMNFFOEHFVTBFFWTJQHPOSF

domingo, 5 de abril de 2009

Criptograma 05/04/09

0074 0115 0473 0115 0086 2021 3149 0038 0473 0737 0086
0329 0146 2881 0851 0074 0235 4453 0022 3149 2021 1739
0082 4489 0219 0851 0451 0077 0074 0989 0781 0621 0187
0215 0046 0077 0034 0122 1369 0086 2491 1111

Podéis enviar vuestro procedimiento de solución a dlerch (en gmail) o publicar un comentario.

The General Number Field Sieve

Actualmente, el algoritmo de factorización más rápido que existe. Dejo aquí mi colección de papers.

Antecedents
- The Factorization of the Ninth Fermat Number , A.K. Lenstra, H.W. Lenstra, M.S. Manasse, and J.M. Pollard (1993).
- The Number Field Sieve , A. K. Lenstra, M. S. Manasse, J. M. Pollard (1990).

Introduction to the GNFS algorithm
- An Introduction to the General Number Field Sieve , Matthew E. Briggs (1998).
- A Beginner's Guide To The General Number Field Sieve , Michael Case.
- The Number Field Sieve , Peter Stevenhagen.
- The Number Field Sieve , Steven Byrnes.

Polynomial Selection
- Polynomial Selection for the Number Field Sieve Factorisation Algorithm , Brian Murphy (1999).
- On quadratic polynomials for the number field sieve , Brian Murphy and Richard P. Brent (1998).
- Rotations and Translations of Number Field Sieve Polynomials Jason Gower (2003).
- The multiple-lattice number field sieve , Daniel J Bernstein.

Sieve
- Continued Fractions and Lattice Sieving , Jens Franke, Thorsten Kleinjung.

Filtering
- Strategies in filtering in the number field sieve , S. Cavallar (2000).

Linear Algebra
- Solving Large Sparse Linear Systems over Finite Fields , B. A. LaMacchia and A. M. Odlyzko (1991).
- A Block Lanczos Algorithm for Finding Dependencies over GF(2) , Peter L. Montgomery.
- Solving large sparse linear systems over finite fields , B. A. Lamacchia, A. M. Odlyzko (1991).

Square Root
- A Montgomery-like square root for the Number Field Sieve , Phong Nguyen, Ecole Normale Superieure (1998).
- Computing a Square Root for the Number Field Sieve , Jean-Marc Couveignes (1993).
- Square Roots of Products of Algebraic Numbers , Peter L. Montgomery.

viernes, 3 de abril de 2009

Cómo diferenciar entre cifrados de transposición y de sustitución

  
En criptoańalisis de cifrados clásicos, el primer problema con el que se enfrenta el criptoanalista es el desconocimiento del tipo de cifrado usado en el criptograma.
  
En criptografía clásica existen dos grandes grupos de sistemas de cifrado: los cifrados de sustitución y los cifrados de transposición.
  
Los primeros son aquellos en los que cada letra es sustituida por otra letra o símbolo. En los segundos, en cambio, no hay sustitución, pues solo se realiza una mezcla de las letras.
  
Mientras que en el caso de los cifrados de sustitución, nuestro objetivo será averiguar que símbolo corresponde a cada letra, en los cifrados de transposición tendremos que encontrar el patrón de 'mezcla' utilizado.


  
Características del Texto Cifrado:

Dado que en los cifrados de transpoción, únicamente se mezclan letras, en el resultado cifrado tendremos las misma letras que en el mensaje en claro. Así pues se mantendrán los porcentajes de vocales y de consonantes de la lengua usada.
Sin embargo, en los cifrados de sustitución, cada símbolo será sustituido por otro, de manera que no se mantendrá la distribución de vocales y consonantes.


 
Técnicas disponibles:

Las características del texto cifrado nos ofrecen dos técnicas para distinguir entre  cifrados de sustitución y cifrados de transposición: El porcentaje de vocales y el análisis de frecuencias.

El porcentaje de vocales en castellano, ronda el 47%. Así pues, si contamos las vocales y las consonantes del criptograma y nos encontramos con un procentaje similar, sabremos que no se han realizado sustituciones y que con alta probabilidad nos encontramos ante un cifrado de transposición.
  
Si, por otra parte, los porcentajes que obtenemos están lejos del 47%, probablemente se trate de un cifrado de sustitución.
  
Para afiinar un poco más realizaremos un análisis de frecuencias. Sabemos que, por ejemplo, en castellano, las letras más frecuentes son la 'a' y la 'e'. Si estas se corresponden con la 'a' y la 'e' del criptagrama, más probabilidades a favor del cifrado por transposición. Si por el contrario, las más frecuentes son letras de baja frecuencia en castellano, como la 'x' o la 'k', dificilmente se tratará de un cifrado de transposición.  Podremos suponer entonces que letras de aparición frecuente han sido sustituidas por 'x' y 'k'.



Ejemplos de Criptogramas Anteriores:

Vamos a apoyar la información expuesta con algunos criptogramas  propuestos anterioremente. 
OTUOBLBNOA LIERYBHAEO ATAMSIEOYS AHRNPIRMUI URNPBENCIP
NIMOAUNEAR UJALBREAUN EAEZUNSVUA RLTQETABAM ASTCASAESA
SHSOBUVNAA IZCUAAEDON SONOBAUNYA UORALMNVES XDETOOSLNO
CORDDSTOAN RAAOTODHD

El porcentaje de vocales es del 45%.
Las letras más frecuentes son la 'a', la 'o', la 'n', la 'e' y la 's'.
Así pues, queda claro que se trata de un cifrado de transposición.
ADZMO YHADG TIYMM ZCAUG CZYJA DYJTG LKSKM DKOZJ
OKEIG JHKAC EZSGQ HYZOG EZMVG HAZSG MYJOZ MNJEG
SZENH GHEIZ JHKDG COMKS ZCCAB IYFAJ GSZMY JOGMN
JZEON FNHGH CNACO ZEYME GHADY JABNT KVZHY VGEAM
DYEMA YMPIA YCOZD ARKCC NYCOG DARKC ZSGMY JOZMP
IACYA COGEY MEZSK JAMEY UKCSG MZGOM ZAMGD YJABN
TKTKD SYZMG DAJYB NTKEI ZJHKA COGHY CKMHA JZHKS
MYSGM ZMCAE KJOMG YDEIZ JHKAC OGCYT IMKAJ OKHZC
SGMOY CAFNO ZMDYH IMGJO AIJON YBSKE IZJHK ACBGC
XIYMO ACNOI KSKJY JOAON YJAIJ OYBSA MZBYJ OKEKD
AMNEK NJOYJ OGNMM NOZMD ACNYC GMMKT ZJOAO MGOZH
YXKBA JOGMC IYTKO NCBKC NDZCO MKSGC AJYBN TZCCA
VGDDZ JUNYJ SMASG MZHGC OMZCI JGMYK MTZJN QGENK
JNJOA JOZHY CKMHA JGMDZ CCNYC OGJIJ NHZCC NABUM
GDZHN CYJCN KJAJO MYCIC XNDGC ZOGEZ GDAJY BNTKE
IZJHK JKACO GSMYS ZMGHK WZSGM AEYEI ZJHKJ KOAYC
SAMGY COZCC KJDGC EDZFA CHYDG FNEOK MNZSG MZADY
COMGO ATZCI JOQIY DGMOA HYDZT IAMMG

  
El porcentaje de vocales es del 23%.
Las letras más frecuentes son la 'm', la 'z', la 'g', la 'y' y la 'a'.
Así pues, queda claro que se trata de un cifrado de sustitución.
  
 

jueves, 2 de abril de 2009

Criptograma 28/03/09: Solución

     
El criptograma corresponde a una doble transposición. Ha sido resuelto únicamente por Altair, que me ha enviado su solución. La adjunto a continuación.
En primer lugar decirte que no soy experto en criptografia, simplemente me gusta y paso algún buen rato intentando descifrar mensajes. He leído un poquito a nivel básico, pero no tengo mas formación sobre estos temas, ni tampoco herramientas potentes, es mas casi no tengo herramientas.


Lo que si tengo claro es que para descifrar un mensaje, se ha de tener en cuenta todo lo que sepamos sobre el mensaje, las circunstancias en las que el mensaje se genera, la personalidad y gustos de autor, en fin, cualquier cosa relacionada con lo que queremos descifrar.


En este caso, los dos mensajes anteriores, eran poesías que había cantado Paco Ibáñez, y en los comentarios se habían hecho referencias a el y a los poetas que los habían compuesto, incluso yo te había hecho un comentario sobre la canción “A galopar”.

Esto era algo que tenia en mente cuando comencé con el mensaje. Miré la frecuencia de aparición de las letras, y ví podía cuadrar con la frecuencia normal en castellano, pero probando sustituciones no llegaba a nada.


Examinando el mensaje con atención ví “fragmentos” de palabras SONOBA, CORD, UJALBR, RNPBENCIP … Esto me hizo suponer que lo que habías hecho era mover las letras de su posición inicial. ¿Pero como?, probaba a mover las columnas de lugar pero no me salía nada en claro, las filas no creía que estuvieran cambiadas, porque todos los “fragmentos” los habia encontrado en horizontal. Y aquí es donde viene la suerte, o la intuición, como quieras llamarlo. Los fragmentos, me hicieron pensar en “erase se una vez un principe malo …..”. Estaban prácticamente las palabras Bruja, CORDeros, Soñaba (Sonoba) etc. En ese momento estaba casi convencido de que el texto era ese poema, pero no sabia por donde empezar con el método de cifrado, porque las trasposiciones que probaba no me llevaban a ninguna parte. Para asegurarme de que el texto era el que yo creía, busque el poema y calculé la frecuencia de aparición de cada letra. Solo había tres pequeñas diferencias, en el cripto habia una N mas que en el poema, en el el poema había una Ñ que no estaba en el criptograma, y en el criptograma había una X. Las dos primeras diferencias estaban claras, no habias usado un alfabeto con Ñ, tu alfabeto era de 26 letras y la Ñ la codificabas como N. Con esto, la frecuencia de las letras cuadraba perfectamente excepto por la X.


Pensé que la X podía ser algún signo de puntuación, un punto, un guión, algo así, pero no me convencía porque en el poema original había mas de un signo, y no tenia sentido que pusieras uno si y los otros no. La otra alternativa era un carácter de relleno, la X. Esta última posibilidad me llamo la atención, porque normalmente un carácter se pone porque nos faltan letras para completar un grupo, y en este caso el ultimo bloque solo tenía 9 letras y no 10 como los demás. Era contradictorio. Pensé que podía ser una variante del que habías puesto de la rejilla de Cardano, pero tampoco encontraba un patrón. Además, las letras no formaban un cuadrado …
Aquí me quedé atascado, hasta que se me ocurrió contar las letras que había y ¡Bingo¡ 169 caracteres, o sea 13x13.


Lo reordené en un cuadrado de estas dimensiones descarte rapidamente la rejilla. Al mirar el mensaje ordenado así, estaba claro que habías jugado con las filas y las columnas. Como estaba seguro de cual era el texto ya fue fácil reordenar las columnas y las filas.



Más o menos, este fue el proceso que seguí.

Adjunto también el proceso usado en el cifrado, paso a paso.
Para poder realizar una transposición doble, basada en una clave, es necesario poder representar el texto en un cuadrado. El lado del cuadrado se corresponderá con la longitud de la clave:6 1 7 12 2 4 5 3 13 8 9 10 11.
Realizamos primero la transposición de las columnas:



6 1 7 12 2 4 5 3 13 8 9 10 11
======================================
E R A S  E U N A  V E Z  U N
L O B I  T O B U  E N O  A L
Q U E M  A L T R  A T A  B A
N T O D  O S L O  S C O  R D
E R O S  Y H A B  I A T  A M
B I E N  U N P R  I N C  I P
E M A L  O U N A  B R U  J A
H E R M  O S A Y  U N P  I R
A T A H  O N R A  D O T  O D
A S E S  T A S C  O S A  S H
A B I A  U N A V  E Z C  U A
N D O Y  O S O N  A B A  U N
M U N D  O A L R  E V E  S X

 
TRANSPOSICION DE COLUMNAS
R E A U N E A E Z U N S V
O T U O B L B N O A L I E
U A R L T Q E T A B A M A
T O O S L N O C O R D D S
R Y B H A E O A T A M S I
I U R N P B E N C I P N I
M O A U N E A R U J A L B
E O Y S A H R N P I R M U
T O A N R A A O T O D H D
S T C A S A E S A S H S O
B U V N A A I Z C U A A E
D O N S O N O B A U N Y A
U O R A L M N V E S X D E


A continuación realizamos la transposición de las filas.


6  R E A U N E A E Z U N S V
1  O T U O B L B N O A L I E
7  U A R L T Q E T A B A M A
12 T O O S L N O C O R D D S
2  R Y B H A E O A T A M S I
4  I U R N P B E N C I P N I
5  M O A U N E A R U J A L B
3  E O Y S A H R N P I R M U
13 T O A N R A A O T O D H D
8  S T C A S A E S A S H S O
9  B U V N A A I Z C U A A E
10 D O N S O N O B A U N Y A
11 U O R A L M N V E S X D E

 
TRANSPOSICION DE FILAS
O T U O B L B N O A L I E
R Y B H A E O A T A M S I
E O Y S A H R N P I R M U
I U R N P B E N C I P N I
M O A U N E A R U J A L B
R E A U N E A E Z U N S V
U A R L T Q E T A B A M A
S T C A S A E S A S H S O
B U V N A A I Z C U A A E
D O N S O N O B A U N Y A
U O R A L M N V E S X D E
T O O S L N O C O R D D S
T O A N R A A O T O D H D

De donde obtenemos el mensaje cifrado:


OTUOBLBNOA LIERYBHAEO ATAMSIEOYS AHRNPIRMUI URNPBENCIP
NIMOAUNEAR UJALBREAUN EAEZUNSVUA RLTQETABAM ASTCASAESA
SHSOBUVNAA IZCUAAEDON SONOBAUNYA UORALMNVES XDETOOSLNO
CORDDSTOAN RAAOTODHD


Desde aquí, mis felicitaciones a Altair.

miércoles, 1 de abril de 2009

Criptograma 01/04/09

 
037 002 007 023 013 011 061 127 043 005 
149 103 059 073 269 011 089 283 067 071 
127 269 173 199 193 011 163 047 197 019 
179 041 003 349 127 353 317 269 109 023 
331 067 097 311 047 197 139 179 167 107 
061 011 353 113 127 359 241 037 269 043 
071 331 067 211 011 163 127 197 269 193 
191 367 011 311 047 353 053 349 149 313 
127 061 179 067 263 283 257 269 173 317
011 005 127 007 002 113 269 197 233 037 
331 353 067 011 017 073 043 263 047 197 
163 103 353 109 179 041 127 199 269 173 
167 241 193 023 002 317 331 029 047 067 
011 007 127 311 103 349 061 241

sábado, 28 de marzo de 2009

Criptograma 28/03/09

 
   OTUOBLBNOA LIERYBHAEO ATAMSIEOYS AHRNPIRMUI URNPBENCIP
   NIMOAUNEAR UJALBREAUN EAEZUNSVUA RLTQETABAM ASTCASAESA
   SHSOBUVNAA IZCUAAEDON SONOBAUNYA UORALMNVES XDETOOSLNO
   CORDDSTOAN RAAOTODHD

viernes, 27 de marzo de 2009

Military Cryptanalysis

 
Desde hace ya bastante tiempo, en la web de la NSA está disponible la conocida obra de William F. Friedman "Military Cryptanalysis". Dejo un enlace:

http://www.nsa.gov/public_info/declass/military_cryptanalysis.shtml

jueves, 26 de marzo de 2009

Criptograma 26/03/09

Y después del aperitivo Kasiski, el plato fuerte!

VRBCI UGJZB JMCJK EVMBF ZSCNX
NIWAN CEGYI UVIQV FRWUZ ANWEH
VLPAT EUQUH RPIIW ONWQB EWXXX
RCVAN CCDHH PKMBF FTJYL HCKSE
EMCAN NFIBB HYTLB EPLCI ZZXLY
UGZOQ VPGYU APWBB RPPAX NVMBB
XYHNT QWMIA FXTHZ AUCDE FTXUY
EPWOY RKTHM EPWUH JXPKN EWVCG
VRVUL URZCC ZEUYM OFWGG FHDMF
EOQFN EQPFL ANDCY FWRCX GQASF
EEIOK ANIPP UIUAA ILSZZ FTFLL

viernes, 20 de marzo de 2009

Criptograma 20/03/09

Para practicar Kasiski ...

BEAOSERIPMXAQUTLXTDMTLDDTCXABIEAEABEAOSIYEGOCMJCWAHVTCTS
NLDOAVXDPBPMJCWAHMPSIRPBPJPNXNDNDTTPXECSTSFUTSXNSICEGOKI
KIGAHJJNIATLTSUUTROONEAAWOGRDAQRTTTPPSDYPVTRPSROBOAAKISA
IESEEAGAQUTNDSBOBECTDSIEPLOAGAHSDBGEAOHPDBGEHYBEOQJICOHQ
JECOWACSPBXDDDTSROALPRBEAOSERIPMXAQUTLXTDMTLDDTCXABIEAEA
BEAOSIYEGOCMJCWAHVTCTSNLDOAVXDPBPMJCWAHMPSAAKISATSAURHPD
TSEIPDPDPNPDXEIEPYJDPAHICOBAHYHIIUHOAOCOPDTLPNIAHTTIGACD
TJPNSOPTGAHAIRPSPNSABURHPCWOSAAESUGOAAIITRGAIOSATLHOAITL
BAGSDNEAGAPQJEALDSFUTHPNHAQISOHECTPRHEHOQRTLDSSEBAHMTLDD
TCXABIPBJEAIIOBEAOSERIPMXPPPPMTLDDXJTRDNBURHPSKEREHYAOWE
DLKISASOHITMERTMPSYOHEPGJSIICGDYIIHOAOPBRDTFVHXJZLBNDPFR

martes, 17 de marzo de 2009

Criptograma II 04/02/09: Solución

El criptograma es una aplicación de los antiguos criptogramas de tipo rejilla. Podemos pensar en ellos como una hoja de papel cuadriculada en la que se realizan diversos agujeros. Aplicando esta rejilla sobre otro papel escribiremos el mensaje en los agujeros. Finalmente, el papel donde se encuentra el mensaje, lo rellenaremos con letras aleatorias. 

Así pues, la rejilla sera nuestra clave. Pues aplicandola sobre la "sopa de letras" podremos leer el mensaje en los agujeros.
En nuetro criptograma, se usa la partida mencionada de Kasparov como rejilla, usando la posición final de la partida, cuando en la jugada 19 Kasparov se rinde.
En la posicion final quedan ocupadas las siguientes casillas:


   X . X . . . . X
   X . . X X . X .
   . . X . . . . X
   . X . X . X . .
   . . X X . . . .
   . . . X . X X .
   . X . . . X X X
   X . . . . . X .


Y esta es la rejilla que descifra el mensaje.


Si ordenamos el criptograma:

   KALU MNIA ASAT UPBA RTAM EPIR CAUD NANN
   HUNI EEVO ALAK MTOI EKSS GLAA TFAG RIUT

en un cuadro de 8x8, como un tablero de ajedrez:

   K A L U M N I A
   A S A T U P B A
   R T A M E P I R
   C A U D N A N N
   H U N I E E V O
   A L A K M T O I
   E K S S G L A A
   T F A G R I U T

Aplicando nuestra rejilla, obtenemos nuestro mensaje:

   K . L . . . . A
   A . . T U . B .
   . . A . . . . R
   . A . D . A . .
   . . N I . . . .
   . . . K . T O .
   . K . . . L A A
   T . . . . . U .


Mensaje: KLAATU BARADA NIKTO

Las celebres palabras de Gort.


.

sábado, 14 de febrero de 2009

OpenDomo visto desde una PSP

                    
Oriol Palenzuela nos muestra en su artículo "Accediendo a OpenDomo desde dispositivos móviles", cómo se ve OpenDomo desde la PSP.

Adjunto las capturas:







miércoles, 11 de febrero de 2009

Documentación sobre la Mente y la Consciencia


El siguiente enlace contiene una gran colección de enlaces a documentación sobre la mente y la consciencia. Sin duda, una mina para todo aquel interesado en la vertiente más pura de la Inteligencia Artificial. No esperéis encontrar muchos algoritmos ;)


MindPapers: A Bibliography of the Philosophy of Mind and the Science of Consciousness


También pueden consultarse únicamente los enlaces a documentos on-line.

.

viernes, 6 de febrero de 2009

Cómo agilizar conexionex SSH

Dejo aquí una pequeña receta que permite agilizar las conexiones ssh, de manera que solo pedirá la contraseña la primera vez. A partir de ese momento las conexiones usarán el mismo canal multiplexado.

Solo hay que añadir en ~/.ssh/config lo siguiente:

Host *
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p

miércoles, 4 de febrero de 2009

Criptograma II 04/02/09

Altair se los come como rosquillas, así que ahí va otro.
No será por falta de criptogramas ...


Pista:   Deep Blue - Kasparov, 1997, Game 6

KALU MNIA ASAT UPBA RTAM EPIR CAUD NANN
HUNI EEVO ALAK MTOI EKSS GLAA TFAG RIUT

Criptograma 04/02/09

No me gusta dejar a los lectores sin 'material' para romperse el coco. Por suerte, aún y con la rapidez de Altair, todavía me quedan unos cuantos criptogramas en la manga.

Que os divirtáis!


TCZVAUAOOQOVNVDMULIAIOPEUTG
DELSMAUALEEETJECJENOELOONSR
RUNYCUIONJEUFONIUNARYEVNODI
SGETREEERROMRRCOSDENOODOEQA
NNOYRURUVUTEEONIGOGLNCRLDLA
EOTAOAUNLISLSNUAEAOEINPRDDS
CSSOAETAOONMMAVLGESANEORNLS