From 4a0757e25122296bcf474374acf326c04a1bad85 Mon Sep 17 00:00:00 2001 From: Sein Coray Date: Mon, 11 May 2020 23:22:47 +0200 Subject: [PATCH 1/2] added escaping to --status-json output --- docs/changes.txt | 1 + src/terminal.c | 28 +++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/docs/changes.txt b/docs/changes.txt index 5c002432b..4e94be43f 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -99,6 +99,7 @@ - Fixed some memory leaks in case mask-files are used in optimized mode - Fixed the 7-Zip parser to allow the entire supported range of encrypted and decrypted data lengths - Fixed the validation of the --brain-client-features command line argument (only values 1, 2 or 3 are allowed) +- Fixed --status-json to correctly escape certain characters in hashes ## ## Improvements diff --git a/src/terminal.c b/src/terminal.c index d1e8834e8..9f16bd5c6 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -1020,9 +1020,33 @@ void status_display_status_json (hashcat_ctx_t *hashcat_ctx) end = time_now + sec_etc; } + char *tmp_target = (char *) hcmalloc (strlen (hashcat_status->hash_target) * 2); + + unsigned long i, j; + + for (i = 0, j = 0; j < strlen (hashcat_status->hash_target); i++, j++) + { + char rep = hashcat_status->hash_target[j]; + + switch (hashcat_status->hash_target[j]) + { + case '\b': rep = 'b'; tmp_target[i] = '\\'; i++; break; + case '\t': rep = 't'; tmp_target[i] = '\\'; i++; break; + case '\n': rep = 'n'; tmp_target[i] = '\\'; i++; break; + case '\f': rep = 'f'; tmp_target[i] = '\\'; i++; break; + case '\r': rep = 'r'; tmp_target[i] = '\\'; i++; break; + case '\\': rep = '\\'; tmp_target[i] = '\\'; i++; break; + case '"': rep = '"'; tmp_target[i] = '\\'; i++; break; + } + + tmp_target[i] = rep; + } + + tmp_target[i] = 0; + printf ("{ \"session\": \"%s\",", hashcat_status->session); printf (" \"status\": %d,", hashcat_status->status_number); - printf (" \"target\": \"%s\",", hashcat_status->hash_target); + printf (" \"target\": \"%s\",", tmp_target); printf (" \"progress\": [%" PRIu64 ", %" PRIu64 "],", hashcat_status->progress_cur_relative_skip, hashcat_status->progress_end_relative_skip); printf (" \"restore_point\": %" PRIu64 ",", hashcat_status->restore_point); printf (" \"recovered_hashes\": [%d, %d],", hashcat_status->digests_done, hashcat_status->digests_cnt); @@ -1030,6 +1054,8 @@ void status_display_status_json (hashcat_ctx_t *hashcat_ctx) printf (" \"rejected\": %" PRIu64 ",", hashcat_status->progress_rejected); printf (" \"devices\": ["); + free(tmp_target); + int device_num = 0; for (int device_id = 0; device_id < hashcat_status->device_info_cnt; device_id++) From d91a25027bfed03a479fb9ec9975e08476d38eab Mon Sep 17 00:00:00 2001 From: Sein Coray Date: Wed, 13 May 2020 13:37:30 +0200 Subject: [PATCH 2/2] minor adjustments to code style and explanatory comment added --- src/terminal.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/terminal.c b/src/terminal.c index 9f16bd5c6..38b5332ef 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -1020,33 +1020,40 @@ void status_display_status_json (hashcat_ctx_t *hashcat_ctx) end = time_now + sec_etc; } - char *tmp_target = (char *) hcmalloc (strlen (hashcat_status->hash_target) * 2); + /* + * As the hash target can contain the hash (in case of a single attacked hash), especially + * some salts can contain chars which need to be escaped to not break the JSON encoding. + * Based on https://www.freeformatter.com/json-escape.html, below these 7 different chars + * are getting escaped before being printed. + */ + + char *target_json_encoded = (char *) hcmalloc (strlen (hashcat_status->hash_target) * 2); unsigned long i, j; - for (i = 0, j = 0; j < strlen (hashcat_status->hash_target); i++, j++) + for (i = 0, j = 0; i < strlen (hashcat_status->hash_target); i++, j++) { - char rep = hashcat_status->hash_target[j]; + char c = hashcat_status->hash_target[i]; - switch (hashcat_status->hash_target[j]) + switch (c) { - case '\b': rep = 'b'; tmp_target[i] = '\\'; i++; break; - case '\t': rep = 't'; tmp_target[i] = '\\'; i++; break; - case '\n': rep = 'n'; tmp_target[i] = '\\'; i++; break; - case '\f': rep = 'f'; tmp_target[i] = '\\'; i++; break; - case '\r': rep = 'r'; tmp_target[i] = '\\'; i++; break; - case '\\': rep = '\\'; tmp_target[i] = '\\'; i++; break; - case '"': rep = '"'; tmp_target[i] = '\\'; i++; break; + case '\b': c = 'b'; target_json_encoded[j] = '\\'; j++; break; + case '\t': c = 't'; target_json_encoded[j] = '\\'; j++; break; + case '\n': c = 'n'; target_json_encoded[j] = '\\'; j++; break; + case '\f': c = 'f'; target_json_encoded[j] = '\\'; j++; break; + case '\r': c = 'r'; target_json_encoded[j] = '\\'; j++; break; + case '\\': c = '\\'; target_json_encoded[j] = '\\'; j++; break; + case '"': c = '"'; target_json_encoded[j] = '\\'; j++; break; } - tmp_target[i] = rep; + target_json_encoded[j] = c; } - tmp_target[i] = 0; + target_json_encoded[j] = 0; printf ("{ \"session\": \"%s\",", hashcat_status->session); printf (" \"status\": %d,", hashcat_status->status_number); - printf (" \"target\": \"%s\",", tmp_target); + printf (" \"target\": \"%s\",", target_json_encoded); printf (" \"progress\": [%" PRIu64 ", %" PRIu64 "],", hashcat_status->progress_cur_relative_skip, hashcat_status->progress_end_relative_skip); printf (" \"restore_point\": %" PRIu64 ",", hashcat_status->restore_point); printf (" \"recovered_hashes\": [%d, %d],", hashcat_status->digests_done, hashcat_status->digests_cnt); @@ -1054,7 +1061,7 @@ void status_display_status_json (hashcat_ctx_t *hashcat_ctx) printf (" \"rejected\": %" PRIu64 ",", hashcat_status->progress_rejected); printf (" \"devices\": ["); - free(tmp_target); + free (target_json_encoded); int device_num = 0;