elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
26 Mayo 2012, 09:36  


Tema destacado: Recuerda que debes registrarte en el foro para poder participar (preguntar y responder)

+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Seguridad
| | |-+  Criptografía (Moderador: APOKLIPTICO)
| | | |-+  Ayuda: invertir algorritmo cifrado
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Ayuda: invertir algorritmo cifrado  (Leído 1,794 veces)
frankener1986

Desconectado Desconectado

Mensajes: 124


Reversing the world


Ver Perfil
Ayuda: invertir algorritmo cifrado
« en: 21 Marzo 2010, 18:01 »

cifrado
-------------------
- Input: 2 DWORDS
- Output: 1 DWORD

Hay 32 rondas.
En cada ronda hay dos HARDCODED DWORDS.
Compara el primer input con un número predefinido y calcula el número de bits en común
Compara el segundo con otro número predefinido y calcula nuevamente el número de bits en común.
El resultado lo guarda a un buffer acumulativo de tal forma:
SUM = 2*SUM + ((númeroBitsComún1 XOR númeroBitsComún2) & 1)

Desencriptación
-------------------
Todavía no he llegado a conseguirlo. Conseguir a partir de 1 DWORD Obtener los 2 necesarios.
Tras mucho comerme la cabeza, he concluido que se puede obtener el (númeroBitsComún1 XOR númeroBitsComún2) & 1
de cada ronda, simplemente haciendo un test de par/impar, restando uno en cada ronda si es necesario y dividiendo entre dos.
Con esto sólo tenemos 32 pistas: si (númeroBitsComún1 XOR númeroBitsComún2) de cada ronda es par o impar.
Ahora bien, habría que desmontar el XOR en cada ronda de alguna forma y reunir las 32 condiciones necesarias (de número de bits en común con los ints predefinidos) para construir nuestros dos números.
La pregunta del millón es: cómo sé cómo desmontar el XOR cada vez, cómo reuno todas esas condiciones y cómo construyo los 2 DWORDS de entrada?

Hay pérdida de datos, pero son suficientes los que tenemos?, sólo se puede hacer por fuerza bruta? se puede reducir el número de posibilidades?

Gracias por la ayuda =)
Si alguien me consigue resolver el problema, le prometo ayuda en lo que quiera


« Última modificación: 21 Marzo 2010, 18:12 por frankener1986 » En línea

Programad en C porfavor, que veo VB y parece un extracto de una novela mas que un codigo! jiji
frankener1986

Desconectado Desconectado

Mensajes: 124


Reversing the world


Ver Perfil
Re: Ayuda: invertir algorritmo cifrado
« Respuesta #1 en: 22 Marzo 2010, 00:02 »

Vale la cosa se ha simplificado bastante pensando un poco por mi parte xD
Código:
for(i=0;i<32;i++)
{
x1 = countCommonBits(input1, const1[i]);
res1 = (res1<<1) + (x1 & 1);
}

for(i=0;i<32;i++)
{
x2 = countCommonBits(input2, const2[i]);
re21 = (res2<<1) + (x2 & 1);
}
res = res1^res2;

Acepto soluciones para invertir el algorritmo y obtener un par de claves válidas.


« Última modificación: 22 Marzo 2010, 01:31 por frankener1986 » En línea

Programad en C porfavor, que veo VB y parece un extracto de una novela mas que un codigo! jiji
APOKLIPTICO
Moderador
***
Desconectado Desconectado

Mensajes: 3.781


Toys in the attic.


Ver Perfil
Re: Ayuda: invertir algorritmo cifrado
« Respuesta #2 en: 22 Marzo 2010, 00:13 »

Hay un par de cosas q no entiendo en tu pseudocodigo:
- Que devuelve la función countcommonbits()?
- Que significa esta expresión: "res1<<1"?
- (x1 & 1) sería un bitwise and? (osea q si la entrada x ejemplo fuese 11001010 el resultado sería 11001010? xq realmente no tiene mucho sentido... o le agrega un bit "1" al final y descarta el primero?)
- Cuando pusiste: res1 = "(res2<<1) + (x2 & 1);" no querrías decir "res2 = (res2<<1) + (x2 & 1);".

Un abrazo
APOKLIPTICO
En línea

