🔨 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.
 
 

174 lines
4.8 KiB

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <inttypes.h>
#include <regex.h>
#include <openssl/evp.h>
#define MAX_LENGTH 32
#define HEX_DIGEST_MAX_LENGTH ((EVP_MAX_MD_SIZE * 2) + 1)
void compute_digest_against_evp(
const EVP_MD *const evp_md_sha,
const char *const message_candidate, const size_t message_candidate_length,
unsigned char *const hash_digest, unsigned int *const hash_digest_length)
{
EVP_MD_CTX *md_ctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(md_ctx, evp_md_sha, NULL);
EVP_DigestUpdate(md_ctx, message_candidate, message_candidate_length);
EVP_DigestFinal_ex(md_ctx, hash_digest, hash_digest_length);
EVP_MD_CTX_destroy(md_ctx);
}
void check_and_store_result(
const char *const hash_method_name,
regex_t *const preg,
const char *const message_candidate,
const char *const hash_digest_hexadecimal)
{
if(regexec(preg, hash_digest_hexadecimal, 0, NULL, 0) == 0)
{
FILE *f_magic_hashes = fopen("magic_hashes.txt", "a");
if(f_magic_hashes == NULL)
{
regfree(preg);
EVP_cleanup();
fprintf(stderr, "Could not open (or create ?) \"magic_hashes.txt\" file : %s\n", strerror(errno));
exit(-1);
}
fprintf(f_magic_hashes, "[openssl_%s]\t%s\t%s\n", hash_method_name, message_candidate, hash_digest_hexadecimal);
if(fclose(f_magic_hashes) != 0)
{
regfree(preg);
EVP_cleanup();
fprintf(stderr, "Could not close \"magic_hashes.txt\" file : %s\n", strerror(errno));
exit(-1);
}
}
}
void raw_digest_to_hexadecimal(
const unsigned char *const hash_digest, const unsigned int hash_digest_length,
char *const hash_digest_hexadecimal)
{
memset(hash_digest_hexadecimal, 0, HEX_DIGEST_MAX_LENGTH * sizeof(*hash_digest_hexadecimal));
for(unsigned int i = 0; i < hash_digest_length; i++)
{
sprintf(hash_digest_hexadecimal + (i * 2), "%02x", hash_digest[i]);
}
}
int main(int argc, char const *argv[])
{
(void)argc;
(void)argv;
// We will generate "plausible" password strings, up to 32-character long.
const char *const char_pool = {
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789"
"!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"
};
const size_t char_pool_length = strlen(char_pool);
// Compile "Magic Hashes" format REGEXP.
regex_t preg;
int err = regcomp(&preg, "^0+e[:digit:]+$", REG_NOSUB | REG_EXTENDED);
if(err != 0)
{
regfree(&preg);
fprintf(stderr, "Could not compile REGEXP pattern : %s\n", strerror(err));
exit(-1);
}
// _____________________________________
// Cryptographic stuffs.
unsigned char hash_digest[EVP_MAX_MD_SIZE];
unsigned int hash_digest_length;
char hash_digest_hexadecimal[HEX_DIGEST_MAX_LENGTH];
OpenSSL_add_all_algorithms();
const EVP_MD *const evp_md_sha224 = EVP_sha224();
const EVP_MD *const evp_md_sha256 = EVP_sha256();
const EVP_MD *const evp_md_sha384 = EVP_sha384();
const EVP_MD *const evp_md_sha512 = EVP_sha512();
// _____________________
// Loop variables.
uint16_t i, j;
uint16_t indexes[MAX_LENGTH + 1] = {0};
char message_candidate[MAX_LENGTH + 1] = "";
// _______________
for(i = 0; ; )
{
// Update our message candidate according to previous indexes, for the current iteration.
for(j = i; ; j--)
{
if(indexes[j] >= char_pool_length)
{
indexes[j] = 0;
message_candidate[j] = char_pool[indexes[j]++];
if(j == 0)
{
i++;
message_candidate[i] = char_pool[indexes[i]++];
break;
}
}
else
{
message_candidate[j] = char_pool[indexes[j]++];
break;
}
}
if(i >= MAX_LENGTH)
{
break;
}
// SHA224
compute_digest_against_evp(evp_md_sha224, message_candidate, i + 1, hash_digest, &hash_digest_length);
raw_digest_to_hexadecimal(hash_digest, hash_digest_length, hash_digest_hexadecimal);
check_and_store_result("sha224", &preg, message_candidate, hash_digest_hexadecimal);
// ______
// SHA256
compute_digest_against_evp(evp_md_sha256, message_candidate, i + 1, hash_digest, &hash_digest_length);
raw_digest_to_hexadecimal(hash_digest, hash_digest_length, hash_digest_hexadecimal);
check_and_store_result("sha256", &preg, message_candidate, hash_digest_hexadecimal);
// ______
// SHA384
compute_digest_against_evp(evp_md_sha384, message_candidate, i + 1, hash_digest, &hash_digest_length);
raw_digest_to_hexadecimal(hash_digest, hash_digest_length, hash_digest_hexadecimal);
check_and_store_result("sha384", &preg, message_candidate, hash_digest_hexadecimal);
// ______
// SHA512
compute_digest_against_evp(evp_md_sha512, message_candidate, i + 1, hash_digest, &hash_digest_length);
raw_digest_to_hexadecimal(hash_digest, hash_digest_length, hash_digest_hexadecimal);
check_and_store_result("sha512", &preg, message_candidate, hash_digest_hexadecimal);
// ______
}
// Free allocations.
regfree(&preg);
EVP_cleanup();
// _________________
return 0;
}