diff --git a/docs/changes.txt b/docs/changes.txt index 1f5c6c136..b50987305 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -14,6 +14,7 @@ - Added JtR-compatible support for hex notation in rules engine - Added OpenCL device utilization to the status information in machine-readable output +- General file handling: Abort if a byte order mark (BOM) was detected in a wordlist, hashlist, maskfile or rulefile - HCCAPX management: Use advanced hints in message_pair stored by hcxtools about endian bitness of replay counter - OpenCL kernels: Abort session if kernel self-test fails - OpenCL kernels: Add '-pure' prefix to kernel filenames to avoid problems caused by reusing existing hashcat installation folder diff --git a/include/shared.h b/include/shared.h index 033788e30..c9dd5cbb5 100644 --- a/include/shared.h +++ b/include/shared.h @@ -47,6 +47,7 @@ bool hc_path_exist (const char *path); bool hc_path_read (const char *path); bool hc_path_write (const char *path); bool hc_path_create (const char *path); +bool hc_path_has_bom (const char *path); bool hc_string_is_digit (const char *s); diff --git a/src/shared.c b/src/shared.c index cd3501379..023d5a76f 100644 --- a/src/shared.c +++ b/src/shared.c @@ -262,6 +262,111 @@ bool hc_path_create (const char *path) return true; } +bool hc_path_has_bom (const char *path) +{ + u8 buf[8] = { 0 }; + + FILE *fp = fopen (path, "rb"); + + if (fp == NULL) return false; + + const size_t nread = fread (buf, 1, sizeof (buf), fp); + + fclose (fp); + + if (nread < 1) return false; + + /* signatures from https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding */ + + // utf-8 + + if ((buf[0] == 0xef) + && (buf[1] == 0xbb) + && (buf[2] == 0xbf)) return true; + + // utf-16 + + if ((buf[0] == 0xfe) + && (buf[1] == 0xff)) return true; + + if ((buf[0] == 0xff) + && (buf[1] == 0xfe)) return true; + + // utf-32 + + if ((buf[0] == 0x00) + && (buf[1] == 0x00) + && (buf[2] == 0xfe) + && (buf[3] == 0xff)) return true; + + if ((buf[0] == 0xff) + && (buf[1] == 0xfe) + && (buf[2] == 0x00) + && (buf[3] == 0x00)) return true; + + // utf-7 + + if ((buf[0] == 0x2b) + && (buf[1] == 0x2f) + && (buf[2] == 0x76) + && (buf[3] == 0x38)) return true; + + if ((buf[0] == 0x2b) + && (buf[1] == 0x2f) + && (buf[2] == 0x76) + && (buf[3] == 0x39)) return true; + + if ((buf[0] == 0x2b) + && (buf[1] == 0x2f) + && (buf[2] == 0x76) + && (buf[3] == 0x2b)) return true; + + if ((buf[0] == 0x2b) + && (buf[1] == 0x2f) + && (buf[2] == 0x76) + && (buf[3] == 0x2f)) return true; + + if ((buf[0] == 0x2b) + && (buf[1] == 0x2f) + && (buf[2] == 0x76) + && (buf[3] == 0x38) + && (buf[4] == 0x2d)) return true; + + // utf-1 + + if ((buf[0] == 0xf7) + && (buf[1] == 0x64) + && (buf[2] == 0x4c)) return true; + + // utf-ebcdic + + if ((buf[0] == 0xdd) + && (buf[1] == 0x73) + && (buf[2] == 0x66) + && (buf[3] == 0x73)) return true; + + // scsu + + if ((buf[0] == 0x0e) + && (buf[1] == 0xfe) + && (buf[2] == 0xff)) return true; + + // bocu-1 + + if ((buf[0] == 0xfb) + && (buf[1] == 0xee) + && (buf[2] == 0x28)) return true; + + // gb-18030 + + if ((buf[0] == 0x84) + && (buf[1] == 0x31) + && (buf[2] == 0x95) + && (buf[3] == 0x33)) return true; + + return false; +} + bool hc_string_is_digit (const char *s) { if (s == NULL) return false; diff --git a/src/straight.c b/src/straight.c index 7738b063c..572d4c4e1 100644 --- a/src/straight.c +++ b/src/straight.c @@ -18,6 +18,13 @@ static int straight_ctx_add_wl (hashcat_ctx_t *hashcat_ctx, const char *dict) { + if (hc_path_has_bom (dict) == true) + { + event_log_error (hashcat_ctx, "%s: Byte Order Mark (BOM) was detected", dict); + + return -1; + } + straight_ctx_t *straight_ctx = hashcat_ctx->straight_ctx; if (straight_ctx->dicts_avail == straight_ctx->dicts_cnt) diff --git a/src/user_options.c b/src/user_options.c index dd0d237dd..08f384264 100644 --- a/src/user_options.c +++ b/src/user_options.c @@ -1754,6 +1754,13 @@ int user_options_check_files (hashcat_ctx_t *hashcat_ctx) return -1; } + + if (hc_path_has_bom (user_options_extra->hc_hash) == true) + { + event_log_error (hashcat_ctx, "%s: Byte Order Mark (BOM) was detected", user_options_extra->hc_hash); + + return -1; + } } } @@ -1797,6 +1804,13 @@ int user_options_check_files (hashcat_ctx_t *hashcat_ctx) return -1; } + + if (hc_path_has_bom (rp_file) == true) + { + event_log_error (hashcat_ctx, "%s: Byte Order Mark (BOM) was detected", rp_file); + + return -1; + } } } else if (user_options->attack_mode == ATTACK_MODE_COMBI) @@ -1829,6 +1843,13 @@ int user_options_check_files (hashcat_ctx_t *hashcat_ctx) return -1; } + if (hc_path_has_bom (dictfile1) == true) + { + event_log_error (hashcat_ctx, "%s: Byte Order Mark (BOM) was detected", dictfile1); + + return -1; + } + if (hc_path_exist (dictfile2) == false) { event_log_error (hashcat_ctx, "%s: %s", dictfile2, strerror (errno)); @@ -1849,6 +1870,13 @@ int user_options_check_files (hashcat_ctx_t *hashcat_ctx) return -1; } + + if (hc_path_has_bom (dictfile2) == true) + { + event_log_error (hashcat_ctx, "%s: Byte Order Mark (BOM) was detected", dictfile2); + + return -1; + } } } else if (user_options->attack_mode == ATTACK_MODE_BF) @@ -1874,6 +1902,13 @@ int user_options_check_files (hashcat_ctx_t *hashcat_ctx) return -1; } + + if (hc_path_has_bom (maskfile) == true) + { + event_log_error (hashcat_ctx, "%s: Byte Order Mark (BOM) was detected", maskfile); + + return -1; + } } } } @@ -1911,6 +1946,13 @@ int user_options_check_files (hashcat_ctx_t *hashcat_ctx) return -1; } + + if (hc_path_has_bom (maskfile) == true) + { + event_log_error (hashcat_ctx, "%s: Byte Order Mark (BOM) was detected", maskfile); + + return -1; + } } } } @@ -1948,6 +1990,13 @@ int user_options_check_files (hashcat_ctx_t *hashcat_ctx) return -1; } + + if (hc_path_has_bom (maskfile) == true) + { + event_log_error (hashcat_ctx, "%s: Byte Order Mark (BOM) was detected", maskfile); + + return -1; + } } } }