├── README.md ├── __init__.py ├── banner.py ├── char_identification.py ├── common_function.py ├── detail_hash_type.py ├── hash_identification.py ├── length_identification.py ├── re_identification.py ├── show.png └── special.py /README.md: -------------------------------------------------------------------------------- 1 | # Cipher_Encryption_Type_Identification 2 | 密文加密类型判断工具。 3 | 4 | 1. 首先这只是一个半成品。继续修改中。主要是增加识别密文的类型,也就是加上更多规则。 5 | 2. 对同一个密文可能符合多种加密方式,所以判断也只能是做推荐。 6 | 3. 不能解密,做的是解密前一步。 7 | 8 | - 用法:
9 | python hash_identification.py 10 | 11 | - 环境:
12 | Python 3 13 | 14 | - 效果展示:
15 | ![image](https://github.com/Snowming04/Cipher_Encryption_Type_Identification/blob/master/show.png) 16 |
17 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /banner.py: -------------------------------------------------------------------------------- 1 | #!先用于帮助内核找到Python解释器, 但是在导入模块时, 将会被忽略. 因此只有被直接执行的文件中才有必要加入#!. 2 | # -*- coding: utf-8 -*- 3 | # __author__ = 'Snowming' 4 | # Description: Snowming is a tool that identifies the hash mode of ciphers. This tools can be used as the pre-step for password cracking. This tool can be used by both input cipher one by one or select the file of ciphers collection. 5 | 6 | def banner(): 7 | # Snowming's banner, doubled slashes added for proper formatting when banner is shown in STDOUT. 8 | print("-" * 100) 9 | print(""" 10 | ___ _ 11 | / __|_ _ _____ __ ___ __ (_)_ _ __ _ 12 | \__ \ ' \/ _ \ V V / ' \| | ' \/ _` | 13 | |___/_||_\___/\_/\_/|_|_|_|_|_||_\__, | 14 | |___/ 15 | 16 | Snowming | A tool for cipher identification. Supporting 300+ kinds of encryption types. 17 | Support version | Python 3 18 | Writer | Written by Snowming 19 | """) 20 | print("Usage | python hash_identification.py") 21 | print("Next step | Input the cipher you want to know its encryption type.") 22 | print() 23 | print("-" * 100) 24 | print() 25 | -------------------------------------------------------------------------------- /char_identification.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # __author__ = 'Snowming' 3 | 4 | from common_function import print_encryption 5 | 6 | 7 | def char_identify(user_input): 8 | # TODO(Snowming, kirioxiang1@gmail.com):包含特殊字符的,比如 /等。 9 | # TODO(Snowming, kirioxiang1@gmail.com):在这里最后一个判断,输入cannot identify。 10 | pass 11 | -------------------------------------------------------------------------------- /common_function.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # __author__ = 'Snowming' 3 | 4 | # 单纯去掉代码重复冗余 5 | def print_encryption(encryption_type): 6 | print(encryption_type) 7 | print() 8 | print("=" * 100) 9 | print() 10 | -------------------------------------------------------------------------------- /detail_hash_type.py: -------------------------------------------------------------------------------- 1 | 2 | # -*- coding: utf-8 -*- 3 | # __author__ = 'Snowming' 4 | # TODO(Snowming, kirioxiang1@gmail.com):用类变量和装饰器改写。 5 | ''' 6 | 装饰器作权限验证 7 | 多几层嵌套返回,看能到哪一步,执行到哪一步就给相应的的权限 8 | ''' 9 | 10 | _TYPE_DICT = { 11 | 'md5_series':""" 12 | MD5 is one kind of authentication method. 13 | 14 | Hash-Mode Hash-Code 15 | ---------------------------------------------------------- 16 | 1. MD5 0 17 | ---------------------------------------------------------- 18 | 2. md5($pass.$salt) 10 19 | ---------------------------------------------------------- 20 | 3. md5($salt.$pass) 20 21 | ---------------------------------------------------------- 22 | 4. md5(utf16le($pass).$salt)   30 23 | ---------------------------------------------------------- 24 | 5. md5($salt.utf16le($pass))   40 25 | ---------------------------------------------------------- 26 | 6. HMAC-MD5 (key = $pass)  50 27 | ---------------------------------------------------------- 28 | 7. HMAC-MD5 (key = $salt)   60 29 | ---------------------------------------------------------- 30 | 8. md5($salt.md5($pass)) 3710 31 | ---------------------------------------------------------- 32 | 9. md5($salt.$pass.$salt) 3800 33 | ---------------------------------------------------------- 34 | 10. md5(md5($pass).md5($salt)) 3910 35 | ---------------------------------------------------------- 36 | 11. md5($salt.md5($salt.$pass))  4010 37 | ---------------------------------------------------------- 38 | 12. md5($salt.md5($pass.$salt))  4110 39 | ---------------------------------------------------------- 40 | 13. md5(strtoupper(md5($pass)))  4300 41 | ---------------------------------------------------------- 42 | 14. md5(sha1($pass))   4400 43 | """, 44 | 'sha1_series':""" 45 | Hash-Mode Hash-Code 46 | ---------------------------------------------------------- 47 | 1. sha1 100 48 | ---------------------------------------------------------- 49 | 2. sha1($pass.$salt) 110 50 | ---------------------------------------------------------- 51 | 3. sha1($salt.$pass) 120 52 | ---------------------------------------------------------- 53 | 4. sha1(utf16le($pass).$salt) 130 54 | ---------------------------------------------------------- 55 | 5. sha1($salt.utf16le($pass)) 140 56 | ---------------------------------------------------------- 57 | 6. HMAC-SHA1 (key = $pass) 150 58 | ---------------------------------------------------------- 59 | 7. HMAC-SHA1 (key = $salt) 160 60 | ---------------------------------------------------------- 61 | 8. sha1(sha1($pass)) 4500 62 | ---------------------------------------------------------- 63 | 9. sha1($salt.sha1($pass)) 4520 64 | ---------------------------------------------------------- 65 | 10. sha1(md5($pass)) 4700 66 | ---------------------------------------------------------- 67 | 11. sha1($salt.$pass.$salt) 4900 68 | """, 69 | 'sha256_series':""" 70 | Hash-Mode Hash-Code 71 | ---------------------------------------------------------- 72 | 1. SHA-256 1400 73 | ---------------------------------------------------------- 74 | 2. sha256($pass.$salt) 1410 75 | ---------------------------------------------------------- 76 | 3. sha256($salt.$pass) 1420 77 | ---------------------------------------------------------- 78 | 4. sha256(utf16le($pass).$salt) 1430 79 | ---------------------------------------------------------- 80 | 5. sha256($salt.utf16le($pass)) 1440 81 | ---------------------------------------------------------- 82 | 6. HMAC-SHA256(key = $pass) 1450 83 | ---------------------------------------------------------- 84 | 7. HMAC-SHA256(key = $salt) 1460 85 | """, 86 | 'sha512_series':""" 87 | Hash-Mode Hash-Code 88 | ---------------------------------------------------------- 89 | 1. SHA-512 1700 90 | ---------------------------------------------------------- 91 | 2. sha512($pass.$salt) 1710 92 | ---------------------------------------------------------- 93 | 3. sha512($salt.$pass) 1720 94 | ---------------------------------------------------------- 95 | 4. sha512(utf16le($pass).$salt) 1730 96 | ---------------------------------------------------------- 97 | 5. sha512($salt.utf16le($pass)) 1740 98 | ---------------------------------------------------------- 99 | 6. HMAC-SHA512(key = $pass) 1750 100 | ---------------------------------------------------------- 101 | 7. HMAC-SHA512(key = $salt) 1760 102 | """ 103 | } 104 | 105 | 106 | # 之前这里是一个 if 的条件判断语句,之所以改成字典,主要是为了查找速度更快 107 | 108 | 109 | def get_type(arg): 110 | print(_TYPE_DICT[arg]) 111 | -------------------------------------------------------------------------------- /hash_identification.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | ' main module ' 5 | 6 | __author__ = 'Snowming' 7 | 8 | import banner 9 | import length_identification 10 | from char_identification import char_identify 11 | from common_function import print_encryption 12 | from detail_hash_type import get_type 13 | from length_identification import length_identify 14 | from re_identification import re_identify 15 | 16 | 17 | 18 | # 预处理步骤 19 | def _process(user_input): 20 | pass 21 | 22 | 23 | def _identify(): 24 | encryption_type = "Sorry cannot identify." 25 | user_input = input('Please input your cipher: ') 26 | ''' 27 | length_identify(input) 28 | re_identify(input) 29 | char_identify(input) 30 | 下面的判断中已经运行了一次了 31 | ''' 32 | # TODO(Snowming, kirioxiang1@gmail.com):下面的判断多次重复,可以设为一个方法。 33 | length_result = length_identify(user_input) 34 | re_result = re_identify(user_input) 35 | if(length_result == "Sorry cannot identify." and re_result== 36 | "Sorry cannot identify."): 37 | print_encryption(encryption_type) 38 | else: 39 | if length_result == "Encryption method may be: MD5.": 40 | answer = input('Do you want to know more detailed hash-mode?(y/n): ') 41 | # TODO(Snowming, kirioxiang1@gmail.com):这里这个判断不顶用啊,用异常改写. no为什么也显示。 42 | if(answer == "y" or "Y" or "yes" or "YES"): 43 | get_type('md5_series') 44 | if length_result == "Encryption method may be :sha1, MySQL4.1, MySQL5+.": 45 | answer = input('Do you want to know more detailed hash-mode?(y/n): ') 46 | if(answer == "y" or "Y" or "yes" or "YES"): 47 | get_type('sha1_series') 48 | if length_result == "Encryption method may be: SHA-256.": 49 | answer = input('Do you want to know more detailed hash-mode?(y/n): ') 50 | if(answer == "y" or "Y" or "yes" or "YES"): 51 | get_type('sha256_series') 52 | if length_result == "Encryption method may be: SHA-512.": 53 | answer = input('Do you want to know more detailed hash-mode?(y/n): ') 54 | if(answer == "y" or "Y" or "yes" or "YES"): 55 | get_type('sha512_series') 56 | 57 | 58 | def main(): 59 | banner.banner() 60 | # TODO(Snowming, kirioxiang1@gmail.com):这里加入异常处理。 61 | while True: 62 | _identify() 63 | 64 | if __name__ == '__main__': 65 | main() 66 | 67 | 68 | 69 | 70 | 71 | ''' 72 | def next(self): 73 | retVal = None 74 | while True: 75 | self.counter += 1 76 | try: 77 | retVal = next(self.iter).rstrip() 78 | except zipfile.error as ex: 79 | errMsg = "something appears to be wrong with " 80 | errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex)) 81 | errMsg += "sure that you haven't made any changes to it" 82 | raise SqlmapInstallationException(errMsg) 83 | except StopIteration: 84 | self.adjust() 85 | retVal = next(self.iter).rstrip() 86 | if not self.proc_count or self.counter % self.proc_count == self.proc_id: 87 | break 88 | return retVal 89 | ''' 90 | -------------------------------------------------------------------------------- /length_identification.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # __author__ = 'Snowming' 3 | 4 | from common_function import print_encryption 5 | 6 | # TODO(Snowming, kirioxiang1@gmail.com):或者后面单独把输入字符串处理这一段取出来。 7 | HEX_DICT = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','A', 8 | 'B','C','D','E','F'] 9 | 10 | def length_identify(user_input): 11 | cipher = user_input.strip() 12 | # 这一行好像没有用到? 13 | encryption_type = "Sorry cannot identify." 14 | one_word = 'Encryption method may be: %s.' 15 | 16 | # TODO(Snowming, kirioxiang1@gmail.com):字符集检验是不是可以单独拆出来? 17 | # TODO(Snowming, kirioxiang1@gmail.com):这一段后面用正则表达式改写。 18 | if len(cipher) in [16,32,40,56,64,96,128]: 19 | for i in cipher: 20 | if i not in HEX_DICT: 21 | # 这里加入异常 22 | # 其实如果恰好为32位包括F之后的字母的话也可能是base64 23 | encryption_type = "Sorry cannot identify." 24 | elif len(cipher) == 16: 25 | encryption_type = one_word % 'MySQL323' 26 | elif len(cipher) == 32: 27 | # encryption_type = "This is on kind of authentication method. Encryption method May be:MD5, LM hash, NTLMv1, NTLMv2." 28 | encryption_type = one_word % 'MD5' 29 | elif len(cipher) == 40: 30 | encryption_type = one_word % 'sha1, MySQL4.1, MySQL5+' 31 | elif len(cipher) == 56: 32 | encryption_type = one_word % 'SHA-224' 33 | elif len(cipher) == 64: 34 | encryption_type = one_word % 'SHA-256' 35 | elif len(cipher) == 96: 36 | encryption_type = one_word % 'SHA-384' 37 | elif len(cipher) == 128: 38 | encryption_type = one_word % 'SHA-512' 39 | # TODO(Snowming, kirioxiang1@gmail.com):下面的判断多次重复,可以设为一个方法。 40 | if(encryption_type != "Sorry cannot identify."): 41 | print_encryption(encryption_type) 42 | return encryption_type 43 | -------------------------------------------------------------------------------- /re_identification.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # __author__ = 'Snowming' 3 | 4 | import re 5 | from common_function import print_encryption 6 | 7 | 8 | # TODO(Snowming, kirioxiang1@gmail.com):在想这个要不要写成类,再在其中 def bcrypt(): 这样 9 | def re_identify(user_input): 10 | # $id$salt$hashed 11 | cipher = user_input.strip() 12 | encryption_type = "Sorry cannot identify." 13 | bcrypt_pattern = r'^\$2[abxy]\$(0[4-9]|1[0-8])\$[.\/A-Za-z0-9]{53}$' 14 | bcrypt_result = re.match(bcrypt_pattern, cipher) 15 | if (bcrypt_result != None): 16 | # TODO(Snowming, kirioxiang1@gmail.com): 这句过长。 17 | encryption_type = "Authentication method may be: Bcrypt. Bcrypt is one kind of Key derivation functions." 18 | # TODO(Snowming, kirioxiang1@gmail.com):下面的判断多次重复,可以设为一个方法。 19 | if(encryption_type != "Sorry cannot identify."): 20 | print_encryption(encryption_type) 21 | return encryption_type 22 | -------------------------------------------------------------------------------- /show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowming04/Cipher_Encryption_Type_Identification/d2b026ec4696328c9208ce51212f6f320cb70c21/show.png -------------------------------------------------------------------------------- /special.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # __author__ = 'Snowming' 3 | 4 | 5 | >>> b'ABC'.decode('ascii') 6 | 'ABC' 7 | >>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8') 8 | '中文' 9 | 10 | >>> b'\xe4\xb8\xad\xff'.decode('utf-8') 11 | Traceback (most recent call last): 12 | ... 13 | UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte 14 | 15 | >>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore') 16 | '中' 17 | 18 | https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431664106267f12e9bef7ee14cf6a8776a479bdec9b9000 19 | --------------------------------------------------------------------------------