:hammer: Some tools to (try to) break "Magic Hashes" https://git.forestier.app/HorlogeSkynet/MagicHashes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
4.7KB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <inttypes.h>
  6. #include <regex.h>
  7. #include <openssl/evp.h>
  8. #define EVER ;;
  9. #define MIN_LENGTH 4
  10. #define MAX_LENGTH 32
  11. #define HEX_DIGEST_MAX_LENGTH ((EVP_MAX_MD_SIZE * 2) + 1)
  12. void compute_digest_against_evp(
  13. const EVP_MD *const evp_md_sha,
  14. const char *const random_string, const size_t random_string_length,
  15. unsigned char *const hash_digest, unsigned int *const hash_digest_length)
  16. {
  17. EVP_MD_CTX *md_ctx = EVP_MD_CTX_create();
  18. EVP_DigestInit_ex(md_ctx, evp_md_sha, NULL);
  19. EVP_DigestUpdate(md_ctx, random_string, random_string_length);
  20. EVP_DigestFinal_ex(md_ctx, hash_digest, hash_digest_length);
  21. EVP_MD_CTX_destroy(md_ctx);
  22. }
  23. void check_and_store_result(
  24. const char *const hash_method_name,
  25. regex_t *const preg,
  26. const char *const random_string,
  27. const char *const hash_digest_hexadecimal)
  28. {
  29. if(regexec(preg, hash_digest_hexadecimal, 0, NULL, 0) == 0)
  30. {
  31. FILE *f_magic_hashes = fopen("magic_hashes.txt", "a");
  32. if(f_magic_hashes == NULL)
  33. {
  34. regfree(preg);
  35. EVP_cleanup();
  36. fprintf(stderr, "Could not open (or create ?) \"magic_hashes.txt\" file : %s\n", strerror(errno));
  37. exit(-1);
  38. }
  39. fprintf(f_magic_hashes, "[openssl_%s]\t%s\t%s\n", hash_method_name, random_string, hash_digest_hexadecimal);
  40. if(fclose(f_magic_hashes) != 0)
  41. {
  42. regfree(preg);
  43. EVP_cleanup();
  44. fprintf(stderr, "Could not close \"magic_hashes.txt\" file : %s\n", strerror(errno));
  45. exit(-1);
  46. }
  47. }
  48. }
  49. void raw_digest_to_hexadecimal(
  50. const unsigned char *const hash_digest, const unsigned int hash_digest_length,
  51. char *const hash_digest_hexadecimal)
  52. {
  53. memset(hash_digest_hexadecimal, 0, HEX_DIGEST_MAX_LENGTH * sizeof(*hash_digest_hexadecimal));
  54. for(unsigned int i = 0; i < hash_digest_length; i++)
  55. {
  56. sprintf(hash_digest_hexadecimal + (i * 2), "%02x", hash_digest[i]);
  57. }
  58. }
  59. int main(int argc, char const *argv[])
  60. {
  61. (void)argc;
  62. (void)argv;
  63. srand(time(NULL));
  64. // We will generate "plausible" password strings, between 4 and 32-character long.
  65. const char *const char_pool = {
  66. "abcdefghijklmnopqrstuvwxyz"
  67. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  68. "0123456789"
  69. "!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"
  70. };
  71. const size_t pool_length = strlen(char_pool);
  72. // Compile "Magic Hashes" format REGEX.
  73. regex_t preg;
  74. int err = regcomp(&preg, "^0+e[:digit:]+$", REG_NOSUB | REG_EXTENDED);
  75. if(err != 0)
  76. {
  77. regfree(&preg);
  78. fprintf(stderr, "Could not compile REGEXP pattern : %s\n", strerror(err));
  79. exit(-1);
  80. }
  81. // _____________________________________
  82. // Cryptographic stuffs.
  83. unsigned char hash_digest[EVP_MAX_MD_SIZE];
  84. unsigned int hash_digest_length;
  85. char hash_digest_hexadecimal[HEX_DIGEST_MAX_LENGTH];
  86. OpenSSL_add_all_algorithms();
  87. const EVP_MD *evp_md_sha224 = EVP_sha224();
  88. const EVP_MD *evp_md_sha256 = EVP_sha256();
  89. const EVP_MD *evp_md_sha384 = EVP_sha384();
  90. const EVP_MD *evp_md_sha512 = EVP_sha512();
  91. // _____________________
  92. // Loop variables.
  93. char random_string[MAX_LENGTH + 1];
  94. size_t random_string_length;
  95. // _______________
  96. for(EVER)
  97. {
  98. // Let's generate a random string !
  99. memset(random_string, 0, (MAX_LENGTH + 1) * sizeof(*random_string));
  100. random_string_length = (rand() % ((MAX_LENGTH - MIN_LENGTH) + 1)) + MIN_LENGTH;
  101. for(uint8_t i = 0; i < random_string_length; i++)
  102. {
  103. random_string[i] = char_pool[rand() % (pool_length + 1)];
  104. }
  105. // ________________________________
  106. // SHA224
  107. compute_digest_against_evp(evp_md_sha224, random_string, random_string_length, hash_digest, &hash_digest_length);
  108. raw_digest_to_hexadecimal(hash_digest, hash_digest_length, hash_digest_hexadecimal);
  109. check_and_store_result("sha224", &preg, random_string, hash_digest_hexadecimal);
  110. // ______
  111. // SHA256
  112. compute_digest_against_evp(evp_md_sha256, random_string, random_string_length, hash_digest, &hash_digest_length);
  113. raw_digest_to_hexadecimal(hash_digest, hash_digest_length, hash_digest_hexadecimal);
  114. check_and_store_result("sha256", &preg, random_string, hash_digest_hexadecimal);
  115. // ______
  116. // SHA384
  117. compute_digest_against_evp(evp_md_sha384, random_string, random_string_length, hash_digest, &hash_digest_length);
  118. raw_digest_to_hexadecimal(hash_digest, hash_digest_length, hash_digest_hexadecimal);
  119. check_and_store_result("sha384", &preg, random_string, hash_digest_hexadecimal);
  120. // ______
  121. // SHA512
  122. compute_digest_against_evp(evp_md_sha512, random_string, random_string_length, hash_digest, &hash_digest_length);
  123. raw_digest_to_hexadecimal(hash_digest, hash_digest_length, hash_digest_hexadecimal);
  124. check_and_store_result("sha512", &preg, random_string, hash_digest_hexadecimal);
  125. // ______
  126. }
  127. // This statement is not supposed to be reached.
  128. regfree(&preg);
  129. EVP_cleanup();
  130. return 0;
  131. // _____________________________________________
  132. }