From 2e465950b740ad3135a272b2d0ec6fd061e7d05b Mon Sep 17 00:00:00 2001 From: brandon Date: Tue, 2 Feb 2021 13:16:37 +0000 Subject: [PATCH 1/3] Changing colour scheme --- name_that_hash/prettifier.py | 12 +- name_that_hash/runner.py | 466 +++++++++++++++++------------------ packages/setup.py | 72 +++--- pyproject.toml | 46 ++-- 4 files changed, 298 insertions(+), 298 deletions(-) diff --git a/name_that_hash/prettifier.py b/name_that_hash/prettifier.py index 73b999d..57d0f7c 100644 --- a/name_that_hash/prettifier.py +++ b/name_that_hash/prettifier.py @@ -56,15 +56,15 @@ def pretty_print(self, objs): self.pretty_print_one(i, multi_print) def pretty_print_one(self, objs: List, multi_print: bool): - out = f"\n[bold #011627 on #ff9f1c]{objs.chash}[/bold #011627 on #ff9f1c]\n" + out = f"\n[bold magenta]{objs.chash}[/bold magenta]\n" # It didn't find any hahses. if len(objs.prototypes) == 0: - out += "[bold #2ec4b6]No hashes found.[/bold #2ec4b6]" + out += "[bold #FF0000]No hashes found.[/bold #FF0000]" console.print(out) return out - out += "\n[bold underline #2ec4b6]Most Likely[/bold underline #2ec4b6] \n" + out += "\n[bold underline #5f5fff]Most Likely[/bold underline #5f5fff] \n" start = objs.prototypes[0:4] rest = objs.prototypes[4:] @@ -78,7 +78,7 @@ def pretty_print_one(self, objs: List, multi_print: bool): # return if accessible is on if not self.a11y: - out += "\n[bold underline #2ec4b6]Least Likely[/bold underline #2ec4b6]\n" + out += "\n[bold underline #5f5fff]Least Likely[/bold underline #5f5fff]\n" for i in rest: out += self.turn_named_tuple_pretty_print(i) + " " @@ -88,7 +88,7 @@ def pretty_print_one(self, objs: List, multi_print: bool): def turn_named_tuple_pretty_print(self, nt: NamedTuple): # This colours red - out = f"[bold #e71d36]{nt['name']}[/bold #e71d36], " + out = f"[bold #ff5f00]{nt['name']}[/bold #ff5f00], " hc = nt["hashcat"] john = nt["john"] @@ -107,6 +107,6 @@ def turn_named_tuple_pretty_print(self, nt: NamedTuple): out += f"John Name: {john}." if des: # Orange - out += f"[#ff9f1c]Summary: {des}[/#ff9f1c]" + out += f"[#8787D7]Summary: {des}[/#8787D7]" return out diff --git a/name_that_hash/runner.py b/name_that_hash/runner.py index 9753097..0a7aaa0 100644 --- a/name_that_hash/runner.py +++ b/name_that_hash/runner.py @@ -1,233 +1,233 @@ -import click -import sys -from typing import NamedTuple, List - -from rich import print, text -from loguru import logger - -logger.add( - sys.stderr, format="{time} {level} {message}", filter="my_module", level="INFO" -) - - -# Lets you import as an API -# or run as a package -try: - import hashes, hash_namer, prettifier -except ModuleNotFoundError: - from name_that_hash import hash_namer, hashes, prettifier - - -class HashObj: - """ - Every hash given to our program will be assiocated with one object - This object contains the possible type of hash - and provides ways to print that hash - """ - - def __init__(self, chash: str, nth, hash_info): - self.chash = chash - self.nth = nth - - self.popular = hash_info.popular - - # prorotypes is given as a generator - self.prototypes = nth.identify(chash) - self.prototypes = self.sort_by_popular() - - self.hash_obj = {self.chash: self.prototypes} - - def get_prototypes(self): - return self.prototypes - - def sort_by_popular(self): - """Sorts the list by popular + everything else - - we do this using the self.popular set. Sets have O(1) lookup, so it's cheap. - If on named_tuple is in the popular set, we add it to the populars list and remove it from prototypes. - - we then return populars list + prototypes. - """ - - to_ret = [] - populars = [] - for i in self.prototypes: - if i.name in self.popular: - populars.append(i.__dict__) - else: - to_ret.append(i.__dict__) - return populars + to_ret - - -class hash_information: - def __init__(self): - self.popular = set( - [ - "MD5", - "MD4", - "NTLM", - "SHA-256", - "SHA-515", - "Keccak-256", - "Keccak-512", - "Blake2", - "bcrypt", - "SHA-1", - "HMAC-SHA1 (key = $salt)", - ] - ) - - -def print_help(ctx): - click.echo(ctx.get_help()) - ctx.exit() - - -def banner(): - text = r"""[bold blue] - _ _ _____ _ _ _ _ _ - | \ | | |_ _| | | | | | | | | | - | \| | __ _ _ __ ___ ___ ______| | | |__ __ _| |_ ______| |_| | __ _ ___| |__ - | . ` |/ _` | '_ ` _ \ / _ \______| | | '_ \ / _` | __|______| _ |/ _` / __| '_ \ - | |\ | (_| | | | | | | __/ | | | | | | (_| | |_ | | | | (_| \__ \ | | | - \_| \_/\__,_|_| |_| |_|\___| \_/ |_| |_|\__,_|\__| \_| |_/\__,_|___/_| |_| -https://twitter.com/bee_sec_san -https://github.com/HashPals/Name-That-Hash [/bold blue] - """ - print(text) - - -@click.command() -@click.option("-t", "--text", help="Check one hash", type=str) -@click.option( - "-f", "--file", type=click.File("rb"), help="Newline separated hash file input" -) -@click.option( - "-g", - "--greppable", - is_flag=True, - type=bool, - help="Are you going to grep this output? Prints in JSON format.", -) -@click.option( - "-a", - "--accessible", - is_flag=True, - help="Turn on accessible mode, does not print ASCII art. Also dooes not print very large blocks of text, as this can cause some pains with screenreaders. This reduces the information you get. If you want the least likely feature but no banner, use --no-banner. ", -) -@click.option("--no-banner", is_flag=True, help="Removes banner from startup.") -@click.option( - "--no-john", is_flag=True, help="Don't print John The Ripper Information." -) -@click.option("--no-hashcat", is_flag=True, help="Don't print Hashcat Information.") -@click.option( - "-v", - "--verbose", - count=True, - type=int, - help="Turn on debugging logs. -vvv for maximum logs.", -) -def main(**kwargs): - """Name That Hash - Instantly name the type of any hash! - - Github:\n - https://github.com/hashpals/name-that-hash - - From the creator of RustScan and Ciphey. Follow me on Twitter!\n - https://twitter.com/bee_sec_san - - Example usage:\n - nth --text '5f4dcc3b5aa765d61d8327deb882cf99'\n - nth --file hash\n - nth --text '5f4dcc3b5aa765d61d8327deb882cf99' --greppable\n - Note: Use single quotes ' as double quotes " do not work well on Linux.\n - """ - no_args = True - for i in kwargs.values(): - if i: - no_args = False - break - if no_args: - with click.Context(main) as ctx: - click.echo(main.get_help(ctx)) - exit(0) - - # Load the verbosity, so that we can start logging - set_logger(kwargs) - logger.debug(kwargs) - - # Banner handling - if not kwargs["accessible"] and not kwargs["no_banner"] and not kwargs["greppable"]: - logger.info("Running the banner.") - banner() - - hash_info = hash_information() - # nth = the object which names the hash types - nth = hash_namer.Name_That_Hash(hashes.prototypes) - # prettifier print things :) - pretty_printer = prettifier.Prettifier(kwargs) - - logger.trace("Initialised the hash_info, nth, and pretty_printer objects.") - - output = [] - - if kwargs["text"]: - output.append(HashObj(kwargs["text"], nth, hash_info)) - elif kwargs["file"]: - logger.trace("performing file opening") - # else it must be a file - for i in kwargs["file"].read().splitlines(): - logger.trace(i) - # for every hash in the file, put it into the output list - # we have to decode it as its bytes str - output.append(HashObj(i.decode("utf-8"), nth, hash_info)) - logger.trace(output + "\n") - - if kwargs["greppable"]: - print(pretty_printer.greppable_output(output)) - else: - pretty_printer.pretty_print(output) - - -def set_logger(kwargs): - # sets the logger value based on args - verbosity = kwargs["verbose"] - if not verbosity: - logger.remove() - return - elif verbosity == 1: - verbosity = "WARNING" - elif verbosity == 2: - verbosity = "DEBUG" - elif verbosity == 3: - verbosity = "TRACE" - logger.add(sink=sys.stderr, level=verbosity, colorize=sys.stderr.isatty()) - logger.opt(colors=True) - - logger.debug(f"Verbosity set to level {verbosity} ({verbosity})") - - -def api_return_hashes_as_json(chash: [str], args: dict = {}): - """ - Using name-that-hash as an API? Call this function! - - Given a list of hashes of strings - return a list of json of all hashes in the same order as the input - """ - logger.remove() - # nth = the object which names the hash types - nth = hash_namer.Name_That_Hash(hashes.prototypes) - # prettifier print things :) - pretty_printer = prettifier.Prettifier(args, api=True) - # for most popular hashes etc - hash_info = hash_information() - - output = [] - for i in chash: - output.append(HashObj(i, nth, hash_info)) - - return pretty_printer.greppable_output(output) - - -if __name__ == "__main__": - main() +import click +import sys +from typing import NamedTuple, List + +from rich import print, text +from loguru import logger + +logger.add( + sys.stderr, format="{time} {level} {message}", filter="my_module", level="INFO" +) + + +# Lets you import as an API +# or run as a package +try: + import hashes, hash_namer, prettifier +except ModuleNotFoundError: + from name_that_hash import hash_namer, hashes, prettifier + + +class HashObj: + """ + Every hash given to our program will be assiocated with one object + This object contains the possible type of hash + and provides ways to print that hash + """ + + def __init__(self, chash: str, nth, hash_info): + self.chash = chash + self.nth = nth + + self.popular = hash_info.popular + + # prorotypes is given as a generator + self.prototypes = nth.identify(chash) + self.prototypes = self.sort_by_popular() + + self.hash_obj = {self.chash: self.prototypes} + + def get_prototypes(self): + return self.prototypes + + def sort_by_popular(self): + """Sorts the list by popular + everything else + + we do this using the self.popular set. Sets have O(1) lookup, so it's cheap. + If on named_tuple is in the popular set, we add it to the populars list and remove it from prototypes. + + we then return populars list + prototypes. + """ + + to_ret = [] + populars = [] + for i in self.prototypes: + if i.name in self.popular: + populars.append(i.__dict__) + else: + to_ret.append(i.__dict__) + return populars + to_ret + + +class hash_information: + def __init__(self): + self.popular = set( + [ + "MD5", + "MD4", + "NTLM", + "SHA-256", + "SHA-515", + "Keccak-256", + "Keccak-512", + "Blake2", + "bcrypt", + "SHA-1", + "HMAC-SHA1 (key = $salt)", + ] + ) + + +def print_help(ctx): + click.echo(ctx.get_help()) + ctx.exit() + + +def banner(): + text = r"""[bold blue] + _ _ _____ _ _ _ _ _ + | \ | | |_ _| | | | | | | | | | + | \| | __ _ _ __ ___ ___ ______| | | |__ __ _| |_ ______| |_| | __ _ ___| |__ + | . ` |/ _` | '_ ` _ \ / _ \______| | | '_ \ / _` | __|______| _ |/ _` / __| '_ \ + | |\ | (_| | | | | | | __/ | | | | | | (_| | |_ | | | | (_| \__ \ | | | + \_| \_/\__,_|_| |_| |_|\___| \_/ |_| |_|\__,_|\__| \_| |_/\__,_|___/_| |_| +https://twitter.com/bee_sec_san +https://github.com/HashPals/Name-That-Hash [/bold blue] + """ + print(text) + + +@click.command() +@click.option("-t", "--text", help="Check one hash", type=str) +@click.option( + "-f", "--file", type=click.File("rb"), help="Newline separated hash file input" +) +@click.option( + "-g", + "--greppable", + is_flag=True, + type=bool, + help="Are you going to grep this output? Prints in JSON format.", +) +@click.option( + "-a", + "--accessible", + is_flag=True, + help="Turn on accessible mode, does not print ASCII art. Also dooes not print very large blocks of text, as this can cause some pains with screenreaders. This reduces the information you get. If you want the least likely feature but no banner, use --no-banner. ", +) +@click.option("--no-banner", is_flag=True, help="Removes banner from startup.") +@click.option( + "--no-john", is_flag=True, help="Don't print John The Ripper Information." +) +@click.option("--no-hashcat", is_flag=True, help="Don't print Hashcat Information.") +@click.option( + "-v", + "--verbose", + count=True, + type=int, + help="Turn on debugging logs. -vvv for maximum logs.", +) +def main(**kwargs): + """Name That Hash - Instantly name the type of any hash! + + Github:\n + https://github.com/hashpals/name-that-hash + + From the creator of RustScan and Ciphey. Follow me on Twitter!\n + https://twitter.com/bee_sec_san + + Example usage:\n + nth --text '5f4dcc3b5aa765d61d8327deb882cf99'\n + nth --file hash\n + nth --text '5f4dcc3b5aa765d61d8327deb882cf99' --greppable\n + Note: Use single quotes ' as double quotes " do not work well on Linux.\n + """ + no_args = True + for i in kwargs.values(): + if i: + no_args = False + break + if no_args: + with click.Context(main) as ctx: + click.echo(main.get_help(ctx)) + exit(0) + + # Load the verbosity, so that we can start logging + set_logger(kwargs) + logger.debug(kwargs) + + # Banner handling + if not kwargs["accessible"] and not kwargs["no_banner"] and not kwargs["greppable"]: + logger.info("Running the banner.") + banner() + + hash_info = hash_information() + # nth = the object which names the hash types + nth = hash_namer.Name_That_Hash(hashes.prototypes) + # prettifier print things :) + pretty_printer = prettifier.Prettifier(kwargs) + + logger.trace("Initialised the hash_info, nth, and pretty_printer objects.") + + output = [] + + if kwargs["text"]: + output.append(HashObj(kwargs["text"], nth, hash_info)) + elif kwargs["file"]: + logger.trace("performing file opening") + # else it must be a file + for i in kwargs["file"].read().splitlines(): + logger.trace(i) + # for every hash in the file, put it into the output list + # we have to decode it as its bytes str + output.append(HashObj(i.decode("utf-8"), nth, hash_info)) + logger.trace(output + "\n") + + if kwargs["greppable"]: + print(pretty_printer.greppable_output(output)) + else: + pretty_printer.pretty_print(output) + + +def set_logger(kwargs): + # sets the logger value based on args + verbosity = kwargs["verbose"] + if not verbosity: + logger.remove() + return + elif verbosity == 1: + verbosity = "WARNING" + elif verbosity == 2: + verbosity = "DEBUG" + elif verbosity == 3: + verbosity = "TRACE" + logger.add(sink=sys.stderr, level=verbosity, colorize=sys.stderr.isatty()) + logger.opt(colors=True) + + logger.debug(f"Verbosity set to level {verbosity} ({verbosity})") + + +def api_return_hashes_as_json(chash: [str], args: dict = {}): + """ + Using name-that-hash as an API? Call this function! + + Given a list of hashes of strings + return a list of json of all hashes in the same order as the input + """ + logger.remove() + # nth = the object which names the hash types + nth = hash_namer.Name_That_Hash(hashes.prototypes) + # prettifier print things :) + pretty_printer = prettifier.Prettifier(args, api=True) + # for most popular hashes etc + hash_info = hash_information() + + output = [] + for i in chash: + output.append(HashObj(i, nth, hash_info)) + + return pretty_printer.greppable_output(output) + + +if __name__ == "__main__": + main() diff --git a/packages/setup.py b/packages/setup.py index c2864b8..a6d31e6 100644 --- a/packages/setup.py +++ b/packages/setup.py @@ -1,36 +1,36 @@ -# -*- coding: utf-8 -*- - -# DO NOT EDIT THIS FILE! -# This file has been autogenerated by dephell <3 -# https://github.com/dephell/dephell - -try: - from setuptools import setup -except ImportError: - from distutils.core import setup - -readme = '' - -setup( - long_description=readme, - name='name-that-hash', - version='0.6.0', - description='The Modern Hash Identifcation System', - python_requires='==3.*,>=3.7.0', - author='brandon', - author_email='brandon@skerritt.blog', - license='GPL-3.0-or-later', - entry_points={ - "console_scripts": [ - "nth = name_that_hash.runner:main", - "name-that-hash = name_that_hash.runner:main" - ] - }, - packages=['Name_That_Hash'], - package_dir={"": "."}, - package_data={}, - install_requires=[ - 'click==7.*,>=7.1.2', 'loguru==0.*,>=0.5.3', 'rich==9.*,>=9.9.0' - ], - extras_require={"dev": ["pytest==5.*,>=5.2.0"]}, -) +# -*- coding: utf-8 -*- + +# DO NOT EDIT THIS FILE! +# This file has been autogenerated by dephell <3 +# https://github.com/dephell/dephell + +try: + from setuptools import setup +except ImportError: + from distutils.core import setup + +readme = '' + +setup( + long_description=readme, + name='name-that-hash', + version='0.6.0', + description='The Modern Hash Identifcation System', + python_requires='==3.*,>=3.7.0', + author='brandon', + author_email='brandon@skerritt.blog', + license='GPL-3.0-or-later', + entry_points={ + "console_scripts": [ + "nth = name_that_hash.runner:main", + "name-that-hash = name_that_hash.runner:main" + ] + }, + packages=['Name_That_Hash'], + package_dir={"": "."}, + package_data={}, + install_requires=[ + 'click==7.*,>=7.1.2', 'loguru==0.*,>=0.5.3', 'rich==9.*,>=9.9.0' + ], + extras_require={"dev": ["pytest==5.*,>=5.2.0"]}, +) diff --git a/pyproject.toml b/pyproject.toml index 4137264..d64e9d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,23 +1,23 @@ -[tool.poetry] -name = "name-that-hash" -version = "0.6.0" -description = "The Modern Hash Identifcation System" -authors = ["brandon "] -license = "GPL-3.0-or-later" - -[tool.poetry.dependencies] -python = "^3.7" -click = "^7.1.2" -rich = "^9.9.0" -loguru = "^0.5.3" - -[tool.poetry.dev-dependencies] -pytest = "^5.2" - -[build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" - -[tool.poetry.scripts] -nth = "name_that_hash.runner:main" -name-that-hash = "name_that_hash.runner:main" +[tool.poetry] +name = "name-that-hash" +version = "0.6.0" +description = "The Modern Hash Identifcation System" +authors = ["brandon "] +license = "GPL-3.0-or-later" + +[tool.poetry.dependencies] +python = "^3.7" +click = "^7.1.2" +rich = "^9.9.0" +loguru = "^0.5.3" + +[tool.poetry.dev-dependencies] +pytest = "^5.2" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry.scripts] +nth = "name_that_hash.runner:main" +name-that-hash = "name_that_hash.runner:main" From f45d84b0441eabeb2551ae6b3e5fc2eaad0d1512 Mon Sep 17 00:00:00 2001 From: brandon Date: Tue, 2 Feb 2021 13:21:42 +0000 Subject: [PATCH 2/3] added release drafter --- .github/release-drafter.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/release-drafter.yml diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000..96b0f95 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,4 @@ +template: | + ## What’s Changed + + $CHANGES \ No newline at end of file From 0928c44987d3dc49d63a8f218609d5a2613e8cfc Mon Sep 17 00:00:00 2001 From: brandon Date: Tue, 2 Feb 2021 13:24:45 +0000 Subject: [PATCH 3/3] fixed title --- name_that_hash/runner.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/name_that_hash/runner.py b/name_that_hash/runner.py index 0a7aaa0..aae7fd4 100644 --- a/name_that_hash/runner.py +++ b/name_that_hash/runner.py @@ -90,7 +90,7 @@ def banner(): | \| | __ _ _ __ ___ ___ ______| | | |__ __ _| |_ ______| |_| | __ _ ___| |__ | . ` |/ _` | '_ ` _ \ / _ \______| | | '_ \ / _` | __|______| _ |/ _` / __| '_ \ | |\ | (_| | | | | | | __/ | | | | | | (_| | |_ | | | | (_| \__ \ | | | - \_| \_/\__,_|_| |_| |_|\___| \_/ |_| |_|\__,_|\__| \_| |_/\__,_|___/_| |_| + \_| \_/\__,_|_| |_| |_|\___| \_/ |_| |_|\__,_|\__| \_| |_/\__,_|___/_| |_| https://twitter.com/bee_sec_san https://github.com/HashPals/Name-That-Hash [/bold blue] """ diff --git a/pyproject.toml b/pyproject.toml index d64e9d5..c11dfcd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "name-that-hash" -version = "0.6.0" +version = "0.8.0" description = "The Modern Hash Identifcation System" authors = ["brandon "] license = "GPL-3.0-or-later"