-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
92768b5
commit 9cfd265
Showing
8 changed files
with
1,675 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# These are supported funding model platforms | ||
|
||
github: p0dalirius | ||
patreon: Podalirius |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
# File name : Argon2Cracker.py | ||
# Author : Podalirius (@podalirius_) | ||
# Date created : 25 Feb 2022 | ||
|
||
import argon2 | ||
import argparse | ||
import base64 | ||
import datetime | ||
import re | ||
import sys | ||
import time | ||
from concurrent.futures import ThreadPoolExecutor | ||
|
||
|
||
def get_ctx_from_hash(hash): | ||
matched = re.search('\$(argon2i(d)?)\$v=([0-9]+)\$([tpm=0-9,]+)\$([a-zA-Z0-9\+]+)\$([a-zA-Z0-9\+]+)', hash) | ||
if matched is not None: | ||
_, _, version, params, salt, hash = matched.groups() | ||
params = {p.split('=')[0]: int(p.split('=')[1]) for p in params.split(',')} | ||
salt = base64.b64decode(salt+"==") | ||
hash = base64.b64decode(hash+"==") | ||
ctx = argon2.PasswordHasher(time_cost=params['t'], memory_cost=params['m'], parallelism=params['p'], hash_len=len(hash), salt_len=len(salt)) | ||
return ctx | ||
else: | ||
return None | ||
|
||
|
||
def worker(ctx, hash, candidate, monitor_data): | ||
if not monitor_data["found"]: | ||
try: | ||
monitor_data["tries"] += 1 | ||
ctx.verify(hash, candidate) | ||
monitor_data["found"] = True | ||
monitor_data["candidate"] = candidate | ||
return True | ||
except argon2.exceptions.VerifyMismatchError as e: | ||
return False | ||
|
||
|
||
def monitor_thread(monitor_data): | ||
last_check, monitoring = 0, True | ||
while monitoring and not monitor_data["found"]: | ||
new_check = monitor_data["tries"] | ||
rate = (new_check - last_check) | ||
print("\r[%s] Status (%d/%d) %5.2f %% | Rate %d H/s " % ( | ||
datetime.datetime.now().strftime("%Y/%m/%d %Hh%Mm%Ss"), | ||
new_check, monitor_data["total"], (new_check/monitor_data["total"])*100, | ||
rate | ||
), end="") | ||
last_check = new_check | ||
time.sleep(1) | ||
if rate == 0 and new_check != 0: | ||
monitoring = False | ||
|
||
if monitor_data["found"]: | ||
print("\n[>] Found: %-30s" % monitor_data["candidate"]) | ||
else: | ||
print("") | ||
|
||
def parseArgs(): | ||
print("Argon2Cracker - v1.0 - by @podalirius_\n") | ||
|
||
parser = argparse.ArgumentParser(description="argon2 hash cracker") | ||
parser.add_argument("hash", default=None, help="argon2 hash") | ||
parser.add_argument("-t", "--threads", dest="threads", action="store", type=int, default=16, required=False, help="Number of threads (Default: 16)") | ||
parser.add_argument("-w", "--wordlist", dest="wordlist", action="store", type=str, default=5, required=True, help="Wordlist") | ||
parser.add_argument("-v", "--verbose", default=False, action="store_true", help='Verbose mode. (default: False)') | ||
|
||
return parser.parse_args() | ||
|
||
|
||
if __name__ == '__main__': | ||
options = parseArgs() | ||
|
||
if options.verbose: | ||
print("[>] Loading wordlist ... ", end="") | ||
sys.stdout.flush() | ||
f = open(options.wordlist, 'r') | ||
wordlist = sorted([l.strip() for l in f.readlines()]) | ||
f.close() | ||
if options.verbose: | ||
print("done. (%d candidates loaded)" % len(wordlist)) | ||
sys.stdout.flush() | ||
|
||
ctx = get_ctx_from_hash(options.hash) | ||
|
||
monitor_data = {"found": False, "tries": 0, "candidate": "", "total": len(wordlist)} | ||
|
||
# Waits for all the threads to be completed | ||
with ThreadPoolExecutor(max_workers=min(options.threads, len(wordlist))+1) as tp: | ||
tp.submit(monitor_thread, monitor_data) | ||
for candidate in wordlist: | ||
tp.submit(worker, ctx, options.hash, candidate, monitor_data) | ||
|
||
if not monitor_data["found"]: | ||
print("[!] Hash could not be cracked from this wordlist.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,49 @@ | ||
# Argon2Cracker | ||
![](./.github/banner.png) | ||
|
||
<p align="center"> | ||
A multithreaded bruteforcer of argon2 hashes. | ||
<br> | ||
<img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/p0dalirius/FindUncommonShares"> | ||
<a href="https://twitter.com/intent/follow?screen_name=podalirius_" title="Follow"><img src="https://img.shields.io/twitter/follow/podalirius_?label=Podalirius&style=social"></a> | ||
<br> | ||
</p> | ||
|
||
## Features | ||
|
||
- [x] Progress updated every second with the number of processed hashes per second. | ||
- [x] Multithreaded bruteforce. | ||
|
||
## Usage | ||
|
||
``` | ||
$ ./Argon2Cracker.py -h | ||
Argon2Cracker - v1.0 - by @podalirius_ | ||
usage: Argon2Cracker.py [-h] [-t THREADS] -w WORDLIST [-v] hash | ||
argon2 hash cracker | ||
positional arguments: | ||
hash argon2 hash | ||
optional arguments: | ||
-h, --help show this help message and exit | ||
-t THREADS, --threads THREADS | ||
Number of threads (Default: 16) | ||
-w WORDLIST, --wordlist WORDLIST | ||
Wordlist | ||
-v, --verbose Verbose mode. (default: False) | ||
``` | ||
|
||
## Example | ||
|
||
``` | ||
./Argon2Cracker.py '$argon2id$v=19$m=102400,t=2,p=8$Xy3Iqq6AmzfugAV7Fo31dA$dAVH9zcRoKHvDDaAy3rdWg' -w ./example/wordlist.txt -v | ||
``` | ||
|
||
![](./.github/example.png) | ||
|
||
## Contributing | ||
|
||
Pull requests are welcome. Feel free to open an issue if you want to add other features. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
# File name : generate_hash.py | ||
# Author : Podalirius (@podalirius_) | ||
# Date created : 25 Feb 2022 | ||
|
||
import argon2 | ||
import argparse | ||
|
||
def parseArgs(): | ||
parser = argparse.ArgumentParser(description="Description message") | ||
parser.add_argument("text", help='Password to hash') | ||
return parser.parse_args() | ||
|
||
|
||
if __name__ == '__main__': | ||
options = parseArgs() | ||
|
||
hash = argon2.PasswordHasher().hash(options.text) | ||
print(hash) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
$argon2id$v=19$m=102400,t=2,p=8$YwEFZi9LzRfVNnRd2o1dgA$UxQEY1WA2kMeyt++wSjZ+g |
Oops, something went wrong.