Diferencia de diccionarios (wordlists)

Iniciado por MA40, 3 Noviembre 2021, 14:22 PM

0 Miembros y 1 Visitante están viendo este tema.

MA40

Hola.

Tengo dos archivos txt diccionarios (wordlists) con miles de millones de palabras (una en cada línea del archivo) y quiero hacer una sustracción de uno sobre el otro. Necesito crear otro archivo que contenga la diferencia de ambos, sería la parte verde de la imagen.



Puedo utilizar comandos Linux o algún software que lo permita. ¿Cómo puedo hacerlo?

Un saludo y gracias.
¿Qué sucedería si se enfrentara una fuerza imparable contra un muro inamovible?
Visita Ediciones MA40 - Libros clásicos de ajedrez y este blog de ajedrez
ChessFaucet.com - Gana bitcoins jugando al ajedrez contra el ordenador

MCKSys Argentina

MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


Serapis

#2
Me edito.... al relerte de nuevo, veo que quieres justo lo contrario a lo que me pareció entender al principio... Tu quieres crear un fichero con las entradas únicas que constan en ambos ficheros, es decir quieres unirlos y por tanto eliminar entradas repetidas...

Dejo al final del mensaje...lo que antes era el contenido del mismo para posibles interesados
Aunque, todavía si al final se unen A2 + B2 + C en un único fichero se consigue el resultado deseado... No obstante puede hacerse más óptimo si se hace un diseño específico.

Lo mejor para eliminar entradas repetidas es usar una tabla hash.

funcion UnirFilesSinRepes(  RutaA, RutaB)
   abrir ficheros A(rutaA), B(rutaB)
   crear y abrir fichero temporal C
   
   THash = crear nueva tabla hash

   AddFileToTHash(tHash, fichero A)
   AddFileToTHash(tHash, fichero B)

   por cada item en THash
       copiar item al fichero C
   siguiente
   vaciar y eliminar tHash

   cerrar fichero C (y quizás renombrar...)
   cerrar y (seguramente) eliminar A, B
fin funcion

funccion AddFileToTHash(tHash, fichero )
   Por cada linea en fichero
       h = Hashing(linea)
       tHash.Add(h, Linea)
       // habitualmente una tabla hash no admite repes, pero si no fuera el caso...
       //si tHash.Contiene(h) = FALSE
       //   tHash.add(h, linea)
       //fin si
   siguiente
fin funcion  




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


======================================================
Quedaría mejor en un spolier, pero el foro no dispone de ellos...

Esta solución es para tener en un fichero las entradas que constan en los dos ficheros  y dejar en cada fichero solo las entradas que no contiene el otro.

Tienes dos opciones, dependiendo de si al menos uno de los dos ficheros está ordenado o ninguno.

Básicamente como quieres crea 1 fichero con la diferencia y los originales (A1 y B1) quedarán también modificados, necesitarás crear 3 ficheros (A2,B2,C)...

- Si alguno de los fichero no está ordenado... leer en memoria y ordenar, luego guardar a fichero
- Ahora que los dos ficheros están ordenados:

funcion DiferenciaFiles(  RutaA, RutaB)
   abrir ficheros A1(rutaA), B1(rutaB)
   crear y abrir ficheros temporales A2, B2, C

   Por cada linea1 en fichero A1
       Por cada linea2 en fichero B1
           Si (linea2 > linea1)
               copiar linea1 al fichero A2 y salir dle bucle
           pero Si (linea2 = linea1)
               copiar linea2 al fichero C y salir del bucle.
           si no // linea2 < linea1
               copiar linea2 al fichero B2
           fin si
       siguiente
   siguiente

   cerrar y eliminar A1, B1
   renombrar A2 como A1, y B2 como B1.
fin funcion

 

- Opcionalmente si ninguno (o solo uno) de los dos ficheros está ordenado.
 Se puede crear una tabla hash, y meter en ella las entradas de un fichero...

funcion DiferenciaFiles(  RutaA, RutaB)
   abrir ficheros A1(rutaA), B1(rutaB)
   crear y abrir ficheros temporales  A2, B2, C

   THash = llenar desde fichero A1
   Por cada linea1 en fichero B1
       h = Hashing(linea1)
       si tHash.Contiene(h)
            copiar linea1 al fichero C y THash.Eliminar(h)
       si no
            copiar linea1 al fichero B2
       fin si
   siguiente
   // como se han ido eliminando las entradas que están contenidas también en B1,
   // al final solo quedan entradas únicas en la tabla hash.
   por cada item en THash
       copiar item al fichero A2
   siguiente

   cerrar y eliminar A1, B1
   renombrar A2 como A1, y B2 como B1.


NOTA: Se supone que siendo un diccionario, en un mismo fichero no habrá entradas repetidas... si fuera el caso, habria que tenerlo en cuenta para modificar el pseudocódigo ofrecido...
======================================================


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

MA40

#3
Muchas gracias a los dos.

La solución es la que comenta MCKSys Argentina, aún me lo estoy estudiando porque no me funciona con la ñ, ¿, ¡, etc.

Para que lo entendáis mejor os pongo un ejemplo:

Supongamos que lanzo un ataque de diccionario contra un hash. El diccionario que utilizo tiene una lista de un millón de contraseñas y ninguna es la correcta.

Una vez terminado el ataque, empiezo otro igual pero con otro diccionario distinto y con otro millón de contraseñas. Pero para estar seguro de que no voy a repetir los intentos fallidos del primer ataque, tengo que eliminar de este segundo diccionario las contraseñas que estén en los dos diccionarios repetidas.

¿Se entiende mejor así?

Un saludo.
¿Qué sucedería si se enfrentara una fuerza imparable contra un muro inamovible?
Visita Ediciones MA40 - Libros clásicos de ajedrez y este blog de ajedrez
ChessFaucet.com - Gana bitcoins jugando al ajedrez contra el ordenador

EdePC

Con PowerShell se puede hacer fácilmente, darle x cantidad de wordlists, que ordene y quite duplicados para que luego se guarde en un nuevo wordlist limpio

CitarPS C:\Users\EdSon\Desktop> Get-Content .\wl01.txt
ñandú
ratón
murciélago
cigüeña

PS C:\Users\EdSon\Desktop> Get-Content .\wl02.txt
caballo
ñandú
lobo
ballena
cigüeña
canario

PS C:\Users\EdSon\Desktop> Get-Content .\wl01.txt, .\wl02.txt | Sort-Object -Unique > .\wl03.txt

PS C:\Users\EdSon\Desktop> Get-Content .\wl03.txt
ballena
caballo
canario
cigüeña
lobo
murciélago
ñandú
ratón

MA40

#5
Hola EdePC.

Eso sería sumar los archivos y yo lo que quiero es restarlos.

Tomando tu ejemplo, lo que me interesaría sería obtener wl03.txt = wl02.txt - wl01.txt.

O sea:

Citarwl03.txt:

    caballo
    lobo
    ballena
    canario

Un saludo.
¿Qué sucedería si se enfrentara una fuerza imparable contra un muro inamovible?
Visita Ediciones MA40 - Libros clásicos de ajedrez y este blog de ajedrez
ChessFaucet.com - Gana bitcoins jugando al ajedrez contra el ordenador

Serapis

#6
Tu necesidad está contenida en mi respuesta.

Por un lado, si tienes dos (o más) diccionarios a aplicar, puede suceder dos cosas:
- Que prepares los ficheros antes de abordar el ataque.
 En este caso, la respuesta la tienes en la parte superior de mi mensaje: Reunir un solo fichero el contenido de ambos sin repeticiones.
- Que abordes el ataque primero con un diccionario y luego debas preparar el segundo.
 en este caso, la respuesta la tienes en la parte inferior de mi mensaje (solo que má s simple, al no requerir guarda cada fichero si no solo el de tu interés): Reunir en un fichero las entradas que constan en el 2º que no contan en el primero.
Citarfuncion DiferenciaFiles(  RutaA, RutaB)
   abrir ficheros A1(rutaA), B1(rutaB)
   crear y abrir ficheros temporales A2, B2, C

   THash = llenar desde fichero A1
   Por cada linea1 en fichero B1
       h = Hashing(linea1)
       si tHash.Contiene(h)
            copiar linea1 al fichero C y THash.Eliminar(h)
       si no
            copiar linea1 al fichero B2
       fin si
   siguiente
   // como se han ido eliminando las entradas que están contenidas también en B1,
   // al final solo quedan entradas únicas en la tabla hash.
   por cada item en THash
       copiar item al fichero A2
   siguiente

   cerrar y eliminar A1, B1
   renombrar A2 como A1, y B2 como B1.

   cerrar ficheros

Adicionalmente, para futuras situaciones lo preferible es que cada diccionario contenga solo entradas únicas. Puedes realizar cualquiera de las soluciones que te propuse, pues la diferencia entre ambos casos es la cantidad de ficheros resultantes (pero en ambos casos cda fichero pasa a tener entradas únicas sin repeticiónes)

- La solución de la parte superior:  reúne en un solo fichero con las entradas que constan en ambos ficheros, pero sin repetidos.

- La solución de la parte inferior: te proporciona 3 ficheros distintos a partir de los 2 de entrada, los 3 tienen entradas unicas... (uno pasa a conteneder las entradas que solo constan en el él y no en el segundo, el otro pasa a tener igualmente las que solo constan en el y no en el primero, y un tercero pasa a contener las entradas que aparecían en ambos pero sin repetirse). Luego, puedes unirlos de la forma que te parezca o dejarlos sueltos.

En cualquiera de los casos dejan de existir entradas repetidas.



Cita de: EdePC en 11 Noviembre 2021, 22:33 PM
Con PowerShell se puede hacer fácilmente, darle x cantidad de wordlists, que ordene y quite duplicados para que luego se guarde en un nuevo wordlist limpio
mmmm... eso de fácilmente, lo tenemos que dejar aparte, si resulta ser verdad cuando dice:
Citar...con miles de millones de palabras
Ordenar miles de millones, requiere su tiempito y me temo que tampoco tendría suficiente RAM...
Un sencillo cálculo:
Imaginemos 4.000 millones (4 es un número pequeño en cuanto a 'miles'), suponiendo solo 10 caracteres por contraseña, ...tendríamos que, mantener en memoria el array supondría unos 37Gb. de RAM (UTF8)... ya ni contamos el tiempo de carga dle fichero al array.

Un problema así no puede abordarse con RAM si no tirando de ficheros... si hay que ordenar manteniendo en fichero, entonces resulta aún más eterno (cada entrada debe ser comparada una enorme cantidad de veces, tanto más cuanto mayor sea el array). Incluso la cantidad de veces que debe escribirse es log2(4.000 millones) más o menos 32 veces (2^32 =aprox. 4 mil 300 millones).

En cambio el uso de tablas hash, tirando de ficheros, no supone una sobrecarga excesiva, porque cada entrada se escribe una sola vez y se lee (de origen una vez +) en cálculo 1 vez + la cantidad de posibles colisiones que tuviere... (pongamos que cada entrada tuviere 10-50 colisiones de media), claro que la cantidad de colisiones de promedio dependerá del algoritmo de hashing utilizado. Pero salvo un muy mal algoritmo, esto sería rápido.

Una cosa es que el código sea 'fácil' de escribir y otra muy distinta que sea rentable ejecutarlo.
...claro que al final comenta sobre diccionarios de 1 millón de entradas (que es muy asumible), nada se sabe si solo es por ejemplificar o si es más o menos el caso real y arriba se coló poniendo 'miles de millones'.

Por descontado tener diccionarios de miles de millones de entrada, es monstruosamente estúpido. Las claves deberían ser generadas automáticamente a medida que se usan... usar y consumir.

MA40

Hola Serapis.

Muchas gracias.

Cita de: Serapis en 12 Noviembre 2021, 01:02 AM

Por descontado tener diccionarios de miles de millones de entrada, es monstruosamente estúpido.


No entiendo ese comentario. ¿Qué quieres decir?

¿Te parece estúpido usar el Top2Billion-probable-v2.txt (1.973.218.846 contraseñas) o el rockyou2021.txt (8.459.060.239 contraseñas)?

Un saludo.
¿Qué sucedería si se enfrentara una fuerza imparable contra un muro inamovible?
Visita Ediciones MA40 - Libros clásicos de ajedrez y este blog de ajedrez
ChessFaucet.com - Gana bitcoins jugando al ajedrez contra el ordenador

Serapis

Cita de: MA40 en 12 Noviembre 2021, 14:13 PM
¿Te parece estúpido usar el Top2Billion-probable-v2.txt (1.973.218.846 contraseñas) o el rockyou2021.txt (8.459.060.239 contraseñas)?
Sí.
No es práctico usar diccionarios gigantes (desde fichero) con fuerza bruta.
Dado el caso específico, tiene sentido tener un conjunto (pongamos 100mil-10millones) de contraseñas preseleccionadas en un fichero.

Si el diccionario es gigante (como esos monstruos de 2mil y 8 mil millones), es preferible crear las secuencias en el momento justo de usarlo sin tener que almacenar nada a fichero.
Además dependiendo del sistema, si la cadencia de pruebas por segundo no es muy elevada, el tiempo para probar por fuerza bruta esa enorme cantidad, puede hacerlo inasequible.

Si quieres ver lo 'bueno' que son tales diccionarios, basta que anotes en un papel media docena de contraseñas que tú mimo uses y las busques en ellos.
- Si no aparece ninguna... debieras preguntarte porqué van a aparecer las de otros.
- Y si te aparecen demasiadas, es señal de que tu patrón para crear constraseñas, sigue eso, un patrón demasiado 'cuadrado' y elemental.
En definitiva, si tus contraseñas tienen un mínimo de 16 caracteres (muchos sitios, programas, etc... limitan el tamaño máximo a una cantidad ridícula, lo que es un error), la probabilidad de que un dicccionario aunque sea de 8 mil millones la contenga es prácticamente nula, salvo que como usuario se siga un patrón torpe.

Es cierto que aún no todos los sitios, limitan por hardware la cantidad de intentos por segundo. Así que aún será posible 'cazar' contraseñas durante alguns años... a incautos. Los programas no debieran limitarlo salvo que se usare el propio algoritmo del programa.