Joven hacker sonriendo

Comprobar Fortaleza Diccionario

Necesidad

Comprobar fortaleza de contraseñas tipo palabra usando diccionarios de contraseñas comunes en COBOL.

Contexto

A continuación se describe las circunstancias bajo las cuales la siguiente solución tiene sentido:

  1. Se está desarrollando una aplicación en COBOL.

  2. Las claves tipo palabra no deben contener palabras de diccionario[1].

Solución

  1. Para la construcción de la solución se debe definir o buscar una lista con contraseñas comunes, las cuales serán usadas para comparar con la contraseña ingresada por el usuario. Existen listas de diccionarios que se recomiendan para realizar la búsqueda.[2],[3],[4],[5],[6]

  2. Por cuestiones de espacio se creó el archivo COMMONPASS con el siguiente contenido:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    123
    password
    hello
    admin
    busy
    12345
    dragon
    qwerty
    system
    mustang
    
  3. Se da inicio al programa definiendo la división IDENTIFICATION DIVISION:

    cobolcpass.cbl
    1
    2
    3
    4
    5
           IDENTIFICATION DIVISION.
          ******************
          * Identification *
          ******************
           PROGRAM-ID. COBOLCPASS.
    
  4. En la división ENVIRONMENT DIVISION se asigna la variable COMMON-PASS al archivo COMMONPASS, el cual contiene las contraseñas comunes:

    1
    2
    3
    4
    5
    6
    7
    8
          ***************
          * Environment *
          ***************
           ENVIRONMENT DIVISION.
           INPUT-OUTPUT SECTION.
           FILE-CONTROL.
               SELECT COMMON-PASS ASSIGN TO "COMMONPASS"
               ORGANIZATION IS SEQUENTIAL.
    
  5. En la división DATA DIVISION se establece la estructura para el archivo con contraseñas comunes:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
          ********
          * Data *
          ********
           DATA DIVISION.
    
           FILE SECTION.
           FD COMMON-PASS.
           01 PASSWORD-RECORD.
               88 WS-PASS-EOF VALUE HIGH-VALUES.
               02 WS-PASSWORD PIC X(26).
    
  6. En la sección de almacenamiento declaramos cuatro variables:

    • WS-USERPASS: Contraseña ingresada por el usuario.

    • WS-COUNT: Contador que indica si la contraseña en el diccionario está contenida en la contraseña ingresada por el usuario.

    • WS-LENGTH: Longitud real de la contraseña en el diccionario.

    • WS-FLAG: Bandera que indica si el requisito es cumplido.

    1
    2
    3
    4
    5
    6
    7
           WORKING-STORAGE SECTION.
           01 WS-USERPASS     PIC X(26).
           01 WS-COUNT        PIC 9(02) VALUE 0.
           01 WS-LENGTH       PIC 9(02).
           01 WS-FLAG         PIC 9     VALUE 0.
               88 WS-FLAG-FALSE VALUE 0.
               88 WS-FLAG-TRUE  VALUE 1.
    
  7. En la división PROCEDURE DIVISION se encuentra la lógica del programa. Obtenemos la contraseña del usuario y la convertimos a mayúscula:

    1
    2
    3
    4
    5
    6
    7
    8
          ********
          * Main *
          ********
           PROCEDURE DIVISION.
           MAIN.
               DISPLAY "Ingrese clave a verificar: ".
               ACCEPT WS-USERPASS.
               MOVE FUNCTION UPPER-CASE(WS-USERPASS) TO WS-USERPASS.
    
  8. Abrimos el archivo con las contraseñas comunes:

    1
           OPEN INPUT COMMON-PASS.
    
  9. Leemos el primer registro del diccionario y a través del uso de la sentencia AT END podemos saber si alcanzó el final del archivo:

    1
    2
    3
           READ COMMON-PASS
               AT END SET WS-PASS-EOF TO TRUE
           END-READ.
    
  10. Convertimos la contraseña en el diccionario a mayúscula y se inicializan las variables WS-COUNT y WS-LENGTH. Tanto la contraseña ingresada por el usuario como la contenida en el diccionario, son convertidas a mayúscula por facilidad de validación:

    1
    2
    3
    4
           PERFORM UNTIL WS-PASS-EOF
               MOVE FUNCTION UPPER-CASE(WS-PASSWORD) TO WS-PASSWORD
               MOVE 0 TO WS-COUNT
               MOVE 0 TO WS-LENGTH
    
  11. Obtenemos la longitud real de la contraseña en el diccionario para evitar problemas con los espacios al final de la misma:

    1
    2
    3
    4
    5
           INSPECT FUNCTION REVERSE(WS-PASSWORD)
           TALLYING WS-LENGTH FOR LEADING SPACES
    
           COMPUTE WS-LENGTH = FUNCTION LENGTH(WS-PASSWORD)
                               - WS-LENGTH
    
  12. Se busca todas las coincidencias de la contraseña en el diccionario dentro de la contraseña ingresada por el usuario:

    1
    2
    3
           INSPECT WS-USERPASS
           TALLYING WS-COUNT
           FOR ALL WS-PASSWORD(1:WS-LENGTH)
    
  13. Si la contraseña está contenida en la contraseña ingresada por el usuario, entonces salimos del procesamiento del archivo:

    1
    2
    3
    4
           IF WS-COUNT > 0 THEN
               MOVE 1 TO WS-FLAG
               PERFORM FINAL-PROCESS
           END-IF
    
  14. A continuación, leemos el próximo registro:

    1
    2
    3
    4
               READ COMMON-PASS
                   AT END SET WS-PASS-EOF TO TRUE
               END-READ
           END-PERFORM
    
  15. Como proceso final, se cierra el archivo:

    1
    2
           FINAL-PROCESS.
               CLOSE COMMON-PASS
    
  16. Si la bandera está en falso, significa que el requisito fue cumplido y la contraseña no contiene palabras de diccionario:

    1
    2
    3
    4
    5
    6
    7
           IF WS-FLAG-FALSE THEN
               DISPLAY "Requisito cumplido"
           ELSE
               DISPLAY "Requisito no cumplido"
           END-IF.
    
           STOP RUN.
    
  17. A continuación se presenta una tabla con los resultados obtenidos luego de ejecutar la aplicación:

    Tabla 1. Resultados obtenidos luego de ejecutar la aplicación.
    Palabra Resultado

    123

    No cumplido

    hello

    No cumplido

    admin

    No cumplido

    SystEM

    No cumplido

    abcd123abcd

    No cumplido

    My-Str0n6_P4assw0rd!

    Cumplido

Descargas

Puedes descargar el código fuente pulsando en el siguiente enlace:

  1. cobolcpass.cbl >> contiene todas las instrucciones COBOL del programa.

Referencias

  1. REQ.0101: El sistema debe tener la capacidad de validar que ninguna contraseña contenga palabras de diccionario.

  2. Dazzlepod Uniqpass.

  3. Openwall Wordlist.

  4. Wordlist project.

  5. Packet Storm Security Wordlists.

  6. Linux Password Security with pam_cracklib.




Haz un comentario