From 461706be5a77adae870f92c0441f20f318e9fa4f Mon Sep 17 00:00:00 2001
From: Abhisha Nirmalathas <a.nirmalathas1@student.unimelb.edu.au>
Date: Sat, 18 May 2019 20:05:19 +1000
Subject: [PATCH] generate using common letter substitutions

---
 common_password_statistics.py |  16 +++-
 common_subs.txt               |  52 +++++++++++
 decrypt.c                     |  37 ++++----
 four_password_strategy.c      |  35 +++++---
 four_password_strategy.h      |   6 +-
 passwords.c                   | 164 ++++++++++++++++++++++++++++++++++
 passwords.h                   |   6 +-
 proj-2_common_passwords.txt   |   1 +
 sha256-helper.c               |   2 +
 six_password_strategy.c       |  36 ++++++--
 six_password_strategy.h       |   8 +-
 11 files changed, 318 insertions(+), 45 deletions(-)
 create mode 100644 common_subs.txt

diff --git a/common_password_statistics.py b/common_password_statistics.py
index a358c2f..140f6e5 100644
--- a/common_password_statistics.py
+++ b/common_password_statistics.py
@@ -100,4 +100,18 @@ def get_character_frequencies():
     f.close()
 
 # create_common_password_substitutions()
-get_character_frequencies()
\ No newline at end of file
+# get_character_frequencies()
+
+def write_out_common_substitutions():
+    f = open("common_subs.txt", "w")
+    for char, subs in common_substituions.items():
+        f.write(char)
+        print(len(char))
+        f.write(": ")
+        for x in subs:
+            f.write(x)
+            f.write(" ")
+        f.write("\n")
+    f.close()
+
+write_out_common_substitutions()
\ No newline at end of file
diff --git a/common_subs.txt b/common_subs.txt
new file mode 100644
index 0000000..de7c917
--- /dev/null
+++ b/common_subs.txt
@@ -0,0 +1,52 @@
+a: A @ 4 
+b: 8 B 
+c: C 
+d: D 0 
+e: E 3 
+f: F 7 
+g: G 6 9 & 
+h: H 
+i: I 1 l ! 
+j: J 
+k: K 
+l: L 1 I 
+m: M 
+n: N V 1 
+o: 0 O 
+p: P 
+q: Q 0 O 
+r: R 
+s: S 5 o $ 
+t: T 7 
+u: U ( ) 
+v: V 
+w: W 
+x: X 
+y: Y 
+z: Z 5 $ 
+A: a @ 4 
+B: 8 b 
+C: c 
+D: d 0 
+E: e 3 
+F: f 7 
+G: g 6 9 & 
+H: h 
+I: i 1 l ! 
+J: j 
+K: k 
+L: l 1 I 
+M: m 
+N: n V 1 
+O: 0 o 
+P: p 
+Q: q 0 O 
+R: r 
+S: s 5 o $ 
+T: t 7 
+U: u ( ) 
+V: v 
+W: w 
+X: x 
+Y: y 
+Z: z 5 $ 
diff --git a/decrypt.c b/decrypt.c
index 91f87d5..35a51cb 100644
--- a/decrypt.c
+++ b/decrypt.c
@@ -8,7 +8,7 @@
 #include "four_password_strategy.h"
 #include "six_password_strategy.h"
 #include "passwords.h"
-// adapted from https://github.com/RemyNoulin/sha256
+
 char** store_password_hashes(char* hashes){
     char **password_hashes = (char**)malloc((strlen(hashes)/64)*sizeof(char*));
     assert(password_hashes);
@@ -21,7 +21,9 @@ char** store_password_hashes(char* hashes){
     return password_hashes;
 }
 
-void read_hash_file_four(FILE *file){
+void read_hash_file_four(char *file_name, int n_guesses){
+    FILE *file;
+    file = fopen(file_name, "r");
     if (file){
         char hashes[650];
         int n=0;
@@ -38,9 +40,9 @@ void read_hash_file_four(FILE *file){
             hash_table_put(password_hashes, words[i], (i+1));
         };
         Passwords *cracked_passwords = create_passwords(10);
-        generate_guesses_four(10, password_hashes, cracked_passwords);
-        popular_character_guess_four(password_hashes, cracked_passwords);
-        brute_force_four(password_hashes, cracked_passwords);
+        n_guesses = generate_guesses_four(n_guesses, password_hashes, cracked_passwords);
+        n_guesses = popular_character_guess_four(password_hashes, cracked_passwords, n_guesses);
+        brute_force_four(password_hashes, cracked_passwords, n_guesses);
         print_passwords(cracked_passwords);
         for(int i=0; i < strlen(hashes)/64; i++){
             printf("%d:    %s\n", i, words[i]);
@@ -54,7 +56,9 @@ void read_hash_file_four(FILE *file){
 }
 
 
-void read_hash_file_six(FILE *file){
+void read_hash_file_six(char *file_name, int n_guesses){
+    FILE *file;
+    file = fopen(file_name, "r");
     if (file){
         char hashes[650];
         int n=0;
@@ -70,9 +74,10 @@ void read_hash_file_six(FILE *file){
             printf("%d:    %s\n", i, words[i]);
             hash_table_put(password_hashes, words[i], (i+1));
         };
-        generate_guesses_six(20, password_hashes);
-        popular_character_guess_six(password_hashes);
-        brute_force_six(password_hashes);
+        Passwords *cracked_passwords = create_passwords(20);
+        n_guesses = generate_guesses_six(n_guesses, password_hashes, cracked_passwords);
+        n_guesses = popular_character_guess_six(password_hashes, cracked_passwords, n_guesses);
+        brute_force_six(password_hashes, cracked_passwords,n_guesses);
         for(int i=0; i < strlen(hashes)/64; i++){
             printf("%d:    %s\n", i, words[i]);
             free(words[i]);
@@ -84,19 +89,19 @@ void read_hash_file_six(FILE *file){
 }
 
 int main(int argc, char *argv[]){
-    FILE *file;
-    file = fopen("pwd4sha256", "r");
-    read_hash_file_four(file);
-    // file = fopen("pwd6sha256", "r");
-    // read_hash_file_six(file);
     if (argc == 1){
         //generate guesses and test against SHA256 hashes
+        read_hash_file_four("pwd4sha256", -1);
+        read_hash_file_six("pwd6sha256", -1);
     }
     else if(argc == 2){
-        int n_guesses = argv[argc-1];
+        int n_guesses = atoi(argv[argc-1]);
+        printf("remaining passwords are : %d\n", n_guesses);
         // have n amount of guesses
+        read_hash_file_four("pwd4sha256", n_guesses);
+        read_hash_file_six("pwd6sha256", n_guesses);
     }
     else if(argc == 3){
         // read file and do stuff
     }
-}
+}
\ No newline at end of file
diff --git a/four_password_strategy.c b/four_password_strategy.c
index bb63978..1a95405 100644
--- a/four_password_strategy.c
+++ b/four_password_strategy.c
@@ -8,11 +8,14 @@
 #include "four_password_strategy.h"
 #include "sha256-helper.h"
 #include "passwords.h"
-void brute_force_four(HashTable *ht, Passwords* solved){
+void brute_force_four(HashTable *ht, Passwords* solved, int n_guesses){
     printf("brute force\n");
     char brute_guess[4];
     SHA256_CTX ctx;
     int hash;
+    if (remaining_hashes(ht) == 0 || n_guesses == 0){
+        return;
+    }
     for(int i=65;i < 127; i++){
         brute_guess[0] = (char)i;
         for(int j=33;j < 127; j++){
@@ -32,10 +35,12 @@ void brute_force_four(HashTable *ht, Passwords* solved){
                         printf("%s %d\n", brute_guess, hash);
                         add_new_cracked(solved, brute_guess);
                         printf("remaining passwords are : %d\n", remaining_hashes(ht));
+                        n_guesses = generate_common_subs_four(solved,n_guesses,ht);
                     }
                     free(hex_guess);
-                    if (remaining_hashes(ht) == 0){
-                        break;
+                    n_guesses--;
+                    if (remaining_hashes(ht) == 0 || n_guesses == 0){
+                        return;
                     }
                 }
             }
@@ -49,7 +54,7 @@ void brute_force_four(HashTable *ht, Passwords* solved){
     }
 }
 
-int popular_character_guess_four(HashTable *ht, Passwords* solved){
+int popular_character_guess_four(HashTable *ht, Passwords* solved, int n_guesses){
     printf("popular character guess strategy\n");
     char brute_guess[4];
     SHA256_CTX ctx;
@@ -58,6 +63,10 @@ int popular_character_guess_four(HashTable *ht, Passwords* solved){
     FILE *file = fopen("common_password_frequency.txt", "r");
     char frequent_characters[60];
     int index = 0;
+    if (remaining_hashes(ht) == 0 || n_guesses == 0){
+        fclose(file);
+        return 0;
+    }
     while (fgets(line, sizeof(line), file)){
         line[1] = '\0';
         frequent_characters[index] = line[0];
@@ -82,24 +91,26 @@ int popular_character_guess_four(HashTable *ht, Passwords* solved){
                         printf("%s %d\n", brute_guess, hash);
                         add_new_cracked(solved, brute_guess);
                         printf("remaining passwords are : %d\n", remaining_hashes(ht));
+                        n_guesses = generate_common_subs_four(solved,n_guesses,ht);
                     }
                     free(hex_guess);
-                    if (remaining_hashes(ht) == 0){
-                        break;
+                    n_guesses--;
+                    if (remaining_hashes(ht) == 0 || n_guesses == 0){
+                        return 0;
                     }
                 }
             }
         }
     }
-    return 0;
+    return n_guesses;
 }
 
-void generate_guesses_four(int n_guesses, HashTable *ht, Passwords* solved){
+int generate_guesses_four(int n_guesses, HashTable *ht, Passwords* solved){
     FILE* file = fopen("proj-2_common_passwords.txt", "r");
     char line[20];
     SHA256_CTX ctx;
     int hash;
-    while (fgets(line, sizeof(line), file) && remaining_hashes(ht) > 0){
+    while (fgets(line, sizeof(line), file) && remaining_hashes(ht) > 0 && n_guesses != 0){
         line[4] = '\0';
         // printf("%s\n", line);
         sha256_init(&ctx);
@@ -110,11 +121,13 @@ void generate_guesses_four(int n_guesses, HashTable *ht, Passwords* solved){
         if ((hash = hash_table_get(ht, hex_guess))>0){
             printf("%s %d\n", line, hash);
             add_new_cracked(solved, line);
-            print_passwords(solved);
             printf("remaining passwords are : %d\n", remaining_hashes(ht));
+            n_guesses = generate_common_subs_four(solved,n_guesses,ht);
         }
+        n_guesses--;
         free(hex_guess);
     }
-    printf("finished file");
+    printf("finished file\n");
     fclose(file);
+    return n_guesses;
 }
\ No newline at end of file
diff --git a/four_password_strategy.h b/four_password_strategy.h
index c65148a..b9492cc 100644
--- a/four_password_strategy.h
+++ b/four_password_strategy.h
@@ -3,8 +3,8 @@
 #include "hashtable.h"
 #include "proj-2_sha256.h"
 #include "passwords.h"
-void brute_force_four(HashTable *ht, Passwords* solved);
+void brute_force_four(HashTable *ht, Passwords* solved, int n_guesses);
 
-int popular_character_guess_four(HashTable *ht, Passwords* solved);
+int popular_character_guess_four(HashTable *ht, Passwords* solved, int n_guesses);
 
-void generate_guesses_four(int n_guesses, HashTable *ht, Passwords* solved);
+int generate_guesses_four(int n_guesses, HashTable *ht, Passwords* solved);
diff --git a/passwords.c b/passwords.c
index dc37220..fa7ae11 100644
--- a/passwords.c
+++ b/passwords.c
@@ -5,6 +5,9 @@
 #include <assert.h>
 #include <string.h>
 
+#include "hashtable.h"
+#include "proj-2_sha256.h"
+#include "sha256-helper.h"
 #include "passwords.h"
 
 struct passwords {
@@ -47,4 +50,165 @@ void print_passwords(Passwords* pwrds){
     for(int i=0; i< pwrds->current_size; i++){
         printf("%s\n", pwrds->cracked[i]);
     }
+}
+
+
+int generate_common_subs_four(Passwords* solved, int n_guesses, HashTable *ht){
+    if (remaining_hashes(ht) == 0 || n_guesses == 0){
+        return 0;
+    }
+    char **subs;
+    subs = calloc(4,sizeof(char*));
+    assert(subs);
+    char *characters = calloc(4, sizeof(char));
+    assert(characters);
+    char *word = solved->cracked[solved->current_size-1];
+    char line[20];
+    int *subs_size = calloc(4, sizeof(int));
+    assert(subs_size);
+    char *token;
+    const char s[2] = " ";
+    for(int i=0; i < 4; i++){
+        subs[i] = malloc(10);
+        assert(subs[i]);
+        subs_size[i] = 0;
+        FILE *file = fopen("common_subs.txt", "r");
+        while (fgets(line, sizeof(line), file)){
+            if(line[0] == word[i]){
+                characters[i] = line[0];
+                subs[i][subs_size[i]] = line[0];
+                subs_size[i]++;
+                token = strtok(strstr(line, s), s);
+                while(token != NULL && strlen(token) == 1){
+                    subs[i][subs_size[i]] = (char)*token;
+                    subs_size[i]++;
+                    token = strtok(NULL, s);
+                }
+            }
+        }fclose(file);
+    }
+    char sub_guess[4];
+    int hash;
+    SHA256_CTX ctx;
+    for(int i=0; i<subs_size[0]; i++){
+        sub_guess[0] = subs[0][i];
+        for(int j=0; j<subs_size[1]; j++){
+            sub_guess[1] = subs[1][j];
+            for(int k=0; k<subs_size[2]; k++){
+                sub_guess[2] = subs[2][k];
+                for(int l=0; l<subs_size[3]; l++){
+                    sub_guess[3] = subs[3][l];
+                    sub_guess[4] = '\0';
+                    sha256_init(&ctx);
+                    sha256_update(&ctx, (BYTE*)sub_guess, strlen(sub_guess));
+                    BYTE guess[32];
+                    sha256_final(&ctx, guess);
+                    char* hex_guess = sha256_byteToHexString(guess);
+                    // printf("%s\n", sub_guess);
+                    if ((hash = hash_table_get(ht, hex_guess))>0){
+                        printf("%s %d\n", sub_guess, hash);
+                        add_new_cracked(solved, sub_guess);
+                        printf("remaining passwords are : %d\n", remaining_hashes(ht));
+                    }
+                    free(hex_guess);
+                    n_guesses--;
+                    if (remaining_hashes(ht) == 0 || n_guesses == 0){
+                        return 0;
+                    }
+                }
+            }
+        }
+    }
+
+
+
+    for(int i=0; i < 4; i++){
+        free(subs[i]);
+    }
+    free(characters);
+    free(subs);
+    free(subs_size);
+    return n_guesses;
+}
+
+
+int generate_common_subs_six(Passwords* solved, int n_guesses, HashTable *ht){
+    if (remaining_hashes(ht) == 0 || n_guesses == 0){
+        return 0;
+    }
+    char **subs;
+    subs = calloc(6,sizeof(char*));
+    assert(subs);
+    char *characters = calloc(6, sizeof(char));
+    assert(characters);
+    char *word = solved->cracked[solved->current_size-1];
+    char line[20];
+    int *subs_size = calloc(6, sizeof(int));
+    assert(subs_size);
+    char *token;
+    const char s[2] = " ";
+    for(int i=0; i < 6; i++){
+        subs[i] = malloc(10);
+        assert(subs[i]);
+        subs_size[i] = 0;
+        FILE *file = fopen("common_subs.txt", "r");
+        while (fgets(line, sizeof(line), file)){
+            if(line[0] == word[i]){
+                characters[i] = line[0];
+                subs[i][subs_size[i]] = line[0];
+                subs_size[i]++;
+                token = strtok(strstr(line, s), s);
+                while(token != NULL && strlen(token) == 1){
+                    subs[i][subs_size[i]] = (char)*token;
+                    subs_size[i]++;
+                    token = strtok(NULL, s);
+                }
+            }
+        }fclose(file);
+    }
+    char sub_guess[6];
+    int hash;
+    SHA256_CTX ctx;
+    for(int i=0; i<subs_size[0]; i++){
+        sub_guess[0] = subs[0][i];
+        for(int j=0; j<subs_size[1]; j++){
+            sub_guess[1] = subs[1][j];
+            for(int k=0; k<subs_size[2]; k++){
+                sub_guess[2] = subs[2][k];
+                for(int l=0; l<subs_size[3]; l++){
+                    sub_guess[3] = subs[3][l];
+                    for(int m=0;m < subs_size[4]; m++){
+                        sub_guess[4] = (char)subs[4][m];
+                        for(int n=0;n < subs_size[5]; n++){
+                            sub_guess[5] = (char)subs[5][n];
+                            sub_guess[6] = '\0';
+                            sha256_init(&ctx);
+                            sha256_update(&ctx, (BYTE*)sub_guess, strlen(sub_guess));
+                            BYTE guess[32];
+                            sha256_final(&ctx, guess);
+                            char* hex_guess = sha256_byteToHexString(guess);
+                            // printf("%s\n", sub_guess);
+                            if ((hash = hash_table_get(ht, hex_guess))>0){
+                                printf("%s %d\n", sub_guess, hash);
+                                add_new_cracked(solved, sub_guess);
+                                printf("remaining passwords are : %d\n", remaining_hashes(ht));
+                            }
+                            free(hex_guess);
+                            n_guesses--;
+                            if (remaining_hashes(ht) == 0 || n_guesses == 0){
+                                return 0;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    for(int i=0; i < 4; i++){
+        free(subs[i]);
+    }
+    free(characters);
+    free(subs);
+    free(subs_size);
+    return n_guesses;
 }
\ No newline at end of file
diff --git a/passwords.h b/passwords.h
index b765b08..888a700 100644
--- a/passwords.h
+++ b/passwords.h
@@ -12,4 +12,8 @@ int remaining_passwords(Passwords *pwrds);
 
 void free_passwords(Passwords* pwrds);
 
-void print_passwords(Passwords* pwrds);
\ No newline at end of file
+void print_passwords(Passwords* pwrds);
+
+int generate_common_subs_four(Passwords* solved, int n_guesses, HashTable *ht);
+
+int generate_common_subs_six(Passwords* solved, int n_guesses, HashTable *ht);
\ No newline at end of file
diff --git a/proj-2_common_passwords.txt b/proj-2_common_passwords.txt
index 8c2b044..eb76544 100644
--- a/proj-2_common_passwords.txt
+++ b/proj-2_common_passwords.txt
@@ -1,3 +1,4 @@
+nirmalathasa
 password
 123456
 12345678
diff --git a/sha256-helper.c b/sha256-helper.c
index 86f8499..1e56c16 100644
--- a/sha256-helper.c
+++ b/sha256-helper.c
@@ -2,6 +2,8 @@
 #include <assert.h>
 #include "proj-2_sha256.h"
 #include "sha256-helper.h"
+
+// adapted from https://github.com/RemyNoulin/sha256
 char *sha256_byteToHexString(BYTE data[]) {
 	char *hexC = "0123456789abcdef";
 	char *hexS = malloc(65);
diff --git a/six_password_strategy.c b/six_password_strategy.c
index 83b3c51..8b5ce8e 100644
--- a/six_password_strategy.c
+++ b/six_password_strategy.c
@@ -7,11 +7,15 @@
 #include "proj-2_sha256.h"
 #include "six_password_strategy.h"
 #include "sha256-helper.h"
+#include "passwords.h"
 
-void brute_force_six(HashTable *ht){
+void brute_force_six(HashTable *ht, Passwords *solved, int n_guesses){
     char brute_guess[6];
     SHA256_CTX ctx;
     int hash;
+    if (remaining_hashes(ht) == 0 || n_guesses == 0){
+        return;
+    }
     for(int i=65;i < 127; i++){
         brute_guess[0] = (char)i;
         for(int j=65;j < 127; j++){
@@ -32,11 +36,14 @@ void brute_force_six(HashTable *ht){
                             char* hex_guess = sha256_byteToHexString(guess);
                             if ((hash = hash_table_get(ht, hex_guess))>0){
                                 printf("%s %d\n", brute_guess, hash);
+                                add_new_cracked(solved, brute_guess);
                                 printf("remaining passwords are : %d\n", remaining_hashes(ht));
+                                n_guesses = generate_common_subs_six(solved, n_guesses, ht);
                             }
                             free(hex_guess);
-                            if (remaining_hashes(ht) == 0){
-                                break;
+                            n_guesses--;
+                            if (remaining_hashes(ht) == 0 || n_guesses == 0){
+                                return;
                             }
                         }
                     }
@@ -51,7 +58,7 @@ void brute_force_six(HashTable *ht){
         }
     }
 }
-int popular_character_guess_six(HashTable *ht){
+int popular_character_guess_six(HashTable *ht, Passwords *solved,int n_guesses){
     printf("popular character guess strategy\n");
     char brute_guess[4];
     SHA256_CTX ctx;
@@ -60,6 +67,10 @@ int popular_character_guess_six(HashTable *ht){
     FILE *file = fopen("common_password_frequency.txt", "r");
     char frequent_characters[60];
     int index = 0;
+    if (remaining_hashes(ht) == 0 || n_guesses == 0){
+        fclose(file);
+        return 0;
+    }
     while (fgets(line, sizeof(line), file)){
         line[1] = '\0';
         frequent_characters[index] = line[0];
@@ -86,31 +97,34 @@ int popular_character_guess_six(HashTable *ht){
                             // printf("%s\n", brute_guess);
                             if ((hash = hash_table_get(ht, hex_guess))>0){
                                 printf("%s %d\n", brute_guess, hash);
+                                add_new_cracked(solved, brute_guess);
                                 printf("remaining passwords are : %d\n", remaining_hashes(ht));
+                                n_guesses = generate_common_subs_six(solved,n_guesses,ht);
                             }
                             free(hex_guess);
-                            if (remaining_hashes(ht) == 0){
-                                break;
+                            n_guesses--;
+                            if (remaining_hashes(ht) == 0 || n_guesses == 0){
+                                return n_guesses;
                             }
                         }
                     }
                 }
             }
         }
-    }return 0;
+    }return n_guesses;
 }
 
 
 
 
 
-void generate_guesses_six(int n_guesses, HashTable *ht){
+int generate_guesses_six(int n_guesses, HashTable *ht, Passwords *solved){
     FILE* file = fopen("proj-2_common_passwords.txt", "r");
     char line[20];
     SHA256_CTX ctx;
     int hash;
     printf("start generate");
-    while (fgets(line, sizeof(line), file) && remaining_hashes(ht) > 0){
+    while (fgets(line, sizeof(line), file) && remaining_hashes(ht) > 0 && n_guesses != 0){
         line[6] = '\0';
         // printf("%s\n", line);
         sha256_init(&ctx);
@@ -120,10 +134,14 @@ void generate_guesses_six(int n_guesses, HashTable *ht){
         char* hex_guess = sha256_byteToHexString(guess);
         if ((hash = hash_table_get(ht, hex_guess))>0){
             printf("%s %d\n", line, hash);
+            add_new_cracked(solved, line);
             printf("remaining passwords are : %d\n", remaining_hashes(ht));
+            n_guesses = generate_common_subs_six(solved,n_guesses,ht);
         }
+        n_guesses--;
         free(hex_guess);
     }
     printf("finished file");
     fclose(file);
+    return n_guesses;
 }
\ No newline at end of file
diff --git a/six_password_strategy.h b/six_password_strategy.h
index 8847660..3809a97 100644
--- a/six_password_strategy.h
+++ b/six_password_strategy.h
@@ -1,7 +1,7 @@
 #include <stdlib.h>
 
 #include "hashtable.h"
-void brute_force_six(HashTable *ht);
-void generate_guesses_six(int n_guesses, HashTable *ht);
-int popular_character_guess_six(HashTable *ht);
-char *sha256_byteToHexString(BYTE data[]);
\ No newline at end of file
+#include "passwords.h"
+void brute_force_six(HashTable *ht, Passwords *solved,int n_guesses);
+int popular_character_guess_six(HashTable *ht, Passwords *solved,int n_guesses);
+int generate_guesses_six(int n_guesses, HashTable *ht, Passwords *solved);
\ No newline at end of file
-- 
GitLab