AMD Phenom II 1075T X6 @ 290 Mhz x 11 (HT 2036 Mhz NB Link 2616 Mhz) 1.23 Vcore
ASUS M4A89GTD-PRO/USB3
2x2gb G-Skill RipjawsX DDR3 1600 Mhz CL7 (7-8-7-24-25-1T)
Seagate 500 Gb
XFX HD4850 512Mb GDDR3. 650 Mhz/995 Mhz 1.1 Tflops.
frankener1986

Desconectado Desconectado

Mensajes: 124


Reversing the world


Ver Perfil
Re: Ayuda: invertir algorritmo cifrado
« Respuesta #3 en: 22 Marzo 2010, 01:36 »

- Que devuelve la función countcommonbits()?

Devuelve el número de bits en común entre dos números, por ejemplo 11001 y 1101 tendrian 2 bits en comun.

- Que significa esta expresión: "res1<<1"?

rota 1 bit a la izquierda. (shift left) o lo que es lo mismo, multiplicar por dos

- (x1 & 1) sería un bitwise and? 

Sí, pero el resultado de 11001010 & 1 no es 11001010, es 0. Esto nos hace centrarnos sólo en el último bit entres lo q entres.
En el caso de hacer & 0xFFFFFFFF sí devuelve el mismo resultado.

-  Cuando pusiste: res1 = "(res2<<1) + (x2 & 1);" no querrías decir "res2 = (res2<<1) + (x2 & 1);".

Sí perdón xD


eso es todo =)
En línea

Programad en C porfavor, que veo VB y parece un extracto de una novela mas que un codigo! jiji
APOKLIPTICO
Moderador
***
Desconectado Desconectado

Mensajes: 3.781


Toys in the attic.


Ver Perfil
Re: Ayuda: invertir algorritmo cifrado
« Respuesta #4 en: 9 Abril 2010, 20:06 »

Hola, perdón x la tardanza, estuve analizando un poco tu algoritmo, hice este programita (Perdón si está un poco desorganizado, preguntá lo q no entiendas).

Código
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define RAND_MAX = 0xFFFFFFFF
 
float CalcEntropy(const unsigned int *buffer, const unsigned int size);
unsigned int const1[32];
unsigned int const2[32];
using namespace std;
void FillConsts();
unsigned int countCommonBits(const unsigned int input1, const unsigned int const1);
unsigned int Encrypt(unsigned int input1, unsigned int input2);
const unsigned int MAX_VAL = 10000;
int main()
{
   FillConsts();
   unsigned int i = 0;
   unsigned int *buffer = new unsigned int[MAX_VAL / 2 + 1];
   for(i = 0; i < MAX_VAL; i+= 8)
   {
 
       unsigned int word1 = (i%256) * 256*256*256 + ((i)%256)*256*256 + ((i)%256)*256 + ((i)%256);
       unsigned int word2 = ((i)%256) * 256*256*256 + ((i)%256)*256*256 + ((i)%256)*256 + ((i)%256);
       buffer[i/8] = word1;
   }
   cout << "Non-Entropic Input Before:" << CalcEntropy(buffer, MAX_VAL / 2) << endl;
   for(i = 0; i < MAX_VAL; i+= 8)
   {
 
       unsigned int word1 = (i%256) * 256*256*256 + ((i)%256)*256*256 + ((i)%256)*256 + ((i)%256);
       unsigned int word2 = ((i)%256) * 256*256*256 + ((i)%256)*256*256 + ((i)%256)*256 + ((i)%256);
       buffer[i / 8] = Encrypt(word1,word2);
   }
   cout << "Non-Entropic Input After:" << CalcEntropy(buffer, MAX_VAL / 2) << endl;
   for(i = 0; i < MAX_VAL; i+= 8)
   {
 
       unsigned int word1 = (rand()%256) * 256*256*256 + (rand()%256)*256*256 + (rand()%256)*256 + (rand()%256);
       unsigned int word2 = (rand()%256) * 256*256*256 + (rand()%256)*256*256 + (rand()%256)*256 + (rand()%256);
       buffer[i/8] = word1;
   }
   cout << "Entropic Input Before:" << CalcEntropy(buffer, MAX_VAL / 2) << endl;
   for(i = 0; i < MAX_VAL; i+= 8)
   {
 
       unsigned int word1 = (rand()%256) * 256*256*256 + (rand()%256)*256*256 + (rand()%256)*256 + (rand()%256);
       unsigned int word2 = (rand()%256) * 256*256*256 + (rand()%256)*256*256 + (rand()%256)*256 + (rand()%256);
       buffer[i / 8] = Encrypt(word1,word2);
   }
   cout << "Entropic Input After:" << CalcEntropy(buffer, MAX_VAL / 2) << endl;
   return 0;
}
 
void FillConsts()
{
   srand(1);
   for(unsigned int i = 0; i < 32; i++)
   {
       const1[i] = (unsigned int) rand();
       const2[i] = (unsigned int) rand();
   }
}
 
unsigned int countCommonBits(const unsigned int input1, const unsigned int const1)
{
   char szInput1[33];
   char szConst1[33];
   unsigned int retVal;
   itoa((int) input1, szInput1, 2);
   itoa((int) const1, szConst1, 2);
   for(int i = 0; i < 32; i++) if(szInput1[i] == szConst1[i]) retVal++;
   return retVal;
}
unsigned int Encrypt(unsigned int input1, unsigned int input2)
{
   unsigned int i = 0;
   unsigned int x1 = 0;
   unsigned int x2 = 0;
   unsigned int res1 = 0;
   unsigned int res2 = 0;
   unsigned int res = 0;
   for(i=0;i<32;i++)
   {
       x1 = countCommonBits(input1, const1[i]);
       res1 = (res1*2) + (x1 & 1);
   }
   for(i=0;i<32;i++)
   {
       x2 = countCommonBits(input2, const2[i]);
       res2 = (res2*2) + (x2 & 1);
   }
   res = res1^res2;
   return res;
}
float CalcEntropy(const unsigned int *buffer, const unsigned int size)
{
   unsigned int i = 0;
  float entropy = 0.0;
long count[256];
float freq[256];
for(i = 0; i < 256; i++)
{
count[i] = 0;
}
for(unsigned int j = 0; j < (size); j++)
{
       unsigned int val = buffer[j];
   for(int t = 0; t < 4; t++)
   {
           unsigned int valbyte = val%256;
           count[valbyte]++;
           val = val/256;
   }
   }
for(i = 1; i <= 255; i++)
{
freq[i] = static_cast<double>(count[i]) / static_cast<double>((size * 4) - count [0]);
#ifdef DEBUG
cout << "Prob(" << i << ") = " << static_cast<double>(freq[i], 10) << " (" << count[i] << " Times)\n";
#endif
if (freq[i] > 0.0){entropy -= freq[i] * (log(freq[i]) / log(2.0));}
}
return entropy;
}
 
 

Cabe decir que el máximo de la entropía es 8.
Este programa es el q uso para analizar la entropía de un algoritmo de cifrado. Tener buena entropía es escencial para la fortaleza de un algoritmo. Como vez este programa pone a prueba el algoritmo dandole primero una input con entropía baja (4.95). Y luego una entropía alta creada por el generador pseudoaleatorio de c++ (7.95). Vemos entonces que la salida del algoritmo, da 4.55 de entropía con el input de entropía baja y 7.54 con el de entropía alta. Concluyendo entonces que este algoritmo disminuye la entropía de la entrada, en vez de aumentarla.
Filtré todos los "0" ya que arruinaban el resultado, debido a que es posible que en 4 bytes aleatorios los primeros bytes sean "0". De todas maneras el resultado es el mismo incluyendo los bytes, pero en este caso aparecen muchisimos "0".

Bueno, espero haberte ayudado, y esperamos con ansias tu proximo algoritmo, o quizas una v2.0 de este.

Un abrazo
APOKLIPTICO
En línea

AMD Phenom II 1075T X6 @ 290 Mhz x 11 (HT 2036 Mhz NB Link 2616 Mhz) 1.23 Vcore
ASUS M4A89GTD-PRO/USB3
2x2gb G-Skill RipjawsX DDR3 1600 Mhz CL7 (7-8-7-24-25-1T)
Seagate 500 Gb
XFX HD4850 512Mb GDDR3. 650 Mhz/995 Mhz 1.1 Tflops.
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines