elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Tutorial básico de Quickjs


  Mostrar Temas
Páginas: 1 2 3 4 5 [6] 7 8 9 10 11 12 13 14 15 16 17 18
51  Programación / Desarrollo Web / Efectos sobre Canvas HTML5 en: 6 Noviembre 2018, 16:18 pm
Muy buen dia compañeros.

Estoy tratando de crear un tipo de efectos sobre un Canvas de HTML5.

El canavas actualmente tiene una imagen creada mediante javascript consiste en las clasicas Barras de Colores que salian en la televisión.




Se crearon con el siguiente codigo.
Código
  1. var canvas = document.getElementById("bars");
  2. var ctx = canvas.getContext("2d");
  3. var colores = ["white", "yellow","cyan", "lime","magenta","red","blue"];
  4. var colores2 =["blue","black","magenta","black","cyan","black","white"];
  5.  
  6. var i;
  7. i = 0;
  8. while(i < 7) {
  9. ctx.fillStyle = colores[i];
  10. ctx.fillRect(i*182,0,(i+1)*182,537);
  11. i++;
  12. }
  13. i = 0;
  14. while(i < 7) {
  15. ctx.fillStyle = colores2[i];
  16. ctx.fillRect(i*182,537,(i+1)*182,72);
  17. i++;
  18. }
  19. // Create gradient
  20. var grd=ctx.createLinearGradient(0,0,1274,115);
  21. grd.addColorStop(0,"white");
  22. grd.addColorStop(1,"black");
  23.  
  24. // Fill with gradient
  25. ctx.fillStyle=grd;
  26. ctx.fillRect(0,609,1274,115);
  27.  

Y queria crear una animación asi tipo distorción.

No se que tipo de operaciones realizar en el canvas, primero pensé en agregarle alguna capa de blur

Pero preguntar aqui por si alguien ya a hecho algo similar en el Canvas HTML

Saludos
52  Foros Generales / Foro Libre / Plan de Ahorro infalible en: 16 Agosto 2018, 23:44 pm
Plan de Ahorro infalible

Sea la moneda que usen en tu pais y estes donde estes puede ser desde 5 Dolares semanales, 5 Euros, 100 Pesos Mexicanos etc..

El unico punto es que tiene que ser SEMANAL y CONSTANTE

La mayoría de los países, si no es que todos, tiene un sistema de inversion en instrumentos Gubernamentales. En algunos casos esta accesible al publico en general.

Nos vamos a concentrar en instrumentos de inversion de liquides mensual.
Estos instrumentos pagan un %de interés al final del periodo de inversion y esta es la Ganancia

El ahorro es para aprovechar la ventaja del Interés compuesto

1ra Semana ahorramos la cantidad elegida en instrumentos a un mes
2da Semana ahorramos la cantidad elegida en instrumentos a un mes
3ra Semana ahorramos la cantidad elegida en instrumentos a un mes
4ta Semana ahorramos la cantidad elegida en instrumentos a un mes
5ta Semana ahorramos la cantidad elegida MAS la cantidad que ahorramos la primera semana ya que esta ya venció y se reinvierte
6ta Semana ahorramos la cantidad elegida MAS la cantidad que ahorramos la segunda semana ya que esta ya venció y se reinvierte
...

Asi sucecivamente

El patron de ahorro anteriormente descrito nos presenta una Liquides Semanal (Apartir del primer mes) hasta por 1/4 parte del total de tu ahorro cada una de las 4 semanas

Ejemplo para una persona de 20 años en mexico ahorrando 200 Pesos Mexicanos (10 USD) a la semana
- Se considera un aumento de ahorro de +25 pesos semanales año, esto para compensar la inflación y ajustando a los aumentos de sueldo que puede tener la persona año con año. Esto es 200 el semanales el primer año, 225 semanales el segundo año, 250 semanales el tercer año y asi sucesivamente.
- Se considera una taza de interes Fija al 7.75% (Ultima taza registrada en los CETES de vencimiento mensual)
- Se considera que las condiciones macroeconomicas del país no varían mucho a lo largo de los años.

A continuation se deja una tabla con la edad de la persona, el interés generado Semanalmente, la suma del interés en 4 Semanas (Un mes) y la cantidad total ahorrada en el periodo de 4 Semanas




El saldo mostrado es al finalizar el año marcado.
53  Programación / Programación General / Migrar funcion de C a C# problema con tamaño de variable 16 y 32 bits en: 21 Marzo 2018, 22:20 pm
Migrar una funcion de un lenguaje a otro no debería de ser problema, sin embargo estoy algo atorado con los resultado que me arroja una vez migrado.

En teoria deberia de ser el mismo resultado en ambos casos, sin embargo no es asi.

Codigo en C (Original sin depuracion)

Código
  1. #include<stdio.h>
  2.  
  3. unsigned short CRC(unsigned char *s, int len, unsigned short crcval);
  4.  
  5. int main() {
  6. unsigned char *test = "\x01\x55\x00\x00";
  7. printf("CRC: %u\n",CRC(test,4,0));
  8. return 0;
  9. }
  10.  
  11. unsigned short CRC(unsigned char *s, int len, unsigned short crcval) {
  12. register unsigned c,q;
  13. for (; len; len--) {
  14. c = *s++;
  15. q = (crcval ^ c) & 017;
  16. crcval = (crcval >> 4) ^ (q * 010201);
  17. q = (crcval ^ (c >> 4)) & 017;
  18. crcval = (crcval >> 4) ^ (q * 010201);
  19. }
  20. return (crcval);
  21. }

Codigo en C (Con depuracion)

Código
  1. #include<stdio.h>
  2.  
  3. unsigned short CRC(unsigned char *s, int len, unsigned short crcval);
  4.  
  5. int main() {
  6. unsigned char *test = "\x01\x55\x00\x00";
  7. printf("CRC: %u\n",CRC(test,4,0));
  8. return 0;
  9. }
  10.  
  11. unsigned short CRC(unsigned char *s, int len, unsigned short crcval) {
  12. register unsigned c,q;
  13. printf("Depurando CRC\n");
  14. for (; len; len--) {
  15. printf("len: %i\n",len);
  16. c = *s++;
  17. printf("c: %u\n",c);
  18. q = (crcval ^ c) & 017;
  19. printf("q: %u\n",q);
  20. crcval = (crcval >> 4) ^ (q * 010201);
  21. printf("crcval: %u\n",crcval);
  22. q = (crcval ^ (c >> 4)) & 017;
  23. printf("q: %u\n",q);
  24. crcval = (crcval >> 4) ^ (q * 010201);
  25. printf("crcval: %u\n",crcval);
  26. }
  27. return (crcval);
  28.  

Salida del codigo en C para el ejemplo Dado:

Código:
Depurando CRC
len: 4
c: 1
q: 1
crcval: 4225
q: 1
crcval: 4489
len: 3
c: 85
q: 12
crcval: 50964
q: 1
crcval: 7408
len: 2
c: 0
q: 0
crcval: 463
q: 15
crcval: 63379
len: 1
c: 0
q: 3
crcval: 16122
q: 10
crcval: 42725
CRC: 42725

Codigo en C#

Código
  1. static void Main(string[] args)
  2. {
  3. byte[] test = new byte[] { 0x01,0x55,0x00,0x00 };
  4. Console.WriteLine("CRC: "+CRC(test,test.Length,0));
  5. }
  6.  
  7. public static ushort CRC(byte[] s,int len,ushort crcval) {
  8. ulong c, q;
  9. uint i = 0;
  10. while(len > 0)
  11. {
  12. Console.WriteLine("len: "+len);
  13. c = s[i];
  14. Console.WriteLine("c: " + c);
  15. q = (crcval ^ c) & 017;
  16. Console.WriteLine("q: " + q);
  17. crcval = (ushort)(((uint)crcval >> 4) ^ (q * 010201));
  18. Console.WriteLine("crcval: " + crcval);
  19. q = (crcval ^ (c >> 4)) & 017;
  20. Console.WriteLine("q: " + q);
  21. crcval = (ushort)(((uint)crcval >> 4) ^ (q * 010201));
  22. Console.WriteLine("crcval: " + crcval);
  23. len--;
  24. i++;
  25. }
  26. return crcval;
  27. }
  28.  
  29.  

Salida del programa en C#

Código:
len: 4
c: 1
q: 1
crcval: 10201
q: 17
crcval: 42772
len: 3
c: 85
q: 1
crcval: 11688
q: 1
crcval: 9475
len: 2
c: 0
q: 1
crcval: 9609
q: 1
crcval: 9601
len: 1
c: 0
q: 1
crcval: 9601
q: 1
crcval: 9601
9601

El problema creo que se encuentra en la conversion de variables de 16 bits a 32 bits, pero e tratado de reasignar los valores con ANDS ( & 0xffff) para que queden de 16 bits y ni aun asi funciona.

Alguna ayuda.

Saludos!
54  Seguridad Informática / Hacking / Sniffear comunicacion Serial [Solucionado, Funcional] en: 17 Marzo 2018, 20:07 pm
Alguno conoce un buen metodo para Sniffear una comunicación Serian entre dos dispositivos mediante puerto RS232?  :huh: :huh:

El punto esta en que estoy realizando Ingeniería Inversa en el protocolo de comunicacion que utilizan 2 dispositivos que se comunican mediante cable serie.

Primero intente utilizar mi computadora como dispositivo intermedio leer todos los datos que manda el HostA y escribirlos hacia el HostB y viceversa.

El programa lo escribi en C# y parecia funcionar bien, vi parte de la comunicación entre los equipos pero llega un punto en el que al parcer por tiempo no se sincroniza bien la comunicación entre ellos y NO SE Comportan los dispositivos de la manera esperada, segun me entere el tiempo de respuesta entre ambos dispositivos no debe de superar los 20 milisegundos entre ellos. Vi el tiempo que tardaba en leer y escribir la información y este supera los 40 milisegundos.

Intente un  programa en C puro y parece ir mas rápido, pero ahora leo información de mas.
Ejemplo.

En el programa en C# leia un byte del host A al host B con valor de 100 y posteriormente leia una respuesta del host B hacia el host A con otro valor X

Y ahora con el programa de C leo hasta 5 bytes continuos con valor 100 cuando realmente conozco de antemano que solo debe de ser un byte con valor 100 seguido de la respuesta.

Alguna sugerencia con otro metodo de snifeo?

Saludos!
55  Programación / Desarrollo Web / Alguna solucion para realizar sleep en IE9 o IE11? sin promesas? en: 5 Diciembre 2017, 20:58 pm
Bueno realmente esto me tiene harto.

Tengo unos dias buscando una solucion para realizar la funcion sleep en javascript y que funcione en  Internet Explorer.

Mi solucion anterior fue usar promesas y funciona de maravilla, pero el detalle que tengo unos patrones que no salen de la edad de piedra y siguen usando Internet Explorer, no quieren usar Chrome por nada del mundo.

Solución anterior:

Código
  1. function sleep(ms) {
  2.    return new Promise(resolve => setTimeout(resolve, ms));
  3. }
  4.  

Funciona al 100 en Crome y otros navegadores mas actualizados pero no sirve ni en Internet Explorer 11. Marca error por que no reconoce las parabras para await y async y no reconoce la sintaxis de => para el resolve....

Ahora tome de stack overflow el siguiente código.

https://stackoverflow.com/questions/36016327/how-to-make-promises-work-in-ie11

y NO FUNCIONA

Código
  1. function sleep(ms) {
  2.    tiempo = ms;
  3.    return new Promise(function(resolve) {
  4.        setTimeout(function() {
  5.            resolve("result");
  6.        }, tiempo);
  7.    });
  8. }
  9.  
  10.  

Este si reconoce la sintaxis de la funcione, pero de todos modos sigue marcando error en los async y await.

Ya intente, genera una peticion async = false al Servidor para que el servidor realizare el tiempo de espera, pero no es respetado por los navegadores.

Tambien he intentado y NO FUNCIONA

Código
  1.      function sleep(delay) {
  2.        var start = new Date().getTime();
  3.        while (new Date().getTime() < start + delay);
  4.      }
  5.  

Tomado de: https://eureka.ykyuen.info/2011/02/20/javascript-sleep-function/

Alguno de ustedes tiene algo de experiencia con esto.

Saludos!
56  Seguridad Informática / Criptografía / vector contra rijndael (AES) con algunos datos conocidos? en: 21 Septiembre 2017, 05:01 am
Conozco el tipo de datos que se están cifrando, y el método de cifrado, tengo acceso a la salida cifrada.

El dato que se esta cifrando es un numero secuencial de 128 bits.

Esto es primero es 1, luego es 2 y asi... aunque no conoco el estado actual de este numero podria ser 1000, 100000  o 8439948 o cualquier otro numero.

La llave es aleatoria y aun que no conozco cual es esta llave, se o creo que esta misma llave es usada para cifrar el siguiente numero. Comento que creo por que no estoy seguro si internamente el algoritmo la cambie.

El Cifrado es rijndael (AES) a 128 bits en modo ECB.

Tengo acceso a una muestra de 65536 Bloques de 128 bits cifrados y los mismos corresponden a los numeros en secuencia de uno en uno.

Alguna idea de conseguir la llave?

Saludos!



57  Seguridad Informática / Criptografía / Crackear GELI [Infeasible] en: 14 Septiembre 2017, 19:07 pm
Antes de empezar tengo que comentar que este método es infeasible.

El método podría tardar toda la vida, incluso podría terminarse el universo y no tener la llave para descifrar la Llave maestra para descifrar el disco duro.

Hace unos días publique un post sobre Extraer la información[2]
 de cifrado (Metadata Usada por Geli[1]). El post sirve solo para extraer información de metadata para su posterior análisis, de hecho el comando

Código:
#geli dump ada0p2

Realiza la misma salida, sin embargo con el programa podemos tener en memoria una copia de la clave cifrada para tratar de crackearla.

Ahora Comento que el programa es infeasible por lo mismo que tardaríamos una eternidad en crackear la clave, posiblemente cuando la clave sea encontrada por mera suerte el disco duro a descifrar ya no exista.

Sin embargo como no he visto ninguna herramienta publica he decidido programar mi propio crack para Discos Duros cifrados con geli.

Métodos de crackeo:

  • Fuerza Bruta a la passphrase mediante diccionario
  • Fuerza Bruta a la clave cifrada


Fuerza Bruta a la passphrase mediante diccionario

La primera opción es incluso mas tardada, pero puede ser que tengamos mas suerte si es que la passphrase escogida por el Sysadmin esta en nuestro diccionario, sin embargo si la palabra no esta en el diccionario es imposible.

En este caso la única limitante es:

Código:
Iterations: 218830

En ese caso tarda como 2 segundos en mi equipo realizar el key derivation con esa cantidad de iteraciones. Sin embargo la ultima instalación de FreeBSD que hice, incremente ese numero de iteraciones a 10485760 y tarda aproximadamente u 41 veces mas en realizar el key derivation.

Entonces en un ataque por diccionario tendriamos que pasar nuestra passphrare y derivarla X cantidad de veces, lo cual seria rapido para un X pequeño pero muy tardado para un X muy grande como el mencionado.

Recomendación  para los sysadmin que utilizen este método de cifrado o un cifrado similar, no elegir una clave que se encuentre en algun diccionario, y si pueden configurar el numero de iteracciones, configuren uno muy alto para que sea desalentador tratar de crackear por este medio.

Fuerza Bruta a la clave cifrada

Este metodo tiene como ventaja que se salta la parte de las iteraciones y como desventaja es que prueba todas las combinaciones posibles.

Sin embargo la probabilidad de que encuentre la clave en los primeros años de ejecución son NULAS, sin embargo a largooooo plazo va a terminar encontrado la llave para descifrar la clave maestra para descifrar el disco duro.

El metodo utiliza un archivo para salvar el progreso actual y poder reanudarlo en cualquier otro momento.

En cada iteracion del programa se realizan 2 pruebas para descifrar la clave.


  • Una clave de 64 Bytes que incrementa de uno en uno en cada ciclo
  • Una clave de 64 bytes de un buffer aleatorio

Una clave de 64 Bytes que incrementa de uno en uno.

Esta es la parte que nos da la certeza de que en algun momento podremos encontrar nuestra clave para descifrar ya que probamos todas las combinaciones posibles.

Una clave de 64 bytes de un buffer aleatorio

Posiblemente una perdidad de tiempo, pero si tenemos la suerte de que el buffer aleatorio coincida con la clave para descifrar la clave maestra. entonces podriamos tener la clave antes de tiempo.

Esta ultima parte se puede omitir y incrementariamos nuestro tiempo de finalizacion a un poco menos de la mitad del actual.

Infeasibilidad del metodo

La llave para descifrar la llave maestra es de 64 bytes de longitud, NO 64 Bits, 64 BYTES de longitud (64*8 bits)

Imaginemos el siguiente numero:
Código:
13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095

Un numero decimal de 155 digitos

Entonces por cada prueba que realize nuestro programa tenemos la posibilidad de 1 en Ese numero de que sea nuestra clave de decifrado.

Para los curiosos esta seria la forma de leer el numero de posibilidades
Código:
13407   quintovigecillones
,807929 cuatorvigecillones
,942597 trivigecillones
,099574 duovigecillones
,024998 unvigecillones
,205846 vigecillones
,127479 nonidecillones
,365820 octidecillones
,592393 septodecillones
,377723 sextodecillones
,561443 quintodecillones
,721764 cuatordecillones
,030073 tridecillones
,546976 Duodecillones
,801874 Undecillones
,298166 Decillones
,903427 Nonillones
,690031 Octillones
,858186 Septillones
,486050 Sextillones
,853753 Quintillones
,882811 Cuatrillones
,946569 Trillones
,946433 Billones
,649006 Millones
,084095

Aunque tengo dudas de la pronunciacion apartir de los decillones.

El codigo para crackear por fuerza bruta esta en:

https://github.com/albertobsd/geli_metadata/blob/master/crackgeli.c


Si alguien quiere probrar tengo en mi firma un Reto para crackear

Crackeame si puedes Wallet.dat

Saludos!



[1] Extraer informacion de Cifrado
https://foro.elhacker.net/criptografia/extraer_informacion_de_cifrado_en_discoduro_de_freebsd-t474262.0.html

[2] Man page of Eli: https://www.freebsd.org/cgi/man.cgi?query=geli&apropos=0&sektion=8&manpath=FreeBSD+11.1-RELEASE&arch=default&format=html
58  Sistemas Operativos / Unix/Unix-Like / Recomendacion para Disco Duro Cifrado en FreeBSD en: 9 Septiembre 2017, 00:44 am
Si estamos usando FreeBSD y queremos cifrar todo nuestro disco duro no duden en preguntar sus dudas.

El comando geli para inicializar la criptografia en nuestro disco duro es el siguiente:

Código:
geli init -a hmac/sha256 -b -e AES-XTS -l 256 -s 4096 -i 524288 -B /tmp/USBTEMP/backup_metadata.eli -K /tmp/USBTEMP/da1p1.key da1p1

Obviamente hablamos de una instalacion nueva. No se puede en una instalacion preexistente, a no ser que vallamos a mover toda nuestra informaacion  de un disco duro sin cifrar a algun disco duro cifrado.

Previamente necesitamos crear un archivo "llave" de manera aleatoria con DD

Código:
dd if=/dev/random of=/tmp/USBTEMP/da1p1.key bs=4096 iseek=128 count=32

Esto nos genera un archivo de 128 Kilobytes (bs=4096 * count=32) de informacion aleatoria, pasandole este archivo a geli, necesitaremos este archivo cada vez que iniciemos nuestro ordenador, y mas nos vale tener al menos otras 3 copias de seguridad de dicho archivo.

Sumado al archivo en la memoria USB para poder cargar nuestro sistema tendremos:

  • Disco Duro cirado con  AES-XTS y una clave de 256 bits
  • Autenticacion de sectores del disco usando hmac/sha256
  • La Autenticacion con hmac/sha256 Envita que nos ataquen usando Replay
  • Peticion de passphrase Antes de montar el Disco Duro principal
  • El passphare es juntado con el salt y nuestro archivo de 128 Kilobytes y derivado 524288 veces para poder descifrar la clave maestra previamente cifrada y guardada en la metadata

La unica desventaja que le veo a esta implementacion es:

  • Disminucion del Performance al momento de Leer/Escribir informacion en el disco ya que todo es cifrado.
  • Lo anterior pordria ser mitigado Teniendo algun Hardware acelarador para operaciones criptograficas y un Disco Duro de Estado solido.
  • Disminucion de Capacidad de almacenamiento, Dado que estamos usando un sistema de Autenticacion, este necesita guardar los checksum de cada sector de disco para determinar que no han sido modificados por terceros
  • Ejemplo de lo Anterior un Disco Duro de 22 Gigabytes termina con capacidad de 19 GB. Pierde al rededor de 14% de Almacenamiento dedicado para la Autenticacion de la información

Saludos!


Source: https://albertobsd.blogspot.mx/2017/09/recomendacion-para-disco-duro-cifrado.html
59  Seguridad Informática / Criptografía / Extraer informacion de Cifrado en DiscoDuro de FreeBSD en: 8 Septiembre 2017, 06:45 am
Extraer informacion de Cifrado en DiscoDuro de FreeBSD

FreeBSD ofrece la opcion de cifrar completamente el disco duro. La principal herramienta es Geli[2].

Para ver la información sobre el cifrado del disco, OJO no la información cifrada, sino la información relacionada con el tipo y modo de cifrado usado para el disco duro en cuestion, es necesario primero obtener acceso fisco al disco, una en otra instalación con FreeBSD podemos extraer el sector que tiene la meta-data a analizar, este sector del disco duro (512 Bytes) se encuentra en el ultimo sector de la particion cifrada.

Si no sabemos cual particion es la particion cifrada podemos extraer el ultimo sector de todas la particiones de el disco duro.

Ejemplo:

Discoduro a analizar /dev/da1

Si listamos /dev/da1* podremos ver que tiene 2 particiones para este caso en particular

Código:
# ls /dev/da1*
/dev/da1p1
/dev/da1p2
Para extraer la informacion tenemos que usar el comando dd.

Tambien necesitamos saber cuanto espacio tiene el disco duro

# geom disk list
o
# gpart list

Ejemplo de salida:

Código:
Providers:
1. Name: da1p1
   Mediasize: 20401094656 (19G)
   Sectorsize: 512
   Stripesize: 0
   Stripeoffset: 32768
   Mode: r1w1e1
   rawtype: 7
   length: 20401094656
   offset: 0
   type: freebsd-ufs
   index: 1
   end: 39845887
   start: 0
2. Name: da1p2
   Mediasize: 1073708032 (1.0G)
   Sectorsize: 512
   Stripesize: 0
   Stripeoffset: 3221258240
   Mode: r1w1e0
   rawtype: 1
   length: 1073708032
   offset: 20401094656
   type: freebsd-swap
   index: 2
   end: 41942973
   start: 39845888

Para este ejemplo la particion tiene 20401094656 con lo cual si dividimos entre 512 nos da un total 39845888 Sectores con lo cual el ultimo sector valido es 39845887 que el que tenemos que leer, entonces el comando para extraer dicho sector es:

# dd if=/dev/da1p1 of=./sector.backup bs=512 iseek=39845887 count=1

Si nuestros calculos fueron acertados tendremos un archivo llamado sector.backup de 512 bytes.

El contenido de ese archivo puede variar mucho dependiendo del estado previo del disco duro.

Si el disco duro esta cifrado con mediante geli el archivo empezara con la siguiente leyenda:

GEOM::ELI, lo restante es informacion en binario con el siguiente orden

Código:
struct g_eli_metadata {
 char  md_magic[16]; /* Magic value. */
 uint32_t md_version;  /* Version number. */
 uint32_t md_flags;  /* Additional flags. */
 uint16_t md_ealgo;  /* Encryption algorithm. */
 uint16_t md_keylen;  /* Key length. */
 uint16_t md_aalgo;  /* Authentication algorithm. */
 uint64_t md_provsize; /* Provider's size. */
 uint32_t md_sectorsize; /* Sector size. */
 uint8_t  md_keys; /* Available keys. */
 int32_t  md_iterations; /* Number of iterations for PKCS#5v2. */
 uint8_t  md_salt[G_ELI_SALTLEN]; /* Salt. */
   /* Encrypted master key (IV-key, Data-key, HMAC). */
 uint8_t  md_mkeys[G_ELI_MAXMKEYS * G_ELI_MKEYLEN];
 u_char  md_hash[16]; /* MD5 hash. */

} __packed;
Me tome la molestia de Generar una herramienta en C que lee la informacion y le pasa las funciones existentes en el codigo fuente de geli para organizar el buffer acorde al formato de la estructura.

El programa puede ser visto en mi cuenta de github[3] si lo compilamos y ejecutamos pasandole como parametro el archivo de 512 bytes tendremos una salida similar a la siguiente [Algunos datos fuero cambiados]:

Código:
albertobsd@XHGC-VMBox:~ % ./eli_metadata sector.backup
Magic: GEOM::ELI
Version: 7
Flags: 2
E ALGO: 22
Key Length: 128
A Algo: 0
P Size: 23622320128
Sector Size: 4096
Avaible Keys: 1
Iterations: 218830
Salt: E8CF4BB53DA62DC60B8CAD36119D62B806D95524828286533728C4045E319DBBA1486522EA0454887E1094AD3FAFA0295E9350F1259AAC4B791D42A02F3A6BF2
Master Key: 3F4E170DAFF6539E9301EEF2840ED233BA3B84D02EB96
3AEBB0CA1EED891034A85A3BB325F7B09398706944DFE84CE4748D2C4F0E1FEA4FD601CC18A922ADE51C9D7DC740292A979153B744FC49F47956E24E23D64BFF854F04E3AD41C39215D834DF5E317FF9C1661D9B3300E40D85CE4C270BF57DD1AA82489A97F6741A119AF25D1987ED584E1585FD7ADAE7406D9119AC7AEE654DA2B9C28D2D39599593E1B751BAE614C921E814660E240D18B7650477E935941299F7D34C91350BD289902B7F7DF23D7523C1B6FC0AB33CAB3AF07E5EA0E97835EF13F31B1F56004A552F074951D8B490FEA605D449E2AEA774574BDFEE9153392E4084DF934FCA40638B676A868E3BAB8CA0E0A1912B348C645F74BCA3AB7D697053DD25107981086284F687D1D5EF1DA16280EE7CD0920A92CDAFAF7970D084C4C344FAB3117D0993A591AA43B1D09BE6D5AFB12C82C375BD980AC60F7E0A65C146F8E54E1D84FA0D73933EC26341E5B1D11BA14AF8FA3990F834C4FA39BEF17EECCE206670E5E854B

MD5: BD5DA8BAE0C0C6AAC7503769A3CE9110

Datos interesantes de la salida:

E ALGO: 22

Podemos ver en
/usr/src/sys/opencrypto/cryptodev.h

#define CRYPTO_AES_XTS  22

Que esta cifrado usando AES_XTS que segun [4] es el estandar recomenado para el cifrado de disco.


Key Length: 128

El cifrado usa una Llave de 128 bits, se podria configurar a 256 para un mejor cifrado.

A Algo: 0

El sistema no tiene Autenticacion, esto quiere decir que no se tiene forma de saber si la informacion que leemos del disco a sido modificada o sobreescirta por terceros, esto tambien da lugar a un ataque tipo replay para poder calcular la clave maestra

Avaible Keys: 1

El sistema solo tiene una llave maestra lo cual si se nos olvida nuestra "passphrase" o se nos pierden nuestras llaves tendremos muy pocas (NULAS) posibilidades de recuperar nuestra informacion

Iterations: 218830

Nuestra "passphrase" junto con el Salt y nuestros Keyfiles si existen es derivada 218830 veces mediante pkcs5v2_genkey en g_eli.c y el resultado de esta operacion se usa para descifrar la llave encripada en.

Master Key: 3F4E170DAFF6539E9301EEF2840ED233BA3B84D02EB96
3AEBB0CA1EED891034A85A3BB325F7B09398706944DFE84CE4748D2C4F0E1FEA4FD601CC18A922ADE51C9D7DC740292A979153B744FC49F47956E24E23D64BFF854F04E3AD41C39215D834DF5E317FF9C1661D9B3300E40D85CE4C270BF57DD1AA82489A97F6741A119AF25D1987ED584E1585FD7ADAE7406D9119AC7AEE654DA2B9C28D2D39599593E1B751BAE614C921E814660E240D18B7650477E935941299F7D34C91350BD289902B7F7DF23D7523C1B6FC0AB33CAB3AF07E5EA0E97835EF13F31B1F56004A552F074951D8B490FEA605D449E2AEA774574BDFEE9153392E4084DF934FCA40638B676A868E3BAB8CA0E0A1912B348C645F74BCA3AB7D697053DD25107981086284F687D1D5EF1DA16280EE7CD0920A92CDAFAF7970D084C4C344FAB3117D0993A591AA43B1D09BE6D5AFB12C82C375BD980AC60F7E0A65C146F8E54E1D84FA0D73933EC26341E5B1D11BA14AF8FA3990F834C4FA39BEF17EECCE206670E5E854B

El archivo termina con un MD5 Checksum de los valores en binario previamente mostrados, solo para validar que la información sea correcta.

Si es posible usar la información contenida en el archivo para Atacar por fuerza bruta y obtener la Clave Maestra decifrada pero en computacionalmente casi imposible de realizar.

[1] Original Post: https://albertobsd.blogspot.mx/2017/09/extraer-informacion-de-cifrado-en.html
[2] Man page of Eli: https://www.freebsd.org/cgi/man.cgi?query=geli&apropos=0&sektion=8&manpath=FreeBSD+11.1-RELEASE&arch=default&format=html
[3] Herramienta Utilizada: https://github.com/albertobsd/geli_metadata
[4] https://en.wikipedia.org/wiki/Disk_encryption_theory
60  Programación / Programación C/C++ / Dejen de usar rand() en C/C++ o los van a Hackear en: 27 Agosto 2017, 15:37 pm
Dejen de usar rand() en C/C++ o los van a HACKEAR  :silbar:

Obviamente nadie usa la funcion rand() en programas del mundo real, ¿o si?

No se si colocar esto aqui o en criptografia o hacking. El tema trata de atacar una implementacion DEBIL de numeros random.

El ataque no es complejo, para el ejemplo mostrado pero muestra el peligro de las aplicaciones que usan numeros aleatorios debiles o predecibles.

Hace mas de una año en el foro publique un pequeño codigo del Juego Piedra Papel y Tijera: [Aporte] Piedra Pape y Tijera - Mini-Autómata + Ejercicio [1]

En ese ejemplo como originalmente lo hice para un video tutorial use por comodidad la funcion rand() que viene por defecto en las librerias estandar de muchas implementaciones y para no meter a los que se estan iniciando en temas de seguridad complejos, decidi usar esa funcion sabiendo que no es tan segura. Sin embargo no me habia dado cuenta de la gravedad de los numeros arrojados por rand aun inicializando con la semilla del tiempo. En cualquier caso lo numeros que arroja se pueden calcular usando la misma funcion rand()  :xD

En un entorno donde no se tiene acceso al codigo fuente de un programa, es posible (dependiendo de lo que el programa realize) tratar de adivinar que procesos internos realiza el programa en especial cuando involucra numeros aleatorios.

Veamos el ejemplo del piedra papel y tijera:

Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<stdbool.h>
  4. #include<time.h>
  5.  
  6. char *cadenas[] = {"Piedra","Papel","Tijera"};
  7.  
  8. //0 empate
  9. //1 Pierde Usuario
  10. //2 Gana Usuario
  11. //Filas Computadora
  12. //Columas Usuario
  13.  
  14. char tabla_resultados[3][3] =
  15. {
  16. {0,2,1},
  17. {1,0,2},
  18. {2,1,0}
  19. };
  20.  
  21. char *resultado[] = {"Empate","Gana la COMPUTADORA","Gana el USUARIO"};
  22.  
  23. int main() {
  24. char buffer[10];
  25. char *error = NULL;
  26. bool entrar = true;
  27. bool jugado = false;
  28. int usuario = 0;
  29. int computadora = 0;
  30. srand(time(NULL));
  31. do {
  32. computadora = rand() % 3;
  33. do { //Entramos en este ciclo hasta que el usuario juege o decida salir para no afectar el valor rand del ejemplo
  34. printf("1) Piedra\n");
  35. printf("2) Papel\n");
  36. printf("3) Tijera\n\n");
  37. printf("S) Salir\n\n");
  38. printf("Seleccione una opcion:");
  39. fgets(buffer,5,stdin);
  40. usuario = (int) strtol(buffer,&error,10);
  41. if(error[0] == 's' || error[0] == 'S') {
  42. entrar = false;
  43. jugado = true;
  44. }
  45. else{
  46. if(usuario <=3 && usuario >= 1){
  47. usuario--; //Le restamos uno al input para poder usarlo en una tabla de estados con index 0
  48. jugado = true;
  49. printf("Usuario %s vs Computadora %s\n",cadenas[usuario],cadenas[computadora]);
  50. printf("Resultado: %s\n",resultado[tabla_resultados[computadora][usuario]]);
  51. }
  52. else {
  53. printf("Seleccione una opcion correcta\n");
  54. jugado = false;
  55. }
  56. }
  57. }while(!jugado);
  58. }while(entrar);
  59. }
  60.  


Veamos las partes importantes:

Código
  1. srand(time(NULL));

Se inicializa el random con la semilla del tiempo como lo haria cual quier persona que esta aprendiendo a programar con numeros aleatorios.
El codigo mostrado lo escribi para compilarlo con GCC pero deberia de funcionar en otros compiladores de C sin muchos cambios.

Código
  1. computadora = rand() % 3;

La computadora usa funcion rand() y le aplica modulo al resultado para obtener valores validos del 0 al 2.

Pues bien para ejemplo es todo lo que necesitamos saber. Bajo la premisa de que el/los programas usan la semilla del tiempo actual en Segundos desde el primero de enero de 1970 [2]

Entonces en otro programa de C podemos buscar todas las semillas de tiempo en un rango determinado y obtener primeras salida de cada una de ellas.

Ejemplo tomemos la fecha de hoy en el formato devuelto por la funcion time(), desde [3] lo podemos obtener para hoy es:

1503838078

Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<stdbool.h>
  4. #include<time.h>
  5.  
  6. int main() {
  7. int i = 0;
  8. int resultado = 0;
  9. srand(1503838078);
  10. while(i < 10) {
  11. resultado = rand() % 3;
  12. printf("Resultado: %i\n",resultado);
  13. i++;
  14. }
  15. }


Salida

Código:
% ./testrand
Resultado: 2
Resultado: 0
Resultado: 0
Resultado: 1
Resultado: 1
Resultado: 1
Resultado: 2
Resultado: 0
Resultado: 0
Resultado: 1

% ./testrand
Resultado: 2
Resultado: 0
Resultado: 0
Resultado: 1
Resultado: 1
Resultado: 1
Resultado: 2
Resultado: 0
Resultado: 0
Resultado: 1

Como vemos la salida del programa es la misma en ambas ocasiones aunque se ejecuta con segundos de diferencia, posiblemente esto le paso a alguien que uso rand sin inicializar el srand, pero no le dio importancia.

¿Ahora que?

El hecho es que podemos reinicializar srand en cualqueir momento del codigo y la salida de rand va a ser la correspondiente a cada semilla ejemplo:

Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<stdbool.h>
  4. #include<time.h>
  5.  
  6. int main() {
  7. int i = 0;
  8. int resultado = 0;
  9. srand(1503838078);
  10. while(i < 5) {
  11. resultado = rand() % 3;
  12. printf("Resultado: %i\n",resultado);
  13. i++;
  14. }
  15. srand(1503838079);
  16. i = 0;
  17. while(i < 5) {
  18. resultado = rand() % 3;
  19. printf("Resultado: %i\n",resultado);
  20. i++;
  21. }
  22. srand(1503838078);
  23. i = 0;
  24. while(i < 5) {
  25. resultado = rand() % 3;
  26. printf("Resultado: %i\n",resultado);
  27. i++;
  28. }
  29. }


Noten el cambio de srand de 1503838078 -> 1503838079 -> 1503838078 por lo cual la primeras 5 salidas van a ser iguales a las 15 ultimas


Salida

Código:
% ./hackrand
Resultado: 2
Resultado: 0
Resultado: 0
Resultado: 1
Resultado: 1
Resultado: 0
Resultado: 2
Resultado: 0
Resultado: 2
Resultado: 1
Resultado: 2
Resultado: 0
Resultado: 0
Resultado: 1
Resultado: 1

Ya con esta salida sabemos que podemos calcular cualquier salida de rand() en cualquier momento conociendo o calculando la semilla inicial

Pues bien es momento de ganarle al Piedra papel y tijera perdiendo  solo los primeros 2 o 3 juegos y en base a estos tratar de calcular cual fue la semilla utilizada.

Hice un programa que que te muestra las salidas de rand ya con X modulo de las semillas +/- 10 al tiempo actual y apartir de ahi elijes cual semilla continuar viendo Y asi sabremos que jugada va a hacer la computadora  antes de tiempo y poderle ganar:

Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<stdbool.h>
  4. #include<time.h>
  5.  
  6.  
  7. int main(int argc, char **argv) {
  8. bool entrar,continuar,seleccione;
  9. char buffer[10];
  10. char *error = NULL;
  11. unsigned int tiempo = 0;
  12. unsigned int base = 0;
  13. int numero = 0;
  14. int resultado = 0,i = 0,j = 0;
  15. int divisor = 0;
  16. if(argc == 2) {
  17. divisor = (int )strtol(argv[1],&error,10);
  18. if(error[0] == 0) {
  19. tiempo = time(NULL);
  20. printf("Valor actual del tiempo %u\n",tiempo);
  21. printf("Calculando modulos en +/- 10\n");
  22. base = tiempo -10;
  23. j = 0;
  24. while( ( base + j) < (tiempo +10)) {
  25. srand(base + j);
  26. printf("Opcion %i:",j+1);
  27. i = 0;
  28. while(i < 10) {
  29. resultado = rand() % divisor;
  30. printf(" %i,",resultado);
  31. i++;
  32. }
  33. printf("\n");
  34. j++;
  35. }
  36. printf("Opcion S: Salir\n");
  37. do {
  38. seleccione = false;
  39. printf("Seleccione una opcion:");
  40. fgets(buffer,5,stdin);
  41. numero = (int)strtol(buffer,&error,10);
  42. if(error[0] == 's' || error[0] == 'S') {
  43. entrar = false;
  44. }
  45. else {
  46. if(numero >= 1 && numero <= 20) {
  47. continuar = true;
  48. numero--; //Restamos para compensar el +1 en el menu
  49. srand(base + numero);
  50. i = 0;
  51. while(i < 10) {
  52. resultado = rand();
  53. i++;
  54. }
  55. printf("Numeros siguientes en la secuencia seleccionada\n");
  56. do {
  57. i = 0;
  58. while(i < 5) {
  59. resultado = rand() % divisor;
  60. printf("%i, ",resultado);
  61. i++;
  62. }
  63. printf("\n");
  64. printf("+) Imprimir mas numeros\n");
  65. printf("S) Salir\n\n");
  66. printf("Seleccione: ");
  67. fgets(buffer,5,stdin);
  68. switch(buffer[0]) {
  69. case 's':
  70. case 'S':
  71. continuar = false;
  72. break;
  73. case '+':
  74. continuar = true;
  75. break;
  76. }
  77. }while(continuar);
  78. }
  79. else {
  80. seleccione = true;
  81. }
  82. }
  83. }while(seleccione);
  84. }
  85. }
  86. else {
  87. printf("Usar: %s <divisor>\n",argv[0]);
  88. }
  89. }
  90.  

Ejecitamos el programa para forcebrutear el srand con el parametro del modulo que estan aplicando:

Código:
% ./crack_rand.exe 3
Valor actual del tiempo 1503839464
Calculando modulos en +/- 10
Opcion 1: 2, 0, 0, 0, 0, 1, 2, 1, 0, 1,
Opcion 2: 2, 0, 0, 1, 1, 1, 0, 2, 1, 0,
Opcion 3: 2, 0, 1, 2, 2, 0, 2, 0, 0, 2,
Opcion 4: 0, 2, 0, 0, 0, 0, 1, 1, 1, 1,
Opcion 5: 0, 2, 0, 1, 1, 0, 0, 1, 1, 2,
Opcion 6: 0, 2, 2, 2, 2, 0, 1, 2, 1, 1,
Opcion 7: 0, 2, 2, 0, 0, 2, 2, 0, 1, 0,
Opcion 8: 1, 1, 1, 1, 0, 2, 1, 1, 1, 2,
Opcion 9: 1, 1, 2, 2, 2, 0, 2, 0, 2, 1,
Opcion 10: 1, 1, 1, 0, 2, 0, 1, 1, 2, 2,
Opcion 11: 1, 0, 1, 1, 0, 2, 2, 2, 2, 1,
Opcion 12: 2, 1, 0, 0, 1, 2, 1, 2, 2, 0,
Opcion 13: 2, 0, 0, 0, 2, 2, 2, 0, 2, 2,
Opcion 14: 2, 2, 0, 1, 0, 1, 1, 1, 2, 0,
Opcion 15: 2, 0, 0, 0, 0, 1, 0, 2, 0, 1,
Opcion 16: 0, 2, 0, 1, 2, 1, 2, 2, 2, 0,
Opcion 17: 0, 2, 2, 1, 2, 2, 0, 0, 0, 2,
Opcion 18: 0, 2, 2, 0, 0, 1, 1, 1, 2, 1,
Opcion 19: 1, 1, 1, 1, 2, 1, 0, 2, 0, 0,
Opcion 20: 1, 1, 2, 1, 2, 1, 1, 1, 2, 2,
Opcion S: Salir
Seleccione una opcion:

Ejecutamos el progrma de priedra papel o tijera y si bien muchas veces no tenemos acceso al codigo fuente, hay cosas que se pueden determinar  con un poco de imaginacion y conocimientos de programacion.

Código:
% ./ppt
1) Piedra
2) Papel
3) Tijera

S) Salir

Seleccione una opcion:1
Usuario Piedra vs Computadora Piedra
Resultado: Empate
1) Piedra
2) Papel
3) Tijera

S) Salir

Seleccione una opcion:1
Usuario Piedra vs Computadora Tijera
Resultado: Gana el USUARIO
1) Piedra
2) Papel
3) Tijera

S) Salir

Seleccione una opcion:1
Usuario Piedra vs Computadora Tijera
Resultado: Gana el USUARIO
1) Piedra
2) Papel
3) Tijera

S) Salir

Seleccione una opcion:1
Usuario Piedra vs Computadora Piedra
Resultado: Empate
1) Piedra
2) Papel
3) Tijera

S) Salir

Seleccione una opcion:2
Usuario Papel vs Computadora Piedra
Resultado: Gana el USUARIO
1) Piedra
2) Papel
3) Tijera

S) Salir

Seleccione una opcion:3
Usuario Tijera vs Computadora Papel
Resultado: Gana el USUARIO
1) Piedra
2) Papel
3) Tijera

S) Salir

Seleccione una opcion:3
Usuario Tijera vs Computadora Papel
Resultado: Gana el USUARIO
1) Piedra
2) Papel
3) Tijera

S) Salir

Seleccione una opcion:3
Usuario Tijera vs Computadora Papel
Resultado: Gana el USUARIO
1) Piedra
2) Papel
3) Tijera

