Created
August 31, 2017 16:12
-
-
Save linickx/6331c38917a7f525e60fe26e4610d0aa to your computer and use it in GitHub Desktop.
cisco_decrypt.py
This file contains hidden or 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 | |
# coding=utf-8 | |
""" | |
My version of cisco_decrypt.py | |
Version 1.0 - Nick Bettison - linickx.com | |
USAGE: | |
------ | |
linickx:~ $ cisco_decrypt.py -e "023530612D5319347A" | |
STZF5vuV | |
linickx:~ $ | |
or simply... | |
linickx:~ $ cisco_decrypt.py 023530612D5319347A | |
STZF5vuV | |
linickx:~ $ | |
or even... | |
linickx:~ $ cisco_decrypt.py 023530612D5319347A 095C4F1A0A1218000F | |
STZF5vuV | |
password | |
linickx:~ $ | |
""" | |
import sys | |
import re | |
import logging | |
logging.basicConfig(format='[%(levelname)s] %(asctime)s %(message)s', level=logging.WARNING) | |
logger = logging.getLogger("cisco_decrypt") | |
from optparse import OptionParser | |
class CiscoPassword: | |
""" | |
Original Work by David M Pennington | |
http://www.pennington.net/py/cisco_decrypt/ | |
Converted from perl code that was written by jbash at cisco.com. | |
COPYRIGHT, LICENSE, and WARRANTY | |
================================ | |
GNU General Public License, v3 | |
This software is (c) 2007 by David Michael Pennington. It can be | |
reused under the terms of the GPL v3 license provided that proper | |
credit for the work of the author is preserved in the form of this | |
copyright notice and license for this package. | |
No warranty of any kind is expressed or implied. By using this software, you | |
are agreeing to assume ALL risks and David M Pennington shall NOT be liable | |
for ANY damages resulting from its use. | |
If you chose to bring legal action against the author, you are automatically | |
granting him the remainder of your lifetime salary, ownership of your | |
retirement plan (you do have one, right??), the deed to your house assuming | |
it isn't a pile of junk, and your perpetual indentured servitude under his | |
direction. | |
""" | |
def __init__(self, string): | |
self.string = string | |
self.decrypted = True | |
def passed(self): | |
""" | |
Did is pass or fail | |
""" | |
return self.decrypted | |
def decrypt(self): | |
"""Cisco Type 7 password decryption. | |
""" | |
ep = self.string | |
xlat = (0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41, 0x2c, | |
0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c, 0x64, 0x4a, | |
0x4b, 0x44, 0x48, 0x53, 0x55, 0x42) | |
dp = "" | |
regex = re.compile("^(..)(.+)") | |
if len(ep) & 1: | |
logger.error("Invalid Hash - %s - Odd number length string", ep) | |
self.decrypted = False | |
else: | |
result = regex.search(ep) | |
try: | |
s, e = int(result.group(1)), result.group(2) | |
except ValueError: | |
# typically get a ValueError for int( result.group(1))) because | |
# the method was called with an unencrypted password. For now | |
# SILENTLY bypass the error | |
s, e = (0, "") | |
logger.error("Invalid Hash - %s - Did you paste a clear txt string?", ep) | |
self.decrypted = False | |
for ii in range(0, len(e), 2): | |
# int( blah, 16) assumes blah is base16... cool | |
magic = int(re.search(".{%s}(..)" % ii, e).group(1), 16) | |
#print("S = %s" % s) | |
if s <= 25: | |
# Algorithm appears unpublished after s = 25 | |
newchar = "%c" % (magic ^ int(xlat[int(s)])) | |
else: | |
newchar = "?" | |
dp = dp + str(newchar) | |
s = s + 1 | |
if s > 25: | |
logger.warning("Password Decryption Failed - Patial response returned") | |
self.decrypted = False | |
return dp | |
# Output Array of all things! | |
logger.debug(str(sys.argv)) | |
# Loop thru inputs | |
for thing in sys.argv: | |
# ignore filenames | |
regmatch = re.match(r'.*\.py$', thing) | |
if regmatch: | |
logger.debug("Ingoring... %s", thing) | |
continue | |
# ignore anyone using minus swithes, such as -e in the original documentation | |
regmatch = re.match('^-', thing) | |
if regmatch: | |
logger.debug("Ingoring... %s", thing) | |
continue | |
# Ok, this is what we're working with | |
logger.debug("Input is %s", thing) | |
# Crack it! | |
crack = CiscoPassword(thing) | |
print(crack.decrypt()) | |
# Exit with error if the crack didn't completly pass | |
if not crack.passed(): | |
sys.exit(1) | |
""" | |
COPYRIGHT, LICENSE, and WARRANTY | |
================================ | |
GNU General Public License, v3 | |
This software is (c) 2017 by Nick Bettison. It can be | |
reused under the terms of the GPL v3 license provided that proper | |
credit for the work of the author is preserved in the form of this | |
copyright notice and license for this package. | |
No warranty of any kind is expressed or implied. By using this software, you | |
are agreeing to assume ALL risks and Nick Bettison shall NOT be liable | |
for ANY damages resulting from its use. | |
If you chose to bring legal action against the author, you are automatically | |
granting him the remainder of your lifetime salary, ownership of your | |
retirement plan (you do have one, right??), the deed to your house assuming | |
it isn't a pile of junk, and your perpetual indentured servitude under his | |
direction. | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment