Created
May 24, 2011 20:09
-
-
Save craSH/989567 to your computer and use it in GitHub Desktop.
Determine password for a PGP private key based on a 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
#!/usr/bin/env python | |
""" | |
Determine password for a PGP private key based on a wordlist. | |
Also performs permutations on passwords in the case of l33tsp3ak, etc. | |
Requires python-gnupg (easy_install/pip install python-gnupg) | |
To quiet down some of the exceptions during signing attempts, the following | |
"patch" is needed within gnupg.py: | |
--- gnupg.py 2011-05-24 13:11:23.000000000 -0400 | |
+++ gnupg_patched.py 2011-05-24 16:02:52.000000000 -0400 | |
@@ -974,6 +974,8 @@ | |
if key in ("USERID_HINT", "NEED_PASSPHRASE", "BAD_PASSPHRASE", | |
"GOOD_PASSPHRASE", "BEGIN_SIGNING"): | |
pass | |
+ elif key == "INV_SGNR": | |
+ pass | |
elif key == "SIG_CREATED": | |
(self.type, | |
algo, hashalgo, cls, | |
Example Usage: | |
gpg_bruteforce.py <key_id> [-p] < /usr/share/dict/words | |
Copyleft 2011 Ian Gallagher <crash@neg9.org> | |
Inspired by idea/work of Aaron Grattifiori <dyn@neg9.org> | |
""" | |
import sys | |
import os | |
from datetime import datetime | |
from gnupg import GPG | |
def verifyPassphrase(signing_key, key_passphrase): | |
""" | |
Return True if passphrase is correct, False if it is not | |
""" | |
# Setup GPG | |
gnupg_home = "%s/.gnupg" % os.environ['HOME'] | |
gpg = GPG(gnupghome=gnupg_home) | |
sig = None | |
try: | |
# This bugger is threaded, so catching exceptions from it isn't really something that works so great | |
sig = gpg.sign('Test String', keyid=signing_key, passphrase=key_passphrase, clearsign=False) | |
except Exception: | |
pass | |
if sig: | |
return True | |
else: | |
return False | |
if "__main__" == __name__: | |
if len(sys.argv) < 2: | |
print >>sys.stderr, "usage: %s <key_id> [-p] < <wordlist>" % sys.argv[0] | |
print >>sys.stderr, "\t<key_id>: PGP KeyID/Fingerprint to test." | |
print >>sys.stderr, "\t-p: Attempt variations of each word in the wordlist." | |
print >>sys.stderr, "\t<wordlist>: A file containing passwords to attempt, one per line." | |
sys.exit(1) | |
keyid = sys.argv[1] | |
try_permutations = True if (len(sys.argv) > 2 and sys.argv[2].lower() == '-p') else False | |
attempts = 0 | |
valid_password = None | |
passwords = sys.stdin.readlines() | |
time_start = datetime.now() | |
for password in passwords: | |
attempts += 1 | |
if verifyPassphrase(keyid, password): | |
valid_password = password | |
break | |
if try_permutations: | |
""" | |
Need to write some code that will take a word, and make a generator of all/many | |
variations of it based on latin "rules" of some sort. | |
E.g/: catfish -> c4tfish, ca7fish, catf!sh, c4tf!5h, Catfish, caTfish, ... | |
""" | |
# TODO: Implement below | |
""" | |
for permutation in permutate(password): | |
attempts += 1 | |
if verifyPassphrase(keyid, permutation): | |
valid_password = password | |
break | |
""" | |
time_end = datetime.now() | |
if valid_password: | |
print "Success! Passphrase for keyid %s: %s" % (keyid, valid_password[:-1] if valid_password[-1] == "\n" else valid_password) | |
print >>sys.stderr, "Number of attempts until success: %d" % attempts | |
else: | |
print "Sorry, no password found after %d attempts :(" % attempts | |
print >>sys.stderr, "Total run time: %s" % (time_end - time_start) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment