├── 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 | 
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 |
--------------------------------------------------------------------------------