├── bin ├── __init__.py ├── attacks │ ├── __init__.py │ └── bruteforce │ │ ├── __init__.py │ │ └── bf_attack.py ├── verify_hashes │ ├── __init__.py │ └── verify.py └── generators │ └── __init__.py ├── lib ├── __init__.py ├── github │ ├── __init__.py │ ├── issue_template │ ├── template │ ├── auth │ │ └── oauth │ └── create_issue.py ├── algorithms │ ├── __init__.py │ └── custom │ │ ├── __init__.py │ │ └── _crc64.py ├── data_files │ └── wordlist_links └── settings.py ├── thirdparty ├── __init__.py ├── blake │ ├── __init__.py │ ├── blake_wrapper.py │ ├── blake_test.py │ └── blake.py ├── des │ ├── __init__.py │ └── pydes.py ├── md2 │ ├── __init__.py │ └── md2_hash.py └── tiger │ ├── __init__.py │ ├── README.textile │ ├── LICENSE │ ├── tiger.py │ ├── test_tiger.py │ └── sboxes.py ├── docs ├── _config.yml └── README.md ├── requirements.txt ├── .gitignore ├── legal ├── thirdparty_info.txt └── LICENSE.md ├── .github └── ISSUE_TEMPLATE.md ├── README.md ├── md5sum └── checksum.md5 └── dagon.py /bin/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/attacks/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/github/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /thirdparty/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/algorithms/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /thirdparty/blake/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /thirdparty/des/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /thirdparty/md2/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /thirdparty/tiger/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/verify_hashes/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/algorithms/custom/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/attacks/bruteforce/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-midnight -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pysha3==1.0.2 2 | requests 3 | colorlog==2.10.0 4 | passlib==1.7.1 5 | bcrypt==3.1.3 -------------------------------------------------------------------------------- /lib/github/issue_template: -------------------------------------------------------------------------------- 1 | Exception: 2 | `{}` 3 | Issue data: `{}` 4 | 5 | Running detail: 6 | OS: `{}` 7 | Hash used: `{}` 8 | CMD args: `{}` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .idea/* 3 | checksum.txt 4 | * ignore hash files 5 | hash_files/ 6 | # ignore bruteforce dicts 7 | bf-dicts/ 8 | # ignore downloads 9 | downloads/ -------------------------------------------------------------------------------- /lib/github/template: -------------------------------------------------------------------------------- 1 | Dagon has failed to crack given hash: `{}`. 2 | 3 | This was attempted on `{}`.. 4 | 5 | Commands that were used during failure: 6 | `{}` 7 | 8 | Algorithm attempted: `{}` -------------------------------------------------------------------------------- /legal/thirdparty_info.txt: -------------------------------------------------------------------------------- 1 | Tiger hashing - https://github.com/browning/tiger-hash-python 2 | Blake hashing - http://www.seanet.com/~bugbee/crypto/blake/ 3 | MD2 hashing - http://urchin.earth.li/~twic/md2.py 4 | DES hashing - http://twhiteman.netfirms.com/des.html -------------------------------------------------------------------------------- /thirdparty/tiger/README.textile: -------------------------------------------------------------------------------- 1 | h3. tiger-hash-python 2 | 3 | This is an implementation of the tiger hashing algorithm in pure python. 4 | The algorithm was created by Ross Anderson and Eli Biham. 5 | Thanks to David Bern (odie5533) for completing this python implementation! 6 | 7 | h3. Example Usage 8 | 9 | pre. >>> import tiger 10 | >>> tiger.hash("") 11 | '24F0130C63AC933216166E76B1BB925FF373DE2D49584E7A' 12 | 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Issue/idea: 2 | 3 | 4 | # Any idea what caused this to happen? 5 | 6 | 7 | # Application running specifics: 8 | - Installation method? 9 | 10 | 11 | - Operating system and architecture: 12 | 13 | 14 | - Dagon version information: 15 | 16 | 17 | - Hash you where attempting to crack: 18 | 21 | 22 | - Exact commands used: 23 | 25 | 26 | # Algorithm(s) used: 27 | 28 | 29 | # Exact error message: 30 | -------------------------------------------------------------------------------- /thirdparty/tiger/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Brian Browning, David Bern 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 4 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 5 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 6 | persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the 9 | Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 12 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 13 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 14 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | -------------------------------------------------------------------------------- /legal/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Thomas Perkins 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /bin/generators/__init__.py: -------------------------------------------------------------------------------- 1 | import string 2 | import itertools 3 | 4 | import bin 5 | 6 | 7 | class Generators(object): 8 | 9 | CHARS = string.ascii_letters 10 | 11 | def __init__(self, wordlist=None): 12 | self.words = wordlist 13 | 14 | def word_generator(self, length_min=5, length_max=8): 15 | """ 16 | Generate the words to be used for bruteforcing 17 | 18 | > :param length_min: minimum length for the word 19 | > :param length_max: max length for the word 20 | > :return: a word 21 | 22 | Example: 23 | >>> Generators().word_generator() 24 | aaaaa 25 | aaaab 26 | aaaac 27 | ... 28 | AAAaA 29 | AAAaB 30 | """ 31 | for n in range(length_min, length_max + 1): 32 | for xs in itertools.product(self.CHARS, repeat=n): 33 | yield ''.join(xs) 34 | 35 | def hash_file_generator(self): 36 | """ 37 | Parse a given file for anything that matches the hashes in the 38 | hash type regex dict. Possible that this will pull random bytes 39 | of data from the files. 40 | """ 41 | matched_hashes = set() 42 | keys = [k for k in bin.verify_hashes.verify.HASH_TYPE_REGEX.iterkeys()] 43 | with open(self.words) as wordlist: 44 | for item in wordlist.readlines(): 45 | for s in item.split(" "): 46 | for k in keys: 47 | if k.match(s): 48 | matched_hashes.add(s) 49 | return list(matched_hashes) 50 | -------------------------------------------------------------------------------- /lib/github/auth/oauth: -------------------------------------------------------------------------------- 1 | Vm0wd2VHUXhUWGRPVldScFVtMW9WRmx0ZEhkVU1WcDBUVlpPVjJKSGVEQlpNM0JIVmpGYWRHVkdXbFpOYm1oUVZtcEJlRll5VGtsaQpSbVJwVmtaYWVWWnRlRlpsUm1SWFVtNU9hUXBTYmtKUFZGUkNTMUpXWkZoa1IzUlVUVlZzTkZZeU5VZFdVWEJwVWpGS1VGZFhNSGhpCk1sWlhWMjVLWVZKR1NtRldiVEZUVjBacmQxWnNaRmRrTTBKd1ZUQldTMVZHV2xoTlZGSnJDazFXV2xoWGExcHJWMGRLVmxkdFJsZGkKV0dnelZqRmFWbVZYVWtoa1JtaFNWMFZLZDFaWE1ERlJNVlpIV2taa1lWSkZTbGxEYlVwWFYyNXdWMDFxVmtoV2EyUkxaRlpHZFZScwpXbWdLWVRCWk1GWkhkR0ZaVms1R1RsWmtZVkpzY0hKVVZFSkxaREZhV0UxVVVtdE5iRXA2VmpKMGExbFdTa2RUYkZaRVlYcEdWMVJzClZtOVdNREYxVlc1YVdsWkZXa3haZWtwUFVqRkdjd3BhUjJ0TFZqQmtibVZzV25GUmJVWmFWakZLUjFSc1dtdFdWMHBZWVVaa1YwMUcKV2t4V2JGcHJWMFV4VlZGc1VrNWlSVmt3Vm1wSk1WVXlTa2RUV0dSWVltdHdSVmxZY0VkbGJGbDVDazVZWkZkTlJFWlpXVlZvWVZZdwpNVWhWYTNoV1lsaE5lRlpxUm5kU2QzQnFVakowVEZaWE1ERlJNa2w0VjJ0a1dHSlZXbUZXYlhNeFUxWmFTR1JIZEZkV01IQlpXbFZhClQxWXdNVWNLVjJ0NFlWSkZXbWhhUlZWNFZsWldkR1JGTlZkaVNFSktWbTF3U2sxV1ZYbFNXR2hVWW14S1YxbHJaRk5TVm14WlkwVmsKYkdKR2JEVkRiVlpJVDFaa2FHVnJXWGhXYkdONFlqRlplUXBTYmtwcVVsaG9XRmxyV25kVVJuQkhWMnQwYW1RelFuRlZiVEZQVkVaYQpXR1ZIUm10TmEydzBWako0YjFSc1drZFRiVVpYWVd0YVRGVnFSbE5XTVdSMVZHeHdWMkV6UVhkWFZsWnJDbUl4V2xkWGExbExWVEowCk5GWXdNVmRqUjJoV1lXdGFjbHBGVlRWV01VNXlUbGRzVTJKclJYbFdiVEYzVXpBeFNGSllhR2xTYlZKV1dWUktiMVl4YkhKYVJGSlQKVm0xNGVsWnROV3NLVjBaS2MySkVWa1JpVmxwSlZERmFiMkZXV2xkWFZFWllWbXhhV0ZscVJscGxVWEJVWVRKU2NWVnFTbTlXTVd4WQpaRWRHVmxKdGR6SlZiWFF3WVcxUmVsRnRhRlpoYTNCeVZrVmFZUXBTTVdSMFQxWktUbFpVVmtsV01uUnZWREZzVjFOclpGUmlSMUpXClZtMHhVMVpHV1hoWGJVWlVVakZLU1ZReFpHOWhWa3BaVVd4a1dGWXpVbWhEYkZGNFYxaGtUbFpYVGt4V2Frb3dDazVHV1hoWGJHUnEKVWpKb1YxbFhkR0ZOTVZaelYyeGthazFXU25sVWJGcFBWVEpLU1ZGdFJsZGlWRVYzV1ZSQmVGSXlTa2RhUm1Sb1RXeEtXbGRYTVhwTgpWMDVYVm01U1RsWnJOVlFLVm0weE5GZHNhM2RXYlhOTFZsUktTMUl4WkhGUmExSnBWbXh3U1ZZeWRHRmhNVmwzVFZWc1VtRXllRmxXCmExWkxaR3hXTmxKdGRGTmtNMEpaV1cxek1WZFdXWGRhUms1WFlrZDRlZ3BXVjNSclZsWktjMVpxVGxoaE1WVXhWbFJHZG1Wc1JuTmEKUm5CcFVteHdXVlpyVm1GaGQzQnFUVmhDU2xkcldrdGhSMVp6VjJ4c1YxWXphSFpaZWtaclpFWmFkVlZ0ZUZOaE0wSlpDbFp0TUhoVQphekZIVlZob1YyRjZiSEJaYTFaTFZteFNWbFp1Y0ZSa01qZzVRMmM5UFFvPQo=10 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dagon - Advanced Hash Manipulation 2 | 3 | #### Named after the prince of Hell, Dagon *(day-gone)* is an advanced hash cracking and manipulation system, capable of bruteforcing multiple hash types, creating bruteforce dictionaries, automatic hashing algorithm verification, random salt generation from Unicode to ASCII, and much more. 4 | 5 | 6 | 7 | 8 | # Screenshots 9 | 10 | Bruteforcing made easy with a built in wordlist creator if you do not specify one. The wordlist will create 100,000 strings to use 11 | ![bruteforce](https://cloud.githubusercontent.com/assets/14183473/26070657/fc6ef54e-396a-11e7-8479-5410ea2d170d.PNG) 12 | 13 | Verify what algorithm was used to create that hash you're trying to crack. You can specify to view all possible algorithms by providing the -L flag (some algorithms are not implemented yet) 14 | ![hash_verification](https://cloud.githubusercontent.com/assets/14183473/26070690/1cd632a2-396b-11e7-89cc-20182d347848.PNG) 15 | 16 | Random salting, unicode random salting, or you can make your own choice on the salt. 17 | ![salting](https://cloud.githubusercontent.com/assets/14183473/26070692/1eb062f0-396b-11e7-91bb-4238bd241bef.PNG) 18 | 19 | # Demo video 20 | 21 | [![demo](https://cloud.githubusercontent.com/assets/14183473/26458859/27a9b61e-413a-11e7-8bd4-0583eae12ddd.PNG)](https://vimeo.com/218966256) 22 | 23 | # Download 24 | 25 | Preferable you can close the repository with `git clone https://github.com/ekultek/dagon.git` alternatively you can download the zip or tarball [here](https://github.com/ekultek/dagon/releases) 26 | 27 | # Basic usage 28 | 29 | For full functionality of Dagon please reference the homepage [here](https://ekultek.github.io/Dagon/) or the [user manual](https://github.com/Ekultek/Dagon/wiki) 30 | 31 | `python dagon.py -h` This will run the help menu and provide a list of all possible flags 32 | 33 | `python dagon.py -c --bruteforce` This will attempt to bruteforce a given hash 34 | 35 | `python dagon.py -l --bruteforce` This will attempt to bruteforce a given file full of hashes (one per line) 36 | 37 | `python dagon.py -v ` This will try to verify the algorithm used to create the hash 38 | 39 | `python dagon.py -V ` This will attempt to verify each hash in a file, one per line 40 | 41 | # Installation 42 | 43 | Dagon requires python version `2.7.x` to run successfully. 44 | 45 | - `git clone https://github.com/ekultek/dagon.git` 46 | - `cd Dagon` 47 | - `pip install -r requirements.txt` 48 | 49 | This should install all the dependencies that you will need to run Dagon 50 | 51 | # Contributions 52 | 53 | All contributions are greatly appreciated and helpful. When you contribute you will get your name placed on the homepage underneath contributions with a link to your contribution. You will also get massive respect from me, and that's a pretty cool thing. What I'm looking for in contributions is some of the following: 54 | 55 | - Hashing algorithm creations, specifically; A quicker MD2 algorithm, full Tiger algorithms, Keychain algorithms for cloud and agile 56 | - More wordlists to download from, please make sure that the link is encoded 57 | - Rainbow table attack implementation 58 | - More regular expressions to verify different hash types 59 | -------------------------------------------------------------------------------- /thirdparty/tiger/tiger.py: -------------------------------------------------------------------------------- 1 | import array 2 | import struct 3 | from sboxes import t1, t2, t3, t4 4 | 5 | def tiger_round(a,b,c,x,mul): 6 | c ^= x 7 | c &= 0xffffffffffffffff 8 | a -= t1[((c) >> (0*8))&0xFF] ^ t2[((c) >> ( 2*8)) & 0xFF] ^ t3[((c) >> (4*8))&0xFF] ^ t4[((c) >> ( 6*8)) & 0xFF] 9 | b += t4[((c) >> (1*8))&0xFF] ^ t3[((c) >> ( 3*8)) & 0xFF] ^ t2[((c) >> (5*8))&0xFF] ^ t1[((c) >> ( 7*8)) & 0xFF] 10 | b *= mul 11 | a &= 0xffffffffffffffff 12 | b &= 0xffffffffffffffff 13 | c &= 0xffffffffffffffff 14 | return {"a": a, "b":b, "c": c} 15 | 16 | def tiger_pass(a,b,c,mul, mystr): 17 | values = tiger_round(a,b,c, mystr[0], mul) 18 | values = tiger_round(values["b"], values["c"], values["a"],mystr[1],mul) 19 | values = { "b": values["a"], "c": values["b"], "a": values["c"] } 20 | values = tiger_round(values["c"], values["a"], values["b"], mystr[2], mul) 21 | values = { "c": values["a"], "a": values["b"], "b": values["c"] } 22 | values = tiger_round(values["a"], values["b"], values["c"],mystr[3],mul) 23 | values = tiger_round(values["b"], values["c"], values["a"],mystr[4],mul) 24 | values = { "b": values["a"], "c": values["b"], "a": values["c"] } 25 | values = tiger_round(values["c"], values["a"], values["b"],mystr[5],mul) 26 | values = { "c": values["a"], "a":values["b"], "b": values["c"] } 27 | values = tiger_round(values["a"], values["b"], values["c"],mystr[6],mul) 28 | values = tiger_round(values["b"], values["c"], values["a"],mystr[7],mul) 29 | values = { "b": values["a"], "c":values["b"], "a": values["c"]} 30 | return values 31 | 32 | def tiger_compress(str, res): 33 | #setup 34 | a = res[0] 35 | b = res[1] 36 | c = res[2] 37 | 38 | x = [] 39 | 40 | for j in range(0,8): 41 | x.append(struct.unpack('Q', str[j*8:j*8+8])[0]) 42 | 43 | # compress 44 | aa = a 45 | bb = b 46 | cc = c 47 | allf = 0xFFFFFFFFFFFFFFFF 48 | for i in range(0, 3): 49 | if i != 0: 50 | x[0] = (x[0] - (x[7] ^ 0xA5A5A5A5A5A5A5A5)&allf ) & allf 51 | x[1] ^= x[0] 52 | x[2] = (x[2] + x[1]) & allf 53 | x[3] = (x[3] - (x[2] ^ (~x[1]&allf) << 19)&allf) & allf 54 | x[4] ^= x[3] 55 | x[5] = (x[5] + x[4]) & allf 56 | x[6] = (x[6] - (x[5] ^ (~x[4]&allf) >> 23)&allf) & allf 57 | x[7] ^= x[6] 58 | x[0] = (x[0] + x[7]) & allf 59 | x[1] = (x[1] - (x[0] ^ (~x[7]&allf) << 19)&allf) & allf 60 | x[2] ^= x[1] 61 | x[3] = (x[3] + x[2]) & allf 62 | x[4] = (x[4] - (x[3] ^ (~x[2]&allf) >> 23)&allf) & allf 63 | x[5] ^= x[4] 64 | x[6] = (x[6] + x[5]) & allf 65 | x[7] = (x[7] - (x[6] ^ 0x0123456789ABCDEF)&allf ) & allf 66 | 67 | if i == 0: 68 | vals = tiger_pass(a,b,c,5, x) 69 | a = vals['a'] 70 | b = vals['b'] 71 | c = vals['c'] 72 | elif i == 1: 73 | vals = tiger_pass(a,b,c,7, x) 74 | a = vals['a'] 75 | b = vals['b'] 76 | c = vals['c'] 77 | else: 78 | vals = tiger_pass(a,b,c,9, x) 79 | a = vals['a'] 80 | b = vals['b'] 81 | c = vals['c'] 82 | tmpa = a 83 | a = c 84 | c = b 85 | b = tmpa 86 | a ^= aa 87 | b = (b - bb) & allf 88 | c = (c + cc) & allf 89 | 90 | # map values out 91 | res[0] = a 92 | res[1] = b 93 | res[2] = c 94 | 95 | def hash(str): 96 | i = 0 97 | 98 | res = [0x0123456789ABCDEF, 0xFEDCBA9876543210, 0xF096A5B4C3B2E187] 99 | offset = 0 100 | length = len(str) 101 | while i < length-63: 102 | tiger_compress( str[i:i+64], res ) 103 | i += 64 104 | temp = array.array('c', str[i:]) 105 | j = len(temp) 106 | temp.append(chr(0x01)) 107 | j += 1 108 | 109 | while j&7 != 0: 110 | temp.append(chr(0)) 111 | j += 1 112 | 113 | if j > 56: 114 | while j < 64: 115 | temp.append(chr(0)) 116 | j += 1 117 | tiger_compress(temp, res) 118 | j = 0 119 | 120 | # make the first 56 bytes 0 121 | temp.extend([chr(0) for i in range(0, 56-j)]) 122 | while j < 56: 123 | temp[j] = chr(0) 124 | j += 1 125 | while len(temp) > 56: 126 | temp.pop(56) 127 | 128 | temp.fromstring(struct.pack('Q', length<<3)) 129 | tiger_compress(temp, res) 130 | 131 | return "%016X%016X%016X" % (res[0], res[1], res[2]) 132 | -------------------------------------------------------------------------------- /lib/github/create_issue.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import json 4 | import urllib 5 | import datetime 6 | import urllib2 7 | import string 8 | import random 9 | import platform 10 | 11 | import lib 12 | 13 | 14 | def __handle(encoded): 15 | data_specs = [ 16 | (0, 10), (10, 30), (30, 40), (40, 60), (60, -1) 17 | ] 18 | 19 | def __find_n(token, retval="1"): 20 | return retval + token[-1] 21 | 22 | def __decode(string, n): 23 | for _ in range(int(n) + 1): 24 | string = string.decode("base64") 25 | return string 26 | 27 | n = __find_n(encoded) 28 | decoded = __decode(encoded, n) 29 | data_list = [ 30 | decoded[data_specs[0][0]:data_specs[0][1]], 31 | decoded[data_specs[1][0]:data_specs[1][1]], 32 | decoded[data_specs[2][0]:data_specs[2][1]], 33 | decoded[data_specs[3][0]:data_specs[3][1]], 34 | decoded[data_specs[4][0]:data_specs[4][1]] 35 | ] 36 | token = data_list[1] + data_list[3] 37 | return token 38 | 39 | 40 | def __get_encoded_string(path="{}/lib/github/auth/oauth"): 41 | with open(path.format(os.getcwd())) as data: 42 | return data.read().strip() 43 | 44 | 45 | def __find_algorithm_used(cmd_line=sys.argv, alg_cmd="-A"): 46 | if alg_cmd in cmd_line: 47 | for i, item in enumerate(cmd_line): 48 | if item == alg_cmd: 49 | return lib.settings.IDENTIFICATION[int(cmd_line[i + 1])].upper() 50 | else: 51 | return None 52 | 53 | 54 | def request_connection(hashed_string, date_created=datetime.datetime.today()): 55 | 56 | lib.settings.LOGGER.warning("automatic issue creation has been turned off for the time being.") 57 | '''def __create_title(s): 58 | return s[:9] 59 | 60 | issue_title = "Hash guarantee ({})".format(__create_title(hashed_string)) 61 | 62 | issue_data = { 63 | "title": issue_title, 64 | "body": open("{}/lib/github/template".format(os.getcwd())).read().format( 65 | hashed_string, date_created, sys.argv, __find_algorithm_used() 66 | ), 67 | "labels": ["hash guarantee", "algorithm issue"] 68 | } 69 | 70 | req = urllib2.Request( 71 | url="https://api.github.com/repos/ekultek/Dagon/issues", data=json.dumps(issue_data), 72 | headers={"Authorization": "token {}".format(__handle(__get_encoded_string()))}) 73 | 74 | urllib2.urlopen(req).read() 75 | lib.settings.LOGGER.info( 76 | "Your issue has been created with the title '{}'. If you so wish " 77 | "you can provide more information about where you got this hash, by " 78 | "sending an email to: {}.\nDoing so will help with the cracking " 79 | "of your hash, and can make the cracking aspect go by faster.\n" 80 | "Information that will need to be provided will be basic, just " 81 | "where you got the hash (database, application, etc), and the " 82 | "type of database, application, etc, that it was gained from.\n" 83 | "If you choose not to provide the information, please allow up-to " 84 | "7 days for an attempt at cracking your hash, along with the patch " 85 | "for your hash to be pushed through.".format( 86 | issue_title, lib.settings.DAGON_EMAIL 87 | ) 88 | )''' 89 | 90 | 91 | def dagon_failure(issue, hashed_string, error): 92 | lib.settings.LOGGER.warning("automatic issue creation has been turned off for the time being.") 93 | '''def __create_issue_ext(): 94 | retval = [] 95 | for _ in range(5): 96 | retval.append(random.choice(string.ascii_letters)) 97 | return ''.join(retval) 98 | 99 | issue_title = "Unhandled Exception {}({})".format(issue, __create_issue_ext()) 100 | issue_data = { 101 | "title": issue_title, 102 | "body": open("{}/lib/github/issue_template".format(os.getcwd())).read().format( 103 | type(error).__name__, (error.args, error.message), platform.platform(), 104 | hashed_string, sys.argv 105 | ) 106 | } 107 | encoded_issue_data = urllib.urlencode(issue_data) 108 | req = urllib2.Request( 109 | url="https://api.github.com/repos/ekultek/Dagon/issues", data=json.dumps(json.dumps(encoded_issue_data)), 110 | headers={"Authorization": "token {}".format(__handle(__get_encoded_string()))}) 111 | 112 | urllib2.urlopen(req).read() 113 | lib.settings.LOGGER.info( 114 | "Your issue has been created with the title '{}'.".format( 115 | issue_title 116 | ) 117 | )''' 118 | -------------------------------------------------------------------------------- /md5sum/checksum.md5: -------------------------------------------------------------------------------- 1 | d41d8cd98f00b204e9800998ecf8427e ./checksum.txt 2 | c120fe499f4d534e6290e5fd3e0b0946 ./README.md 3 | 5c2118501321299e1c36537a33ac76a9 ./requirements.txt 4 | 9c46102f688549819085a7c8f3ca34f4 ./md5sum/checksum.md5 5 | d41d8cd98f00b204e9800998ecf8427e ./bin/__init__.py 6 | d41d8cd98f00b204e9800998ecf8427e ./bin/verify_hashes/__init__.py 7 | ec95deeb6c3a531276926f068aa8ccc2 ./bin/verify_hashes/verify.py 8 | d41d8cd98f00b204e9800998ecf8427e ./bin/attacks/__init__.py 9 | d41d8cd98f00b204e9800998ecf8427e ./bin/attacks/bruteforce/__init__.py 10 | 84a2fee20780c2ae0823e705fe303923 ./bin/attacks/bruteforce/bf_attack.py 11 | 2c10265111b84f4d8266651562c20ea7 ./bin/generators/__init__.py 12 | d41d8cd98f00b204e9800998ecf8427e ./lib/algorithms/__init__.py 13 | d41d8cd98f00b204e9800998ecf8427e ./lib/algorithms/custom/__init__.py 14 | 8b94aaadf0174a1b20f533343dd8be59 ./lib/algorithms/custom/_crc64.py 15 | c7f4e9924337c96a1489f6d088a0e014 ./lib/algorithms/hashing_algs.py 16 | d41d8cd98f00b204e9800998ecf8427e ./lib/__init__.py 17 | 93b89e91fe6b04b8383cfcbd92852214 ./lib/settings.py 18 | fc2b557071264104a4635f29a6bc3316 ./lib/data_files/wordlist_links 19 | d41d8cd98f00b204e9800998ecf8427e ./lib/github/__init__.py 20 | 2ce608724e4e2a06333bb1b4912e341d ./lib/github/issue_template 21 | c34819db47b9733324384f6a9d468e4c ./lib/github/template 22 | eef4e2b523dbbe2b13a99222aa3dca8b ./lib/github/create_issue.py 23 | bd55e842beb7306fa14f6a08ef4d10c1 ./lib/github/auth/oauth 24 | 192d7018c1ea6003f56dac720f5b7882 ./.idea/misc.xml 25 | 166acef3d301bd241d0d6da15bc5ad3c ./.idea/vcs.xml 26 | 5d07a57a76d32c94866fb8f6b4382b86 ./.idea/workspace.xml 27 | a3d11079520b18e3f6780291d1152696 ./.idea/dagon.iml 28 | 917d7377a1d655c67504cb92818b05ee ./.idea/modules.xml 29 | e7a5341d4a055f5a4b9f76aae301cc57 ./.github/ISSUE_TEMPLATE.md 30 | 57f45675567ff8b527b9bc1f15c46973 ./docs/README.md 31 | 2d2776841d6164413357f7f227b722a7 ./docs/_config.yml 32 | 39e387b0e340c4404be10fcdcd534772 ./thirdparty/blake/blake_test.py 33 | d41d8cd98f00b204e9800998ecf8427e ./thirdparty/blake/__init__.py 34 | 19bb74d4d4e62749564e4b98db1e8068 ./thirdparty/blake/blake_wrapper.py 35 | 62cd797fafacc7bf657b2f95df21abb7 ./thirdparty/blake/blake.py 36 | d41d8cd98f00b204e9800998ecf8427e ./thirdparty/__init__.py 37 | 5b12b4942fb7669a032a5201cf720a95 ./thirdparty/md2/md2_hash.py 38 | d41d8cd98f00b204e9800998ecf8427e ./thirdparty/md2/__init__.py 39 | e940d4065d04d78004385cb8bde1e77c ./thirdparty/des/pydes.py 40 | d41d8cd98f00b204e9800998ecf8427e ./thirdparty/des/__init__.py 41 | d41d8cd98f00b204e9800998ecf8427e ./thirdparty/tiger/__init__.py 42 | 67a62cf48bb0412daaa00f4a6e4fa620 ./thirdparty/tiger/README.textile 43 | 1ae74957f5bd17f61d5bef0cdb36ae27 ./thirdparty/tiger/LICENSE 44 | 0fce37bd61cfbb36ee0b3cb4b2e1f701 ./thirdparty/tiger/test_tiger.py 45 | d95c3420002f6de555eedff8b81e3489 ./thirdparty/tiger/tiger.py 46 | ed62155328c906f0498815e2bb48d04a ./thirdparty/tiger/sboxes.py 47 | 82b60101f4bc313bc5cd777386daf2c7 ./dagon.py 48 | 2ad18ec82c20af7b5926ed9cea6aeedd ./.git/hooks/pre-receive.sample 49 | 7dfe15854212a30f346da5255c1d794b ./.git/hooks/prepare-commit-msg.sample 50 | 579a3c1e12a1e74a98169175fb913012 ./.git/hooks/commit-msg.sample 51 | 01b1688f97f94776baae85d77b06048b ./.git/hooks/pre-commit.sample 52 | 3c5989301dd4b949dfa1f43738a22819 ./.git/hooks/pre-push.sample 53 | 2b7ea5cee3c49ff53d41e00785eb974c ./.git/hooks/post-update.sample 54 | 054f9ffb8bfe04a599751cc757226dda ./.git/hooks/pre-applypatch.sample 55 | 3ff6ba9cf6d8e5332978e057559b5562 ./.git/hooks/pre-rebase.sample 56 | ce562e08d8098926a3862fc6e7905199 ./.git/hooks/applypatch-msg.sample 57 | 517f14b9239689dff8bda3022ebd9004 ./.git/hooks/update.sample 58 | a0a7c3fff21f2aea3cfa1d0316dd816c ./.git/description 59 | f388339de366adf28026591b24ad29f6 ./.git/index 60 | 4cf2d64e44205fe628ddd534e1151b58 ./.git/HEAD 61 | 0118f40cb11283c5efd064d82ed348bd ./.git/packed-refs 62 | e1cfbf2bc3793b4ca4bf4939653fd945 ./.git/FETCH_HEAD 63 | b7e2d84bcd0648bb1b231787eb5554df ./.git/config 64 | 036208b4a1ab4a235d75c181e685e5a3 ./.git/info/exclude 65 | 9db688c0dbfc03b3cd40a9ac7f9c938e ./.git/logs/HEAD 66 | 9db688c0dbfc03b3cd40a9ac7f9c938e ./.git/logs/refs/heads/master 67 | 9db688c0dbfc03b3cd40a9ac7f9c938e ./.git/logs/refs/remotes/origin/HEAD 68 | 992dad47d0c3b8bff161c1706bdf6136 ./.git/refs/heads/master 69 | 73a00957034783b7b5c8294c54cd3e12 ./.git/refs/remotes/origin/HEAD 70 | 1b20608aa91973cb2aab98e47442d2d2 ./.git/objects/pack/pack-229c385788cb0bab3b89c407df52cf657c8ea08c.idx 71 | a76724d79452c3b15c2faec1798ea35d ./.git/objects/pack/pack-229c385788cb0bab3b89c407df52cf657c8ea08c.pack 72 | 992dad47d0c3b8bff161c1706bdf6136 ./.git/ORIG_HEAD 73 | 5b7537fe8628e5c1d260217c46fb5150 ./legal/thirdparty_info.txt 74 | 035b4e652110fb12d636a807e8f1c68c ./legal/LICENSE.md 75 | 878b7e297202a7f83cf5c7db781dee30 ./.gitignore 76 | -------------------------------------------------------------------------------- /bin/verify_hashes/verify.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import re 4 | 5 | from lib.settings import ( 6 | DAGON_ISSUE_LINK, 7 | LOGGER, 8 | shutdown, 9 | hash_guarantee 10 | ) 11 | 12 | 13 | # Has to be the first function so I can use it in the regex 14 | def build_re(hex_len, prefix=r"", suffix=r"(:.+)?"): 15 | regex_string = r"^{}[a-f0-9]{{{}}}{}$".format(prefix, hex_len, suffix) 16 | return re.compile(regex_string, re.IGNORECASE) 17 | 18 | 19 | # Top: Most likely algorithm 20 | # Bottom: Least likely algorithm (may not be implemented) 21 | HASH_TYPE_REGEX = { 22 | build_re(8, prefix="(0x)?", suffix="(L)?"): [ 23 | ("crc32", None), (None, None) 24 | ], 25 | build_re(20): [ 26 | ("half sha1", None), (None, None) 27 | ], 28 | build_re(32, prefix="(md5)?"): [ 29 | ("md5", "md4", "md2", "ntlm", "postgresql", 30 | "md5(md5(pass)+md5(salt))", "md5(md5(pass))", "md5(salt+pass+salt)", 31 | "md5(md5(md5(pass)))"), 32 | ("ripe128", "haval128", "tiger128", 33 | "skein256(128)", "skein512(128)", "skype", 34 | "zipmonster", "prestashop") 35 | ], 36 | build_re(16, prefix="(0x)?", suffix="(L)?"): [ 37 | ("half md5", "oracle 10g", "crc64"), (None, None) 38 | ], 39 | build_re(64): [ 40 | ("sha256", "sha3_256"), 41 | ("haval256", "gost r 34.1194", 42 | "gost cryptopro sbox", "skein256", "skein512(256)", 43 | "ventrilo", "ripemd256") 44 | ], 45 | build_re(128): [ 46 | ("sha512", "whirlpool", "sha3_512"), 47 | ("salsa10", "salsa20", "skein512", 48 | "skein1024(512)") 49 | ], 50 | build_re(54, prefix="0x0100", suffix=""): [ 51 | ("mssql 2005", None), 52 | (None, None) 53 | ], 54 | build_re(56, suffix=""): [ 55 | ("sha224", "sha3_224"), 56 | ("skein256(224)", "skein512(224)", "haval224") 57 | ], 58 | build_re(40): [ 59 | ("sha1", "ripemd160", "sha1(rounds(pass))"), 60 | ("haval160", "tiger160", "has160", 61 | "skein256(160)", "skein512(160)", "dsa") 62 | ], 63 | build_re(96, suffix="", prefix="(0x0100)?"): [ 64 | ("sha384", "sha3_384", "mssql 2000"), ("skein512(384)", "skein1024(384") 65 | ], 66 | build_re(40, prefix=r"\*", suffix=""): [ 67 | ("mysql", None), (None, None) 68 | ], 69 | build_re(48, suffix=""): [ 70 | ("tiger192", None), 71 | ("haval192", "sha1(oracle)", "xsha v10.4-v10.6") 72 | ], 73 | re.compile("\A\$1\$.{1,8}\$[./a-zA-Z0-9]+\Z", re.IGNORECASE): [ 74 | ("md5 crypt", None), (None, None) 75 | ], 76 | #re.compile(r"^\$\w+\$\w+(\$)?\w+(.)?$", re.IGNORECASE): [ 77 | # ("wordpress", None), ("Joomla", None) 78 | #], 79 | re.compile(r"^\$\d\w\$\d+\$\S{53}$", re.IGNORECASE): [ 80 | ("blowfish", None), (None, None) 81 | ], 82 | re.compile(r"^S:[a-zA-Z0-9]{60}$", re.IGNORECASE): [ 83 | ("oracle 11g", None), (None, None) 84 | ], 85 | re.compile(r"^[0-9a-z]{4,12}:[0-9a-f]{16,20}:[0-9a-z]{2080}$", re.IGNORECASE): [ 86 | ("agile", None), (None, None) 87 | ], 88 | re.compile(r"^[0-9a-f]{64,70}:[a-f0-9]{32,40}:\d+:[a-f0-9]{608,620}$", re.IGNORECASE): [ 89 | ("cloud", None), (None, None) 90 | ], 91 | re.compile(r"^\{SSHA\S+$", re.IGNORECASE): [ 92 | ("ssha", None), (None, None) 93 | ], 94 | re.compile(r"^\w+:\d+:[a-z0-9]{32}:[a-z0-9]{32}:::$", re.IGNORECASE): [ 95 | ("windows local (ntlm)", None), (None, None) 96 | ] 97 | } 98 | 99 | 100 | def verify_hash_type(hash_to_verify, least_likely=False, verbose=False): 101 | """ 102 | Attempt to verify a given hash by type (md5, sha1, etc..) 103 | 104 | > :param hash_to_verify: hash string 105 | > :param least_likely: show least likely options as well 106 | > :return: likely options, least likely options, or none 107 | 108 | Example: 109 | >>> verify_hash_type("098f6bcd4621d373cade4e832627b4f6", least_likely=True) 110 | [('md5', 'md4', 'md2'), ('double md5', 'lm', ... )] 111 | """ 112 | for regex, hash_types in HASH_TYPE_REGEX.items(): # iter is not available in Python 3.x 113 | if verbose: 114 | LOGGER.debug("Testing: {}".format(hash_types)) 115 | if regex.match(hash_to_verify): 116 | return hash_types if least_likely else hash_types[0] 117 | error_msg = ( 118 | "Unable to find any algorithms to match the given hash. If you " 119 | "feel this algorithm should be implemented make an issue here: {}") 120 | LOGGER.fatal(error_msg.format(DAGON_ISSUE_LINK)) 121 | # hash_guarantee(hash_to_verify) 122 | LOGGER.warning("`hash_guarantee` has been turned off for the time being") 123 | shutdown(1) 124 | -------------------------------------------------------------------------------- /thirdparty/tiger/test_tiger.py: -------------------------------------------------------------------------------- 1 | # These tests can be run using nosetests 2 | 3 | import tiger 4 | 5 | def round_helper(a, b, c, x, mul, new_a,new_b,new_c): 6 | ret_values = tiger.tiger_round(a, b, c, x, mul) 7 | 8 | assert ret_values["a"] == new_a, \ 9 | "a failed: " + str(ret_values["a"]) + " != " + str(new_a) + "\n" 10 | assert ret_values["c"] == new_c, \ 11 | "c failed: " + str(ret_values["c"]) + " != " + str(new_c) + "\n" 12 | assert ret_values["b"] == new_b, \ 13 | "b failed: " + str(ret_values["b"]) + " != " + str(new_b) + "\n" 14 | 15 | def test_tiger_round(): 16 | round_helper(13065445776871430898,17855811585246249540,518233413090174763, \ 17 | 12311797252403697916,7, \ 18 | 4821272432160810520,17424479681440429243,12532788606137106391) 19 | 20 | def test_tiger_round2(): 21 | round_helper(6280199717849618378, 8343645101657805456, 5997044206234503415,\ 22 | 12062177936022666431, 9, \ 23 | 11604645957211426640, 3986339792283275959, 17608143266212181064) 24 | 25 | def test_tiger_round3(): 26 | round_helper(11604645957211426640,3986339792283275959,17608143266212181064,\ 27 | 11490956213547313652, 9, \ 28 | 6441804261801137295,13333871996800360137,7720474646982516156) 29 | 30 | 31 | """ 32 | Results from reference: 33 | A: 6280199717849618378 34 | B: 8343645101657805456 35 | C: 5997044206234503415 36 | mul: 9 37 | x0: 12062177936022666431 38 | x1: 11490956213547313652 39 | x2: 16829172008830410301 40 | x3: 11899344311637024046 41 | x4: 3757253942274655973 42 | x5: 17835857420906997132 43 | x6: 10787740079658512390 44 | x7: 17590610739856314589 45 | new A: 1509595445172618351 46 | new B: 206383248218352883 47 | new C: 2725617220977123037 48 | 49 | """ 50 | def test_tiger_pass(): 51 | a = 6280199717849618378 52 | b = 8343645101657805456 53 | c = 5997044206234503415 54 | mul = 9 55 | data = [12062177936022666431, 11490956213547313652, 16829172008830410301, \ 56 | 11899344311637024046, 3757253942274655973, 17835857420906997132, \ 57 | 10787740079658512390, 17590610739856314589] 58 | 59 | ret_values = tiger.tiger_pass(a, b, c, mul, data) 60 | 61 | assert ret_values["a"] == 1509595445172618351, \ 62 | "a failed, " + str(ret_values["a"]) + " != 1509595445172618351" 63 | assert ret_values["b"] == 206383248218352883, \ 64 | "b failed, " + str(ret_values["b"]) + " != 206383248218352883" 65 | assert ret_values["c"] == 2725617220977123037, \ 66 | "c failed, " + str(ret_values["c"]) + " != 2725617220977123037" 67 | 68 | 69 | def test_tiger_compress(): 70 | # input data for tiger_compress must be 64 bytes long 71 | x = "TigerTigerTigerTigerTigerTigerTigerTigerTigerTigerTigerTigerTige" 72 | res = [ 81985529216486895, 18364758544493064720, 17336226011405279623] 73 | 74 | tiger.tiger_compress(x, res) 75 | assert res[0] == 0x29CCDEE812891C0F, \ 76 | "r1 failed, %X != 0x29CCDEE812891C0F" % res[0] 77 | assert res[1] == 0xA18BA64634ACD11A, \ 78 | "r2 failed, %X != 0xA18BA64634ACD11A" % res[1] 79 | assert res[2] == 0x5FA4D4854FCE7BCA, \ 80 | "r3 failed, %X != 0x5FA4D4854FCE7BCA" % res[2] 81 | 82 | # The following are the test hashes provided by the example C implementation 83 | def test_tiger_hash(): 84 | assert tiger.hash('') == '24F0130C63AC933216166E76B1BB925FF373DE2D49584E7A' 85 | assert tiger.hash('abc') == \ 86 | 'F258C1E88414AB2A527AB541FFC5B8BF935F7B951C132951' 87 | assert tiger.hash('Tiger') == \ 88 | '9F00F599072300DD276ABB38C8EB6DEC37790C116F9D2BDF' 89 | assert tiger.hash("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01" \ 90 | "23456789+-") == '87FB2A9083851CF7470D2CF810E6DF9EB586445034A5A386' 91 | assert tiger.hash("ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+" \ 92 | "0123456789") == '467DB80863EBCE488DF1CD1261655DE957896565975F9197' 93 | assert tiger.hash("Tiger - A Fast New Hash Function, by Ross Anderson and" \ 94 | " Eli Biham") == '0C410A042968868A1671DA5A3FD29A725EC1E457D3CDB303' 95 | assert tiger.hash("Tiger - A Fast New Hash Function, by Ross Anderson and" \ 96 | " Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.") == \ 97 | 'EBF591D5AFA655CE7F22894FF87F54AC89C811B6B0DA3193' 98 | assert tiger.hash("Tiger - A Fast New Hash Function, by Ross Anderson and" \ 99 | " Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 19" \ 100 | "96.") == '3D9AEB03D1BD1A6357B2774DFD6D5B24DD68151D503974FC' 101 | assert tiger.hash("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01" \ 102 | "23456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345" \ 103 | "6789+-") == '00B83EB4E53440C576AC6AAEE0A7485825FD15E70A59FFE4' 104 | 105 | 106 | -------------------------------------------------------------------------------- /lib/data_files/wordlist_links: -------------------------------------------------------------------------------- 1 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrL2FhODgyMDk5ZWQxYzNlZjAwNWYzYWY2ZjhmYmFhZTExL3Jhdy84ODQ4NjBhNjAzZWQ0MjE3MTgyN2E1MmE3M2VjNzAzMjNhOGExZWY5L2dpc3RmaWxlMS50eHQ= 2 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrLzAwNWU3OWQ2NmU2MzA2YWI0MzZjOGJmYTc1ZTRiODMwL3Jhdy8xNjY5YjNjMDFmMjRhM2Q2OTMwZDNmNDE1Mjk3ZTg5OGQ1YjY2NGUzL29wZW53YWxsXzMudHh0 3 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrLzE4NTBmM2EwZGNjNDE0YWZlOGM3NjYyMjBlOTYxYjE4L3Jhdy9iYWQ0NTA0NjcwY2FmM2UxNDY1NWI2ZjJlZGQ0MjJmOTJjMzI2MWI5L215c3BhY2UudHh0 4 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrLzBkYWU2YTI5MjgzMjcyNmE2Y2MyN2VlNmVjOTdmMTFjL3Jhdy84MWFkOWFkOWUwZjQxMmY2YjIwMTM3MDI2NDcxZGRmNDJlN2JjMjkyL2pvaG4udHh0 5 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrL2Q4ZjZiYjE2MGEzYzY2YzgyNWEwYWY0NDdhMDM1MDVhL3Jhdy83MWI4NmM5MGU3NDRkZjM0YzY3ODFjM2U0MmFjMThkOGM4ZjdkYjNlL2NhaW4udHh0 6 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrL2JmM2MwYjQwMTVlYzlkMzY4YzBlNTczNzQ0MTAzYmU1L3Jhdy9lNzBhMThmOTUwNGYwZmMyYjRhMWRmN2M0Mjg2YjcyOWUyMzQ5ODljL29wZW53YWxsXzIudHh0 7 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrLzQ1ZTExZDBhMzNjZGE1YjM3NDM5OGYyMDgxYjEwZWZiL3Jhdy8wNzQ1ZGMzNjFlZDU5NjJiMjNkYjUxM2FkOWQyOTNlODk0YjI0YTY0L2RjLnR4dA== 8 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrLzNmMzcxMWUzMDdlOGM0ZTM0MDkzYzI1OGFkN2UzZWZkL3Jhdy9hMjNiYmM3YTgxNTZhOGU5NTU3NmViYTA3MmIwZDg4ZTJmYjk1MzZiL2dtYWlsXzIudHh0 9 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrL2U3MzE4MGM3MGZmMzY3NDFhM2M4NzIzMDZiNTFhOTU1L3Jhdy9jODE0YjFjOTZiNGJkYzZlYTRlZDE3MmMzNDIwOTg2NTBjOTcyYWZjL2J0NC50eHQ= 10 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2JlcnplcmswL1Byb2JhYmxlLVdvcmRsaXN0cy9tYXN0ZXIvRGljdGlvbmFyeS1TdHlsZS9NYWluRW5nbGlzaERpY3Rpb25hcnkudHh0 11 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RhbmllbG1pZXNzbGVyL1NlY0xpc3RzL21hc3Rlci9QYXNzd29yZHMvdHdpdHRlci1iYW5uZWQudHh0 12 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RhbmllbG1pZXNzbGVyL1NlY0xpc3RzL21hc3Rlci9QYXNzd29yZHMvdHVzY2wudHh0 13 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RhbmllbG1pZXNzbGVyL1NlY0xpc3RzL21hc3Rlci9QYXNzd29yZHMvMTBfbWlsbGlvbl9wYXNzd29yZF9saXN0X3RvcF8xMDAwMDAwLnR4dA== 14 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RhbmllbG1pZXNzbGVyL1NlY0xpc3RzL21hc3Rlci9QYXNzd29yZHMvTGl6YXJkX1NxdWFkLnR4dA== 15 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrLzZjNTEzNzdhMzM5YzM4YTdiMDIwMjc3NGYyOWQ5MWUyL3Jhdy82MWM1Y2I2NWNkMTljMmI4YjNkYmY4N2EzOTFkN2NkNzcxYjZjZTljL2V4YW1wbGUuZGljdA== 16 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrL2Q0ODc4NWNhODAxMjcwZjc3MzI3NzY1ZDI0Y2Y2MWM4L3Jhdy9iOTg3N2ZjYmVhZGEyMjNjM2I1ZmRhMGJmNWI4YmFiMzBmNmNhNGE0L2dkaWN0LnR4dA== 17 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RhbmllbG1pZXNzbGVyL1NlY0xpc3RzL21hc3Rlci9QYXNzd29yZHMvMTBfbWlsbGlvbl9wYXNzd29yZF9saXN0X3RvcF8xMDAwMDAwLnR4dA== 18 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RhbmllbG1pZXNzbGVyL1NlY0xpc3RzL21hc3Rlci9QYXNzd29yZHMvTW9zdFBvcHVsYXJMZXR0ZXJQYXNzZXMudHh0 19 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RhbmllbG1pZXNzbGVyL1NlY0xpc3RzL21hc3Rlci9QYXNzd29yZHMvS2V5Ym9hcmRDb21iaW5hdGlvbnMudHh0 20 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2JlcnplcmswL1Byb2JhYmxlLVdvcmRsaXN0cy9tYXN0ZXIvUmVhbC1QYXNzd29yZHMvVG9wOTVUaG91c2FuZC1wcm9iYWJsZS50eHQ= 21 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2JlcnplcmswL1Byb2JhYmxlLVdvcmRsaXN0cy9tYXN0ZXIvRGljdGlvbmFyeS1TdHlsZS9NYWluRW5nbGlzaERpY3Rpb25hcnkudHh0 22 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2JlcnplcmswL1Byb2JhYmxlLVdvcmRsaXN0cy9tYXN0ZXIvUmVhbC1QYXNzd29yZHMvV1BBLUxlbmd0aC9Ub3AxOTMzLXByb2JhYmxlLVdQQS50eHQ= 23 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0VrdWx0ZWsvd29yZGxpc3RzL21hc3Rlci8weGMwZGEtcHRici50eHQ= 24 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0VrdWx0ZWsvd29yZGxpc3RzL21hc3Rlci9iaWJsaWMtd29yZHMtcHQtYnIudHh0 25 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0VrdWx0ZWsvd29yZGxpc3RzL21hc3Rlci9icmF6aWxpYW4tc29jY2VyLXRlYW1zLnR4dA== 26 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0VrdWx0ZWsvd29yZGxpc3RzL21hc3Rlci9kaWMtcHRici11dGY4LTIudHh0 27 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0VrdWx0ZWsvd29yZGxpc3RzL21hc3Rlci91bWJhbmRhX2NhbmRvbWJsZV90ZXJtc19zbWFsbC50eHQ= 28 | aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2dlb3ZlZGkvaW5kb25lc2lhbi13b3JkbGlzdC9tYXN0ZXIvMDUtaXZhbmxhbmluMjAxMS1zb3J0LWFscGhhLmxzdA== 29 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrL2Q2MTI2ZDU0MGIzZTdhYzdiYjJjMmI3NjMyMzMwNWM3L3Jhdy83NWJhODI5YTkxNTVkZGJlMzI4NzgyYmM1MmI2NDFjM2E3NDI0MzA5L2RhdGEudHh0LnR4dA== 30 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrLzdjNjM0ZDM2NjAzYWMyMmUwZjMzMzQ3YjdiOTdmNzk2L3Jhdy85YTZmMjM4YTNjMmM3ZWNlYTIxMmZmZDExMzE5YThhNDFjOGZjYWU3L2RpY3Rpb25hcnlfYWZyaWNhYW4uZGlj 31 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrLzBmZDk3M2ZhMDhkMGUwNGY4MjA5ZWE3OWJiMjM1NzE3L3Jhdy9kOGYzMjI4MzZkYjc3MTZjYWI2YjczZmYwZmUxNTVjYjVlNzI1M2U2L2RpY3Rpb25hcnlfYnJhemlsaWFuLmRpYw== 32 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrL2Q0Y2YwYWFjMDhlMDNhOTQ4NDBjODFmZWIxZTM3OTFiL3Jhdy9kYzFhNDk0NTY5YjlkYjUwM2FmMmZlMTJjZDVlNTg3MGI1MWVmNDQ0L2RpY3Rpb25hcnlfY2hpbmVzZS5kaWM= 33 | aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Fa3VsdGVrL2Y0YjdmOWYxZmViZTU0NzRiMzA4MTc3OWVkZjJiOWUzL3Jhdy8yODlkN2IwMWFhMTY3ODZlNDdmNDFjZDhhNzE2NDNkYmM0MDFhNjcwL2RpY3Rpb25hcnlfY3JvYXRpYW4uZGlj -------------------------------------------------------------------------------- /lib/algorithms/custom/_crc64.py: -------------------------------------------------------------------------------- 1 | crc_crypto_table = [ 2 | 0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5, 3 | 0x493366450E42ECDF, 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A, 4 | 0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D, 0x17870F5D4F51B498, 0x5577EEB6E6BB820B, 5 | 0xDB55AACF12C73561, 0x99A54B24BB2D03F2, 0x5EB4691841135847, 0x1C4488F3E8F96ED4, 6 | 0x663D78FF90E185EF, 0x24CD9914390BB37C, 0xE3DCBB28C335E8C9, 0xA12C5AC36ADFDE5A, 7 | 0x2F0E1EBA9EA36930, 0x6DFEFF5137495FA3, 0xAAEFDD6DCD770416, 0xE81F3C86649D3285, 8 | 0xF45BB4758C645C51, 0xB6AB559E258E6AC2, 0x71BA77A2DFB03177, 0x334A9649765A07E4, 9 | 0xBD68D2308226B08E, 0xFF9833DB2BCC861D, 0x388911E7D1F2DDA8, 0x7A79F00C7818EB3B, 10 | 0xCC7AF1FF21C30BDE, 0x8E8A101488293D4D, 0x499B3228721766F8, 0x0B6BD3C3DBFD506B, 11 | 0x854997BA2F81E701, 0xC7B97651866BD192, 0x00A8546D7C558A27, 0x4258B586D5BFBCB4, 12 | 0x5E1C3D753D46D260, 0x1CECDC9E94ACE4F3, 0xDBFDFEA26E92BF46, 0x990D1F49C77889D5, 13 | 0x172F5B3033043EBF, 0x55DFBADB9AEE082C, 0x92CE98E760D05399, 0xD03E790CC93A650A, 14 | 0xAA478900B1228E31, 0xE8B768EB18C8B8A2, 0x2FA64AD7E2F6E317, 0x6D56AB3C4B1CD584, 15 | 0xE374EF45BF6062EE, 0xA1840EAE168A547D, 0x66952C92ECB40FC8, 0x2465CD79455E395B, 16 | 0x3821458AADA7578F, 0x7AD1A461044D611C, 0xBDC0865DFE733AA9, 0xFF3067B657990C3A, 17 | 0x711223CFA3E5BB50, 0x33E2C2240A0F8DC3, 0xF4F3E018F031D676, 0xB60301F359DBE0E5, 18 | 0xDA050215EA6C212F, 0x98F5E3FE438617BC, 0x5FE4C1C2B9B84C09, 0x1D14202910527A9A, 19 | 0x93366450E42ECDF0, 0xD1C685BB4DC4FB63, 0x16D7A787B7FAA0D6, 0x5427466C1E109645, 20 | 0x4863CE9FF6E9F891, 0x0A932F745F03CE02, 0xCD820D48A53D95B7, 0x8F72ECA30CD7A324, 21 | 0x0150A8DAF8AB144E, 0x43A04931514122DD, 0x84B16B0DAB7F7968, 0xC6418AE602954FFB, 22 | 0xBC387AEA7A8DA4C0, 0xFEC89B01D3679253, 0x39D9B93D2959C9E6, 0x7B2958D680B3FF75, 23 | 0xF50B1CAF74CF481F, 0xB7FBFD44DD257E8C, 0x70EADF78271B2539, 0x321A3E938EF113AA, 24 | 0x2E5EB66066087D7E, 0x6CAE578BCFE24BED, 0xABBF75B735DC1058, 0xE94F945C9C3626CB, 25 | 0x676DD025684A91A1, 0x259D31CEC1A0A732, 0xE28C13F23B9EFC87, 0xA07CF2199274CA14, 26 | 0x167FF3EACBAF2AF1, 0x548F120162451C62, 0x939E303D987B47D7, 0xD16ED1D631917144, 27 | 0x5F4C95AFC5EDC62E, 0x1DBC74446C07F0BD, 0xDAAD56789639AB08, 0x985DB7933FD39D9B, 28 | 0x84193F60D72AF34F, 0xC6E9DE8B7EC0C5DC, 0x01F8FCB784FE9E69, 0x43081D5C2D14A8FA, 29 | 0xCD2A5925D9681F90, 0x8FDAB8CE70822903, 0x48CB9AF28ABC72B6, 0x0A3B7B1923564425, 30 | 0x70428B155B4EAF1E, 0x32B26AFEF2A4998D, 0xF5A348C2089AC238, 0xB753A929A170F4AB, 31 | 0x3971ED50550C43C1, 0x7B810CBBFCE67552, 0xBC902E8706D82EE7, 0xFE60CF6CAF321874, 32 | 0xE224479F47CB76A0, 0xA0D4A674EE214033, 0x67C58448141F1B86, 0x253565A3BDF52D15, 33 | 0xAB1721DA49899A7F, 0xE9E7C031E063ACEC, 0x2EF6E20D1A5DF759, 0x6C0603E6B3B7C1CA, 34 | 0xF6FAE5C07D3274CD, 0xB40A042BD4D8425E, 0x731B26172EE619EB, 0x31EBC7FC870C2F78, 35 | 0xBFC9838573709812, 0xFD39626EDA9AAE81, 0x3A28405220A4F534, 0x78D8A1B9894EC3A7, 36 | 0x649C294A61B7AD73, 0x266CC8A1C85D9BE0, 0xE17DEA9D3263C055, 0xA38D0B769B89F6C6, 37 | 0x2DAF4F0F6FF541AC, 0x6F5FAEE4C61F773F, 0xA84E8CD83C212C8A, 0xEABE6D3395CB1A19, 38 | 0x90C79D3FEDD3F122, 0xD2377CD44439C7B1, 0x15265EE8BE079C04, 0x57D6BF0317EDAA97, 39 | 0xD9F4FB7AE3911DFD, 0x9B041A914A7B2B6E, 0x5C1538ADB04570DB, 0x1EE5D94619AF4648, 40 | 0x02A151B5F156289C, 0x4051B05E58BC1E0F, 0x87409262A28245BA, 0xC5B073890B687329, 41 | 0x4B9237F0FF14C443, 0x0962D61B56FEF2D0, 0xCE73F427ACC0A965, 0x8C8315CC052A9FF6, 42 | 0x3A80143F5CF17F13, 0x7870F5D4F51B4980, 0xBF61D7E80F251235, 0xFD913603A6CF24A6, 43 | 0x73B3727A52B393CC, 0x31439391FB59A55F, 0xF652B1AD0167FEEA, 0xB4A25046A88DC879, 44 | 0xA8E6D8B54074A6AD, 0xEA16395EE99E903E, 0x2D071B6213A0CB8B, 0x6FF7FA89BA4AFD18, 45 | 0xE1D5BEF04E364A72, 0xA3255F1BE7DC7CE1, 0x64347D271DE22754, 0x26C49CCCB40811C7, 46 | 0x5CBD6CC0CC10FAFC, 0x1E4D8D2B65FACC6F, 0xD95CAF179FC497DA, 0x9BAC4EFC362EA149, 47 | 0x158E0A85C2521623, 0x577EEB6E6BB820B0, 0x906FC95291867B05, 0xD29F28B9386C4D96, 48 | 0xCEDBA04AD0952342, 0x8C2B41A1797F15D1, 0x4B3A639D83414E64, 0x09CA82762AAB78F7, 49 | 0x87E8C60FDED7CF9D, 0xC51827E4773DF90E, 0x020905D88D03A2BB, 0x40F9E43324E99428, 50 | 0x2CFFE7D5975E55E2, 0x6E0F063E3EB46371, 0xA91E2402C48A38C4, 0xEBEEC5E96D600E57, 51 | 0x65CC8190991CB93D, 0x273C607B30F68FAE, 0xE02D4247CAC8D41B, 0xA2DDA3AC6322E288, 52 | 0xBE992B5F8BDB8C5C, 0xFC69CAB42231BACF, 0x3B78E888D80FE17A, 0x7988096371E5D7E9, 53 | 0xF7AA4D1A85996083, 0xB55AACF12C735610, 0x724B8ECDD64D0DA5, 0x30BB6F267FA73B36, 54 | 0x4AC29F2A07BFD00D, 0x08327EC1AE55E69E, 0xCF235CFD546BBD2B, 0x8DD3BD16FD818BB8, 55 | 0x03F1F96F09FD3CD2, 0x41011884A0170A41, 0x86103AB85A2951F4, 0xC4E0DB53F3C36767, 56 | 0xD8A453A01B3A09B3, 0x9A54B24BB2D03F20, 0x5D45907748EE6495, 0x1FB5719CE1045206, 57 | 0x919735E51578E56C, 0xD367D40EBC92D3FF, 0x1476F63246AC884A, 0x568617D9EF46BED9, 58 | 0xE085162AB69D5E3C, 0xA275F7C11F7768AF, 0x6564D5FDE549331A, 0x279434164CA30589, 59 | 0xA9B6706FB8DFB2E3, 0xEB46918411358470, 0x2C57B3B8EB0BDFC5, 0x6EA7525342E1E956, 60 | 0x72E3DAA0AA188782, 0x30133B4B03F2B111, 0xF7021977F9CCEAA4, 0xB5F2F89C5026DC37, 61 | 0x3BD0BCE5A45A6B5D, 0x79205D0E0DB05DCE, 0xBE317F32F78E067B, 0xFCC19ED95E6430E8, 62 | 0x86B86ED5267CDBD3, 0xC4488F3E8F96ED40, 0x0359AD0275A8B6F5, 0x41A94CE9DC428066, 63 | 0xCF8B0890283E370C, 0x8D7BE97B81D4019F, 0x4A6ACB477BEA5A2A, 0x089A2AACD2006CB9, 64 | 0x14DEA25F3AF9026D, 0x562E43B4931334FE, 0x913F6188692D6F4B, 0xD3CF8063C0C759D8, 65 | 0x5DEDC41A34BBEEB2, 0x1F1D25F19D51D821, 0xD80C07CD676F8394, 0x9AFCE626CE85B507 66 | ] 67 | 68 | 69 | class CRC64(object): 70 | 71 | def __init__(self): 72 | self.crc = 0xffffffffffffffff 73 | 74 | def _append(self, buffer): 75 | for c in buffer: 76 | tab = ((self.crc >> 56) ^ ord(c)) & 0xFF 77 | self.crc = crc_crypto_table[tab] ^ ((self.crc << 8) & 0xffffffffffffffff) 78 | 79 | def finalize(self): 80 | return self.crc ^ 0 81 | 82 | 83 | def crc64(string): 84 | crc = CRC64() 85 | crc._append(string) 86 | return crc.finalize() 87 | -------------------------------------------------------------------------------- /thirdparty/md2/md2_hash.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | """ 4 | An implementation of the MD2 message digest algorithm, as specified in RFC 1319 (corrected for the reported erratum). The API is pretty much the same as in the standard md5 module. 5 | 6 | (c) 2006 Tom Anderson 7 | 8 | Redistribution and use in source and binary forms, with or without modification, are permitted. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | 12 | """ 13 | 14 | digest_size = 16 15 | 16 | 17 | def pad(buf, size): 18 | n = size - len(buf) 19 | return buf + ([n] * n) 20 | 21 | 22 | S = [ 23 | 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, 19, 24 | 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 76, 130, 202, 25 | 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 138, 23, 229, 18, 26 | 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 245, 142, 187, 47, 238, 122, 27 | 169, 104, 121, 145, 21, 178, 7, 63, 148, 194, 16, 137, 11, 34, 95, 33, 28 | 128, 127, 93, 154, 90, 144, 50, 39, 53, 62, 204, 231, 191, 247, 151, 3, 29 | 255, 25, 48, 179, 72, 165, 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 30 | 79, 184, 56, 210, 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 31 | 69, 157, 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 32 | 27, 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, 33 | 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 234, 38, 34 | 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 129, 77, 82, 35 | 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 8, 12, 189, 177, 74, 36 | 120, 136, 149, 139, 227, 99, 232, 109, 233, 203, 213, 254, 59, 0, 29, 57, 37 | 242, 239, 183, 14, 102, 88, 208, 228, 166, 119, 114, 248, 235, 117, 75, 10, 38 | 49, 68, 80, 180, 143, 237, 31, 26, 219, 153, 141, 51, 159, 17, 131, 20] 39 | 40 | 41 | def checksum_errant(c, buf): # without erratum applied 42 | l = c[-1] 43 | for i in xrange(digest_size): 44 | l = S[(buf[i] ^ l)] 45 | c[i] = l 46 | 47 | 48 | def checksum(c, buf): 49 | l = c[-1] 50 | for i in xrange(digest_size): 51 | l = S[(buf[i] ^ l)] ^ c[i] 52 | c[i] = l 53 | 54 | 55 | def digest(d, buf): 56 | for i in xrange(digest_size): 57 | b = buf[i] 58 | d[(i + digest_size)] = b 59 | d[(i + (2 * digest_size))] = b ^ d[i] 60 | t = 0 61 | for n in xrange(18): # 18 rounds 62 | for i in xrange((3 * digest_size)): 63 | t = d[i] ^ S[t] 64 | d[i] = t 65 | t = (t + n) & 0xff 66 | 67 | 68 | HEX = "0123456789abcdef" 69 | 70 | 71 | def hexch(b): 72 | return HEX[((b >> 4) & 0xf)] + HEX[(b & 0xf)] 73 | 74 | 75 | def hexstr(bytes): 76 | return "".join(map(hexch, bytes)) 77 | 78 | 79 | class MD2(object): 80 | """Works exactly like an md5 object. 81 | 82 | """ 83 | 84 | def __init__(self, m=None): 85 | self.digest_size = digest_size 86 | self.buf = [] 87 | self.c = [0] * digest_size 88 | self.d = [0] * (3 * digest_size) 89 | if (m != None): 90 | self.update(m) 91 | 92 | def update(self, m): 93 | # todo: direct handling of 16-byte chunks with large enough inputs (len(m) >= (digest_size - len(buf)), then len(m_remaining) >= digest_size) 94 | # but also handle values of m which do not respond to len or indexing, eg byte iterators 95 | for ch in m: 96 | self.buf.append(ord(ch)) 97 | if (len(self.buf) == digest_size): 98 | self.updateblock(self.buf) 99 | del self.buf[:] 100 | 101 | def updateblock(self, buf): 102 | checksum(self.c, buf) 103 | digest(self.d, buf) 104 | 105 | def digest(self): 106 | buf = pad(self.buf, self.digest_size) 107 | c = list(self.c) 108 | checksum(c, buf) 109 | #print "*** checksum after padding = ", hexstr(c) 110 | d = list(self.d) 111 | digest(d, buf) 112 | digest(d, c) 113 | return d[0:16] 114 | 115 | def hexdigest(self): 116 | return hexstr(self.digest()) 117 | 118 | def copy(self): 119 | copy = MD2() 120 | copy.buf = list(self.buf) 121 | copy.c = self.c 122 | copy.d = self.d 123 | return copy 124 | 125 | 126 | def new(m=None): 127 | "Creates a new MD2 object, with an optional initial argument." 128 | return MD2(m) 129 | 130 | 131 | def md2(m): 132 | "Computes the MD2 digest of a message." 133 | return MD2(m).digest() 134 | 135 | 136 | def md2h(m): 137 | "Computes the MD2 digest of a message, and returns as a hex string." 138 | return MD2(m).hexdigest() 139 | 140 | 141 | def readchars(f): 142 | "Returns an iteration over the characters in a file." 143 | while True: 144 | b = f.read(1) 145 | if (b == ""): return 146 | yield b 147 | 148 | 149 | def printmd2(name, f): 150 | print(md2h(readchars(f)) + "\t" + name) # compatible with python 3.x 151 | 152 | 153 | """TEST_VECTORS = { 154 | "": "8350e5a3e24c153df2275c9f80692773", 155 | "a": "32ec01ec4a6dac72c0ab96fb34c0b5d1", 156 | "abc": "da853b0d3f88d99b30283a69e6ded6bb", 157 | "message digest": "ab4f496bfb2a530b219ff33031fe06b0", 158 | "abcdefghijklmnopqrstuvwxyz": "4e8ddff3650292ab5a4108c3aa47940b", 159 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": "da33def2a42df13975352846c30338cd", 160 | "12345678901234567890123456789012345678901234567890123456789012345678901234567890": "d5976f79d83d3a0dc9806c3c66f3efd8" 161 | } 162 | 163 | if (__name__ == "__main__"): 164 | # act like md5sum 165 | import sys 166 | 167 | if (len(sys.argv) == 1): 168 | printmd2("-", sys.stdin) 169 | else: 170 | for filename in sys.argv[1:]: 171 | if (filename == "-x"): 172 | for s in sorted(TEST_VECTORS.keys(), key=len): 173 | d = md2h(s) 174 | print "MD2 (\"%s\") = %s" % (s, d) 175 | # assert d == TEST_VECTORS[s], s 176 | continue 177 | f = file(filename) 178 | printmd2(filename, f) 179 | f.close()""" -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Dagon - Advanced hash manipulation 2 | #### Named after the prince of Hell, Dagon *(day-gone)* is an advanced hash cracking and manipulation system, capable of bruteforcing multiple hash types, creating bruteforce dictionaries, automatic hashing algorithm verification, random salt generation from Unicode to ASCII, and much more. 3 | 4 | ###### Here you will find the complete functionality of Dagon, along with pretty pictures to help you along the way. 5 | 6 | ![help](https://cloud.githubusercontent.com/assets/14183473/26105976/e1ba4830-3a09-11e7-8bfd-11e1ae056d49.PNG) 7 | 8 | # Functionality 9 | 10 | Dagon has a lot of options and is capable of cracking almost anything when used properly. 11 | 12 | ## Mandatory arguments 13 | 14 | There are of course mandatory arguments that must be passed so that Dagon can run successfully, in this section I will go over each one of these arguments and tell you a little bit about it, lets begin. 15 | 16 | #### _Cracking hashes_: 17 | 18 | To crack a hash you must provide a singular hash using the `-c/--crack` flag. This flag will tell Dagon that you are trying to crack a single hash, after you have provided the `-c/--crack` flag you will need to tell Dagon what sort of cracking needs to take place. Here's an example of the cracking flag, for this example we will be using the MD5 hashing algorithm. 19 | 20 | Notice that when a wordlist is not provided, Dagon will create its own. This wordlist will contain all possible combinations (up to one million lines) of the letters 'abc' from 7 to 15 characters long 21 | 22 | ![wordlist_gen](https://cloud.githubusercontent.com/assets/14183473/26103895/359f712c-3a01-11e7-8d36-55a312da0264.PNG) 23 | 24 | After the wordlist has been generated, you will be able to crack the password, using that wordlist. Dagon will automatically attempt to verify the algorithm used to create the hash and attempt to crack using the most likely algorithms 25 | 26 | ![cracking](https://cloud.githubusercontent.com/assets/14183473/26104116/f8538cda-3a01-11e7-87a7-7136042ffc0e.PNG) 27 | 28 | #### _Doing a dictionary attack_: 29 | 30 | To do a dictionary attack you will just need to use the wordlist flag (`--wordlist`) in order for the bruteforce section to read from the wordlist. 31 | 32 | ![wordlist_attack](https://cloud.githubusercontent.com/assets/14183473/26204867/c28c226a-3ba5-11e7-8e0f-4410d1deb3ef.PNG) 33 | 34 | #### _Cracking a hash list_: 35 | 36 | To crack a list of hashes (file of hashes) you can use the `-l/--hash-list` flag. You will need to provide a full path to a file so that Dagon can attempt to crack each hash. Lets use a file with three hashes in three different algorithms, SHA1, MD5, and WHIRLPOOL. Notice how it will prompt you if you want to crack the hash or not: 37 | 38 | ![hash_list](https://cloud.githubusercontent.com/assets/14183473/26104288/c9adf220-3a02-11e7-8879-88a6f2a76a42.PNG) 39 | 40 | #### _Verify a hashing algorithm_: 41 | 42 | You ever have to crack a hash, and the next thing you know you needed to know the hashing algorithm that was used in order to finish the cracking? Well look no further! I have a fix for that as well, using the `-v/--verify` flag! Dagon will not only automatically attempt to verify a hash before cracking, but it can also be provided a hash in order to verify what algorithm was used to create it. 43 | 44 | ![verify_hash](https://cloud.githubusercontent.com/assets/14183473/26104876/5c9cad90-3a05-11e7-9055-ef6f2c2ad57c.PNG) 45 | 46 | You can also pass the `-L/--least-likely` flag and see all possible algorithms that could have been used to create this hash, everything from most likely, to least likely. 47 | 48 | ![verify_all](https://cloud.githubusercontent.com/assets/14183473/26104919/860ff9de-3a05-11e7-9ad4-69b43981609a.PNG) 49 | 50 | ### Manipulation arguments 51 | 52 | These arguments are given to manipulate the way the application runs, or to manipulate the givens hashes. 53 | 54 | #### _Salt manipulation options_: 55 | 56 | There are many ways to manipulate the salt in Dagon, anything from using random Unicode salt `--urandom`, random integers `-R`, random characters `-R --use-chars`, random characters & integers `-R --use-chars --use-int`, or creating your own `-S\--salt , `. You can also change the length of the salt using the `--salt-size` flag. Most salts are around 10-12 characters long. So making the salt any bigger will produce a warning letting you know: 57 | 58 | For random unicode salts, you will need to provide the length of the salt, please keep in mind that Unicode can make the hashing process slower. 59 | 60 | ![unicode_salt](https://cloud.githubusercontent.com/assets/14183473/26105454/a32957de-3a07-11e7-93c6-2b728d5b7c20.PNG) 61 | 62 | Default for random salt is integers 63 | 64 | ![random_salt](https://cloud.githubusercontent.com/assets/14183473/26105456/a32a3654-3a07-11e7-93d4-3d7d875f3b52.PNG) 65 | 66 | Of course you can use just characters if you want to, it's up to you not me 67 | 68 | ![just_chars](https://cloud.githubusercontent.com/assets/14183473/26105455/a329fe28-3a07-11e7-9e07-79810de38b02.PNG) 69 | 70 | But where's the fun in using just characters? You can also use characters and integers 71 | 72 | ![chars_and_int_salt](https://cloud.githubusercontent.com/assets/14183473/26105457/a32d1e96-3a07-11e7-9c6a-befa73a75778.PNG) 73 | 74 | Or, you can always just create your own 75 | 76 | ![create_your_own](https://cloud.githubusercontent.com/assets/14183473/26105458/a3fb81e6-3a07-11e7-9f03-d357f2c29600.PNG) 77 | 78 | You can also change the salt size, because hey, who uses 12 character salts anymore? 79 | 80 | ![salt_size](https://cloud.githubusercontent.com/assets/14183473/26105647/5dad0be6-3a08-11e7-8757-bb6bc9e375c2.PNG) 81 | 82 | ### Algorithms available and ID numbers 83 | 84 | #### Currently supported hash types 85 | 86 | 87 | |Algorithm |ID | 88 | |-----------|----| 89 | |MD5 |100 | 90 | |MD2 |110 | 91 | |MD4 |120 | 92 | |Blake-224 |200 | 93 | |Blake-256 |210 | 94 | |Blake-384 |220 | 95 | |Blake-512 |230 | 96 | |SHA-1 |300 | 97 | |SHA-224 |310 | 98 | |SHA-256 |320 | 99 | |SHA-384 |330 | 100 | |SHA-512 |340 | 101 | |SHA3-224 |400 | 102 | |SHA3-256 |410 | 103 | |SHA3-384 |420 | 104 | |SHA3-512 |430 | 105 | |Blowfish |500 | 106 | |MySQL |510 | 107 | |Oracle 11g |520 | 108 | |Oracle 10g |530 | 109 | |MsSQL 2005 |540 | 110 | |PostgreSQL |550 | 111 | |MsSQL 2000 |560 | 112 | |Ripemd-160 |600 | 113 | |Tiger-192 |700 | 114 | |Whirlpool |800 | 115 | |CRC-32 |900 | 116 | |NTLM |1000| 117 | 118 | 119 | #### Special algorithms currently available 120 | 121 | |Algorithm |ID | 122 | |-------------------------------------|---| 123 | |MD5(MD5(**pass**)+MD5(_salt_)) |130| 124 | |MD5(MD5(**pass**)) |131| 125 | |Half MD5 |132| 126 | |MD5(_salt_+**pass**+_salt_) |133| 127 | |MD5(MD5(MD5(pass)))_:salt_ |134| 128 | |Half SHA-1 |351| 129 | |SHA-1(SHA-1(**pass**)) |352| 130 | |SSHA |353| 131 | |SHA-1(SHA-1(SHA-1(pass)))_:salt_ |354| 132 | 133 | 134 | #### Algorithms in the process of being created 135 | 136 | - DSA 137 | - Scrypt 138 | - SHA2 139 | - Wordpress 140 | 141 | ## Shout out to contributors 142 | 143 | - 4w4k3 (Alisson Moretto) 144 | - The creator of Insanity Framework. Thank you for being an all around badass. When you get a chance go check out the repo's: https://github.com/4w4k3 145 | - delirious-lettuce 146 | - Multiple pull requests in a one day span, straight badass and deserves everything good in the world -------------------------------------------------------------------------------- /thirdparty/blake/blake_wrapper.py: -------------------------------------------------------------------------------- 1 | 2 | intro = """ 3 | blake_wrapper.py 4 | version 4 5 | 6 | This is a Python ctypes wrapper for the C reference version 7 | of BLAKE compiled as a shared library. It is *MUCH* faster 8 | than any of the pure Python implementations. 9 | 10 | This wrapper can be used with Python2 and Python3 programs. 11 | 12 | 13 | Instructions: 14 | ------------- 15 | 16 | 1. Obtain a copy of blake_ref.c and blake_ref.h from 17 | 18 | http://www.131002.net/blake/#dl 19 | 20 | 2. Make a trivial mod to blake_ref.h and blake_ref.c: 21 | 22 | To properly support BLAKE's hashState, we need to 23 | allocate space in the wrapper and pass that state to 24 | various functions. The wrapper implements BLAKE as 25 | a class hiding the passing of the state, nevertheless, 26 | we need know how much memory to allocate. ...and to 27 | do so we need to add a function that returns the size 28 | of hashState. 29 | 30 | So, to blake_ref.h add: 31 | 32 | /* 33 | get the hash state size so a wrapper can 34 | allocate sufficient space for state 35 | 36 | RETURNS 37 | size of hashState in bytes 38 | */ 39 | int GetHashStateSize( void ); 40 | 41 | And to blake_ref.c add: 42 | 43 | int GetHashStateSize( void ) { 44 | return sizeof(hashState); 45 | } 46 | 47 | 3. Compile blake_ref.c as a shared library, NOT as a Python 48 | extension. I created my libblake.so with the following: 49 | 50 | gcc -O3 -dynamiclib -arch x86_64 -o libblake.so blake_ref.c 51 | 52 | For Linux, change -dynamiclib to -shared. 53 | 54 | Use your favorite tool to create Windows DLLs. I don't 55 | have a Windows machine. When I must I use Digital Mars. 56 | See: 57 | http://buggywhip.blogspot.com/2007/07/making-simple-dlls-simply.html 58 | 59 | 4. Install the library somewhere on your library search 60 | list: 61 | Linux: LD_LIBRARY_PATH 62 | Darwin: DYLD_LIBRARY_PATH 63 | 64 | 5. Sample usage: 65 | 66 | from blake_wrapper import BLAKE 67 | 68 | blake = BLAKE(256) 69 | blake.update('Now is the time for all good ') 70 | blake.update('men to come to the aid of their ') 71 | digest = blake.final('country.') 72 | 73 | 74 | I used blake_ref.c and this wrapper supports that API. If 75 | you choose to use another implementation you may need to 76 | modify this wrapper to support another API. Those changes 77 | should be fairly straightforward. 78 | 79 | 80 | Legal: 81 | ------ 82 | 83 | Copyright (c) 2009-2012 by Larry Bugbee, Kent, WA 84 | ALL RIGHTS RESERVED. 85 | 86 | blake_wrapper.py IS EXPERIMENTAL SOFTWARE FOR EDUCATIONAL 87 | PURPOSES ONLY. IT IS MADE AVAILABLE "AS-IS" WITHOUT 88 | WARRANTY OR GUARANTEE OF ANY KIND. ITS USE SIGNIFIES 89 | FULL ACCEPTANCE OF ALL RISK, UNDER ALL CIRCUMSTANCES, NO 90 | EXCEPTIONS. 91 | 92 | To make your learning and experimentation less cumbersome, 93 | blake_wrapper.py is free for any use. 94 | 95 | 96 | Enjoy, 97 | 98 | Larry Bugbee 99 | March 2011 100 | May 2011 - fixed Python version check (tx JP) 101 | - modded to use shared library 102 | Apr 2012 - obsolesced BLAKE_func() to make APIs the same 103 | as blake.py 104 | 105 | 106 | 107 | """ 108 | 109 | 110 | import sys 111 | from ctypes import * 112 | 113 | _version = 4 114 | 115 | _defaultlibname = 'blake' # as in libblake.so 116 | 117 | 118 | # -------------------------------------------------------------------------- 119 | 120 | class BLAKE(object): 121 | """ This class supports data in even increments of bytes. 122 | """ 123 | 124 | def __init__(self, hashbitlen): 125 | """ 126 | load the hashSate structure (copy hashbitlen...) 127 | hashbitlen: length of the hash output 128 | """ 129 | if hashbitlen not in [224, 256, 384, 512]: 130 | raise Exception('hash length not 224, 256, 384 or 512') 131 | 132 | self.hashbitlen = hashbitlen 133 | self.state = c_buffer(LIB.GetHashStateSize()) 134 | ret = LIB.Init(self.state, hashbitlen) 135 | if ret: 136 | raise Exception('Init() ret = %d', ret) 137 | self.init = 1 138 | 139 | 140 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 141 | 142 | def addsalt(self, salt): 143 | """ adds a salt to the hash function (OPTIONAL) 144 | should be called AFTER Init, and BEFORE update 145 | salt: a bytestring, length determined by hashbitlen. 146 | if hashbitlen=224 or 256, then salt will be 16 bytes 147 | if hashbitlen=384 or 512, then salt will be 32 bytes 148 | """ 149 | # fail if addsalt() was not called at the right time 150 | if self.init != 1: 151 | raise Exception('addsalt() not called after init() and before update()') 152 | 153 | # is salt size correct? 154 | saltsize = 16 if self.hashbitlen in [224, 256] else 32 155 | if len(salt) != saltsize: 156 | raise Exception('incorrect salt length') 157 | 158 | # do it 159 | ret = LIB.AddSalt(self.state, salt) 160 | if ret: 161 | raise Exception('AddSalt() ret = %d', ret) 162 | 163 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 164 | 165 | def update(self, data): 166 | """ update the state with new data, storing excess data 167 | as necessary. may be called multiple times and if a 168 | call sends less than a full block in size, the leftover 169 | is cached and will be consumed in the next call 170 | data: data to be hashed (bytestring) 171 | """ 172 | self.init = 2 173 | 174 | datalen = len(data ) *8 175 | if not datalen: return 176 | 177 | ret = LIB.Update(self.state, data, datalen) 178 | if ret: 179 | raise Exception('Update() ret = %d', ret) 180 | 181 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 182 | 183 | def final(self, data=b''): 184 | """ finalize the hash -- pad and hash remaining data 185 | returns hashval, the digest 186 | """ 187 | if data: 188 | self.update(data) 189 | 190 | hashval = c_buffer(int(self. hashbitlen /8)) 191 | ret = LIB.Final(self.state, hashval) 192 | if ret: 193 | raise Exception('Final() ret = %d', ret) 194 | return hashval.raw 195 | 196 | digest = final # may use .digest() as a synonym for .final() 197 | 198 | 199 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 200 | # BLAKE_func() is obsolescent and is provided here for backward 201 | # compatability. I will remove this someday. 202 | def BLAKE_func(hashbitlen, data, databitlen): 203 | """ all-in-one function 204 | hashbitlen must be one of 224, 256, 384, 512 205 | data data to be hashed (bytestring) 206 | databitlen length of data to be hashed in *bits* 207 | returns digest value (bytestring) 208 | """ 209 | return BLAKE(hashbitlen).final(data) 210 | 211 | 212 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 213 | # load the shared library into ctypes 214 | 215 | def loadLib(name): 216 | # prefix might need to change for some platforms ??? 217 | prefix = '' 218 | # get the correct library suffix 219 | libsuffixes = {'darwin': '.so', # .dylib ??? 220 | 'linux': '.so', 221 | 'linux2': '.so', 222 | 'win32': '.dll'} # .lib ??? 223 | try: 224 | libsuffix = libsuffixes[sys.platform] 225 | except: 226 | raise Exception('library suffix for "%s" is what?' % 227 | sys.platform) 228 | libname = prefix+ 'lib' + name + libsuffix 229 | return CDLL(libname) # load and return the library 230 | 231 | 232 | LIB = loadLib(_defaultlibname) 233 | 234 | LIB.GetHashStateSize.restype = c_int 235 | LIB.Init.restype = c_int 236 | LIB.Update.restype = c_int 237 | LIB.Final.restype = c_int 238 | LIB.GetHashStateSize.argtypes = [] 239 | LIB.Init.argtypes = [c_void_p, c_int] 240 | LIB.Update.argtypes = [c_void_p, c_void_p, c_int] 241 | LIB.Final.argtypes = [c_void_p, c_void_p] 242 | 243 | # -------------------------------------------------------------------------- 244 | # -------------------------------------------------------------------------- 245 | # -------------------------------------------------------------------------- -------------------------------------------------------------------------------- /bin/attacks/bruteforce/bf_attack.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import os 4 | import codecs 5 | 6 | from bin.verify_hashes.verify import verify_hash_type 7 | from bin.generators import Generators 8 | from lib.settings import ( 9 | DAGON_ISSUE_LINK, 10 | FUNC_DICT, 11 | LOGGER, 12 | WORDLIST_RE, 13 | match_found, 14 | prompt, 15 | random_salt_generator, 16 | shutdown, 17 | create_dir, 18 | ) 19 | 20 | # The name of the wordlist 21 | WORDLIST_NAME = "Dagon-bfdict-" + random_salt_generator(use_string=True, length=7)[0] + ".txt" 22 | 23 | 24 | def create_wordlist(warning=True, verbose=False, add=False): 25 | """ 26 | Create a bruteforcing wordlist 27 | 28 | > :param max_length: max amount of words to have 29 | > :param max_word_length: how long the words should be 30 | > :param warning: output the warning message to say that BF'ing sucks 31 | > :return: a wordlist 32 | """ 33 | max_length, max_word_length, dirname = 10000000, 10, "bf-dicts" 34 | if add: 35 | max_word_length += 2 36 | 37 | warn_msg = ( 38 | "It is highly advised to use a dictionary attack over bruteforce. " 39 | "Bruteforce requires extreme amounts of memory to accomplish and " 40 | "it is possible that it could take a lifetime to successfully " 41 | "crack your hash. To run a dictionary attack all you need to do is" 42 | " pass the wordlist switch ('-w/--wordlist PATH') with the path to " 43 | "your wordlist. (IE: --bruteforce -w ~/dicts/dict.txt)" 44 | ) 45 | 46 | if warning: 47 | LOGGER.warning(warn_msg) 48 | 49 | if verbose: 50 | LOGGER.debug("Creating {} words with a max length of {} characters".format(max_length, max_word_length)) 51 | 52 | create_dir(dirname, verbose=verbose) 53 | with open(dirname + "/" + WORDLIST_NAME, "a+") as lib: 54 | word = Generators().word_generator(length_max=max_word_length) 55 | lib.seek(0, 0) 56 | line_count = len(lib.readlines()) 57 | try: 58 | for _ in range(line_count, max_length): 59 | lib.write(next(word) + "\n") 60 | except StopIteration: # SHOULD NEVER GET HERE 61 | # if we run out of mutations we'll retry with a different word length 62 | lib.seek(0, 0) 63 | err_msg = ( 64 | "Ran out of mutations at {} mutations. You can try upping " 65 | "the max length or just use what was processed. If you " 66 | "make the choice not to continue the program will add +2 " 67 | "to the max length and try to create the wordlist again.." 68 | ).format(len(lib.readlines())) 69 | LOGGER.error(err_msg) 70 | q = prompt("Would you like to continue", "y/N") 71 | if not q.startswith(("y", "Y")): 72 | lib.truncate(0) 73 | create_wordlist(warning=False, add=True) 74 | LOGGER.info("Wordlist generated, words saved to: {}. Please re-run the application, exiting..".format(WORDLIST_NAME)) 75 | shutdown() 76 | 77 | 78 | def hash_words(verify_hash, wordlist, algorithm, salt=None, placement=None, 79 | posx="", use_hex=False, verbose=False, rounds=10): 80 | """ 81 | Hash the words and verify if they match or not 82 | 83 | > :param verify_hash: the has to be verified 84 | > :param wordlist: the wordlist to be used 85 | > :param algorithm: the algorithm to be used 86 | > :param salt: the salt string 87 | > :param placement: where to place the salt if given 88 | > :return: the word that matched the hash when hashed, the hash, the amount of tries, and algorithm 89 | 90 | """ 91 | tries = 0 92 | with codecs.open(wordlist, encoding="utf-8", mode="r") as words: 93 | for i, word in enumerate(words.readlines(), start=1): 94 | if type(word.strip()) is unicode: 95 | word = word.strip().encode("utf-8") 96 | if salt is not None: 97 | if placement == "front": 98 | hashed = FUNC_DICT[algorithm.lower()](word.strip(), salt=salt, front=True, 99 | posx=posx, use_hex=use_hex, rounds=rounds) 100 | else: 101 | hashed = FUNC_DICT[algorithm.lower()](word.strip(), salt=salt, back=True, 102 | posx=posx, use_hex=use_hex, rounds=rounds) 103 | else: 104 | hashed = FUNC_DICT[algorithm.lower()](word.strip(), posx=posx, use_hex=use_hex, rounds=rounds) 105 | tries += 1 106 | 107 | if verbose and tries % 10000 == 0: LOGGER.debug("Testing against: '{}', attempt #{}..".format(hashed, tries)) 108 | 109 | if verify_hash.lower() == hashed.lower(): 110 | return word.strip(), hashed, tries, algorithm 111 | 112 | 113 | def bruteforce_main(verf_hash, algorithm=None, wordlist=None, salt=None, placement=None, all_algs=False, posx="", 114 | use_hex=False, verbose=False, batch=False, rounds=10): 115 | """ 116 | Main function to be used for bruteforcing a hash 117 | """ 118 | wordlist_created = False 119 | if wordlist is None: 120 | create_dir("bf-dicts", verbose=verbose) 121 | for item in os.listdir(os.getcwd() + "/bf-dicts"): 122 | if WORDLIST_RE.match(item): 123 | wordlist_created = True 124 | wordlist = "{}/bf-dicts/{}".format(os.getcwd(), item) 125 | if not wordlist_created: 126 | LOGGER.info("Creating wordlist..") 127 | create_wordlist(verbose=verbose) 128 | else: 129 | LOGGER.info("Reading from, {}..".format(wordlist)) 130 | 131 | if algorithm is None: 132 | hash_type = verify_hash_type(verf_hash, least_likely=all_algs) 133 | LOGGER.info("Found {} possible hash type(s) to run against: {} ".format(len(hash_type) - 1 if hash_type[1] is None 134 | else len(hash_type), 135 | hash_type[0] if hash_type[1] is None else 136 | hash_type)) 137 | for alg in hash_type: 138 | if alg is None: 139 | err_msg = ( 140 | "Ran out of algorithms to try. There are no more " 141 | "algorithms currently available that match this hashes " 142 | "length, and complexity.") 143 | LOGGER.fatal(err_msg.format(DAGON_ISSUE_LINK)) 144 | break 145 | else: 146 | if ":::" in verf_hash: 147 | LOGGER.debug("It appears that you are trying to crack an '{}' hash, " 148 | "these hashes have a certain sequence to them that looks " 149 | "like this 'USERNAME:SID:LM_HASH:NTLM_HASH:::'. What you're " 150 | "wanting is the NTLM part, of the hash, fix your hash and try " 151 | "again..".format(alg.upper())) 152 | shutdown(1) 153 | LOGGER.info("Starting bruteforce with {}..".format(alg.upper())) 154 | bruteforcing = hash_words(verf_hash, wordlist, alg, salt=salt, placement=placement, posx=posx, 155 | use_hex=use_hex, verbose=verbose, rounds=rounds) 156 | if bruteforcing is None: 157 | LOGGER.warning("Unable to find a match for '{}', using {}..".format(verf_hash, alg.upper())) 158 | else: 159 | match_found(bruteforcing) 160 | break 161 | else: 162 | LOGGER.info("Using algorithm, {}..".format(algorithm.upper())) 163 | results = hash_words(verf_hash, wordlist, algorithm, salt=salt, placement=placement, posx=posx, verbose=verbose) 164 | if results is None: 165 | LOGGER.warning("Unable to find a match using {}..".format(algorithm.upper())) 166 | if not batch: 167 | verify = prompt("Would you like to attempt to verify the hash type automatically and crack it", "y/N") 168 | else: 169 | verify = "n" 170 | if verify.startswith(("y", "Y")): 171 | bruteforce_main(verf_hash, wordlist=wordlist, salt=salt, placement=placement, posx=posx, use_hex=use_hex, 172 | verbose=verbose) 173 | else: 174 | LOGGER.warning("Unable to produce a result for given hash '{}' using {}..".format( 175 | verf_hash, algorithm.upper())) 176 | else: 177 | match_found(results) 178 | -------------------------------------------------------------------------------- /thirdparty/blake/blake_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | intro = """ 5 | blake_test.py 6 | version 4 7 | 8 | This program tests blake.py individually and against a C 9 | reference implementation wrapped with blake_wrapper.py. 10 | It works for both Python2 and Python3. 11 | 12 | Copyright (c) 2009-2012 by Larry Bugbee, Kent, WA 13 | ALL RIGHTS RESERVED. 14 | 15 | blake_test.py IS EXPERIMENTAL SOFTWARE FOR EDUCATIONAL 16 | PURPOSES ONLY. IT IS MADE AVAILABLE "AS-IS" WITHOUT 17 | WARRANTY OR GUARANTEE OF ANY KIND. ITS USE SIGNIFIES 18 | FULL ACCEPTANCE OF ALL RISK, UNDER ALL CIRCUMSTANCES, NO 19 | EXCEPTIONS. 20 | 21 | To make your learning and experimentation less cumbersome, 22 | blake_test.py is free for any use. 23 | 24 | 25 | Enjoy, 26 | 27 | Larry Bugbee 28 | April 2012 29 | 30 | """ 31 | 32 | import sys 33 | from ctypes import * 34 | from binascii import hexlify, unhexlify 35 | 36 | _version = '1' 37 | 38 | # import two modules with identical class and method names, but 39 | # keep them individually identifiable 40 | have_blake = False 41 | have_blake_wrapper = False 42 | 43 | try: 44 | from blake import BLAKE as BLAKEpy 45 | 46 | have_blake = True 47 | except: 48 | print('\n *** unable to import blake.py *** \n') 49 | 50 | try: 51 | from blake_wrapper import BLAKE as BLAKEwrap 52 | # the next line is obsolesent and will be removed someday 53 | from blake_wrapper import BLAKE_func as BLAKEwrap_func 54 | 55 | have_blake_wrapper = True 56 | except: 57 | print('\n *** unable to import blake_wrapper.py *** \n') 58 | 59 | 60 | # --------------------------------------------------------------- 61 | # test vectors 62 | 63 | def basic_tests(): 64 | if 0: 65 | print(intro) 66 | 67 | def test_BLAKE(hashlen, msg, expect): 68 | print(' BLAKE-%d: msg = %s length = %d' % 69 | (hashlen, msg.decode(), len(msg))) 70 | digest = BLAKE(hashlen).digest(msg) 71 | print(' %s %s' % ('valid ' if digest == unhexlify(expect) 72 | else 'ERROR >>>', hexlify(digest).decode())) 73 | 74 | if 1: 75 | print('') 76 | print(' single null-byte message:') 77 | msg = b'\x00' 78 | 79 | hashlen = 256 80 | expect = (b'0ce8d4ef4dd7cd8d62dfded9d4edb0a7' + 81 | b'74ae6a41929a74da23109e8f11139c87') 82 | test_BLAKE(hashlen, msg, expect) 83 | 84 | hashlen = 224 85 | expect = (b'4504cb0314fb2a4f7a692e696e487912' + 86 | b'fe3f2468fe312c73a5278ec5') 87 | test_BLAKE(hashlen, msg, expect) 88 | 89 | hashlen = 512 90 | expect = (b'97961587f6d970faba6d2478045de6d1' + 91 | b'fabd09b61ae50932054d52bc29d31be4' + 92 | b'ff9102b9f69e2bbdb83be13d4b9c0609' + 93 | b'1e5fa0b48bd081b634058be0ec49beb3') 94 | test_BLAKE(hashlen, msg, expect) 95 | 96 | hashlen = 384 97 | expect = (b'10281f67e135e90ae8e882251a355510' + 98 | b'a719367ad70227b137343e1bc122015c' + 99 | b'29391e8545b5272d13a7c2879da3d807') 100 | test_BLAKE(hashlen, msg, expect) 101 | 102 | if 1: 103 | print('') 104 | print(' 72 null-bytes message:') 105 | msg = b'\x00' * 72 106 | 107 | hashlen = 256 108 | expect = (b'd419bad32d504fb7d44d460c42c5593f' + 109 | b'e544fa4c135dec31e21bd9abdcc22d41') 110 | test_BLAKE(hashlen, msg, expect) 111 | 112 | hashlen = 224 113 | expect = (b'f5aa00dd1cb847e3140372af7b5c46b4' + 114 | b'888d82c8c0a917913cfb5d04') 115 | test_BLAKE(hashlen, msg, expect) 116 | 117 | print('') 118 | print(' 144 null-bytes message:') 119 | msg = b'\x00' * 144 120 | 121 | hashlen = 512 122 | expect = (b'313717d608e9cf758dcb1eb0f0c3cf9f' + 123 | b'c150b2d500fb33f51c52afc99d358a2f' + 124 | b'1374b8a38bba7974e7f6ef79cab16f22' + 125 | b'ce1e649d6e01ad9589c213045d545dde') 126 | test_BLAKE(hashlen, msg, expect) 127 | 128 | hashlen = 384 129 | expect = (b'0b9845dd429566cdab772ba195d271ef' + 130 | b'fe2d0211f16991d766ba749447c5cde5' + 131 | b'69780b2daa66c4b224a2ec2e5d09174c') 132 | test_BLAKE(hashlen, msg, expect) 133 | 134 | if 1: 135 | print('') 136 | print(' more:') 137 | 138 | if 1: 139 | msg = b'Kilroy was here!' 140 | hashlen = 256 141 | expect = (b'b25c02ccfa1f664d25a15d999b56a4be' + 142 | b'1ad84a029a96be5d654387a2def99916') 143 | test_BLAKE(hashlen, msg, expect) 144 | 145 | msg = b'The quick brown fox jumps over the lazy dog' 146 | hashlen = 512 147 | expect = (b'1F7E26F63B6AD25A0896FD978FD050A1' + 148 | b'766391D2FD0471A77AFB975E5034B7AD' + 149 | b'2D9CCF8DFB47ABBBE656E1B82FBC634B' + 150 | b'A42CE186E8DC5E1CE09A885D41F43451') 151 | test_BLAKE(hashlen, msg, expect) 152 | 153 | if 1: 154 | msg = b'\x00' * 55 155 | hashlen = 256 156 | expect = (b'dc980544f4181cc43505318e317cdfd4' + 157 | b'334dab81ae035a28818308867ce23060') 158 | test_BLAKE(hashlen, msg, expect) 159 | 160 | msg = b'\x00' * 56 161 | hashlen = 256 162 | expect = (b'26ae7c289ebb79c9f3af2285023ab103' + 163 | b'7a9a6db63f0d6b6c6bbd199ab1627508') 164 | test_BLAKE(hashlen, msg, expect) 165 | 166 | msg = b'\x00' * 111 167 | hashlen = 512 168 | expect = (b'125695c5cc01de48d8b107c101778fc4' + 169 | b'47a55ad3440a17dc153c6c652faecdbf' + 170 | b'017aed68f4f48826b9dfc413ef8f14ae' + 171 | b'7dfd8b74a0afcf47b61ce7dcb1058976') 172 | test_BLAKE(hashlen, msg, expect) 173 | 174 | msg = b'\x00' * 112 175 | hashlen = 512 176 | expect = (b'aa42836448c9db34e0e45a49f916b54c' + 177 | b'25c9eefe3f9f65db0c13654bcbd9a938' + 178 | b'c24251f3bedb7105fa4ea54292ce9ebf' + 179 | b'5adea15ce530fb71cdf409387a78c6ff') 180 | test_BLAKE(hashlen, msg, expect) 181 | 182 | if 0: 183 | import time 184 | print('') 185 | print(' simple timimg test:') 186 | 187 | def time_it(hashsize, iter): 188 | t0 = time.time() 189 | for i in range(iter): 190 | digest = BLAKE(hashsize).digest(b'\x00') # hash a single null byte 191 | t1 = time.time() 192 | template = ' %8d iterations of single-block BLAKE-%d took %8.6f seconds' 193 | print(template % (iter, hashsize, (t1 - t0))) 194 | 195 | iterations = [10, 100, 1000] 196 | hashsizes = [256, 512] 197 | for hashsize in hashsizes: 198 | for iter in iterations: 199 | time_it(hashsize, iter) 200 | 201 | 202 | # -------------------------------------------------------------------------- 203 | # -------------------------------------------------------------------------- 204 | 205 | if have_blake: 206 | # testing blake.py independently 207 | BLAKE = BLAKEpy 208 | print('\n Testing blake.py:') 209 | print(' -----------------') 210 | basic_tests() 211 | 212 | if have_blake_wrapper: 213 | # testing blake_wrapper.py independently 214 | BLAKE = BLAKEwrap 215 | BLAKE_func = BLAKEwrap_func 216 | print('\n Testing blake_wrapper.py:') 217 | print(' -------------------------') 218 | basic_tests() 219 | 220 | if have_blake and have_blake_wrapper: 221 | # now run a series of tests against each other 222 | 223 | print('\n Comparing results fm blake.py with blake_wrapper.py:') 224 | print(' ----------------------------------------------------') 225 | hashsizes = [256, 512] 226 | testchar = b'\xff' 227 | for hashsize in hashsizes: 228 | print(' BLAKE-%d:' % hashsize) 229 | errors = 0 230 | for i in range(550): 231 | if (BLAKEpy(hashsize).final(testchar * i) != 232 | BLAKEwrap(hashsize).final(testchar * i)): 233 | errors += 1 234 | print(' *** blake.py and blake_wrapper.py' + 235 | ' do not agree for chr(%d)*%d ***' % (testchar, i)) 236 | if not errors: 237 | print(' no errors found') 238 | 239 | print('') 240 | 241 | 242 | # -------------------------------------------------------------------------- 243 | # -------------------------------------------------------------------------- 244 | # -------------------------------------------------------------------------- -------------------------------------------------------------------------------- /thirdparty/blake/blake.py: -------------------------------------------------------------------------------- 1 | intro = """ 2 | blake.py 3 | version 5, 2-Apr-2014 4 | 5 | BLAKE is a SHA3 round-3 finalist designed and submitted by 6 | Jean-Philippe Aumasson et al. 7 | 8 | At the core of BLAKE is a ChaCha-like mixer, very similar 9 | to that found in the stream cipher, ChaCha8. Besides being 10 | a very good mixer, ChaCha is fast. 11 | 12 | References: 13 | http://www.131002.net/blake/ 14 | http://csrc.nist.gov/groups/ST/hash/sha-3/index.html 15 | http://en.wikipedia.org/wiki/BLAKE_(hash_function) 16 | 17 | This implementation assumes all data is in increments of 18 | whole bytes. (The formal definition of BLAKE allows for 19 | hashing individual bits.) Note too that this implementation 20 | does include the round-3 tweaks where the number of rounds 21 | was increased to 14/16 from 10/14. 22 | 23 | This version can be imported into both Python2 (2.6 and 2.7) 24 | and Python3 programs. Python 2.5 requires an older version 25 | of blake.py (version 4). 26 | 27 | Here are some comparative times for different versions of 28 | Python: 29 | 30 | 64-bit: 31 | 2.6 6.284s 32 | 2.7 6.343s 33 | 3.2 7.620s 34 | pypy (2.7) 2.080s 35 | 36 | 32-bit: 37 | 2.5 (32) 15.389s (with psyco) 38 | 2.7-32 13.645s 39 | 3.2-32 12.574s 40 | 41 | One test on a 2.0GHz Core 2 Duo of 10,000 iterations of 42 | BLAKE-256 on a short message produced a time of 5.7 seconds. 43 | Not bad, but if raw speed is what you want, look to the 44 | the C version. It is 40x faster and did the same thing 45 | in 0.13 seconds. 46 | 47 | Copyright (c) 2009-2012 by Larry Bugbee, Kent, WA 48 | ALL RIGHTS RESERVED. 49 | 50 | blake.py IS EXPERIMENTAL SOFTWARE FOR EDUCATIONAL 51 | PURPOSES ONLY. IT IS MADE AVAILABLE "AS-IS" WITHOUT 52 | WARRANTY OR GUARANTEE OF ANY KIND. USE SIGNIFIES 53 | ACCEPTANCE OF ALL RISK. 54 | 55 | To make your learning and experimentation less cumbersome, 56 | blake.py is free for any use. 57 | 58 | Enjoy, 59 | 60 | Larry Bugbee 61 | March 2011 62 | rev May 2011 - fixed Python version check (tx JP) 63 | rev Apr 2012 - fixed an out-of-order bit set in final() 64 | - moved self-test to a separate test pgm 65 | - this now works with Python2 and Python3 66 | rev Apr 2014 - added test and conversion of string input 67 | to byte string in update() (tx Soham) 68 | - added hexdigest() method. 69 | - now support state 3 so only one call to 70 | final() per instantiation is allowed. all 71 | subsequent calls to final(), digest() or 72 | hexdigest() simply return the stored value. 73 | 74 | """ 75 | 76 | import struct 77 | from binascii import hexlify, unhexlify 78 | 79 | 80 | # --------------------------------------------------------------- 81 | 82 | class BLAKE(object): 83 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - 84 | # initial values, constants and padding 85 | 86 | # IVx for BLAKE-x 87 | 88 | IV64 = [ 89 | 0x6A09E667F3BCC908, 0xBB67AE8584CAA73B, 90 | 0x3C6EF372FE94F82B, 0xA54FF53A5F1D36F1, 91 | 0x510E527FADE682D1, 0x9B05688C2B3E6C1F, 92 | 0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179, 93 | ] 94 | 95 | IV48 = [ 96 | 0xCBBB9D5DC1059ED8, 0x629A292A367CD507, 97 | 0x9159015A3070DD17, 0x152FECD8F70E5939, 98 | 0x67332667FFC00B31, 0x8EB44A8768581511, 99 | 0xDB0C2E0D64F98FA7, 0x47B5481DBEFA4FA4, 100 | ] 101 | 102 | # note: the values here are the same as the high-order 103 | # half-words of IV64 104 | IV32 = [ 105 | 0x6A09E667, 0xBB67AE85, 106 | 0x3C6EF372, 0xA54FF53A, 107 | 0x510E527F, 0x9B05688C, 108 | 0x1F83D9AB, 0x5BE0CD19, 109 | ] 110 | 111 | # note: the values here are the same as the low-order 112 | # half-words of IV48 113 | IV28 = [ 114 | 0xC1059ED8, 0x367CD507, 115 | 0x3070DD17, 0xF70E5939, 116 | 0xFFC00B31, 0x68581511, 117 | 0x64F98FA7, 0xBEFA4FA4, 118 | ] 119 | 120 | # constants for BLAKE-64 and BLAKE-48 121 | C64 = [ 122 | 0x243F6A8885A308D3, 0x13198A2E03707344, 123 | 0xA4093822299F31D0, 0x082EFA98EC4E6C89, 124 | 0x452821E638D01377, 0xBE5466CF34E90C6C, 125 | 0xC0AC29B7C97C50DD, 0x3F84D5B5B5470917, 126 | 0x9216D5D98979FB1B, 0xD1310BA698DFB5AC, 127 | 0x2FFD72DBD01ADFB7, 0xB8E1AFED6A267E96, 128 | 0xBA7C9045F12C7F99, 0x24A19947B3916CF7, 129 | 0x0801F2E2858EFC16, 0x636920D871574E69, 130 | ] 131 | 132 | # constants for BLAKE-32 and BLAKE-28 133 | # note: concatenate and the values are the same as the values 134 | # for the 1st half of C64 135 | C32 = [ 136 | 0x243F6A88, 0x85A308D3, 137 | 0x13198A2E, 0x03707344, 138 | 0xA4093822, 0x299F31D0, 139 | 0x082EFA98, 0xEC4E6C89, 140 | 0x452821E6, 0x38D01377, 141 | 0xBE5466CF, 0x34E90C6C, 142 | 0xC0AC29B7, 0xC97C50DD, 143 | 0x3F84D5B5, 0xB5470917, 144 | ] 145 | 146 | # the 10 permutations of:0,...15} 147 | SIGMA = [ 148 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], 149 | [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], 150 | [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], 151 | [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8], 152 | [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13], 153 | [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9], 154 | [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], 155 | [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], 156 | [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], 157 | [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], 158 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], 159 | [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], 160 | [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], 161 | [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8], 162 | [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13], 163 | [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9], 164 | [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], 165 | [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], 166 | [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], 167 | [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], 168 | ] 169 | 170 | MASK32BITS = 0xFFFFFFFF 171 | MASK64BITS = 0xFFFFFFFFFFFFFFFF 172 | 173 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - 174 | 175 | def __init__(self, hashbitlen): 176 | """ 177 | load the hashSate structure (copy hashbitlen...) 178 | hashbitlen: length of the hash output 179 | """ 180 | if hashbitlen not in [224, 256, 384, 512]: 181 | raise Exception('hash length not 224, 256, 384 or 512') 182 | 183 | self.hashbitlen = hashbitlen 184 | self.h = [0] * 8 # current chain value (initialized to the IV) 185 | self.t = 0 # number of *BITS* hashed so far 186 | self.cache = b'' # cached leftover data not yet compressed 187 | self.salt = [0] * 4 # salt (null by default) 188 | self.state = 1 # set to 2 by update and 3 by final 189 | self.nullt = 0 # Boolean value for special case \ell_i=0 190 | 191 | # The algorithm is the same for both the 32- and 64- versions 192 | # of BLAKE. The difference is in word size (4 vs 8 bytes), 193 | # blocksize (64 vs 128 bytes), number of rounds (14 vs 16) 194 | # and a few very specific constants. 195 | if (hashbitlen == 224) or (hashbitlen == 256): 196 | # setup for 32-bit words and 64-bit block 197 | self.byte2int = self._fourByte2int 198 | self.int2byte = self._int2fourByte 199 | self.MASK = self.MASK32BITS 200 | self.WORDBYTES = 4 201 | self.WORDBITS = 32 202 | self.BLKBYTES = 64 203 | self.BLKBITS = 512 204 | self.ROUNDS = 14 # was 10 before round 3 205 | self.cxx = self.C32 206 | self.rot1 = 16 # num bits to shift in G 207 | self.rot2 = 12 # num bits to shift in G 208 | self.rot3 = 8 # num bits to shift in G 209 | self.rot4 = 7 # num bits to shift in G 210 | self.mul = 0 # for 32-bit words, 32<>1 is the same as i/2 but faster) 264 | v[12] = v[12] ^ (self.t & MASK) 265 | v[13] = v[13] ^ (self.t & MASK) 266 | v[14] = v[14] ^ (self.t >> self.WORDBITS) 267 | v[15] = v[15] ^ (self.t >> self.WORDBITS) 268 | 269 | # - - - - - - - - - - - - - - - - - 270 | # ready? let's ChaCha!!! 271 | 272 | def G(a, b, c, d, i): 273 | va = v[a] # it's faster to deref and reref later 274 | vb = v[b] 275 | vc = v[c] 276 | vd = v[d] 277 | 278 | sri = SIGMA[round][i] 279 | sri1 = SIGMA[round][i + 1] 280 | 281 | va = ((va + vb) + (m[sri] ^ cxx[sri1])) & MASK 282 | x = vd ^ va 283 | vd = (x >> rot1) | ((x << (WORDBITS - rot1)) & MASK) 284 | vc = (vc + vd) & MASK 285 | x = vb ^ vc 286 | vb = (x >> rot2) | ((x << (WORDBITS - rot2)) & MASK) 287 | 288 | va = ((va + vb) + (m[sri1] ^ cxx[sri])) & MASK 289 | x = vd ^ va 290 | vd = (x >> rot3) | ((x << (WORDBITS - rot3)) & MASK) 291 | vc = (vc + vd) & MASK 292 | x = vb ^ vc 293 | vb = (x >> rot4) | ((x << (WORDBITS - rot4)) & MASK) 294 | 295 | v[a] = va 296 | v[b] = vb 297 | v[c] = vc 298 | v[d] = vd 299 | 300 | for round in range(self.ROUNDS): 301 | # column step 302 | G(0, 4, 8, 12, 0) 303 | G(1, 5, 9, 13, 2) 304 | G(2, 6, 10, 14, 4) 305 | G(3, 7, 11, 15, 6) 306 | # diagonal step 307 | G(0, 5, 10, 15, 8) 308 | G(1, 6, 11, 12, 10) 309 | G(2, 7, 8, 13, 12) 310 | G(3, 4, 9, 14, 14) 311 | 312 | # - - - - - - - - - - - - - - - - - 313 | 314 | # save current hash value (use i&0x3 to get 0,1,2,3,0,1,2,3) 315 | self.h = [self.h[i] ^ v[i] ^ v[i + 8] ^ self.salt[i & 0x3] 316 | for i in range(8)] 317 | 318 | # print 'self.h', [num2hex(h) for h in self.h] 319 | 320 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - 321 | 322 | def addsalt(self, salt): 323 | """ adds a salt to the hash function (OPTIONAL) 324 | should be called AFTER Init, and BEFORE update 325 | salt: a bytestring, length determined by hashbitlen. 326 | if not of sufficient length, the bytestring 327 | will be assumed to be a big endian number and 328 | prefixed with an appropriate number of null 329 | bytes, and if too large, only the low order 330 | bytes will be used. 331 | 332 | if hashbitlen=224 or 256, then salt will be 16 bytes 333 | if hashbitlen=384 or 512, then salt will be 32 bytes 334 | """ 335 | # fail if addsalt() was not called at the right time 336 | if self.state != 1: 337 | raise Exception('addsalt() not called after init() and before update()') 338 | # salt size is to be 4x word size 339 | saltsize = self.WORDBYTES * 4 340 | # if too short, prefix with null bytes. if too long, 341 | # truncate high order bytes 342 | if len(salt) < saltsize: 343 | salt = (chr(0) * (saltsize - len(salt)) + salt) 344 | else: 345 | salt = salt[-saltsize:] 346 | # prep the salt array 347 | self.salt[0] = self.byte2int(salt[: 4 << self.mul]) 348 | self.salt[1] = self.byte2int(salt[4 << self.mul: 8 << self.mul]) 349 | self.salt[2] = self.byte2int(salt[8 << self.mul:12 << self.mul]) 350 | self.salt[3] = self.byte2int(salt[12 << self.mul:]) 351 | 352 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - 353 | 354 | def update(self, data): 355 | """ update the state with new data, storing excess data 356 | as necessary. may be called multiple times and if a 357 | call sends less than a full block in size, the leftover 358 | is cached and will be consumed in the next call 359 | data: data to be hashed (bytestring) 360 | """ 361 | self.state = 2 362 | 363 | BLKBYTES = self.BLKBYTES # de-referenced for improved readability 364 | BLKBITS = self.BLKBITS 365 | 366 | datalen = len(data) 367 | if not datalen: return 368 | 369 | if type(data) == type(u''): 370 | # use either of the next two lines for a proper 371 | # response under both Python2 and Python3 372 | data = data.encode('UTF-8') # converts to byte string 373 | # data = bytearray(data, 'utf-8') # use if want mutable 374 | 375 | # This next line works for Py3 but fails under 376 | # Py2 because the Py2 version of bytes() will 377 | # accept only *one* argument. Arrrrgh!!! 378 | # data = bytes(data, 'utf-8') # converts to immutable byte 379 | # string but... under p7 380 | # bytes() wants only 1 arg 381 | # ...a dummy, 2nd argument like encoding=None 382 | # that does nothing would at least allow 383 | # compatibility between Python2 and Python3. 384 | 385 | left = len(self.cache) 386 | fill = BLKBYTES - left 387 | 388 | # if any cached data and any added new data will fill a 389 | # full block, fill and compress 390 | if left and datalen >= fill: 391 | self.cache = self.cache + data[:fill] 392 | self.t += BLKBITS # update counter 393 | self._compress(self.cache) 394 | self.cache = b'' 395 | data = data[fill:] 396 | datalen -= fill 397 | 398 | # compress new data until not enough for a full block 399 | while datalen >= BLKBYTES: 400 | self.t += BLKBITS # update counter 401 | self._compress(data[:BLKBYTES]) 402 | data = data[BLKBYTES:] 403 | datalen -= BLKBYTES 404 | 405 | # cache all leftover bytes until next call to update() 406 | if datalen > 0: 407 | self.cache = self.cache + data[:datalen] 408 | 409 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - 410 | 411 | def final(self, data=''): 412 | """ finalize the hash -- pad and hash remaining data 413 | returns hashval, the digest 414 | """ 415 | if self.state == 3: 416 | # we have already finalized so simply return the 417 | # previously calculated/stored hash value 418 | return self.hash 419 | 420 | if data: 421 | self.update(data) 422 | 423 | ZZ = b'\x00' 424 | ZO = b'\x01' 425 | OZ = b'\x80' 426 | OO = b'\x81' 427 | PADDING = OZ + ZZ * 128 # pre-formatted padding data 428 | 429 | # copy nb. bits hash in total as a 64-bit BE word 430 | # copy nb. bits hash in total as a 128-bit BE word 431 | tt = self.t + (len(self.cache) << 3) 432 | if self.BLKBYTES == 64: 433 | msglen = self._int2eightByte(tt) 434 | else: 435 | low = tt & self.MASK 436 | high = tt >> self.WORDBITS 437 | msglen = self._int2eightByte(high) + self._int2eightByte(low) 438 | 439 | # size of block without the words at the end that count 440 | # the number of bits, 55 or 111. 441 | # Note: (((self.WORDBITS/8)*2)+1) equals ((self.WORDBITS>>2)+1) 442 | sizewithout = self.BLKBYTES - ((self.WORDBITS >> 2) + 1) 443 | 444 | if len(self.cache) == sizewithout: 445 | # special case of one padding byte 446 | self.t -= 8 447 | if self.hashbitlen in [224, 384]: 448 | self.update(OZ) 449 | else: 450 | self.update(OO) 451 | else: 452 | if len(self.cache) < sizewithout: 453 | # enough space to fill the block 454 | # use t=0 if no remaining data 455 | if len(self.cache) == 0: 456 | self.nullt = 1 457 | self.t -= (sizewithout - len(self.cache)) << 3 458 | self.update(PADDING[:sizewithout - len(self.cache)]) 459 | else: 460 | # NOT enough space, need 2 compressions 461 | # ...add marker, pad with nulls and compress 462 | self.t -= (self.BLKBYTES - len(self.cache)) << 3 463 | self.update(PADDING[:self.BLKBYTES - len(self.cache)]) 464 | # ...now pad w/nulls leaving space for marker & bit count 465 | self.t -= (sizewithout + 1) << 3 466 | self.update(PADDING[1:sizewithout + 1]) # pad with zeroes 467 | 468 | self.nullt = 1 # raise flag to set t=0 at the next _compress 469 | 470 | # append a marker byte 471 | if self.hashbitlen in [224, 384]: 472 | self.update(ZZ) 473 | else: 474 | self.update(ZO) 475 | self.t -= 8 476 | 477 | # append the number of bits (long long) 478 | self.t -= self.BLKBYTES 479 | self.update(msglen) 480 | 481 | hashval = [] 482 | if self.BLKBYTES == 64: 483 | for h in self.h: 484 | hashval.append(self._int2fourByte(h)) 485 | else: 486 | for h in self.h: 487 | hashval.append(self._int2eightByte(h)) 488 | 489 | self.hash = b''.join(hashval)[:self.hashbitlen >> 3] 490 | self.state = 3 491 | 492 | return self.hash 493 | 494 | digest = final # may use digest() as a synonym for final() 495 | 496 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - 497 | 498 | def hexdigest(self, data=''): 499 | return hexlify(self.final(data)).decode('UTF-8') 500 | 501 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 502 | # utility functions 503 | 504 | def _fourByte2int(self, bytestr): # see also long2byt() below 505 | """ convert a 4-byte string to an int (long) """ 506 | return struct.unpack('!L', bytestr)[0] 507 | 508 | def _eightByte2int(self, bytestr): 509 | """ convert a 8-byte string to an int (long long) """ 510 | return struct.unpack('!Q', bytestr)[0] 511 | 512 | def _int2fourByte(self, x): # see also long2byt() below 513 | """ convert a number to a 4-byte string, high order 514 | truncation possible (in Python x could be a BIGNUM) 515 | """ 516 | return struct.pack('!L', x) 517 | 518 | def _int2eightByte(self, x): 519 | """ convert a number to a 8-byte string, high order 520 | truncation possible (in Python x could be a BIGNUM) 521 | """ 522 | return struct.pack('!Q', x) 523 | 524 | 525 | # --------------------------------------------------------------- 526 | # --------------------------------------------------------------- 527 | # --------------------------------------------------------------- -------------------------------------------------------------------------------- /lib/settings.py: -------------------------------------------------------------------------------- 1 | from __future__ import with_statement 2 | 3 | import logging 4 | import re 5 | import string 6 | import sys 7 | import time 8 | import math 9 | import platform 10 | 11 | import requests 12 | from colorlog import ColoredFormatter 13 | 14 | from lib.algorithms.hashing_algs import * 15 | from lib.github.create_issue import ( 16 | request_connection, 17 | dagon_failure 18 | ) 19 | 20 | # Create logging 21 | log_level = logging.DEBUG 22 | logger_format = "[%(log_color)s%(asctime)s %(levelname)s%(reset)s] %(log_color)s%(message)s%(reset)s" 23 | logging.root.setLevel(log_level) 24 | formatter = ColoredFormatter(logger_format, datefmt="%H:%M:%S", 25 | log_colors={ 26 | "DEBUG": "cyan", 27 | "INFO": "bold,green", 28 | "WARNING": "yellow", 29 | "ERROR": "red", 30 | "CRITICAL": "bold,red" 31 | }) 32 | stream = logging.StreamHandler() 33 | stream.setLevel(log_level) 34 | stream.setFormatter(formatter) 35 | LOGGER = logging.getLogger('configlog') 36 | LOGGER.setLevel(log_level) 37 | LOGGER.addHandler(stream) 38 | 39 | # dagons email address 40 | DAGON_EMAIL = "dagonhashguarantee@gmail.com" 41 | # Version number ... 42 | VERSION = "1.15.37.60" 43 | # Colors, green if stable, yellow if dev 44 | TYPE_COLORS = {"dev": 33, "stable": 92} 45 | # Version string, dev or stable release? 46 | if len(VERSION) >= 4: 47 | VERSION_STRING = "\033[92mv{}\033[0m(\033[{}m\033[1mdev\033[0m)".format(VERSION, TYPE_COLORS["dev"]) 48 | else: 49 | VERSION_STRING = "\033[92mv{}\033[0m(\033[{}m\033[1mstable\033[0m)".format(VERSION, TYPE_COLORS["stable"]) 50 | # Program saying 51 | SAYING = "\033[97mAdvanced Hash Manipulation\033[0m" 52 | # Clone link 53 | CLONE = "\033[97mhttps://github.com/ekultek/dagon.git\033[0m" 54 | # Homepage link 55 | HOMEPAGE = "\033[97mhttps://ekultek.github.io/Dagon/\033[0m" 56 | # Issue page 57 | DAGON_ISSUE_LINK = "https://github.com/Ekultek/Dagon/issues/new" 58 | # Sexy banner to display when asked for 59 | BANNER = """\033[91m 60 | '||''|. 61 | || || .... ... . ... .. ... 62 | || || '' .|| ||_|| .| '|. || || 63 | || || .|' || |'' || || || || 64 | .||...|' '|..'|' '||||. '|..|' .||. ||. [][][] 65 | .|....'\033[0m 66 | {} ... {} 67 | Clone: {} 68 | Home: {} 69 | """.format(SAYING, VERSION_STRING, CLONE, HOMEPAGE) 70 | # Algorithm function dict 71 | FUNC_DICT = { 72 | "md2": md2, "md4": md4, "md5": md5, "half md5": half_md5, "md5(md5(pass)+md5(salt))": md5_pass_salt, 73 | "md5(md5(pass))": md5_md5_pass, "md5(salt+pass+salt)": md5_salt_pass_salt, "md5(md5(md5(pass)))": md5_md5_md5_pass, 74 | "md5 crypt": md5_crypt, 75 | "mysql": mysql_hash, "blowfish": blowfish, "oracle 11g": oracle_11g, "oracle 10g": oracle_10g, 76 | "mssql 2005": mssql_2005, "postgresql": postgres, "mssql 2000": mssql_2000, 77 | "ripemd160": ripemd160, 78 | "blake224": blake224, "blake256": blake256, "blake384": blake384, "blake512": blake512, 79 | "sha1": sha1, "sha224": sha224, "sha256": sha256, "sha384": sha384, "sha512": sha512, 80 | "half sha1": half_sha1, "ssha": ssha, "sha1(rounds(pass))": sha1_rounds, 81 | "sha3_224": sha3_224, "sha3_256": sha3_256, "sha3_384": sha3_384, "sha3_512": sha3_512, 82 | "whirlpool": whirlpool, "crc32": crc32, "ntlm": ntlm, "windows local (ntlm)": ntlm, "crc64": crc64, 83 | "tiger192": tiger192 84 | } 85 | # Identity numbers 86 | IDENTIFICATION = { 87 | # MD indicators 88 | 100: "md5", 110: "md2", 120: "md4", 89 | # MD special indicators 90 | 130: "md5(md5(pass)+md5(salt))", 131: "md5(md5(pass))", 132: "half md5", 91 | 133: "md5(salt+pass+salt)", 134: "md5(md5(md5(pass)))", 135: "md5 crypt", 92 | 93 | # Blake indicators 94 | 200: "blake224", 210: "blake256", 220: "blake384", 230: "blake512", 95 | 96 | # SHA indicators 97 | 300: "sha1", 310: "sha224", 320: "sha256", 330: "sha384", 340: "sha512", 98 | 400: "sha3_224", 410: "sha3_256", 420: "sha3_384", 430: "sha3_512", 99 | # SHA special indicators 100 | 351: "half sha1", 352: "sha1(rounds(pass))", 353: "ssha", 101 | 102 | # Database and external hash indicators 103 | 500: "blowfish", 510: "mysql", 520: "oracle 11g", 530: "oracle 10g", 540: "mssql 2005", 550: "postgresql", 104 | 560: "mssql 2000", 105 | 106 | # Ripemd indicators 107 | 600: "ripemd160", 108 | 109 | # Tiger indicators 110 | 700: "tiger192", 111 | 112 | # Other 113 | 800: "whirlpool", 900: "crc32", 1000: "ntlm", 1100: "crc64" 114 | } 115 | # Regular expression to see if you already have a bruteforce wordlist created 116 | WORDLIST_RE = re.compile("Dagon-bfdict-[a-zA-Z]{7}.txt") 117 | # default for how many rounds the algorithm does 118 | DEFAULT_ROUNDS = 10 119 | 120 | 121 | def start_up(verbose=False): 122 | """ Start the application """ 123 | if not verbose: 124 | print("\n[*] Starting up at {}..\n".format(time.strftime("%H:%M:%S"))) 125 | else: 126 | print("[*] Starting up at: {}({})..\n".format(str(time.time()), time.strftime("%H:%M:%S"))) 127 | 128 | 129 | def shutdown(exit_key=0, verbose=False): 130 | """ Shut down the application """ 131 | if not verbose: 132 | print('\n[*] Shutting down at {}..\n'.format(time.strftime("%H:%M:%S"))) 133 | exit(exit_key) 134 | else: 135 | print("\n[*] Shutting down at {}({})..\n".format(str(time.time()), time.strftime("%H:%M:%S"))) 136 | exit(exit_key) 137 | 138 | 139 | def convert_file_size(byte_size, magic_num=1024): 140 | """ 141 | Convert a integer to a file size (B, KB, MB, etc..) 142 | > :param byte_size: integer that is the amount of data in bytes 143 | > :param magic_num: the magic number that makes everything work, 1024 144 | > :return: the amount of data in bytes, kilobytes, megabytes, etc.. 145 | """ 146 | byte_size = float(byte_size) 147 | if byte_size == 0: 148 | return "0B" 149 | # Probably won't need more then GB, but still it's good to have 150 | size_data_names = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") 151 | floored = int(math.floor(math.log(byte_size, magic_num))) 152 | pow_data = math.pow(magic_num, floored) 153 | rounded_data = round(byte_size / pow_data, 2) 154 | return "{}{}".format(rounded_data, size_data_names[floored]) 155 | 156 | 157 | def _get_install_link(system_data): 158 | links = { 159 | "windows": "https://www.python.org/ftp/python/2.7.13/python-2.7.13.msi", 160 | "linux": "sudo apt-get install python", 161 | "other": "https://www.python.org/downloads/release/python-2713/" 162 | } 163 | for item in links.keys(): 164 | if item in system_data: 165 | return links[item] 166 | 167 | 168 | def verify_python_version(verbose=False, ver_re="2.[0-9]{1,2}.[0-9]{1,3}"): # and we're back :| 169 | """ 170 | Verify python version 171 | """ 172 | if verbose: 173 | LOGGER.debug("Verifying what version of Python you have..") 174 | current_py_version = sys.version.split(" ")[0] 175 | if not re.match(ver_re, current_py_version): 176 | LOGGER.fatal( 177 | "{filename} currently requires a Python version that is <= 2.7.x, " 178 | "you currently have Python version {version} installed. If you " 179 | "want to run {filename} please install a Python version that matches " 180 | "the above outlined requirements and re-run {filename}. You can download " 181 | "the required Python version here: {link}".format( 182 | version=current_py_version, filename=str(os.path.basename(__file__).split(".")[0].title()), 183 | link=_get_install_link(platform.platform().lower()) 184 | ) 185 | ) 186 | 187 | 188 | def show_banner(): 189 | """ 190 | Show the banner of the program 191 | 192 | > :return: banner 193 | """ 194 | print(BANNER) 195 | 196 | 197 | def show_hidden_banner(): 198 | """ 199 | Show the hidden banner (just saying and clone) 200 | 201 | > :return: a hidden banner 202 | """ 203 | print("Dagon .. {} {}\nClone: {}\n".format(SAYING, VERSION_STRING, CLONE)) 204 | 205 | 206 | def prompt(question, choices): 207 | """ 208 | Create a prompt for the user 209 | 210 | > :param question: a string containing the question needed to be answered 211 | > :param choices: a string containing choices 212 | > :return: a prompt 213 | """ 214 | try: 215 | return raw_input("[{} PROMPT] {}[{}]: ".format(time.strftime("%H:%M:%S"), question, choices)) 216 | except: # idk what the exception is, so if you know it lemme know 217 | return input("[{} PROMPT] {}[{}]: ".format(time.strftime("%H:%M:%S"), question, choices)) 218 | 219 | 220 | def download_rand_wordlist(verbose=False, multi=1, filepath="{}/lib/data_files/wordlist_links", dirname="downloads"): 221 | """ 222 | Download a random wordlist from some wordlist_links I have laying around 223 | 224 | > :param b64link: a base64 encoded wordlist link 225 | """ 226 | with open(filepath.format(os.getcwd())) as wordlist_links: 227 | if multi == 1: 228 | b64link = random.choice(wordlist_links.readlines()) 229 | filename = "Download-" + random_salt_generator(use_string=True)[0] 230 | LOGGER.info("Beginning download..") 231 | create_dir(dirname, verbose=verbose) 232 | with open("{}/{}/{}.txt".format(os.getcwd(), dirname, filename), "a+") as wordlist: 233 | response = requests.get(base64.b64decode(b64link.strip()), stream=True) 234 | total_length = response.headers.get('content-length') 235 | if verbose: 236 | LOGGER.debug("Content length to be downloaded: {}..".format(convert_file_size(int(total_length)))) 237 | LOGGER.debug("Wordlist link downloading from: '{}'..".format(b64link.strip())) 238 | if total_length is None: 239 | wordlist.write(response.content) 240 | else: 241 | start = time.time() 242 | if verbose: 243 | LOGGER.debug("Starting download at {}..".format(start)) 244 | downloaded = 0 245 | total_length = int(total_length) 246 | for data in response.iter_content(chunk_size=1024): 247 | downloaded += len(data) 248 | wordlist.write(data) 249 | done = int(50 * downloaded / total_length) 250 | sys.stdout.write("\r[\033[93m{}\033[0m{}]".format("#" * done, " " * (50-done))) 251 | sys.stdout.flush() 252 | print("") 253 | LOGGER.info("Download complete, saved under: {}/{}/{}.txt. Time elapsed: {}s".format( 254 | os.getcwd(), dirname, filename, time.time() - start 255 | )) 256 | else: 257 | if multi <= len(wordlist_links.readlines()): 258 | for _ in range(int(multi)): 259 | LOGGER.info("Downloading wordlist #{}..".format(_ + 1)) 260 | download_rand_wordlist(verbose=verbose) 261 | else: 262 | wordlist_links.seek(0) 263 | LOGGER.fatal( 264 | "There are currently {} wordlist_links available for download, and you " 265 | "have chose to download {}. Seeing as there aren't that many right now " 266 | "this download will fail, try again with a smaller number..".format(len(wordlist_links.readlines()), 267 | multi) 268 | ) 269 | 270 | 271 | def random_salt_generator(use_string=False, use_number=False, length=None, warning=True): 272 | """ 273 | Create a random string of salt to append to the beginning of a hash 274 | 275 | Example: 276 | >>> random_salt_generator(use_string=True) 277 | fUFVsatp 278 | """ 279 | try: 280 | salt_length = int(length) 281 | except TypeError: 282 | salt_length = 8 # default to 8 if length is None 283 | except ValueError: 284 | raise ValueError('length must be an integer!') # default to 8 again??? 285 | 286 | char_set = '' 287 | salt_type = [] 288 | if use_string: 289 | char_set += string.ascii_letters 290 | salt_type.append('characters') 291 | if use_number: 292 | char_set += string.digits 293 | salt_type.append('integers') 294 | if not salt_type: 295 | # if both `use_string` & `use_number` are False, default to digits 296 | if warning: 297 | LOGGER.warning("No choice given as salt, defaulting to numbers..") 298 | char_set = string.digits 299 | salt_type.append('integers') 300 | 301 | if salt_length >= 12: 302 | LOGGER.warning( 303 | "It is recommended to keep salt length under 12 {} for faster hashing..".format( 304 | ' and '.join(salt_type))) 305 | 306 | salt = ''.join(random.choice(char_set) for _ in range(salt_length)) 307 | placement = random.choice(("front", "back")) 308 | return salt, placement 309 | 310 | 311 | def match_found(data_tuple, data_sep="-" * 75, item_found="+", least_likely="-", kind="cracked", all_types=False): 312 | """ 313 | Create a banner for finding a match 314 | 315 | > :param data_tuple: tuple containing the information required 316 | > :param data_sep: what to separate the information with 317 | > :param item_found: makes it look pretty for the items 318 | > :param least_likely: makes more pretty formatting for least likely hashes 319 | """ 320 | if data_tuple is None: 321 | no_alg_err = ( 322 | "It appears that no algorithm that can match this hash has " 323 | "been implemented yet. If you feel that this is wrong, " 324 | "please make a issue regarding this, and we'll see if we " 325 | "can get it implemented.") 326 | LOGGER.fatal(no_alg_err) 327 | shutdown(1) 328 | if data_tuple[0][1] is None and all_types: 329 | LOGGER.warning("Only one possible type found for given hash..") 330 | sort_cracked = ["Clear Text: ", "Hash: ", "Tries attempted (from file): ", "Algorithm Used: "] 331 | if kind == "cracked": 332 | print(data_sep + "\n" + "[{}] Match found:\n".format(item_found) + data_sep) 333 | for i, item in enumerate(sort_cracked): 334 | print("[{}] {}{}".format(item_found, item, data_tuple[i].upper() if i == 3 else data_tuple[i])) 335 | print(data_sep) 336 | else: 337 | if all_types: 338 | data_tuple = data_tuple[0] + data_tuple[1] 339 | print(data_sep + "\n" + "[{}] Most Likely Hash Type(s):\n".format(item_found) + data_sep) 340 | for i, _ in enumerate(data_tuple): 341 | if i <= 2: 342 | if _ is not None: 343 | print("[{}] {}".format(item_found, data_tuple[i].upper())) 344 | if i == 2: 345 | print(data_sep + "\n" + 346 | "[{}] Least Likely Hash Type(s)(possibly not implemented):\n".format( 347 | least_likely) + data_sep) 348 | else: 349 | if _ is not None: 350 | print("[{}] {} {}".format(least_likely, data_tuple[i].upper(), "(not implemented yet)" if _ not in FUNC_DICT.keys() else "")) 351 | 352 | print(data_sep) 353 | else: 354 | print(data_sep + "\n" + "[{}] Most Likely Hash Types:\n".format(item_found) + data_sep) 355 | for i, _ in enumerate(data_tuple): 356 | if i <= 2: 357 | if _ is not None: 358 | print("[{}] {}".format(item_found, data_tuple[i].upper())) 359 | print(data_sep) 360 | 361 | 362 | def update_system(): 363 | """ Update Dagon to the newest development version """ 364 | if ".git" in os.listdir(os.getcwd()): 365 | can_update = True 366 | else: 367 | can_update = False 368 | if can_update: 369 | os.system("git pull origin master") 370 | return 0 371 | else: 372 | return -1 373 | 374 | 375 | def show_available_algs(show_all=False, supp="+", not_yet="-", spacer1=" "*5, spacer2=" "*3): 376 | """ Show all algorithms available in the program """ 377 | being_worked_on = [ 378 | "wordpress", "scrypt", "sha2", 379 | "dsa", "haval160", "tiger160" 380 | ] 381 | misc_info_msg = ( 382 | "There are currently {} supported algorithms in Dagon. To " 383 | "suggest the creation of a new algorithm please go make an " 384 | "issue here {}") 385 | LOGGER.info(misc_info_msg.format(len(IDENTIFICATION), DAGON_ISSUE_LINK)) 386 | print("\n{space1}ID#{space2}Alg:\n{space1}---{space2}----".format(space1=spacer1, space2=spacer2)) 387 | for item in sorted(IDENTIFICATION.keys()): 388 | print("\033[94m[{}]\033[0m {}{}{}".format( 389 | supp, item, " " * 3 if len(str(item)) == 3 else " " * 2, IDENTIFICATION[item].upper()) 390 | ) 391 | if show_all: 392 | print("\nNot implemented yet:") 393 | for item in sorted(being_worked_on): 394 | print("\033[91m[{}]\033[0m {}".format(not_yet, item.upper())) 395 | 396 | 397 | def algorithm_pointers(pointer_identity): 398 | """ Point to the correct algorithm given by an identification number """ 399 | try: 400 | return IDENTIFICATION[int(pointer_identity)] 401 | except TypeError: 402 | return None 403 | except (KeyError, ValueError): 404 | LOGGER.fatal("The algorithm identification number you have specified is invalid.") 405 | LOGGER.debug("Valid identification numbers are: {}".format(IDENTIFICATION)) 406 | 407 | 408 | def integrity_check(url="https://raw.githubusercontent.com/Ekultek/Dagon/master/md5sum/checksum.md5", 409 | path="{}/md5sum/checksum.md5"): 410 | """ Check the integrity of the program """ 411 | LOGGER.info("Checking program integrity...") 412 | if open(path.format(os.getcwd())).read() != requests.get(url).text: 413 | checksum_fail = ( 414 | "MD5 sums did not match from origin master, integrity check" 415 | " has failed, this could be because there is a new version " 416 | "available. Please check for a new version and download " 417 | "that ({}), or be sure that you have not changed any of the" 418 | " applications code.") 419 | LOGGER.fatal(checksum_fail.format("https://github.com/ekultek/dagon.git")) 420 | shutdown(-1) 421 | return True 422 | 423 | 424 | def create_dir(dirname, verbose=False): 425 | """ 426 | Create a directory if it does not exist 427 | :param dirname: name of the directory 428 | """ 429 | if not os.path.exists(dirname): 430 | if verbose: 431 | LOGGER.debug("Directory '{}/*' not found, creating it..".format(dirname)) 432 | os.mkdir(dirname) 433 | else: 434 | if verbose: 435 | LOGGER.debug("Directory found, skipping..") 436 | 437 | 438 | def create_file_list(directory=None, cmd_line=None, verbose=False): 439 | """ 440 | Create a list of files to use either from the terminal line or from a directory 441 | 442 | > :param directory: full path to a directory 443 | > :param cmd_line: the string given from the command line 444 | > :param verbose: verbosity run 445 | > :return: a list 446 | 447 | Example: 448 | >>> create_file_list(directory=True) 449 | ['test.txt', 'testing.txt', 'tests.txt'] 450 | """ 451 | if directory is not None: 452 | if verbose: LOGGER.debug("Searching '{}'..".format(directory)) 453 | file_list = os.listdir(directory) 454 | if verbose: LOGGER.debug("Found '{}', with a total of {} files..".format(file_list, len(file_list))) 455 | else: 456 | file_list = cmd_line.split(",") 457 | if verbose: LOGGER.debug("Found a total of {} files to use..".format(len(file_list))) 458 | return file_list 459 | 460 | 461 | def hash_guarantee(hashed_string): 462 | """ This will be asked if Dagon fails to find a hash to match yours. """ 463 | question = prompt( 464 | "Dagon comes with a hash guarantee, if Dagon is unable to crack " 465 | "your hash successfully, Ekultek will personally attempt to crack " 466 | "your hash for you. Would you like to automatically create a Github " 467 | "issue containing your hash", "y/N" 468 | ) 469 | if question.lower().startswith("y"): 470 | LOGGER.warning("`hash_guarantee` has been turned off for the time being") 471 | # request_connection(hashed_string) 472 | 473 | 474 | def auto_issue(hashed_string, error, issue): 475 | """ automatically create a Github issue from a given exception """ 476 | question = prompt( 477 | "Dagon has encountered an unhandled exception, would you like to " 478 | "anonymously create a Github issue and get this patched", "y/N" 479 | ) 480 | if question.lower().startswith("y"): 481 | dagon_failure(issue, hashed_string, error) 482 | 483 | 484 | def force_encoding(word, enc="utf-8"): 485 | """ 486 | Force the encoding of a string, this will help with reading from files that 487 | contain unicode characters. 488 | 489 | > :param word: word to be encoded 490 | > :param enc: the encoding to use 491 | > :return: a string encoded into UTF-8 492 | """ 493 | if type(word.strip()) == unicode: 494 | return word.strip().encode(enc) 495 | -------------------------------------------------------------------------------- /dagon.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import optparse 4 | import os 5 | import random 6 | import subprocess 7 | import sys 8 | import time 9 | import traceback 10 | 11 | from bin.verify_hashes.verify import verify_hash_type 12 | from bin.generators import Generators 13 | from bin.attacks.bruteforce.bf_attack import ( 14 | bruteforce_main, 15 | ) 16 | from lib.settings import ( 17 | LOGGER, 18 | VERSION_STRING, 19 | DEFAULT_ROUNDS, 20 | algorithm_pointers, 21 | download_rand_wordlist, 22 | integrity_check, 23 | match_found, 24 | prompt, 25 | random_salt_generator, 26 | show_available_algs, 27 | show_banner, 28 | show_hidden_banner, 29 | start_up, shutdown, 30 | update_system, 31 | verify_python_version, 32 | create_dir, create_file_list, 33 | hash_guarantee, 34 | auto_issue 35 | ) 36 | 37 | if __name__ == '__main__': 38 | 39 | # # # # # # # # # 40 | # DO NOT REMOVE THIS 41 | # I don't know how, I don't know why, but this fixes pretty much 42 | # all of the `ascii can't decode byte` errors. This has to be the 43 | # very first thing done in order for some of the hashes to work 44 | # successfully. Once again, I don't know how or why it works, 45 | # but it works. 46 | reload(sys) 47 | sys.setdefaultencoding("utf8") 48 | # # # # # # # # # # 49 | 50 | parser = optparse.OptionParser(usage="dagon [c|v|V|l] HASH|HASH-LIST --bruteforce [OPTS]") 51 | 52 | # Mandatory arguments, required for program to run 53 | mandatory = optparse.OptionGroup(parser, "Mandatory arguments", 54 | description="These arguments are mandatory to run the application") 55 | mandatory.add_option("-c", "--crack", dest="hashToCrack", metavar="HASH", 56 | help="Specify a hash to crack") 57 | mandatory.add_option("-l", "--hash-list", dest="hashListToCrack", metavar="FILE-PATH", 58 | help="Provide a file of hashes to crack") 59 | mandatory.add_option("-v", "--verify", dest="verifyHashType", metavar="HASH", 60 | help="Attempt to find the type of algorithm used given a specified hash.") 61 | mandatory.add_option("-V", "--verify-list", dest="verifyHashList", metavar="PATH", 62 | help="Run through a file containing hashes (one per line) and attempt to verify them") 63 | 64 | # Specific arguments, what do you want the program to do? 65 | tech = optparse.OptionGroup(parser, "Technique arguments", 66 | description="These arguments tell the program what to do technique wise.") 67 | tech.add_option("-b", "--bruteforce", action="store_true", dest="bruteforceCrack", 68 | help="Attempt to bruteforce a given hash") 69 | tech.add_option("-r", "--rainbow", dest="rainbowTableAttack", metavar="FILE-PATH", 70 | help=optparse.SUPPRESS_HELP) # Not implemented yet TODO:// 71 | 72 | # Manipulation arguments to manipulate the hashes into what you want them to be 73 | manipulation = optparse.OptionGroup(parser, "Manipulation arguments", 74 | description="These arguments can manipulate the hashes") 75 | manipulation.add_option("-S", "--salt", dest="saltToUseAndPlacement", nargs=2, metavar="SALT, PLACEMENT", 76 | help="Choose your salt and placement to use in the hashing") 77 | manipulation.add_option("-R", "--rand-salt", dest="randomSaltAndPlacement", action="store_true", 78 | help="Randomly generate the salt and the placement to put the salt in") 79 | manipulation.add_option("-A", "--algorithm", dest="algToUse", metavar="ALGORITHM-IDENTIFIER", 80 | help="Specify what algorithm to use for cracking") 81 | manipulation.add_option("--use-chars", dest="useCharsAsSalt", action="store_true", 82 | help="Use random characters for the salt") 83 | manipulation.add_option("--use-int", dest="useIntAsSalt", action="store_true", 84 | help="Use random integers as the salt, default if no option is given") 85 | manipulation.add_option("--salt-size", dest="saltSizeToUse", metavar="SALT-LENGTH", 86 | help="Choose how long you want your salt to be") 87 | manipulation.add_option("--urandom", dest="useURandomSaltAndRandomPlacement", metavar="LENGTH", 88 | help="Use random bytes as the salt, randomness is based on your OS.") 89 | manipulation.add_option("--posx", dest="returnThisPartOfHash", metavar="POSITION", 90 | help="Choose which part of the hashes you want to return, " 91 | "only valid for half algorithms functions") 92 | manipulation.add_option("--use-hex", action="store_true", dest="useHexCodeNotHash", 93 | help="Use the CRC32/CRC64 hexcode instead of the hash"), 94 | manipulation.add_option("--rounds", dest="useRounds", metavar="# OF ROUNDS (default 10)", type=int, 95 | help="Specify a number of rounds to use for the hashing") 96 | 97 | # Manipulate your dictionary attacks with these options 98 | dictionary_attack_opts = optparse.OptionGroup(parser, "Dictionary attack arguments", 99 | description="These are the options available to manipulate your " 100 | "dict attacks") 101 | dictionary_attack_opts.add_option("-w", "--wordlist", dest="wordListToUse", metavar="FILE-PATH", 102 | help="Specify a wordlist to do the cracking with") 103 | dictionary_attack_opts.add_option("-W", "--multi-wordlist", dest="multiWordLists", metavar="WORDLISTS", 104 | help="Use multiple wordlists at a time to do the cracking seperated by" 105 | " a comma, IE 'test.txt, testing.txt'") 106 | dictionary_attack_opts.add_option("-D", "--use-dir", dest="useDirForWordlists", metavar="DIRECTORY-PATH", 107 | help="Pass a directory to use every file in the specified " 108 | "directory as a wordlist") 109 | dictionary_attack_opts.add_option("--download", dest="downloadWordList", action="store_true", 110 | help="Download a random wordlist") 111 | dictionary_attack_opts.add_option("--download-x", dest="downloadMultiple", metavar="AMOUNT", type=int, 112 | help="Download multiple wordlists at a time") 113 | 114 | # Misc arguments that you can give to the program 115 | misc = optparse.OptionGroup(parser, "Miscellaneous arguments", 116 | description="Misc arguments that can be given to help with processing") 117 | misc.add_option("-L", "--least-likely", dest="displayLeastLikely", action="store_true", 118 | help="Display the least likely hash types during verification") 119 | misc.add_option("-B", "--benchmark", dest="runBenchMarkTest", action="store_true", 120 | help="Find out how long it took to finish the process by timing the application") 121 | misc.add_option("-H", "--hash-file", dest="createHashFile", metavar="FILENAME", 122 | help='Parse a singular file or a series of files separated by commas for hashes. ' 123 | 'IE -F "test.txt, testing.txt" or -F test.txt') 124 | misc.add_option("-I", "--integrity-check", action="store_true", dest="testProgramIntegrity", 125 | help="Run an integrity check on the program, this can be used to check for updates," 126 | "check if the program md5sums match, or just to check your internet connection") 127 | misc.add_option("--banner", action="store_true", dest="hideBanner", 128 | help="Display the full Dagon banner") 129 | misc.add_option("--update", dest="updateDagon", action="store_true", 130 | help="Update the program to the latest development version") 131 | misc.add_option("--avail-algs", action="store_true", dest="showAvailableAlgorithms", 132 | help="Show all available algorithms that are currently functional.") 133 | misc.add_option("--all-algs", action="store_true", dest="showAllAlgorithms", 134 | help="Use in conjunction with --avail-algs to show future supported algorithms") 135 | misc.add_option("--version", action="store_true", dest="displayVersionInfo", 136 | help="Display the version information and exit.") 137 | misc.add_option("--batch", action="store_true", dest="runInBatchMode", 138 | help="Run in batch and skip the questions") 139 | misc.add_option("--verbose", action="store_true", dest="runInVerbose", 140 | help="Run the application verbosely") 141 | 142 | parser.add_option_group(mandatory) 143 | parser.add_option_group(manipulation) 144 | parser.add_option_group(dictionary_attack_opts) 145 | parser.add_option_group(tech) 146 | parser.add_option_group(misc) 147 | 148 | # Pay no attention to the _ it's required.. 149 | opt, _ = parser.parse_args() 150 | 151 | verify_python_version(verbose=opt.runInVerbose) # need this again :| 152 | 153 | required_args = ["-c", "--crack", 154 | "-l", "--hash-list", 155 | "-v", "--verify", 156 | "-V", "--verify-list"] 157 | args_in_params = 0 158 | 159 | show_banner() if opt.hideBanner else show_hidden_banner() 160 | 161 | if len(sys.argv) <= 1: 162 | LOGGER.fatal("You have failed to provide a flag to the application and have been redirected to the help menu.") 163 | time.sleep(1.7) 164 | subprocess.call("python dagon.py --help", shell=True) 165 | else: 166 | try: 167 | if opt.testProgramIntegrity: 168 | status = integrity_check() 169 | if status: 170 | LOGGER.info( 171 | "Integrity check has passed successfully, there are no updates " 172 | "available at the moment and you are running the latest version." 173 | ) 174 | exit(0) 175 | 176 | # Download a random wordlist 177 | if opt.downloadWordList or opt.downloadMultiple: 178 | download_rand_wordlist(verbose=opt.runInVerbose, 179 | multi=opt.downloadMultiple if opt.downloadMultiple is not None else 1) 180 | exit(0) 181 | 182 | # Output all supported algorithms 183 | if opt.showAvailableAlgorithms: 184 | show_available_algs(show_all=opt.showAllAlgorithms) 185 | exit(0) 186 | 187 | # Display the version and exit 188 | if opt.displayVersionInfo: 189 | LOGGER.info(VERSION_STRING) 190 | exit(0) 191 | 192 | # Update Dagon 193 | if opt.updateDagon: 194 | LOGGER.info("Update in progress..") 195 | update_status = update_system() 196 | if update_status == 0: 197 | pass 198 | else: 199 | LOGGER.fatal("No git repository found in path..") 200 | exit(0) 201 | 202 | # create a hash list from a given file or a series of given files 203 | # for this to work effectively when passing multiple files you must 204 | # enclose them in quotes and separate them by commas, IE -H "test.txt, testing.txt". 205 | # This will parse the given file for anything pertaining to a hash and save it 206 | # under a new file. You can then pass that file to the program 207 | if opt.createHashFile: 208 | files_to_process = opt.createHashFile 209 | hash_file_name = "hash-file-{}.hash".format(random_salt_generator(use_string=True)[0]) 210 | create_dir("{}/hash_files".format(os.getcwd()), verbose=opt.runInVerbose) 211 | full_hash_path = "{}/{}/{}".format(os.getcwd(), "hash_files", hash_file_name) 212 | with open(full_hash_path, "a+") as filename: 213 | if len(files_to_process.split(",")) > 1: 214 | LOGGER.info("Found multiple files to process: '{}'..".format(files_to_process)) 215 | for f in files_to_process.split(","): 216 | try: 217 | for item in Generators(f.strip()).hash_file_generator(): 218 | filename.write(item.strip() + "\n") 219 | except IOError: 220 | LOGGER.warning("Provided file '{}' does not exist, skipping..".format(f.strip())) 221 | continue 222 | else: 223 | LOGGER.info("Reading from singular file '{}'...".format(files_to_process)) 224 | for item in Generators(opt.createHashFile).hash_file_generator(): 225 | filename.write(item.strip() + "\n") 226 | 227 | if not open(full_hash_path).readlines(): 228 | LOGGER.warning("No processable hashes found in '{}'..".format(files_to_process)) 229 | else: 230 | LOGGER.info("Created file '{}' under '{}'..".format(hash_file_name, full_hash_path)) 231 | exit(0) 232 | 233 | # Check that you provided a mandatory argument 234 | for i, _ in enumerate(sys.argv): 235 | if sys.argv[i] in required_args: 236 | args_in_params += 1 237 | 238 | # If you provided an argument continue.. 239 | if args_in_params > 0: 240 | 241 | start_up(verbose=opt.runInVerbose) 242 | 243 | # Show the options being used at the time of the run if verbose is True 244 | if opt.runInVerbose: 245 | opts_being_used = [] 246 | for o, v in opt.__dict__.items(): 247 | if v is not None: 248 | opts_being_used.append((o, v)) 249 | LOGGER.debug("Options being used: {}..".format(dict(opts_being_used))) 250 | 251 | # Benchmark testing 252 | if opt.runBenchMarkTest: 253 | start_time = time.time() 254 | 255 | # Creating random salts and random placements 256 | if opt.randomSaltAndPlacement: 257 | salt, placement = random_salt_generator(opt.useCharsAsSalt, opt.useIntAsSalt, 258 | opt.saltSizeToUse) 259 | LOGGER.info("Using random salt: '{}' and random placement: '{}'...".format(salt, placement)) 260 | 261 | # If you provided your own salt and your own placements 262 | elif opt.saltToUseAndPlacement is not None: 263 | salt, placement = opt.saltToUseAndPlacement[0], opt.saltToUseAndPlacement[1].lower() 264 | LOGGER.info("Using salt: '{}' on the '{}' of the hash...".format(salt, placement)) 265 | 266 | # Unicode random salt and placement 267 | elif opt.useURandomSaltAndRandomPlacement is not None: 268 | salt, placement = str(os.urandom(int(opt.useURandomSaltAndRandomPlacement))), random.choice( 269 | ["front", "back"]) 270 | LOGGER.info("Using urandom salt: '{}' on the '{}' of the hash...".format(salt, placement)) 271 | 272 | # No salt or placement 273 | else: 274 | salt, placement = None, None 275 | 276 | # Bruteforce this shit 277 | if opt.bruteforceCrack and opt.hashToCrack is not None and opt.hashListToCrack is None: 278 | if opt.useRounds is not None and opt.useRounds > DEFAULT_ROUNDS: 279 | LOGGER.warning("Keep in mind, the more rounds, the slower the algorithm..") 280 | try: 281 | if opt.multiWordLists is not None: 282 | file_list = create_file_list(cmd_line=opt.multiWordLists, verbose=opt.runInVerbose) 283 | for item in file_list: 284 | bruteforce_main(opt.hashToCrack, algorithm=algorithm_pointers(opt.algToUse), 285 | wordlist=item.strip(), salt=salt, placement=placement, 286 | posx=opt.returnThisPartOfHash, 287 | use_hex=opt.useHexCodeNotHash, verbose=opt.runInVerbose, 288 | batch=opt.runInBatchMode, rounds=opt.useRounds or DEFAULT_ROUNDS) 289 | elif opt.useDirForWordlists is not None: 290 | file_list = create_file_list(directory=opt.useDirForWordlists, verbose=opt.runInVerbose) 291 | for item in file_list: 292 | bruteforce_main(opt.hashToCrack, algorithm=algorithm_pointers(opt.algToUse), 293 | wordlist="{}/{}".format(opt.useDirForWordlists, item.strip()), 294 | salt=salt, placement=placement, 295 | posx=opt.returnThisPartOfHash, 296 | use_hex=opt.useHexCodeNotHash, verbose=opt.runInVerbose, 297 | batch=opt.runInBatchMode, rounds=opt.useRounds or DEFAULT_ROUNDS) 298 | else: 299 | bruteforce_main(opt.hashToCrack, algorithm=algorithm_pointers(opt.algToUse), 300 | wordlist=opt.wordListToUse, 301 | salt=salt, placement=placement, posx=opt.returnThisPartOfHash, 302 | use_hex=opt.useHexCodeNotHash, verbose=opt.runInVerbose, 303 | batch=opt.runInBatchMode, rounds=opt.useRounds or DEFAULT_ROUNDS) 304 | except KeyError as e: 305 | LOGGER.fatal("It seems that algorithm is not implemented yet: {}..".format(e)) 306 | # hash_guarantee(opt.hashToCrack) 307 | LOGGER.warning("`hash_guarantee` has been turned off for the time being") 308 | shutdown(-1) 309 | except UnicodeError as e: 310 | LOGGER.fatal( 311 | "{} ran into a '{}' with arguments: '{}' and further information: '{}'\n\n" 312 | "These kinds of errors usually happen when you are trying to read from " 313 | "a file that contains Unicode characters in it. Run dagon in verbose " 314 | "(--verbose) and post all the output from the verbose mode in an issue.".format( 315 | os.path.basename(__file__), type(e), e.args, traceback.format_exception( 316 | e, e.args, e.message 317 | 318 | ) 319 | ) 320 | ) 321 | auto_issue(opt.hashToCrack, e, e.message) 322 | except Exception as e: 323 | LOGGER.fatal("{} failed with error code: '{}'.".format(os.path.basename(__file__), e)) 324 | auto_issue(opt.hashToCrack, e, e.message) 325 | 326 | # Bruteforce a list of hashes 327 | elif opt.bruteforceCrack and opt.hashListToCrack is not None and opt.hashToCrack is None: 328 | try: 329 | with open(opt.hashListToCrack) as hashes: 330 | for i, hash_to_crack in enumerate(hashes.readlines(), start=1): 331 | if opt.runInBatchMode: 332 | crack_or_not = "y" 333 | else: 334 | crack_or_not = prompt("Attempt to crack: '{}'".format(hash_to_crack.strip()), "y/N") 335 | 336 | if crack_or_not.startswith(("y", "Y")): 337 | LOGGER.info("Cracking hash number {}..".format(i)) 338 | bruteforce_main(hash_to_crack.strip(), algorithm=algorithm_pointers(opt.algToUse), 339 | wordlist=opt.wordListToUse, salt=salt, 340 | placement=placement, posx=opt.returnThisPartOfHash, 341 | use_hex=opt.useHexCodeNotHash, verbose=opt.runInVerbose, 342 | rounds=opt.useRounds) 343 | 344 | print("\n") 345 | except Exception as e: 346 | LOGGER.fatal("Failed with error code: '{}'. Check the file and try again..".format(e)) 347 | auto_issue("None, used list", e, e.message) 348 | 349 | # TODO:/ create rainbow attacks 350 | 351 | # Verify a given hash to see what type of algorithm might have been used 352 | elif opt.verifyHashType is not None: 353 | LOGGER.info("Analyzing given hash: '{}'...".format(opt.verifyHashType)) 354 | match_found(verify_hash_type(opt.verifyHashType, least_likely=opt.displayLeastLikely), kind="else", 355 | all_types=opt.displayLeastLikely) 356 | 357 | # Verify a file of hashes, one per line 358 | elif opt.verifyHashList is not None: 359 | with open(opt.verifyHashList) as hashes: 360 | hashes.seek(0, 0) 361 | total_hashes = hashes.readlines() 362 | LOGGER.info("Found a total of {} hashes to verify..".format(len(total_hashes))) 363 | for h in total_hashes: 364 | print("") 365 | LOGGER.info("Analyzing hash: '{}'".format(h.strip())) 366 | if opt.runInBatchMode: 367 | q = "y" 368 | else: 369 | q = prompt("Attempt to verify hash '{}'".format(h.strip()), "y/N") 370 | 371 | if q.startswith(("y", "Y")): 372 | match_found(verify_hash_type(h.strip(), least_likely=opt.displayLeastLikely), 373 | kind="else", 374 | all_types=opt.displayLeastLikely) 375 | 376 | # Finish the benchmark test 377 | if opt.runBenchMarkTest: 378 | stop_time = time.time() 379 | LOGGER.info("Time elapsed during benchmark test: {} seconds".format(stop_time - start_time)) 380 | 381 | shutdown(verbose=opt.runInVerbose) 382 | 383 | # You never provided a mandatory argument 384 | else: 385 | LOGGER.fatal("Missing mandatory argument, redirecting to help menu..") 386 | subprocess.call("python dagon.py --help", shell=True) 387 | 388 | # Why you gotta interrupt my awesome? 389 | except KeyboardInterrupt: 390 | LOGGER.fatal("User exited process...") 391 | # TODO:/ Pause/resume function''' 392 | -------------------------------------------------------------------------------- /thirdparty/tiger/sboxes.py: -------------------------------------------------------------------------------- 1 | t1 = [ 0x02AAB17CF7E90C5E , 0xAC424B03E243A8EC , 2 | 0x72CD5BE30DD5FCD3 , 0x6D019B93F6F97F3A , 3 | 0xCD9978FFD21F9193 , 0x7573A1C9708029E2 , 4 | 0xB164326B922A83C3 , 0x46883EEE04915870 , 5 | 0xEAACE3057103ECE6 , 0xC54169B808A3535C , 6 | 0x4CE754918DDEC47C , 0x0AA2F4DFDC0DF40C , 7 | 0x10B76F18A74DBEFA , 0xC6CCB6235AD1AB6A , 8 | 0x13726121572FE2FF , 0x1A488C6F199D921E , 9 | 0x4BC9F9F4DA0007CA , 0x26F5E6F6E85241C7 , 10 | 0x859079DBEA5947B6 , 0x4F1885C5C99E8C92 , 11 | 0xD78E761EA96F864B , 0x8E36428C52B5C17D , 12 | 0x69CF6827373063C1 , 0xB607C93D9BB4C56E , 13 | 0x7D820E760E76B5EA , 0x645C9CC6F07FDC42 , 14 | 0xBF38A078243342E0 , 0x5F6B343C9D2E7D04 , 15 | 0xF2C28AEB600B0EC6 , 0x6C0ED85F7254BCAC , 16 | 0x71592281A4DB4FE5 , 0x1967FA69CE0FED9F , 17 | 0xFD5293F8B96545DB , 0xC879E9D7F2A7600B , 18 | 0x860248920193194E , 0xA4F9533B2D9CC0B3 , 19 | 0x9053836C15957613 , 0xDB6DCF8AFC357BF1 , 20 | 0x18BEEA7A7A370F57 , 0x037117CA50B99066 , 21 | 0x6AB30A9774424A35 , 0xF4E92F02E325249B , 22 | 0x7739DB07061CCAE1 , 0xD8F3B49CECA42A05 , 23 | 0xBD56BE3F51382F73 , 0x45FAED5843B0BB28 , 24 | 0x1C813D5C11BF1F83 , 0x8AF0E4B6D75FA169 , 25 | 0x33EE18A487AD9999 , 0x3C26E8EAB1C94410 , 26 | 0xB510102BC0A822F9 , 0x141EEF310CE6123B , 27 | 0xFC65B90059DDB154 , 0xE0158640C5E0E607 , 28 | 0x884E079826C3A3CF , 0x930D0D9523C535FD , 29 | 0x35638D754E9A2B00 , 0x4085FCCF40469DD5 , 30 | 0xC4B17AD28BE23A4C , 0xCAB2F0FC6A3E6A2E , 31 | 0x2860971A6B943FCD , 0x3DDE6EE212E30446 , 32 | 0x6222F32AE01765AE , 0x5D550BB5478308FE , 33 | 0xA9EFA98DA0EDA22A , 0xC351A71686C40DA7 , 34 | 0x1105586D9C867C84 , 0xDCFFEE85FDA22853 , 35 | 0xCCFBD0262C5EEF76 , 0xBAF294CB8990D201 , 36 | 0xE69464F52AFAD975 , 0x94B013AFDF133E14 , 37 | 0x06A7D1A32823C958 , 0x6F95FE5130F61119 , 38 | 0xD92AB34E462C06C0 , 0xED7BDE33887C71D2 , 39 | 0x79746D6E6518393E , 0x5BA419385D713329 , 40 | 0x7C1BA6B948A97564 , 0x31987C197BFDAC67 , 41 | 0xDE6C23C44B053D02 , 0x581C49FED002D64D , 42 | 0xDD474D6338261571 , 0xAA4546C3E473D062 , 43 | 0x928FCE349455F860 , 0x48161BBACAAB94D9 , 44 | 0x63912430770E6F68 , 0x6EC8A5E602C6641C , 45 | 0x87282515337DDD2B , 0x2CDA6B42034B701B , 46 | 0xB03D37C181CB096D , 0xE108438266C71C6F , 47 | 0x2B3180C7EB51B255 , 0xDF92B82F96C08BBC , 48 | 0x5C68C8C0A632F3BA , 0x5504CC861C3D0556 , 49 | 0xABBFA4E55FB26B8F , 0x41848B0AB3BACEB4 , 50 | 0xB334A273AA445D32 , 0xBCA696F0A85AD881 , 51 | 0x24F6EC65B528D56C , 0x0CE1512E90F4524A , 52 | 0x4E9DD79D5506D35A , 0x258905FAC6CE9779 , 53 | 0x2019295B3E109B33 , 0xF8A9478B73A054CC , 54 | 0x2924F2F934417EB0 , 0x3993357D536D1BC4 , 55 | 0x38A81AC21DB6FF8B , 0x47C4FBF17D6016BF , 56 | 0x1E0FAADD7667E3F5 , 0x7ABCFF62938BEB96 , 57 | 0xA78DAD948FC179C9 , 0x8F1F98B72911E50D , 58 | 0x61E48EAE27121A91 , 0x4D62F7AD31859808 , 59 | 0xECEBA345EF5CEAEB , 0xF5CEB25EBC9684CE , 60 | 0xF633E20CB7F76221 , 0xA32CDF06AB8293E4 , 61 | 0x985A202CA5EE2CA4 , 0xCF0B8447CC8A8FB1 , 62 | 0x9F765244979859A3 , 0xA8D516B1A1240017 , 63 | 0x0BD7BA3EBB5DC726 , 0xE54BCA55B86ADB39 , 64 | 0x1D7A3AFD6C478063 , 0x519EC608E7669EDD , 65 | 0x0E5715A2D149AA23 , 0x177D4571848FF194 , 66 | 0xEEB55F3241014C22 , 0x0F5E5CA13A6E2EC2 , 67 | 0x8029927B75F5C361 , 0xAD139FABC3D6E436 , 68 | 0x0D5DF1A94CCF402F , 0x3E8BD948BEA5DFC8 , 69 | 0xA5A0D357BD3FF77E , 0xA2D12E251F74F645 , 70 | 0x66FD9E525E81A082 , 0x2E0C90CE7F687A49 , 71 | 0xC2E8BCBEBA973BC5 , 0x000001BCE509745F , 72 | 0x423777BBE6DAB3D6 , 0xD1661C7EAEF06EB5 , 73 | 0xA1781F354DAACFD8 , 0x2D11284A2B16AFFC , 74 | 0xF1FC4F67FA891D1F , 0x73ECC25DCB920ADA , 75 | 0xAE610C22C2A12651 , 0x96E0A810D356B78A , 76 | 0x5A9A381F2FE7870F , 0xD5AD62EDE94E5530 , 77 | 0xD225E5E8368D1427 , 0x65977B70C7AF4631 , 78 | 0x99F889B2DE39D74F , 0x233F30BF54E1D143 , 79 | 0x9A9675D3D9A63C97 , 0x5470554FF334F9A8 , 80 | 0x166ACB744A4F5688 , 0x70C74CAAB2E4AEAD , 81 | 0xF0D091646F294D12 , 0x57B82A89684031D1 , 82 | 0xEFD95A5A61BE0B6B , 0x2FBD12E969F2F29A , 83 | 0x9BD37013FEFF9FE8 , 0x3F9B0404D6085A06 , 84 | 0x4940C1F3166CFE15 , 0x09542C4DCDF3DEFB , 85 | 0xB4C5218385CD5CE3 , 0xC935B7DC4462A641 , 86 | 0x3417F8A68ED3B63F , 0xB80959295B215B40 , 87 | 0xF99CDAEF3B8C8572 , 0x018C0614F8FCB95D , 88 | 0x1B14ACCD1A3ACDF3 , 0x84D471F200BB732D , 89 | 0xC1A3110E95E8DA16 , 0x430A7220BF1A82B8 , 90 | 0xB77E090D39DF210E , 0x5EF4BD9F3CD05E9D , 91 | 0x9D4FF6DA7E57A444 , 0xDA1D60E183D4A5F8 , 92 | 0xB287C38417998E47 , 0xFE3EDC121BB31886 , 93 | 0xC7FE3CCC980CCBEF , 0xE46FB590189BFD03 , 94 | 0x3732FD469A4C57DC , 0x7EF700A07CF1AD65 , 95 | 0x59C64468A31D8859 , 0x762FB0B4D45B61F6 , 96 | 0x155BAED099047718 , 0x68755E4C3D50BAA6 , 97 | 0xE9214E7F22D8B4DF , 0x2ADDBF532EAC95F4 , 98 | 0x32AE3909B4BD0109 , 0x834DF537B08E3450 , 99 | 0xFA209DA84220728D , 0x9E691D9B9EFE23F7 , 100 | 0x0446D288C4AE8D7F , 0x7B4CC524E169785B , 101 | 0x21D87F0135CA1385 , 0xCEBB400F137B8AA5 , 102 | 0x272E2B66580796BE , 0x3612264125C2B0DE , 103 | 0x057702BDAD1EFBB2 , 0xD4BABB8EACF84BE9 , 104 | 0x91583139641BC67B , 0x8BDC2DE08036E024 , 105 | 0x603C8156F49F68ED , 0xF7D236F7DBEF5111 , 106 | 0x9727C4598AD21E80 , 0xA08A0896670A5FD7 , 107 | 0xCB4A8F4309EBA9CB , 0x81AF564B0F7036A1 , 108 | 0xC0B99AA778199ABD , 0x959F1EC83FC8E952 , 109 | 0x8C505077794A81B9 , 0x3ACAAF8F056338F0 , 110 | 0x07B43F50627A6778 , 0x4A44AB49F5ECCC77 , 111 | 0x3BC3D6E4B679EE98 , 0x9CC0D4D1CF14108C , 112 | 0x4406C00B206BC8A0 , 0x82A18854C8D72D89 , 113 | 0x67E366B35C3C432C , 0xB923DD61102B37F2 , 114 | 0x56AB2779D884271D , 0xBE83E1B0FF1525AF , 115 | 0xFB7C65D4217E49A9 , 0x6BDBE0E76D48E7D4 , 116 | 0x08DF828745D9179E , 0x22EA6A9ADD53BD34 , 117 | 0xE36E141C5622200A , 0x7F805D1B8CB750EE , 118 | 0xAFE5C7A59F58E837 , 0xE27F996A4FB1C23C , 119 | 0xD3867DFB0775F0D0 , 0xD0E673DE6E88891A , 120 | 0x123AEB9EAFB86C25 , 0x30F1D5D5C145B895 , 121 | 0xBB434A2DEE7269E7 , 0x78CB67ECF931FA38 , 122 | 0xF33B0372323BBF9C , 0x52D66336FB279C74 , 123 | 0x505F33AC0AFB4EAA , 0xE8A5CD99A2CCE187 , 124 | 0x534974801E2D30BB , 0x8D2D5711D5876D90 , 125 | 0x1F1A412891BC038E , 0xD6E2E71D82E56648 , 126 | 0x74036C3A497732B7 , 0x89B67ED96361F5AB , 127 | 0xFFED95D8F1EA02A2 , 0xE72B3BD61464D43D , 128 | 0xA6300F170BDC4820 , 0xEBC18760ED78A77A ] 129 | 130 | t2 = [ 0xE6A6BE5A05A12138 , 0xB5A122A5B4F87C98 , 131 | 0x563C6089140B6990 , 0x4C46CB2E391F5DD5 , 132 | 0xD932ADDBC9B79434 , 0x08EA70E42015AFF5 , 133 | 0xD765A6673E478CF1 , 0xC4FB757EAB278D99 , 134 | 0xDF11C6862D6E0692 , 0xDDEB84F10D7F3B16 , 135 | 0x6F2EF604A665EA04 , 0x4A8E0F0FF0E0DFB3 , 136 | 0xA5EDEEF83DBCBA51 , 0xFC4F0A2A0EA4371E , 137 | 0xE83E1DA85CB38429 , 0xDC8FF882BA1B1CE2 , 138 | 0xCD45505E8353E80D , 0x18D19A00D4DB0717 , 139 | 0x34A0CFEDA5F38101 , 0x0BE77E518887CAF2 , 140 | 0x1E341438B3C45136 , 0xE05797F49089CCF9 , 141 | 0xFFD23F9DF2591D14 , 0x543DDA228595C5CD , 142 | 0x661F81FD99052A33 , 0x8736E641DB0F7B76 , 143 | 0x15227725418E5307 , 0xE25F7F46162EB2FA , 144 | 0x48A8B2126C13D9FE , 0xAFDC541792E76EEA , 145 | 0x03D912BFC6D1898F , 0x31B1AAFA1B83F51B , 146 | 0xF1AC2796E42AB7D9 , 0x40A3A7D7FCD2EBAC , 147 | 0x1056136D0AFBBCC5 , 0x7889E1DD9A6D0C85 , 148 | 0xD33525782A7974AA , 0xA7E25D09078AC09B , 149 | 0xBD4138B3EAC6EDD0 , 0x920ABFBE71EB9E70 , 150 | 0xA2A5D0F54FC2625C , 0xC054E36B0B1290A3 , 151 | 0xF6DD59FF62FE932B , 0x3537354511A8AC7D , 152 | 0xCA845E9172FADCD4 , 0x84F82B60329D20DC , 153 | 0x79C62CE1CD672F18 , 0x8B09A2ADD124642C , 154 | 0xD0C1E96A19D9E726 , 0x5A786A9B4BA9500C , 155 | 0x0E020336634C43F3 , 0xC17B474AEB66D822 , 156 | 0x6A731AE3EC9BAAC2 , 0x8226667AE0840258 , 157 | 0x67D4567691CAECA5 , 0x1D94155C4875ADB5 , 158 | 0x6D00FD985B813FDF , 0x51286EFCB774CD06 , 159 | 0x5E8834471FA744AF , 0xF72CA0AEE761AE2E , 160 | 0xBE40E4CDAEE8E09A , 0xE9970BBB5118F665 , 161 | 0x726E4BEB33DF1964 , 0x703B000729199762 , 162 | 0x4631D816F5EF30A7 , 0xB880B5B51504A6BE , 163 | 0x641793C37ED84B6C , 0x7B21ED77F6E97D96 , 164 | 0x776306312EF96B73 , 0xAE528948E86FF3F4 , 165 | 0x53DBD7F286A3F8F8 , 0x16CADCE74CFC1063 , 166 | 0x005C19BDFA52C6DD , 0x68868F5D64D46AD3 , 167 | 0x3A9D512CCF1E186A , 0x367E62C2385660AE , 168 | 0xE359E7EA77DCB1D7 , 0x526C0773749ABE6E , 169 | 0x735AE5F9D09F734B , 0x493FC7CC8A558BA8 , 170 | 0xB0B9C1533041AB45 , 0x321958BA470A59BD , 171 | 0x852DB00B5F46C393 , 0x91209B2BD336B0E5 , 172 | 0x6E604F7D659EF19F , 0xB99A8AE2782CCB24 , 173 | 0xCCF52AB6C814C4C7 , 0x4727D9AFBE11727B , 174 | 0x7E950D0C0121B34D , 0x756F435670AD471F , 175 | 0xF5ADD442615A6849 , 0x4E87E09980B9957A , 176 | 0x2ACFA1DF50AEE355 , 0xD898263AFD2FD556 , 177 | 0xC8F4924DD80C8FD6 , 0xCF99CA3D754A173A , 178 | 0xFE477BACAF91BF3C , 0xED5371F6D690C12D , 179 | 0x831A5C285E687094 , 0xC5D3C90A3708A0A4 , 180 | 0x0F7F903717D06580 , 0x19F9BB13B8FDF27F , 181 | 0xB1BD6F1B4D502843 , 0x1C761BA38FFF4012 , 182 | 0x0D1530C4E2E21F3B , 0x8943CE69A7372C8A , 183 | 0xE5184E11FEB5CE66 , 0x618BDB80BD736621 , 184 | 0x7D29BAD68B574D0B , 0x81BB613E25E6FE5B , 185 | 0x071C9C10BC07913F , 0xC7BEEB7909AC2D97 , 186 | 0xC3E58D353BC5D757 , 0xEB017892F38F61E8 , 187 | 0xD4EFFB9C9B1CC21A , 0x99727D26F494F7AB , 188 | 0xA3E063A2956B3E03 , 0x9D4A8B9A4AA09C30 , 189 | 0x3F6AB7D500090FB4 , 0x9CC0F2A057268AC0 , 190 | 0x3DEE9D2DEDBF42D1 , 0x330F49C87960A972 , 191 | 0xC6B2720287421B41 , 0x0AC59EC07C00369C , 192 | 0xEF4EAC49CB353425 , 0xF450244EEF0129D8 , 193 | 0x8ACC46E5CAF4DEB6 , 0x2FFEAB63989263F7 , 194 | 0x8F7CB9FE5D7A4578 , 0x5BD8F7644E634635 , 195 | 0x427A7315BF2DC900 , 0x17D0C4AA2125261C , 196 | 0x3992486C93518E50 , 0xB4CBFEE0A2D7D4C3 , 197 | 0x7C75D6202C5DDD8D , 0xDBC295D8E35B6C61 , 198 | 0x60B369D302032B19 , 0xCE42685FDCE44132 , 199 | 0x06F3DDB9DDF65610 , 0x8EA4D21DB5E148F0 , 200 | 0x20B0FCE62FCD496F , 0x2C1B912358B0EE31 , 201 | 0xB28317B818F5A308 , 0xA89C1E189CA6D2CF , 202 | 0x0C6B18576AAADBC8 , 0xB65DEAA91299FAE3 , 203 | 0xFB2B794B7F1027E7 , 0x04E4317F443B5BEB , 204 | 0x4B852D325939D0A6 , 0xD5AE6BEEFB207FFC , 205 | 0x309682B281C7D374 , 0xBAE309A194C3B475 , 206 | 0x8CC3F97B13B49F05 , 0x98A9422FF8293967 , 207 | 0x244B16B01076FF7C , 0xF8BF571C663D67EE , 208 | 0x1F0D6758EEE30DA1 , 0xC9B611D97ADEB9B7 , 209 | 0xB7AFD5887B6C57A2 , 0x6290AE846B984FE1 , 210 | 0x94DF4CDEACC1A5FD , 0x058A5BD1C5483AFF , 211 | 0x63166CC142BA3C37 , 0x8DB8526EB2F76F40 , 212 | 0xE10880036F0D6D4E , 0x9E0523C9971D311D , 213 | 0x45EC2824CC7CD691 , 0x575B8359E62382C9 , 214 | 0xFA9E400DC4889995 , 0xD1823ECB45721568 , 215 | 0xDAFD983B8206082F , 0xAA7D29082386A8CB , 216 | 0x269FCD4403B87588 , 0x1B91F5F728BDD1E0 , 217 | 0xE4669F39040201F6 , 0x7A1D7C218CF04ADE , 218 | 0x65623C29D79CE5CE , 0x2368449096C00BB1 , 219 | 0xAB9BF1879DA503BA , 0xBC23ECB1A458058E , 220 | 0x9A58DF01BB401ECC , 0xA070E868A85F143D , 221 | 0x4FF188307DF2239E , 0x14D565B41A641183 , 222 | 0xEE13337452701602 , 0x950E3DCF3F285E09 , 223 | 0x59930254B9C80953 , 0x3BF299408930DA6D , 224 | 0xA955943F53691387 , 0xA15EDECAA9CB8784 , 225 | 0x29142127352BE9A0 , 0x76F0371FFF4E7AFB , 226 | 0x0239F450274F2228 , 0xBB073AF01D5E868B , 227 | 0xBFC80571C10E96C1 , 0xD267088568222E23 , 228 | 0x9671A3D48E80B5B0 , 0x55B5D38AE193BB81 , 229 | 0x693AE2D0A18B04B8 , 0x5C48B4ECADD5335F , 230 | 0xFD743B194916A1CA , 0x2577018134BE98C4 , 231 | 0xE77987E83C54A4AD , 0x28E11014DA33E1B9 , 232 | 0x270CC59E226AA213 , 0x71495F756D1A5F60 , 233 | 0x9BE853FB60AFEF77 , 0xADC786A7F7443DBF , 234 | 0x0904456173B29A82 , 0x58BC7A66C232BD5E , 235 | 0xF306558C673AC8B2 , 0x41F639C6B6C9772A , 236 | 0x216DEFE99FDA35DA , 0x11640CC71C7BE615 , 237 | 0x93C43694565C5527 , 0xEA038E6246777839 , 238 | 0xF9ABF3CE5A3E2469 , 0x741E768D0FD312D2 , 239 | 0x0144B883CED652C6 , 0xC20B5A5BA33F8552 , 240 | 0x1AE69633C3435A9D , 0x97A28CA4088CFDEC , 241 | 0x8824A43C1E96F420 , 0x37612FA66EEEA746 , 242 | 0x6B4CB165F9CF0E5A , 0x43AA1C06A0ABFB4A , 243 | 0x7F4DC26FF162796B , 0x6CBACC8E54ED9B0F , 244 | 0xA6B7FFEFD2BB253E , 0x2E25BC95B0A29D4F , 245 | 0x86D6A58BDEF1388C , 0xDED74AC576B6F054 , 246 | 0x8030BDBC2B45805D , 0x3C81AF70E94D9289 , 247 | 0x3EFF6DDA9E3100DB , 0xB38DC39FDFCC8847 , 248 | 0x123885528D17B87E , 0xF2DA0ED240B1B642 , 249 | 0x44CEFADCD54BF9A9 , 0x1312200E433C7EE6 , 250 | 0x9FFCC84F3A78C748 , 0xF0CD1F72248576BB , 251 | 0xEC6974053638CFE4 , 0x2BA7B67C0CEC4E4C , 252 | 0xAC2F4DF3E5CE32ED , 0xCB33D14326EA4C11 , 253 | 0xA4E9044CC77E58BC , 0x5F513293D934FCEF , 254 | 0x5DC9645506E55444 , 0x50DE418F317DE40A , 255 | 0x388CB31A69DDE259 , 0x2DB4A83455820A86 , 256 | 0x9010A91E84711AE9 , 0x4DF7F0B7B1498371 , 257 | 0xD62A2EABC0977179 , 0x22FAC097AA8D5C0E ] 258 | 259 | t3 = [ 0xF49FCC2FF1DAF39B , 0x487FD5C66FF29281 , 260 | 0xE8A30667FCDCA83F , 0x2C9B4BE3D2FCCE63 , 261 | 0xDA3FF74B93FBBBC2 , 0x2FA165D2FE70BA66 , 262 | 0xA103E279970E93D4 , 0xBECDEC77B0E45E71 , 263 | 0xCFB41E723985E497 , 0xB70AAA025EF75017 , 264 | 0xD42309F03840B8E0 , 0x8EFC1AD035898579 , 265 | 0x96C6920BE2B2ABC5 , 0x66AF4163375A9172 , 266 | 0x2174ABDCCA7127FB , 0xB33CCEA64A72FF41 , 267 | 0xF04A4933083066A5 , 0x8D970ACDD7289AF5 , 268 | 0x8F96E8E031C8C25E , 0xF3FEC02276875D47 , 269 | 0xEC7BF310056190DD , 0xF5ADB0AEBB0F1491 , 270 | 0x9B50F8850FD58892 , 0x4975488358B74DE8 , 271 | 0xA3354FF691531C61 , 0x0702BBE481D2C6EE , 272 | 0x89FB24057DEDED98 , 0xAC3075138596E902 , 273 | 0x1D2D3580172772ED , 0xEB738FC28E6BC30D , 274 | 0x5854EF8F63044326 , 0x9E5C52325ADD3BBE , 275 | 0x90AA53CF325C4623 , 0xC1D24D51349DD067 , 276 | 0x2051CFEEA69EA624 , 0x13220F0A862E7E4F , 277 | 0xCE39399404E04864 , 0xD9C42CA47086FCB7 , 278 | 0x685AD2238A03E7CC , 0x066484B2AB2FF1DB , 279 | 0xFE9D5D70EFBF79EC , 0x5B13B9DD9C481854 , 280 | 0x15F0D475ED1509AD , 0x0BEBCD060EC79851 , 281 | 0xD58C6791183AB7F8 , 0xD1187C5052F3EEE4 , 282 | 0xC95D1192E54E82FF , 0x86EEA14CB9AC6CA2 , 283 | 0x3485BEB153677D5D , 0xDD191D781F8C492A , 284 | 0xF60866BAA784EBF9 , 0x518F643BA2D08C74 , 285 | 0x8852E956E1087C22 , 0xA768CB8DC410AE8D , 286 | 0x38047726BFEC8E1A , 0xA67738B4CD3B45AA , 287 | 0xAD16691CEC0DDE19 , 0xC6D4319380462E07 , 288 | 0xC5A5876D0BA61938 , 0x16B9FA1FA58FD840 , 289 | 0x188AB1173CA74F18 , 0xABDA2F98C99C021F , 290 | 0x3E0580AB134AE816 , 0x5F3B05B773645ABB , 291 | 0x2501A2BE5575F2F6 , 0x1B2F74004E7E8BA9 , 292 | 0x1CD7580371E8D953 , 0x7F6ED89562764E30 , 293 | 0xB15926FF596F003D , 0x9F65293DA8C5D6B9 , 294 | 0x6ECEF04DD690F84C , 0x4782275FFF33AF88 , 295 | 0xE41433083F820801 , 0xFD0DFE409A1AF9B5 , 296 | 0x4325A3342CDB396B , 0x8AE77E62B301B252 , 297 | 0xC36F9E9F6655615A , 0x85455A2D92D32C09 , 298 | 0xF2C7DEA949477485 , 0x63CFB4C133A39EBA , 299 | 0x83B040CC6EBC5462 , 0x3B9454C8FDB326B0 , 300 | 0x56F56A9E87FFD78C , 0x2DC2940D99F42BC6 , 301 | 0x98F7DF096B096E2D , 0x19A6E01E3AD852BF , 302 | 0x42A99CCBDBD4B40B , 0xA59998AF45E9C559 , 303 | 0x366295E807D93186 , 0x6B48181BFAA1F773 , 304 | 0x1FEC57E2157A0A1D , 0x4667446AF6201AD5 , 305 | 0xE615EBCACFB0F075 , 0xB8F31F4F68290778 , 306 | 0x22713ED6CE22D11E , 0x3057C1A72EC3C93B , 307 | 0xCB46ACC37C3F1F2F , 0xDBB893FD02AAF50E , 308 | 0x331FD92E600B9FCF , 0xA498F96148EA3AD6 , 309 | 0xA8D8426E8B6A83EA , 0xA089B274B7735CDC , 310 | 0x87F6B3731E524A11 , 0x118808E5CBC96749 , 311 | 0x9906E4C7B19BD394 , 0xAFED7F7E9B24A20C , 312 | 0x6509EADEEB3644A7 , 0x6C1EF1D3E8EF0EDE , 313 | 0xB9C97D43E9798FB4 , 0xA2F2D784740C28A3 , 314 | 0x7B8496476197566F , 0x7A5BE3E6B65F069D , 315 | 0xF96330ED78BE6F10 , 0xEEE60DE77A076A15 , 316 | 0x2B4BEE4AA08B9BD0 , 0x6A56A63EC7B8894E , 317 | 0x02121359BA34FEF4 , 0x4CBF99F8283703FC , 318 | 0x398071350CAF30C8 , 0xD0A77A89F017687A , 319 | 0xF1C1A9EB9E423569 , 0x8C7976282DEE8199 , 320 | 0x5D1737A5DD1F7ABD , 0x4F53433C09A9FA80 , 321 | 0xFA8B0C53DF7CA1D9 , 0x3FD9DCBC886CCB77 , 322 | 0xC040917CA91B4720 , 0x7DD00142F9D1DCDF , 323 | 0x8476FC1D4F387B58 , 0x23F8E7C5F3316503 , 324 | 0x032A2244E7E37339 , 0x5C87A5D750F5A74B , 325 | 0x082B4CC43698992E , 0xDF917BECB858F63C , 326 | 0x3270B8FC5BF86DDA , 0x10AE72BB29B5DD76 , 327 | 0x576AC94E7700362B , 0x1AD112DAC61EFB8F , 328 | 0x691BC30EC5FAA427 , 0xFF246311CC327143 , 329 | 0x3142368E30E53206 , 0x71380E31E02CA396 , 330 | 0x958D5C960AAD76F1 , 0xF8D6F430C16DA536 , 331 | 0xC8FFD13F1BE7E1D2 , 0x7578AE66004DDBE1 , 332 | 0x05833F01067BE646 , 0xBB34B5AD3BFE586D , 333 | 0x095F34C9A12B97F0 , 0x247AB64525D60CA8 , 334 | 0xDCDBC6F3017477D1 , 0x4A2E14D4DECAD24D , 335 | 0xBDB5E6D9BE0A1EEB , 0x2A7E70F7794301AB , 336 | 0xDEF42D8A270540FD , 0x01078EC0A34C22C1 , 337 | 0xE5DE511AF4C16387 , 0x7EBB3A52BD9A330A , 338 | 0x77697857AA7D6435 , 0x004E831603AE4C32 , 339 | 0xE7A21020AD78E312 , 0x9D41A70C6AB420F2 , 340 | 0x28E06C18EA1141E6 , 0xD2B28CBD984F6B28 , 341 | 0x26B75F6C446E9D83 , 0xBA47568C4D418D7F , 342 | 0xD80BADBFE6183D8E , 0x0E206D7F5F166044 , 343 | 0xE258A43911CBCA3E , 0x723A1746B21DC0BC , 344 | 0xC7CAA854F5D7CDD3 , 0x7CAC32883D261D9C , 345 | 0x7690C26423BA942C , 0x17E55524478042B8 , 346 | 0xE0BE477656A2389F , 0x4D289B5E67AB2DA0 , 347 | 0x44862B9C8FBBFD31 , 0xB47CC8049D141365 , 348 | 0x822C1B362B91C793 , 0x4EB14655FB13DFD8 , 349 | 0x1ECBBA0714E2A97B , 0x6143459D5CDE5F14 , 350 | 0x53A8FBF1D5F0AC89 , 0x97EA04D81C5E5B00 , 351 | 0x622181A8D4FDB3F3 , 0xE9BCD341572A1208 , 352 | 0x1411258643CCE58A , 0x9144C5FEA4C6E0A4 , 353 | 0x0D33D06565CF620F , 0x54A48D489F219CA1 , 354 | 0xC43E5EAC6D63C821 , 0xA9728B3A72770DAF , 355 | 0xD7934E7B20DF87EF , 0xE35503B61A3E86E5 , 356 | 0xCAE321FBC819D504 , 0x129A50B3AC60BFA6 , 357 | 0xCD5E68EA7E9FB6C3 , 0xB01C90199483B1C7 , 358 | 0x3DE93CD5C295376C , 0xAED52EDF2AB9AD13 , 359 | 0x2E60F512C0A07884 , 0xBC3D86A3E36210C9 , 360 | 0x35269D9B163951CE , 0x0C7D6E2AD0CDB5FA , 361 | 0x59E86297D87F5733 , 0x298EF221898DB0E7 , 362 | 0x55000029D1A5AA7E , 0x8BC08AE1B5061B45 , 363 | 0xC2C31C2B6C92703A , 0x94CC596BAF25EF42 , 364 | 0x0A1D73DB22540456 , 0x04B6A0F9D9C4179A , 365 | 0xEFFDAFA2AE3D3C60 , 0xF7C8075BB49496C4 , 366 | 0x9CC5C7141D1CD4E3 , 0x78BD1638218E5534 , 367 | 0xB2F11568F850246A , 0xEDFABCFA9502BC29 , 368 | 0x796CE5F2DA23051B , 0xAAE128B0DC93537C , 369 | 0x3A493DA0EE4B29AE , 0xB5DF6B2C416895D7 , 370 | 0xFCABBD25122D7F37 , 0x70810B58105DC4B1 , 371 | 0xE10FDD37F7882A90 , 0x524DCAB5518A3F5C , 372 | 0x3C9E85878451255B , 0x4029828119BD34E2 , 373 | 0x74A05B6F5D3CECCB , 0xB610021542E13ECA , 374 | 0x0FF979D12F59E2AC , 0x6037DA27E4F9CC50 , 375 | 0x5E92975A0DF1847D , 0xD66DE190D3E623FE , 376 | 0x5032D6B87B568048 , 0x9A36B7CE8235216E , 377 | 0x80272A7A24F64B4A , 0x93EFED8B8C6916F7 , 378 | 0x37DDBFF44CCE1555 , 0x4B95DB5D4B99BD25 , 379 | 0x92D3FDA169812FC0 , 0xFB1A4A9A90660BB6 , 380 | 0x730C196946A4B9B2 , 0x81E289AA7F49DA68 , 381 | 0x64669A0F83B1A05F , 0x27B3FF7D9644F48B , 382 | 0xCC6B615C8DB675B3 , 0x674F20B9BCEBBE95 , 383 | 0x6F31238275655982 , 0x5AE488713E45CF05 , 384 | 0xBF619F9954C21157 , 0xEABAC46040A8EAE9 , 385 | 0x454C6FE9F2C0C1CD , 0x419CF6496412691C , 386 | 0xD3DC3BEF265B0F70 , 0x6D0E60F5C3578A9E ] 387 | 388 | t4 = [ 0x5B0E608526323C55 , 0x1A46C1A9FA1B59F5 , 389 | 0xA9E245A17C4C8FFA , 0x65CA5159DB2955D7 , 390 | 0x05DB0A76CE35AFC2 , 0x81EAC77EA9113D45 , 391 | 0x528EF88AB6AC0A0D , 0xA09EA253597BE3FF , 392 | 0x430DDFB3AC48CD56 , 0xC4B3A67AF45CE46F , 393 | 0x4ECECFD8FBE2D05E , 0x3EF56F10B39935F0 , 394 | 0x0B22D6829CD619C6 , 0x17FD460A74DF2069 , 395 | 0x6CF8CC8E8510ED40 , 0xD6C824BF3A6ECAA7 , 396 | 0x61243D581A817049 , 0x048BACB6BBC163A2 , 397 | 0xD9A38AC27D44CC32 , 0x7FDDFF5BAAF410AB , 398 | 0xAD6D495AA804824B , 0xE1A6A74F2D8C9F94 , 399 | 0xD4F7851235DEE8E3 , 0xFD4B7F886540D893 , 400 | 0x247C20042AA4BFDA , 0x096EA1C517D1327C , 401 | 0xD56966B4361A6685 , 0x277DA5C31221057D , 402 | 0x94D59893A43ACFF7 , 0x64F0C51CCDC02281 , 403 | 0x3D33BCC4FF6189DB , 0xE005CB184CE66AF1 , 404 | 0xFF5CCD1D1DB99BEA , 0xB0B854A7FE42980F , 405 | 0x7BD46A6A718D4B9F , 0xD10FA8CC22A5FD8C , 406 | 0xD31484952BE4BD31 , 0xC7FA975FCB243847 , 407 | 0x4886ED1E5846C407 , 0x28CDDB791EB70B04 , 408 | 0xC2B00BE2F573417F , 0x5C9590452180F877 , 409 | 0x7A6BDDFFF370EB00 , 0xCE509E38D6D9D6A4 , 410 | 0xEBEB0F00647FA702 , 0x1DCC06CF76606F06 , 411 | 0xE4D9F28BA286FF0A , 0xD85A305DC918C262 , 412 | 0x475B1D8732225F54 , 0x2D4FB51668CCB5FE , 413 | 0xA679B9D9D72BBA20 , 0x53841C0D912D43A5 , 414 | 0x3B7EAA48BF12A4E8 , 0x781E0E47F22F1DDF , 415 | 0xEFF20CE60AB50973 , 0x20D261D19DFFB742 , 416 | 0x16A12B03062A2E39 , 0x1960EB2239650495 , 417 | 0x251C16FED50EB8B8 , 0x9AC0C330F826016E , 418 | 0xED152665953E7671 , 0x02D63194A6369570 , 419 | 0x5074F08394B1C987 , 0x70BA598C90B25CE1 , 420 | 0x794A15810B9742F6 , 0x0D5925E9FCAF8C6C , 421 | 0x3067716CD868744E , 0x910AB077E8D7731B , 422 | 0x6A61BBDB5AC42F61 , 0x93513EFBF0851567 , 423 | 0xF494724B9E83E9D5 , 0xE887E1985C09648D , 424 | 0x34B1D3C675370CFD , 0xDC35E433BC0D255D , 425 | 0xD0AAB84234131BE0 , 0x08042A50B48B7EAF , 426 | 0x9997C4EE44A3AB35 , 0x829A7B49201799D0 , 427 | 0x263B8307B7C54441 , 0x752F95F4FD6A6CA6 , 428 | 0x927217402C08C6E5 , 0x2A8AB754A795D9EE , 429 | 0xA442F7552F72943D , 0x2C31334E19781208 , 430 | 0x4FA98D7CEAEE6291 , 0x55C3862F665DB309 , 431 | 0xBD0610175D53B1F3 , 0x46FE6CB840413F27 , 432 | 0x3FE03792DF0CFA59 , 0xCFE700372EB85E8F , 433 | 0xA7BE29E7ADBCE118 , 0xE544EE5CDE8431DD , 434 | 0x8A781B1B41F1873E , 0xA5C94C78A0D2F0E7 , 435 | 0x39412E2877B60728 , 0xA1265EF3AFC9A62C , 436 | 0xBCC2770C6A2506C5 , 0x3AB66DD5DCE1CE12 , 437 | 0xE65499D04A675B37 , 0x7D8F523481BFD216 , 438 | 0x0F6F64FCEC15F389 , 0x74EFBE618B5B13C8 , 439 | 0xACDC82B714273E1D , 0xDD40BFE003199D17 , 440 | 0x37E99257E7E061F8 , 0xFA52626904775AAA , 441 | 0x8BBBF63A463D56F9 , 0xF0013F1543A26E64 , 442 | 0xA8307E9F879EC898 , 0xCC4C27A4150177CC , 443 | 0x1B432F2CCA1D3348 , 0xDE1D1F8F9F6FA013 , 444 | 0x606602A047A7DDD6 , 0xD237AB64CC1CB2C7 , 445 | 0x9B938E7225FCD1D3 , 0xEC4E03708E0FF476 , 446 | 0xFEB2FBDA3D03C12D , 0xAE0BCED2EE43889A , 447 | 0x22CB8923EBFB4F43 , 0x69360D013CF7396D , 448 | 0x855E3602D2D4E022 , 0x073805BAD01F784C , 449 | 0x33E17A133852F546 , 0xDF4874058AC7B638 , 450 | 0xBA92B29C678AA14A , 0x0CE89FC76CFAADCD , 451 | 0x5F9D4E0908339E34 , 0xF1AFE9291F5923B9 , 452 | 0x6E3480F60F4A265F , 0xEEBF3A2AB29B841C , 453 | 0xE21938A88F91B4AD , 0x57DFEFF845C6D3C3 , 454 | 0x2F006B0BF62CAAF2 , 0x62F479EF6F75EE78 , 455 | 0x11A55AD41C8916A9 , 0xF229D29084FED453 , 456 | 0x42F1C27B16B000E6 , 0x2B1F76749823C074 , 457 | 0x4B76ECA3C2745360 , 0x8C98F463B91691BD , 458 | 0x14BCC93CF1ADE66A , 0x8885213E6D458397 , 459 | 0x8E177DF0274D4711 , 0xB49B73B5503F2951 , 460 | 0x10168168C3F96B6B , 0x0E3D963B63CAB0AE , 461 | 0x8DFC4B5655A1DB14 , 0xF789F1356E14DE5C , 462 | 0x683E68AF4E51DAC1 , 0xC9A84F9D8D4B0FD9 , 463 | 0x3691E03F52A0F9D1 , 0x5ED86E46E1878E80 , 464 | 0x3C711A0E99D07150 , 0x5A0865B20C4E9310 , 465 | 0x56FBFC1FE4F0682E , 0xEA8D5DE3105EDF9B , 466 | 0x71ABFDB12379187A , 0x2EB99DE1BEE77B9C , 467 | 0x21ECC0EA33CF4523 , 0x59A4D7521805C7A1 , 468 | 0x3896F5EB56AE7C72 , 0xAA638F3DB18F75DC , 469 | 0x9F39358DABE9808E , 0xB7DEFA91C00B72AC , 470 | 0x6B5541FD62492D92 , 0x6DC6DEE8F92E4D5B , 471 | 0x353F57ABC4BEEA7E , 0x735769D6DA5690CE , 472 | 0x0A234AA642391484 , 0xF6F9508028F80D9D , 473 | 0xB8E319A27AB3F215 , 0x31AD9C1151341A4D , 474 | 0x773C22A57BEF5805 , 0x45C7561A07968633 , 475 | 0xF913DA9E249DBE36 , 0xDA652D9B78A64C68 , 476 | 0x4C27A97F3BC334EF , 0x76621220E66B17F4 , 477 | 0x967743899ACD7D0B , 0xF3EE5BCAE0ED6782 , 478 | 0x409F753600C879FC , 0x06D09A39B5926DB6 , 479 | 0x6F83AEB0317AC588 , 0x01E6CA4A86381F21 , 480 | 0x66FF3462D19F3025 , 0x72207C24DDFD3BFB , 481 | 0x4AF6B6D3E2ECE2EB , 0x9C994DBEC7EA08DE , 482 | 0x49ACE597B09A8BC4 , 0xB38C4766CF0797BA , 483 | 0x131B9373C57C2A75 , 0xB1822CCE61931E58 , 484 | 0x9D7555B909BA1C0C , 0x127FAFDD937D11D2 , 485 | 0x29DA3BADC66D92E4 , 0xA2C1D57154C2ECBC , 486 | 0x58C5134D82F6FE24 , 0x1C3AE3515B62274F , 487 | 0xE907C82E01CB8126 , 0xF8ED091913E37FCB , 488 | 0x3249D8F9C80046C9 , 0x80CF9BEDE388FB63 , 489 | 0x1881539A116CF19E , 0x5103F3F76BD52457 , 490 | 0x15B7E6F5AE47F7A8 , 0xDBD7C6DED47E9CCF , 491 | 0x44E55C410228BB1A , 0xB647D4255EDB4E99 , 492 | 0x5D11882BB8AAFC30 , 0xF5098BBB29D3212A , 493 | 0x8FB5EA14E90296B3 , 0x677B942157DD025A , 494 | 0xFB58E7C0A390ACB5 , 0x89D3674C83BD4A01 , 495 | 0x9E2DA4DF4BF3B93B , 0xFCC41E328CAB4829 , 496 | 0x03F38C96BA582C52 , 0xCAD1BDBD7FD85DB2 , 497 | 0xBBB442C16082AE83 , 0xB95FE86BA5DA9AB0 , 498 | 0xB22E04673771A93F , 0x845358C9493152D8 , 499 | 0xBE2A488697B4541E , 0x95A2DC2DD38E6966 , 500 | 0xC02C11AC923C852B , 0x2388B1990DF2A87B , 501 | 0x7C8008FA1B4F37BE , 0x1F70D0C84D54E503 , 502 | 0x5490ADEC7ECE57D4 , 0x002B3C27D9063A3A , 503 | 0x7EAEA3848030A2BF , 0xC602326DED2003C0 , 504 | 0x83A7287D69A94086 , 0xC57A5FCB30F57A8A , 505 | 0xB56844E479EBE779 , 0xA373B40F05DCBCE9 , 506 | 0xD71A786E88570EE2 , 0x879CBACDBDE8F6A0 , 507 | 0x976AD1BCC164A32F , 0xAB21E25E9666D78B , 508 | 0x901063AAE5E5C33C , 0x9818B34448698D90 , 509 | 0xE36487AE3E1E8ABB , 0xAFBDF931893BDCB4 , 510 | 0x6345A0DC5FBBD519 , 0x8628FE269B9465CA , 511 | 0x1E5D01603F9C51EC , 0x4DE44006A15049B7 , 512 | 0xBF6C70E5F776CBB1 , 0x411218F2EF552BED , 513 | 0xCB0C0708705A36A3 , 0xE74D14754F986044 , 514 | 0xCD56D9430EA8280E , 0xC12591D7535F5065 , 515 | 0xC83223F1720AEF96 , 0xC3A0396F7363A51F ] 516 | -------------------------------------------------------------------------------- /thirdparty/des/pydes.py: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Documentation # 3 | ############################################################################# 4 | 5 | # Author: Todd Whiteman 6 | # Date: 16th March, 2009 7 | # Version: 2.0.1 8 | # License: Public Domain - free to do as you wish 9 | # Homepage: http://twhiteman.netfirms.com/des.html 10 | # 11 | # This is a pure python implementation of the DES encryption algorithm. 12 | # It's pure python to avoid portability issues, since most DES 13 | # implementations are programmed in C (for performance reasons). 14 | # 15 | # Triple DES class is also implemented, utilising the DES base. Triple DES 16 | # is either DES-EDE3 with a 24 byte key, or DES-EDE2 with a 16 byte key. 17 | # 18 | # See the README.txt that should come with this python module for the 19 | # implementation methods used. 20 | # 21 | # Thanks to: 22 | # * David Broadwell for ideas, comments and suggestions. 23 | # * Mario Wolff for pointing out and debugging some triple des CBC errors. 24 | # * Santiago Palladino for providing the PKCS5 padding technique. 25 | # * Shaya for correcting the PAD_PKCS5 triple des CBC errors. 26 | # 27 | """A pure python implementation of the DES and TRIPLE DES encryption algorithms. 28 | Class initialization 29 | -------------------- 30 | pyDes.des(key, [mode], [IV], [pad], [padmode]) 31 | pyDes.triple_des(key, [mode], [IV], [pad], [padmode]) 32 | key -> Bytes containing the encryption key. 8 bytes for DES, 16 or 24 bytes 33 | for Triple DES 34 | mode -> Optional argument for encryption type, can be either 35 | pyDes.ECB (Electronic Code Book) or pyDes.CBC (Cypher Block Chaining) 36 | IV -> Optional Initial Value bytes, must be supplied if using CBC mode. 37 | Length must be 8 bytes. 38 | pad -> Optional argument, set the pad character (PAD_NORMAL) to use during 39 | all encrypt/decrpt operations done with this instance. 40 | padmode -> Optional argument, set the padding mode (PAD_NORMAL or PAD_PKCS5) 41 | to use during all encrypt/decrpt operations done with this instance. 42 | I recommend to use PAD_PKCS5 padding, as then you never need to worry about any 43 | padding issues, as the padding can be removed unambiguously upon decrypting 44 | data that was encrypted using PAD_PKCS5 padmode. 45 | Common methods 46 | -------------- 47 | encrypt(data, [pad], [padmode]) 48 | decrypt(data, [pad], [padmode]) 49 | data -> Bytes to be encrypted/decrypted 50 | pad -> Optional argument. Only when using padmode of PAD_NORMAL. For 51 | encryption, adds this characters to the end of the data block when 52 | data is not a multiple of 8 bytes. For decryption, will remove the 53 | trailing characters that match this pad character from the last 8 54 | bytes of the unencrypted data block. 55 | padmode -> Optional argument, set the padding mode, must be one of PAD_NORMAL 56 | or PAD_PKCS5). Defaults to PAD_NORMAL. 57 | Example 58 | ------- 59 | from pyDes import * 60 | data = "Please encrypt my data" 61 | k = des("DESCRYPT", CBC, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) 62 | # For Python3, you'll need to use bytes, i.e.: 63 | # data = b"Please encrypt my data" 64 | # k = des(b"DESCRYPT", CBC, b"\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) 65 | d = k.encrypt(data) 66 | print "Encrypted: %r" % d 67 | print "Decrypted: %r" % k.decrypt(d) 68 | assert k.decrypt(d, padmode=PAD_PKCS5) == data 69 | See the module source (pyDes.py) for more examples of use. 70 | You can also run the pyDes.py file without and arguments to see a simple test. 71 | Note: This code was not written for high-end systems needing a fast 72 | implementation, but rather a handy portable solution with small usage. 73 | """ 74 | 75 | import sys 76 | 77 | # _pythonMajorVersion is used to handle Python2 and Python3 differences. 78 | _pythonMajorVersion = sys.version_info[0] 79 | 80 | # Modes of crypting / cyphering 81 | ECB = 0 82 | CBC = 1 83 | 84 | # Modes of padding 85 | PAD_NORMAL = 1 86 | PAD_PKCS5 = 2 87 | 88 | # PAD_PKCS5: is a method that will unambiguously remove all padding 89 | # characters after decryption, when originally encrypted with 90 | # this padding mode. 91 | # For a good description of the PKCS5 padding technique, see: 92 | # http://www.faqs.org/rfcs/rfc1423.html 93 | 94 | # The base class shared by des and triple des. 95 | class _baseDes(object): 96 | def __init__(self, mode=ECB, IV=None, pad=None, padmode=PAD_NORMAL): 97 | if IV: 98 | IV = self._guardAgainstUnicode(IV) 99 | if pad: 100 | pad = self._guardAgainstUnicode(pad) 101 | self.block_size = 8 102 | # Sanity checking of arguments. 103 | if pad and padmode == PAD_PKCS5: 104 | raise ValueError("Cannot use a pad character with PAD_PKCS5") 105 | if IV and len(IV) != self.block_size: 106 | raise ValueError("Invalid Initial Value (IV), must be a multiple of " + str(self.block_size) + " bytes") 107 | 108 | # Set the passed in variables 109 | self._mode = mode 110 | self._iv = IV 111 | self._padding = pad 112 | self._padmode = padmode 113 | 114 | def getKey(self): 115 | """getKey() -> bytes""" 116 | return self.__key 117 | 118 | def setKey(self, key): 119 | """Will set the crypting key for this object.""" 120 | key = self._guardAgainstUnicode(key) 121 | self.__key = key 122 | 123 | def getMode(self): 124 | """getMode() -> pyDes.ECB or pyDes.CBC""" 125 | return self._mode 126 | 127 | def setMode(self, mode): 128 | """Sets the type of crypting mode, pyDes.ECB or pyDes.CBC""" 129 | self._mode = mode 130 | 131 | def getPadding(self): 132 | """getPadding() -> bytes of length 1. Padding character.""" 133 | return self._padding 134 | 135 | def setPadding(self, pad): 136 | """setPadding() -> bytes of length 1. Padding character.""" 137 | if pad is not None: 138 | pad = self._guardAgainstUnicode(pad) 139 | self._padding = pad 140 | 141 | def getPadMode(self): 142 | """getPadMode() -> pyDes.PAD_NORMAL or pyDes.PAD_PKCS5""" 143 | return self._padmode 144 | 145 | def setPadMode(self, mode): 146 | """Sets the type of padding mode, pyDes.PAD_NORMAL or pyDes.PAD_PKCS5""" 147 | self._padmode = mode 148 | 149 | def getIV(self): 150 | """getIV() -> bytes""" 151 | return self._iv 152 | 153 | def setIV(self, IV): 154 | """Will set the Initial Value, used in conjunction with CBC mode""" 155 | if not IV or len(IV) != self.block_size: 156 | raise ValueError("Invalid Initial Value (IV), must be a multiple of " + str(self.block_size) + " bytes") 157 | IV = self._guardAgainstUnicode(IV) 158 | self._iv = IV 159 | 160 | def _padData(self, data, pad, padmode): 161 | # Pad data depending on the mode 162 | if padmode is None: 163 | # Get the default padding mode. 164 | padmode = self.getPadMode() 165 | if pad and padmode == PAD_PKCS5: 166 | raise ValueError("Cannot use a pad character with PAD_PKCS5") 167 | 168 | if padmode == PAD_NORMAL: 169 | if len(data) % self.block_size == 0: 170 | # No padding required. 171 | return data 172 | 173 | if not pad: 174 | # Get the default padding. 175 | pad = self.getPadding() 176 | if not pad: 177 | raise ValueError("Data must be a multiple of " + str(self.block_size) + " bytes in length. Use padmode=PAD_PKCS5 or set the pad character.") 178 | data += (self.block_size - (len(data) % self.block_size)) * pad 179 | 180 | elif padmode == PAD_PKCS5: 181 | pad_len = 8 - (len(data) % self.block_size) 182 | if _pythonMajorVersion < 3: 183 | data += pad_len * chr(pad_len) 184 | else: 185 | data += bytes([pad_len] * pad_len) 186 | 187 | return data 188 | 189 | def _unpadData(self, data, pad, padmode): 190 | # Unpad data depending on the mode. 191 | if not data: 192 | return data 193 | if pad and padmode == PAD_PKCS5: 194 | raise ValueError("Cannot use a pad character with PAD_PKCS5") 195 | if padmode is None: 196 | # Get the default padding mode. 197 | padmode = self.getPadMode() 198 | 199 | if padmode == PAD_NORMAL: 200 | if not pad: 201 | # Get the default padding. 202 | pad = self.getPadding() 203 | if pad: 204 | data = data[:-self.block_size] + \ 205 | data[-self.block_size:].rstrip(pad) 206 | 207 | elif padmode == PAD_PKCS5: 208 | if _pythonMajorVersion < 3: 209 | pad_len = ord(data[-1]) 210 | else: 211 | pad_len = data[-1] 212 | data = data[:-pad_len] 213 | 214 | return data 215 | 216 | def _guardAgainstUnicode(self, data): 217 | # Only accept byte strings or ascii unicode values, otherwise 218 | # there is no way to correctly decode the data into bytes. 219 | if _pythonMajorVersion < 3: 220 | if isinstance(data, unicode): 221 | raise ValueError("pyDes can only work with bytes, not Unicode strings.") 222 | else: 223 | if isinstance(data, str): 224 | # Only accept ascii unicode values. 225 | try: 226 | return data.encode('ascii') 227 | except UnicodeEncodeError: 228 | pass 229 | raise ValueError("pyDes can only work with encoded strings, not Unicode.") 230 | return data 231 | 232 | ############################################################################# 233 | # DES # 234 | ############################################################################# 235 | class des(_baseDes): 236 | """DES encryption/decrytpion class 237 | Supports ECB (Electronic Code Book) and CBC (Cypher Block Chaining) modes. 238 | pyDes.des(key,[mode], [IV]) 239 | key -> Bytes containing the encryption key, must be exactly 8 bytes 240 | mode -> Optional argument for encryption type, can be either pyDes.ECB 241 | (Electronic Code Book), pyDes.CBC (Cypher Block Chaining) 242 | IV -> Optional Initial Value bytes, must be supplied if using CBC mode. 243 | Must be 8 bytes in length. 244 | pad -> Optional argument, set the pad character (PAD_NORMAL) to use 245 | during all encrypt/decrpt operations done with this instance. 246 | padmode -> Optional argument, set the padding mode (PAD_NORMAL or 247 | PAD_PKCS5) to use during all encrypt/decrpt operations done 248 | with this instance. 249 | """ 250 | 251 | 252 | # Permutation and translation tables for DES 253 | __pc1 = [56, 48, 40, 32, 24, 16, 8, 254 | 0, 57, 49, 41, 33, 25, 17, 255 | 9, 1, 58, 50, 42, 34, 26, 256 | 18, 10, 2, 59, 51, 43, 35, 257 | 62, 54, 46, 38, 30, 22, 14, 258 | 6, 61, 53, 45, 37, 29, 21, 259 | 13, 5, 60, 52, 44, 36, 28, 260 | 20, 12, 4, 27, 19, 11, 3 261 | ] 262 | 263 | # number left rotations of pc1 264 | __left_rotations = [ 265 | 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 266 | ] 267 | 268 | # permuted choice key (table 2) 269 | __pc2 = [ 270 | 13, 16, 10, 23, 0, 4, 271 | 2, 27, 14, 5, 20, 9, 272 | 22, 18, 11, 3, 25, 7, 273 | 15, 6, 26, 19, 12, 1, 274 | 40, 51, 30, 36, 46, 54, 275 | 29, 39, 50, 44, 32, 47, 276 | 43, 48, 38, 55, 33, 52, 277 | 45, 41, 49, 35, 28, 31 278 | ] 279 | 280 | # initial permutation IP 281 | __ip = [57, 49, 41, 33, 25, 17, 9, 1, 282 | 59, 51, 43, 35, 27, 19, 11, 3, 283 | 61, 53, 45, 37, 29, 21, 13, 5, 284 | 63, 55, 47, 39, 31, 23, 15, 7, 285 | 56, 48, 40, 32, 24, 16, 8, 0, 286 | 58, 50, 42, 34, 26, 18, 10, 2, 287 | 60, 52, 44, 36, 28, 20, 12, 4, 288 | 62, 54, 46, 38, 30, 22, 14, 6 289 | ] 290 | 291 | # Expansion table for turning 32 bit blocks into 48 bits 292 | __expansion_table = [ 293 | 31, 0, 1, 2, 3, 4, 294 | 3, 4, 5, 6, 7, 8, 295 | 7, 8, 9, 10, 11, 12, 296 | 11, 12, 13, 14, 15, 16, 297 | 15, 16, 17, 18, 19, 20, 298 | 19, 20, 21, 22, 23, 24, 299 | 23, 24, 25, 26, 27, 28, 300 | 27, 28, 29, 30, 31, 0 301 | ] 302 | 303 | # The (in)famous S-boxes 304 | __sbox = [ 305 | # S1 306 | [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 307 | 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 308 | 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 309 | 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13], 310 | 311 | # S2 312 | [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 313 | 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 314 | 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 315 | 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9], 316 | 317 | # S3 318 | [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 319 | 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 320 | 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 321 | 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12], 322 | 323 | # S4 324 | [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 325 | 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 326 | 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 327 | 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14], 328 | 329 | # S5 330 | [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 331 | 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 332 | 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 333 | 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3], 334 | 335 | # S6 336 | [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 337 | 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 338 | 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 339 | 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13], 340 | 341 | # S7 342 | [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 343 | 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 344 | 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 345 | 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12], 346 | 347 | # S8 348 | [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 349 | 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 350 | 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 351 | 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11], 352 | ] 353 | 354 | 355 | # 32-bit permutation function P used on the output of the S-boxes 356 | __p = [ 357 | 15, 6, 19, 20, 28, 11, 358 | 27, 16, 0, 14, 22, 25, 359 | 4, 17, 30, 9, 1, 7, 360 | 23,13, 31, 26, 2, 8, 361 | 18, 12, 29, 5, 21, 10, 362 | 3, 24 363 | ] 364 | 365 | # final permutation IP^-1 366 | __fp = [ 367 | 39, 7, 47, 15, 55, 23, 63, 31, 368 | 38, 6, 46, 14, 54, 22, 62, 30, 369 | 37, 5, 45, 13, 53, 21, 61, 29, 370 | 36, 4, 44, 12, 52, 20, 60, 28, 371 | 35, 3, 43, 11, 51, 19, 59, 27, 372 | 34, 2, 42, 10, 50, 18, 58, 26, 373 | 33, 1, 41, 9, 49, 17, 57, 25, 374 | 32, 0, 40, 8, 48, 16, 56, 24 375 | ] 376 | 377 | # Type of crypting being done 378 | ENCRYPT = 0x00 379 | DECRYPT = 0x01 380 | 381 | # Initialisation 382 | def __init__(self, key, mode=ECB, IV=None, pad=None, padmode=PAD_NORMAL): 383 | # Sanity checking of arguments. 384 | if len(key) != 8: 385 | raise ValueError("Invalid DES key size. Key must be exactly 8 bytes long.") 386 | _baseDes.__init__(self, mode, IV, pad, padmode) 387 | self.key_size = 8 388 | 389 | self.L = [] 390 | self.R = [] 391 | self.Kn = [ [0] * 48 ] * 16 # 16 48-bit keys (K1 - K16) 392 | self.final = [] 393 | 394 | self.setKey(key) 395 | 396 | def setKey(self, key): 397 | """Will set the crypting key for this object. Must be 8 bytes.""" 398 | _baseDes.setKey(self, key) 399 | self.__create_sub_keys() 400 | 401 | def __String_to_BitList(self, data): 402 | """Turn the string data, into a list of bits (1, 0)'s""" 403 | if _pythonMajorVersion < 3: 404 | # Turn the strings into integers. Python 3 uses a bytes 405 | # class, which already has this behaviour. 406 | data = [ord(c) for c in data] 407 | l = len(data) * 8 408 | result = [0] * l 409 | pos = 0 410 | for ch in data: 411 | i = 7 412 | while i >= 0: 413 | if ch & (1 << i) != 0: 414 | result[pos] = 1 415 | else: 416 | result[pos] = 0 417 | pos += 1 418 | i -= 1 419 | 420 | return result 421 | 422 | def __BitList_to_String(self, data): 423 | """Turn the list of bits -> data, into a string""" 424 | result = [] 425 | pos = 0 426 | c = 0 427 | while pos < len(data): 428 | c += data[pos] << (7 - (pos % 8)) 429 | if (pos % 8) == 7: 430 | result.append(c) 431 | c = 0 432 | pos += 1 433 | 434 | if _pythonMajorVersion < 3: 435 | return ''.join([ chr(c) for c in result ]) 436 | else: 437 | return bytes(result) 438 | 439 | def __permutate(self, table, block): 440 | """Permutate this block with the specified table""" 441 | return list(map(lambda x: block[x], table)) 442 | 443 | # Transform the secret key, so that it is ready for data processing 444 | # Create the 16 subkeys, K[1] - K[16] 445 | def __create_sub_keys(self): 446 | """Create the 16 subkeys K[1] to K[16] from the given key""" 447 | key = self.__permutate(des.__pc1, self.__String_to_BitList(self.getKey())) 448 | i = 0 449 | # Split into Left and Right sections 450 | self.L = key[:28] 451 | self.R = key[28:] 452 | while i < 16: 453 | j = 0 454 | # Perform circular left shifts 455 | while j < des.__left_rotations[i]: 456 | self.L.append(self.L[0]) 457 | del self.L[0] 458 | 459 | self.R.append(self.R[0]) 460 | del self.R[0] 461 | 462 | j += 1 463 | 464 | # Create one of the 16 subkeys through pc2 permutation 465 | self.Kn[i] = self.__permutate(des.__pc2, self.L + self.R) 466 | 467 | i += 1 468 | 469 | # Main part of the encryption algorithm, the number cruncher :) 470 | def __des_crypt(self, block, crypt_type): 471 | """Crypt the block of data through DES bit-manipulation""" 472 | block = self.__permutate(des.__ip, block) 473 | self.L = block[:32] 474 | self.R = block[32:] 475 | 476 | # Encryption starts from Kn[1] through to Kn[16] 477 | if crypt_type == des.ENCRYPT: 478 | iteration = 0 479 | iteration_adjustment = 1 480 | # Decryption starts from Kn[16] down to Kn[1] 481 | else: 482 | iteration = 15 483 | iteration_adjustment = -1 484 | 485 | i = 0 486 | while i < 16: 487 | # Make a copy of R[i-1], this will later become L[i] 488 | tempR = self.R[:] 489 | 490 | # Permutate R[i - 1] to start creating R[i] 491 | self.R = self.__permutate(des.__expansion_table, self.R) 492 | 493 | # Exclusive or R[i - 1] with K[i], create B[1] to B[8] whilst here 494 | self.R = list(map(lambda x, y: x ^ y, self.R, self.Kn[iteration])) 495 | B = [self.R[:6], self.R[6:12], self.R[12:18], self.R[18:24], self.R[24:30], self.R[30:36], self.R[36:42], self.R[42:]] 496 | # Optimization: Replaced below commented code with above 497 | #j = 0 498 | #B = [] 499 | #while j < len(self.R): 500 | # self.R[j] = self.R[j] ^ self.Kn[iteration][j] 501 | # j += 1 502 | # if j % 6 == 0: 503 | # B.append(self.R[j-6:j]) 504 | 505 | # Permutate B[1] to B[8] using the S-Boxes 506 | j = 0 507 | Bn = [0] * 32 508 | pos = 0 509 | while j < 8: 510 | # Work out the offsets 511 | m = (B[j][0] << 1) + B[j][5] 512 | n = (B[j][1] << 3) + (B[j][2] << 2) + (B[j][3] << 1) + B[j][4] 513 | 514 | # Find the permutation value 515 | v = des.__sbox[j][(m << 4) + n] 516 | 517 | # Turn value into bits, add it to result: Bn 518 | Bn[pos] = (v & 8) >> 3 519 | Bn[pos + 1] = (v & 4) >> 2 520 | Bn[pos + 2] = (v & 2) >> 1 521 | Bn[pos + 3] = v & 1 522 | 523 | pos += 4 524 | j += 1 525 | 526 | # Permutate the concatination of B[1] to B[8] (Bn) 527 | self.R = self.__permutate(des.__p, Bn) 528 | 529 | # Xor with L[i - 1] 530 | self.R = list(map(lambda x, y: x ^ y, self.R, self.L)) 531 | # Optimization: This now replaces the below commented code 532 | #j = 0 533 | #while j < len(self.R): 534 | # self.R[j] = self.R[j] ^ self.L[j] 535 | # j += 1 536 | 537 | # L[i] becomes R[i - 1] 538 | self.L = tempR 539 | 540 | i += 1 541 | iteration += iteration_adjustment 542 | 543 | # Final permutation of R[16]L[16] 544 | self.final = self.__permutate(des.__fp, self.R + self.L) 545 | return self.final 546 | 547 | 548 | # Data to be encrypted/decrypted 549 | def crypt(self, data, crypt_type): 550 | """Crypt the data in blocks, running it through des_crypt()""" 551 | 552 | # Error check the data 553 | if not data: 554 | return '' 555 | if len(data) % self.block_size != 0: 556 | if crypt_type == des.DECRYPT: # Decryption must work on 8 byte blocks 557 | raise ValueError("Invalid data length, data must be a multiple of " + str(self.block_size) + " bytes\n.") 558 | if not self.getPadding(): 559 | raise ValueError("Invalid data length, data must be a multiple of " + str(self.block_size) + " bytes\n. Try setting the optional padding character") 560 | else: 561 | data += (self.block_size - (len(data) % self.block_size)) * self.getPadding() 562 | # print "Len of data: %f" % (len(data) / self.block_size) 563 | 564 | if self.getMode() == CBC: 565 | if self.getIV(): 566 | iv = self.__String_to_BitList(self.getIV()) 567 | else: 568 | raise ValueError("For CBC mode, you must supply the Initial Value (IV) for ciphering") 569 | 570 | # Split the data into blocks, crypting each one seperately 571 | i = 0 572 | dict = {} 573 | result = [] 574 | #cached = 0 575 | #lines = 0 576 | while i < len(data): 577 | # Test code for caching encryption results 578 | #lines += 1 579 | #if dict.has_key(data[i:i+8]): 580 | #print "Cached result for: %s" % data[i:i+8] 581 | # cached += 1 582 | # result.append(dict[data[i:i+8]]) 583 | # i += 8 584 | # continue 585 | 586 | block = self.__String_to_BitList(data[i:i+8]) 587 | 588 | # Xor with IV if using CBC mode 589 | if self.getMode() == CBC: 590 | if crypt_type == des.ENCRYPT: 591 | block = list(map(lambda x, y: x ^ y, block, iv)) 592 | #j = 0 593 | #while j < len(block): 594 | # block[j] = block[j] ^ iv[j] 595 | # j += 1 596 | 597 | processed_block = self.__des_crypt(block, crypt_type) 598 | 599 | if crypt_type == des.DECRYPT: 600 | processed_block = list(map(lambda x, y: x ^ y, processed_block, iv)) 601 | #j = 0 602 | #while j < len(processed_block): 603 | # processed_block[j] = processed_block[j] ^ iv[j] 604 | # j += 1 605 | iv = block 606 | else: 607 | iv = processed_block 608 | else: 609 | processed_block = self.__des_crypt(block, crypt_type) 610 | 611 | 612 | # Add the resulting crypted block to our list 613 | #d = self.__BitList_to_String(processed_block) 614 | #result.append(d) 615 | result.append(self.__BitList_to_String(processed_block)) 616 | #dict[data[i:i+8]] = d 617 | i += 8 618 | 619 | # print "Lines: %d, cached: %d" % (lines, cached) 620 | 621 | # Return the full crypted string 622 | if _pythonMajorVersion < 3: 623 | return ''.join(result) 624 | else: 625 | return bytes.fromhex('').join(result) 626 | 627 | def encrypt(self, data, pad=None, padmode=None): 628 | """encrypt(data, [pad], [padmode]) -> bytes 629 | data : Bytes to be encrypted 630 | pad : Optional argument for encryption padding. Must only be one byte 631 | padmode : Optional argument for overriding the padding mode. 632 | The data must be a multiple of 8 bytes and will be encrypted 633 | with the already specified key. Data does not have to be a 634 | multiple of 8 bytes if the padding character is supplied, or 635 | the padmode is set to PAD_PKCS5, as bytes will then added to 636 | ensure the be padded data is a multiple of 8 bytes. 637 | """ 638 | data = self._guardAgainstUnicode(data) 639 | if pad is not None: 640 | pad = self._guardAgainstUnicode(pad) 641 | data = self._padData(data, pad, padmode) 642 | return self.crypt(data, des.ENCRYPT) 643 | 644 | def decrypt(self, data, pad=None, padmode=None): 645 | """decrypt(data, [pad], [padmode]) -> bytes 646 | data : Bytes to be encrypted 647 | pad : Optional argument for decryption padding. Must only be one byte 648 | padmode : Optional argument for overriding the padding mode. 649 | The data must be a multiple of 8 bytes and will be decrypted 650 | with the already specified key. In PAD_NORMAL mode, if the 651 | optional padding character is supplied, then the un-encrypted 652 | data will have the padding characters removed from the end of 653 | the bytes. This pad removal only occurs on the last 8 bytes of 654 | the data (last data block). In PAD_PKCS5 mode, the special 655 | padding end markers will be removed from the data after decrypting. 656 | """ 657 | data = self._guardAgainstUnicode(data) 658 | if pad is not None: 659 | pad = self._guardAgainstUnicode(pad) 660 | data = self.crypt(data, des.DECRYPT) 661 | return self._unpadData(data, pad, padmode) 662 | 663 | 664 | 665 | ############################################################################# 666 | # Triple DES # 667 | ############################################################################# 668 | class triple_des(_baseDes): 669 | """Triple DES encryption/decrytpion class 670 | This algorithm uses the DES-EDE3 (when a 24 byte key is supplied) or 671 | the DES-EDE2 (when a 16 byte key is supplied) encryption methods. 672 | Supports ECB (Electronic Code Book) and CBC (Cypher Block Chaining) modes. 673 | pyDes.des(key, [mode], [IV]) 674 | key -> Bytes containing the encryption key, must be either 16 or 675 | 24 bytes long 676 | mode -> Optional argument for encryption type, can be either pyDes.ECB 677 | (Electronic Code Book), pyDes.CBC (Cypher Block Chaining) 678 | IV -> Optional Initial Value bytes, must be supplied if using CBC mode. 679 | Must be 8 bytes in length. 680 | pad -> Optional argument, set the pad character (PAD_NORMAL) to use 681 | during all encrypt/decrpt operations done with this instance. 682 | padmode -> Optional argument, set the padding mode (PAD_NORMAL or 683 | PAD_PKCS5) to use during all encrypt/decrpt operations done 684 | with this instance. 685 | """ 686 | def __init__(self, key, mode=ECB, IV=None, pad=None, padmode=PAD_NORMAL): 687 | _baseDes.__init__(self, mode, IV, pad, padmode) 688 | self.setKey(key) 689 | 690 | def setKey(self, key): 691 | """Will set the crypting key for this object. Either 16 or 24 bytes long.""" 692 | self.key_size = 24 # Use DES-EDE3 mode 693 | if len(key) != self.key_size: 694 | if len(key) == 16: # Use DES-EDE2 mode 695 | self.key_size = 16 696 | else: 697 | raise ValueError("Invalid triple DES key size. Key must be either 16 or 24 bytes long") 698 | if self.getMode() == CBC: 699 | if not self.getIV(): 700 | # Use the first 8 bytes of the key 701 | self._iv = key[:self.block_size] 702 | if len(self.getIV()) != self.block_size: 703 | raise ValueError("Invalid IV, must be 8 bytes in length") 704 | self.__key1 = des(key[:8], self._mode, self._iv, 705 | self._padding, self._padmode) 706 | self.__key2 = des(key[8:16], self._mode, self._iv, 707 | self._padding, self._padmode) 708 | if self.key_size == 16: 709 | self.__key3 = self.__key1 710 | else: 711 | self.__key3 = des(key[16:], self._mode, self._iv, 712 | self._padding, self._padmode) 713 | _baseDes.setKey(self, key) 714 | 715 | # Override setter methods to work on all 3 keys. 716 | 717 | def setMode(self, mode): 718 | """Sets the type of crypting mode, pyDes.ECB or pyDes.CBC""" 719 | _baseDes.setMode(self, mode) 720 | for key in (self.__key1, self.__key2, self.__key3): 721 | key.setMode(mode) 722 | 723 | def setPadding(self, pad): 724 | """setPadding() -> bytes of length 1. Padding character.""" 725 | _baseDes.setPadding(self, pad) 726 | for key in (self.__key1, self.__key2, self.__key3): 727 | key.setPadding(pad) 728 | 729 | def setPadMode(self, mode): 730 | """Sets the type of padding mode, pyDes.PAD_NORMAL or pyDes.PAD_PKCS5""" 731 | _baseDes.setPadMode(self, mode) 732 | for key in (self.__key1, self.__key2, self.__key3): 733 | key.setPadMode(mode) 734 | 735 | def setIV(self, IV): 736 | """Will set the Initial Value, used in conjunction with CBC mode""" 737 | _baseDes.setIV(self, IV) 738 | for key in (self.__key1, self.__key2, self.__key3): 739 | key.setIV(IV) 740 | 741 | def encrypt(self, data, pad=None, padmode=None): 742 | """encrypt(data, [pad], [padmode]) -> bytes 743 | data : bytes to be encrypted 744 | pad : Optional argument for encryption padding. Must only be one byte 745 | padmode : Optional argument for overriding the padding mode. 746 | The data must be a multiple of 8 bytes and will be encrypted 747 | with the already specified key. Data does not have to be a 748 | multiple of 8 bytes if the padding character is supplied, or 749 | the padmode is set to PAD_PKCS5, as bytes will then added to 750 | ensure the be padded data is a multiple of 8 bytes. 751 | """ 752 | ENCRYPT = des.ENCRYPT 753 | DECRYPT = des.DECRYPT 754 | data = self._guardAgainstUnicode(data) 755 | if pad is not None: 756 | pad = self._guardAgainstUnicode(pad) 757 | # Pad the data accordingly. 758 | data = self._padData(data, pad, padmode) 759 | if self.getMode() == CBC: 760 | self.__key1.setIV(self.getIV()) 761 | self.__key2.setIV(self.getIV()) 762 | self.__key3.setIV(self.getIV()) 763 | i = 0 764 | result = [] 765 | while i < len(data): 766 | block = self.__key1.crypt(data[i:i+8], ENCRYPT) 767 | block = self.__key2.crypt(block, DECRYPT) 768 | block = self.__key3.crypt(block, ENCRYPT) 769 | self.__key1.setIV(block) 770 | self.__key2.setIV(block) 771 | self.__key3.setIV(block) 772 | result.append(block) 773 | i += 8 774 | if _pythonMajorVersion < 3: 775 | return ''.join(result) 776 | else: 777 | return bytes.fromhex('').join(result) 778 | else: 779 | data = self.__key1.crypt(data, ENCRYPT) 780 | data = self.__key2.crypt(data, DECRYPT) 781 | return self.__key3.crypt(data, ENCRYPT) 782 | 783 | def decrypt(self, data, pad=None, padmode=None): 784 | """decrypt(data, [pad], [padmode]) -> bytes 785 | data : bytes to be encrypted 786 | pad : Optional argument for decryption padding. Must only be one byte 787 | padmode : Optional argument for overriding the padding mode. 788 | The data must be a multiple of 8 bytes and will be decrypted 789 | with the already specified key. In PAD_NORMAL mode, if the 790 | optional padding character is supplied, then the un-encrypted 791 | data will have the padding characters removed from the end of 792 | the bytes. This pad removal only occurs on the last 8 bytes of 793 | the data (last data block). In PAD_PKCS5 mode, the special 794 | padding end markers will be removed from the data after 795 | decrypting, no pad character is required for PAD_PKCS5. 796 | """ 797 | ENCRYPT = des.ENCRYPT 798 | DECRYPT = des.DECRYPT 799 | data = self._guardAgainstUnicode(data) 800 | if pad is not None: 801 | pad = self._guardAgainstUnicode(pad) 802 | if self.getMode() == CBC: 803 | self.__key1.setIV(self.getIV()) 804 | self.__key2.setIV(self.getIV()) 805 | self.__key3.setIV(self.getIV()) 806 | i = 0 807 | result = [] 808 | while i < len(data): 809 | iv = data[i:i+8] 810 | block = self.__key3.crypt(iv, DECRYPT) 811 | block = self.__key2.crypt(block, ENCRYPT) 812 | block = self.__key1.crypt(block, DECRYPT) 813 | self.__key1.setIV(iv) 814 | self.__key2.setIV(iv) 815 | self.__key3.setIV(iv) 816 | result.append(block) 817 | i += 8 818 | if _pythonMajorVersion < 3: 819 | data = ''.join(result) 820 | else: 821 | data = bytes.fromhex('').join(result) 822 | else: 823 | data = self.__key3.crypt(data, DECRYPT) 824 | data = self.__key2.crypt(data, ENCRYPT) 825 | data = self.__key1.crypt(data, DECRYPT) 826 | return self._unpadData(data, pad, padmode) --------------------------------------------------------------------------------