houndsniff

Hash identification tool
git clone git@git.mcdim.xyz:/var/www/git/houndsniff.git
Log | Files | Refs | README | LICENSE

commit 95df29a43761a7cfd92904e25a7644e171fe03bf
parent 1a6b4c68f2feff1ec92a375c3bdc6b6a984d9efd
Author: Michael Constantine Dimopoulos <mk@mcdim.xyz>
Date:   Sun, 13 Feb 2022 02:51:52 +0000

Scriptable mode!

Diffstat:
MREADME.md | 8++++++--
Msrc/houndsniff.1 | 10++++++++--
Msrc/main.c | 108++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/select.c | 38+++++++++++++++++++++++++++++++-------
Msrc/select.h | 3++-
5 files changed, 110 insertions(+), 57 deletions(-)

diff --git a/README.md b/README.md @@ -7,7 +7,7 @@ By Michael Constantine Dimopoulos, et al with significant contributions by [Christopher Wellons](https://github.com/skeeto) and revisions & suggestions by [Martin K.](https://github.com/kurahaupo) as well as tuu and fizzie on ##c on Freenode. -Current version: 2.0.1 +Current version: 2.1 ![Screenshot](https://blogger.googleusercontent.com/img/a/AVvXsEh7UuJAMRdL4MOA82DH7C2g78X1t_kvsQuKcG-Cww6SqbZ68f_G8TZ3ibOJi7s09bMopa34NkzCbWILgWo0budEUbSlsTtK6GUDogOkZvtZQ0lqhiz2GBBkQkzR7PRDosDHm5RMbcQ6gHOQH3DxL-hJy2ncIlyxIb2gU1fcs5aLaIAM83ezm2NtnrPa=s16000) @@ -27,10 +27,14 @@ houndsniff [HASH] ``` or, alternatively you can use the interactive shell: ``` -houndsniff -s +houndsniff -i ``` You can exit with ^C. +You can also use scripting mode, which allows houndsniff to get hashes from stdin and print to stdout without much eye-candy + +echo "$hash" | houndsnif -s + Thanks ---- Thanks a lot to tuu and fizzie, as well as kurahaupo on ##c @ freenode for their revisions and suggestions! (even though I've yet to implement everything). I truly appreciate the help. diff --git a/src/houndsniff.1 b/src/houndsniff.1 @@ -1,6 +1,6 @@ .\" Manpage for Houndsniff -.TH man 8 "10 Mar 2021" "2.0.1" "Houndsniff manual page" +.TH man 8 "10 Mar 2021" "2.1" "Houndsniff manual page" .SH NAME Houndsniff \- Hash algorithm identification .SH SYNOPSIS @@ -20,9 +20,15 @@ or contribute to the github project: https://github.com/MichaelDim02/houndsniff .SH OPTIONS --h display help panel & exit +-i use interactive shell + +-s use scripting mode -l list supported hashing algorithms + +-v display version and & exit + +-h display help panel & exit .SH AUTHOR Michael Constantine Dimopoulos et al diff --git a/src/main.c b/src/main.c @@ -1,5 +1,5 @@ /* - * Houndsniff - version 2.0.1 + * Houndsniff - version 2.1 * * by Michael Constantine Dimopoulos et al * https://mcdim.xyz <mk@mcdim.xyz> GNU GPLv3 @@ -15,7 +15,9 @@ #include <readline/readline.h> #include "select.h" -#define VERSION "2.0.1" +#define VERSION "2.1" + +#define BUFFER_SIZE 1024 #define RED "\x1b[31m" #define RESET "\x1b[0m" @@ -26,9 +28,10 @@ hasUpper(char ch[]) int len = strlen(ch); int i; - for (i=0; i<len; i++) { + for (i = 0; i < len; i++) { if (isupper(ch[i])) return 1; } + return 0; } @@ -54,10 +57,14 @@ starts_with(const char *a, const char *b) } static void -dprint(char *name) +dprint(char *name, int clean_out) { - printf("[" RED "+" RESET "] Definite identification: " + if (!clean_out) { + printf("[" RED "+" RESET "] Definite identification: " RED "%s" RESET "\n", name); + } else { + printf("%s 100.00\n", replace(name)); + } } @@ -66,29 +73,29 @@ dprint(char *name) * based on *definite* characteristics */ void -definite(char string[], int length) +definite(char string[], int length, int co) { if (starts_with(string, "$P")) - dprint("Wordpress hash"); + dprint("Wordpress hash", co); else if (starts_with(string, "$1$")) - dprint("MD5 crypt(3)"); + dprint("MD5 crypt(3)", co); else if (starts_with(string, "$5$")) - dprint("SHA256 crypt(3)"); + dprint("SHA256 crypt(3)", co); else if (starts_with(string, "$6$")) - dprint("SHA512 crypt(3)"); + dprint("SHA512 crypt(3)", co); else if (string[length-1]=='=') - dprint("Base64 or Base32"); + dprint("Base64 or Base32", co); else if (starts_with(string, "$apr1$")) - dprint("APR1"); + dprint("APR1", co); else if (starts_with(string, "$H$")) - dprint("phpBB"); + dprint("phpBB", co); else if (starts_with(string, "sha1$")) - dprint("SHA1 Django"); + dprint("SHA1 Django", co); else if (length==65 && string[32]==':') - dprint("MD5 Joomla (pass:salt)"); + dprint("MD5 Joomla (pass:salt)", co); else if (starts_with(string, "$2y$")) - dprint("PHP password_hash"); + dprint("PHP password_hash", co); } /* this function determines charset*/ @@ -110,58 +117,59 @@ charset(char string[]) static void help(char *exename) { - printf( "Houndsniff is a hash recognition tool.\n" - "It works by extracting some info about \n" - "the hash and comparing it to info about\n" - "other hashes in a local database. Then,\n" - "it prints the matches sorted by their \n" - "popularity, which is determined by web \n" - "search result numbers in comparison to \n" - "other hashes with the same features \n\n" - - "If your hash includes a dollar sign ($)\n" - "make sure you place it in between quotes.\n\n" - - "By Michael Constantine Dimopoulos et al\n" - "Contributors:" + printf( "If your hash includes a dollar sign ($) or other\n" + "special symbols, make sure you place it in between\n" + "quotes.\n\n" + + "Contributors:\n" "Christopher Wellons, Martin K.\n" "tuu & fizzie on ##c@freenode\n\n" - "-l to list supported hashing algorithms\n" - "-s for an interactive shell\n" - "-h to display this panel and exit\n" - "\nUsage: Usage: %s [HASH] [-h] [-l] [-s]\n", + " -i use interactive shell\n" + " -s use scripting mode\n" + " -l list supported hashing algorithms\n" + " -h display this panel and exit\n" + " -v print version and exit\n" + "\nUsage: Usage: %s [HASH] [-h|-v|-l] [-i] [-s]\n", exename); } void -driver(char *hash) +driver(char *hash, int clean_out) { int len = strlen(hash); const char* chars = charset(hash); - printf("Hash: " RED "%s" RESET "\n", hash); - printf("Length: " RED "%d" RESET "\n",len); - printf("Charset: " RED "%s" RESET "\n\n", chars); - sel(len, chars); - definite(hash, len); + + if (!clean_out) { + printf("Hash: " RED "%s" RESET "\n", hash); + printf("Length: " RED "%d" RESET "\n",len); + printf("Charset: " RED "%s" RESET "\n\n", chars); + } + + sel(len, chars, clean_out); + definite(hash, len, clean_out); + printf("\n"); } void main(int argc, char* argv[]) { - banner(); if (argc==1) { - printf("Usage: %s [HASH] [-h] [-l] [-s]\n", argv[0]); + banner(); + printf("Usage: %s [HASH] [-h|-v|-l] [-i] [-s]\n", argv[0]); exit(EXIT_FAILURE); } if (strcmp(argv[1],"-h")==0 || strcmp(argv[1],"--help")==0){ + banner(); help(argv[0]); } else if (strcmp(argv[1], "-l")==0) { + banner(); list(); - } else if (strcmp(argv[1], "-s")==0) { + } else if (strcmp(argv[1], "-i")==0) { + banner(); using_history(); while(1) { char *hash; @@ -171,12 +179,22 @@ main(int argc, char* argv[]) if (!hash) break; add_history(hash); - driver(hash); + driver(hash, 0); printf("--------------------------\n"); free(hash); } + } else if (strcmp(argv[1], "-s")==0) { + char buffer[BUFFER_SIZE]; + while (fgets(buffer, sizeof(buffer), stdin) != NULL) { + strtok(buffer, "\n"); + driver(buffer, 1); + } + + } else if (strcmp(argv[1], "-v")==0) { + printf("houndsniff-v%s\n", VERSION); } else { - driver(argv[1]); + banner(); + driver(argv[1], 0); } exit(EXIT_SUCCESS); } diff --git a/src/select.c b/src/select.c @@ -19,7 +19,25 @@ void list(void); int matchcmp(const void *, const void *); -void sel(int length, const char *charset); +void sel(int length, const char *charset, int clean_out); +char *replace(char *str); + +char * +replace(char *str) +{ + int len = strlen(str); + char *str2 = malloc (sizeof (char) * len); + int i; + + for(i = 0; i < len; i++) { + if(str[i] == ' ') + str2[i] = '_'; + else + str2[i] = str[i]; + } + + return str2; +} /* Notes: 1. The popularity integer determines how the results are sorted @@ -68,7 +86,7 @@ static const struct { {"HAVAL160,4", 40, 'a', 13.83}, {"Tiger160,3", 40, 'a', 8.99}, {"Tiger160,4", 40, 'a', 8.81}, - {"RIPEMD160 ", 40, 'a', 8.18}, + {"RIPEMD160", 40, 'a', 8.18}, {"HAVAL160,3", 40, 'a', 8.08}, {"HAVAL160,5", 40, 'a', 6.21}, @@ -108,7 +126,7 @@ static const struct { }; void -sel(int length, const char *charset) +sel(int length, const char *charset, int clean_out) { int i; int nmatch = 0; @@ -122,11 +140,17 @@ sel(int length, const char *charset) qsort(matches, nmatch, sizeof(*matches), matchcmp); - printf("Possible results:\n\n"); + if (!clean_out) printf("Possible results:\n\n"); + for (i = 0; i < nmatch; i++) { - printf("[" RED "%d" RESET "] %s - " RED "%.2f%" RESET "\n", - i + 1, hashes[matches[i]].name, - hashes[matches[i]].likelihood); + if (!clean_out) { + printf("[" RED "%d" RESET "] %s - " RED "%.2f%" RESET "\n", + i + 1, hashes[matches[i]].name, + hashes[matches[i]].likelihood); + } else { + printf("%s %.2f\n", replace(hashes[matches[i]].name), + hashes[matches[i]].likelihood); + } } } diff --git a/src/select.h b/src/select.h @@ -15,6 +15,7 @@ #define RED "\x1b[31m" #define RESET "\x1b[0m" void list(void); -void sel(int length, const char *charset); +void sel(int length, const char *charset, int clean_out); +char *replace(char *str); #endif