S) Salir

Seleccione una opcion:1
Usuario Piedra vs Computadora Tijera
Resultado: Gana el USUARIO
1) Piedra
2) Papel
3) Tijera

S) Salir

Seleccione una opcion:3
Usuario Tijera vs Computadora Papel
Resultado: Gana el USUARIO
1) Piedra
2) Papel
3) Tijera

S) Salir

Seleccione una opcion:


Despues de los primeros intentos del programa: podemos darnos cuenta que la secuencia que se esta jugando es la 7 o la 18 del ejemplo

Código:
Opcion 7: 0, 2, 2, 0, 0, 2, 2, 0, 1, 0,
Opcion 18: 0, 2, 2, 0, 0, 1, 1, 1, 2, 1,

Y vemos que en los ultimos juegos Gane todos los piedra papel tijera que jugue.

Si bien es cierto que sin el codigo fuente o binario decompilado no es podible saber la cantidad de veces que se llama a la funcion rand antes de que realmente inicie el programa, si es posible calcular  incluso darnos cuenta de que podemos tener una base de datos o programa que calcule los modulos adecuados y tarde o temprano sabremos que semilla se utilizo para el caso de srand

Espero que dejen de usar srand y rand, buscando alguna funcion mas segura, si estan en Linux o un sistema libre, tendran siempre un /dev/random con bastantes numeros aleatorios muy dificiles de predecir.


¿Que alcance tiene esto?

Existen maquinas de juego electronico (bingo,loteria, balckjack) que utilizan funciones aleatorias y podria ser posible que alguna utilize rand() % X para algunos de sus calculos. Digo estas maquinas por que es probable que sus programadores se preocupen menos por la calidad de numeros generado, en maquinas de azar solo importa que los numeros sean uniformes (Todos con la misma probabilidad de salir) esto con el objetivo de calcular tablas de pagos adecuadas para la probabilidad de cada maquina.

Y pues temas se seguridad informatica como la generacion de passwords y otros usos de los numeros PseudoAlearorios, es recomendable buscar fuentes no predecibles de estos.

[1] https://foro.elhacker.net/programacion_cc/aporte_piedra_pape_y_tijera_miniautomata_ejercicio-t454850.0.html
[2] https://www.freebsd.org/cgi/man.cgi?query=time&sektion=3
[3] https://www.epochconverter.com/
Páginas: 1 2 3 4 5 [6] 7 8 9 10 11 12 13 14 15 16 17 18
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines