ajout code td passwords
This commit is contained in:
		
							
								
								
									
										131
									
								
								td3-code/skeleton.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										131
									
								
								td3-code/skeleton.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,131 @@ | ||||
| #!/usr/bin/env python3 | ||||
|  | ||||
| import time | ||||
| import sys | ||||
| from toolbox import * | ||||
|  | ||||
| # You should tweak these values during the work | ||||
| nblogins = 10         # would be larger in real-life | ||||
| nbpasswords = 1000000 # would be larger in real-life | ||||
| nbiterations = 10     # 10000 is currently recommended, should be adapted to the usecase and changed with time (improvement of computation power), like a key size | ||||
|  | ||||
|  | ||||
| ############################################ | ||||
| # Part of the script to edit               # | ||||
| ############################################ | ||||
|  | ||||
| # Hint : you can call decrypt(key,data) to decrypt data using key | ||||
| def crackencrypted(database): | ||||
|     key = readfile("enckey")[0] | ||||
|     crackeddb = [] | ||||
|     for i in database: | ||||
|         # i[0] is the login, i[1] is the encrypted password | ||||
|         #... | ||||
|         crackeddb.append((i[0],i[1])) # second argument should contain cleartext password | ||||
|     return crackeddb | ||||
|  | ||||
| # Hint : - genshahashes(passwords) returns all the hashes of passwords dictionary | ||||
| #        - getpassfromshahash(hashes, hash) returns the password which hashed as "hash" in hashes | ||||
| def cracksha(database): | ||||
|     global nbpasswords | ||||
|     passwords = getPassDict(nbpasswords) # passwords contains a dictionary of passwords | ||||
|     #... | ||||
|     crackeddb = [] | ||||
|     for i in database: | ||||
|         # i[0] is the login, i[1] is the hashed password | ||||
|         #... | ||||
|         crackeddb.append((i[0],i[1])) # second argument should contain cleartext password | ||||
|     return crackeddb | ||||
|  | ||||
| # Hint : salthash(password, salt) return the salted hash of password | ||||
| def cracksaltedsha(database): | ||||
|     global nbpasswords | ||||
|     passwords = getPassDict(nbpasswords) | ||||
|     crackeddb = [] | ||||
|     for i in database: | ||||
|         # i[0] is the login, i[1] is the hashed password, i[2] is the salt | ||||
|         #... | ||||
|         crackeddb.append((i[0],i[1])) # second argument should contain cleartext password | ||||
|     return crackeddb | ||||
|  | ||||
| # Hint : pbkdf2(password, salt, nbiterations) returns the pbkdf2 of password using salt and nbiterations | ||||
| def crackpbkdf2(database): | ||||
|     global nbpasswords | ||||
|     passwords = getPassDict(nbpasswords) | ||||
|     crackeddb = [] | ||||
|     for i in database: | ||||
|         # i[0] is the login, i[1] is the hashed password, i[2] is the salt, i[3] is the iteration count | ||||
|         #... | ||||
|         crackeddb.append((i[0],i[1])) # second argument should contain cleartext password | ||||
|     return crackeddb | ||||
|  | ||||
|  | ||||
|  | ||||
| ############################################ | ||||
| # Nothing to change after this line !      # | ||||
| ############################################ | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     # When called with init | ||||
|     if len(sys.argv) > 1 and sys.argv[1] == "init": | ||||
|         initworkspace(nblogins,nbpasswords,nbiterations) | ||||
|         print("Workspace initialized in files/ subdirectory") | ||||
|         exit(0) | ||||
|  | ||||
|     # Test whether init has been called before | ||||
|     try : | ||||
|         readfile("plain") | ||||
|     except FileNotFoundError: | ||||
|         initworkspace(nblogins,nbpasswords,nbiterations) | ||||
|         print("Workspace initialized in files/ subdirectory") | ||||
|  | ||||
|     # test plain DB | ||||
|     print("\n============\nPlain storage:") | ||||
|     plaindb = readfile("plain") | ||||
|     print("Plain DB is : " + str(plaindb)) | ||||
|     print("Authenticating with plain DB : " + str(authplain(plaindb[0][0],plaindb[0][1],plaindb))) | ||||
|  | ||||
|     #test encrypted db | ||||
|     print("\n============\nEncrypted storage:") | ||||
|     encdb = readfile("enc") | ||||
|     print("Encrypted DB is " + str(encdb)) | ||||
|     print("Authenticating with encrypted DB : " + str(authencrypted(plaindb[1][0],plaindb[1][1],encdb))) | ||||
|     start = time.time() | ||||
|     crackedenc = crackencrypted(encdb) | ||||
|     end = time.time() | ||||
|     print("Time to crack encrypted DB : " + str(end-start) + " seconds") | ||||
|     print("Cracked encrypted DB is " + str(crackedenc)) | ||||
|  | ||||
|     #test SHA db | ||||
|     print("\n============\nSHA storage:") | ||||
|     shadb = readfile("sha") | ||||
|     print("SHA DB is " + str(shadb)) | ||||
|     print("Authenticating with SHA DB : " + str(authsha(plaindb[0][0],plaindb[0][1],shadb))) | ||||
|     start = time.time() | ||||
|     crackedsha = cracksha(shadb) | ||||
|     end = time.time() | ||||
|     print("Time to crack SHA DB : " + str(end-start) + " seconds") | ||||
|     print("Cracked SHA DB is " + str(crackedsha)) | ||||
|  | ||||
|     #test Salted SHA db | ||||
|     print("\n============\nSalted SHA storage:") | ||||
|     saltedshadb = readfile("saltedsha") | ||||
|     print("Salted SHA DB is " + str(saltedshadb)) | ||||
|     print("Authenticating with Salted SHA DB : " + str(authsaltedsha(plaindb[0][0],plaindb[0][1],saltedshadb))) | ||||
|     start = time.time() | ||||
|     crackedsaltedsha = cracksaltedsha(saltedshadb) | ||||
|     end = time.time() | ||||
|     print("Time to crack salted SHA DB : " + str(end-start) + " seconds") | ||||
|     print("Cracked salted SHA DB is " + str(crackedsaltedsha)) | ||||
|  | ||||
|     # test PBKDF2 DB | ||||
|     print("\n============\nPBKDF2 storage:") | ||||
|     pbkdf2db = readfile("pbkdf2") | ||||
|     print("PBKDF2 DB is " + str(pbkdf2db)) | ||||
|     print("Authenticating with PBKDF2 DB : " + str(authpbkdf2(plaindb[0][0],plaindb[0][1],pbkdf2db))) | ||||
|     start = time.time() | ||||
|     crackedpbkdf2 = crackpbkdf2(pbkdf2db) | ||||
|     end = time.time() | ||||
|     print("Time to crack PBKDF2 DB : " + str(end-start) + " seconds") | ||||
|     print("Cracked PBKDF2 DB is " + str(crackedpbkdf2)) | ||||
							
								
								
									
										250
									
								
								td3-code/toolbox.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										250
									
								
								td3-code/toolbox.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,250 @@ | ||||
| #!/usr/bin/env python3 | ||||
|  | ||||
| # Avoir une lib avec des briques prêtes | ||||
| # Avoir un script qui crée les fichiers de password SHA/PB/etc. pour pouvoir les manipuler en texte | ||||
| # TD : associer les briques pour évaluer les attaques sur un pass / une base | ||||
| # mettre un « except ImportError » et ressayer avec « Cryptodome » a la place de « Crypto » | ||||
|  | ||||
| import re | ||||
| import time | ||||
| import random | ||||
| import hashlib | ||||
| # tweak to (try to) handle different crypto lib naming across systems (Linux, Mac, Win) | ||||
| try: | ||||
|     from Crypto.Cipher import AES | ||||
|     from Crypto import Random | ||||
| except ImportError: | ||||
|     try: | ||||
|         from crypto.Cipher import AES | ||||
|         from crypto import Random | ||||
|     except ImportError: | ||||
|         from Cryptodome.Cipher import AES | ||||
|         from Cryptodome import Random | ||||
| import base64 | ||||
| import os | ||||
| import urllib.request | ||||
| import string | ||||
|  | ||||
| # returns an array of a dictionary of passwords | ||||
| def getPassDict(nbpasswords): | ||||
|     try: | ||||
|         f = open("files/passwords.txt") | ||||
|     except FileNotFoundError: | ||||
|         print("Downloading a passwords list...") | ||||
|         urllib.request.urlretrieve("https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/10-million-password-list-top-1000000.txt?raw=true", "files/passwords.txt") | ||||
|         print("Done !") | ||||
|         f = open("files/passwords.txt") | ||||
|     passwords = [] | ||||
|     #nbpasswords = 10000 | ||||
|     passtogen = nbpasswords | ||||
|     for password in f: | ||||
|         passwords.append(password.strip()) | ||||
|         passtogen-=1 | ||||
|         if passtogen == 0: | ||||
|             break | ||||
|     return passwords | ||||
|  | ||||
| def genRandomPassword(): | ||||
|     length = 6 | ||||
|     chars = string.ascii_letters + string.digits | ||||
|     return ''.join(random.choice(chars) for i in range(length)) | ||||
|  | ||||
| # reads/writes shadow-style files | ||||
| def readfile(filename): | ||||
|     f = open("files/"+filename) | ||||
|     res = [] | ||||
|     for line in f: | ||||
|         output = line.strip().split(":") | ||||
|         res.append(output) | ||||
|     return res | ||||
|  | ||||
| def writeFile(filename, array): | ||||
|     f = open("files/"+filename,'w') | ||||
|     for line in array: | ||||
|         towrite = "" | ||||
|         for item in line: | ||||
|             towrite+=item + ":" | ||||
|         towrite = towrite[:-1] | ||||
|         f.write(towrite) | ||||
|         f.write('\n') | ||||
|  | ||||
|  | ||||
| # Plain storage | ||||
| def genplain(nblogins,nbpasswords): | ||||
|     passwords = getPassDict(nbpasswords) | ||||
|     logins = [] | ||||
|     for i in range(0,nblogins): | ||||
|         login = "user" + str(i) | ||||
|         if (random.randint(0,10) < 4): | ||||
|             logins.append((login,passwords[random.randint(0,len(passwords)-1)])) | ||||
|         else: | ||||
|             logins.append((login,genRandomPassword())) | ||||
|     return logins | ||||
|  | ||||
| def authplain(login, passwd, database): | ||||
|     for i in database: | ||||
|         if i[0] == login: | ||||
|             current = i[1] | ||||
|     return (current == passwd) | ||||
|  | ||||
| # Encrypted storage | ||||
| def genencrypted(logins): | ||||
|     encdb = [] | ||||
|     key = Random.new().read(16) | ||||
|     iv = Random.new().read(AES.block_size) | ||||
|     f = open("files/enckey",'wb') | ||||
|     f.write((base64.b64encode(key))) | ||||
|     f.write(b":") | ||||
|     #f = open("files/enciv",'wb') | ||||
|     f.write((base64.b64encode(iv))) | ||||
|     for i in logins: | ||||
|         cipher = AES.new(key, AES.MODE_CFB, iv) | ||||
|         enc =  (base64.b64encode(cipher.encrypt(i[1].encode('utf-8')))).decode("utf-8") | ||||
|         encdb.append((i[0],enc)) | ||||
|         #print(enc) | ||||
|     return encdb | ||||
|  | ||||
| def authencrypted(login, passwd, database): | ||||
|     for i in database: | ||||
|         if i[0] == login: | ||||
|             current = i[1] | ||||
|     keyiv = readfile("enckey")[0] | ||||
|     key = base64.b64decode(keyiv[0]) | ||||
|     iv = base64.b64decode(keyiv[1]) | ||||
|     #key = base64.b64decode(readfile("enckey")[0][0]) | ||||
|     #iv =  base64.b64decode(readfile("enciv")[0][0]) | ||||
|     cipher = AES.new(key, AES.MODE_CFB, iv) | ||||
|     return (passwd == cipher.decrypt(base64.b64decode(current)).decode('utf-8')) | ||||
|  | ||||
| def decrypt(keyiv,data): | ||||
|     key = base64.b64decode(keyiv[0]) | ||||
|     iv = base64.b64decode(keyiv[1]) | ||||
|     cipher = AES.new(key, AES.MODE_CFB, iv) | ||||
|     return cipher.decrypt(base64.b64decode(data)).decode('utf-8') | ||||
|  | ||||
|  | ||||
| # SHA storage | ||||
| def gensha(logins): | ||||
|     db = [] | ||||
|     for i in logins: | ||||
|         csum = hashlib.sha256(i[1].encode('utf-8')).hexdigest() | ||||
|         db.append((i[0],csum)) | ||||
|     return db | ||||
|  | ||||
| def authsha(login, passwd, database): | ||||
|     for i in database: | ||||
|         if i[0] == login: | ||||
|             current = i[1] | ||||
|     return (current == hashlib.sha256(passwd.encode('utf-8')).hexdigest()) | ||||
|  | ||||
| def genshahashes(passwords): | ||||
|     hashes = [] | ||||
|     for passwd in passwords: | ||||
|         hashes.append([hashlib.sha256(passwd.encode('utf-8')).hexdigest(),passwd]) | ||||
|     return hashes | ||||
|  | ||||
| def getpassfromshahash(hashes, hash): | ||||
|     for j in hashes: | ||||
|         if j[0] == hash: | ||||
|             return j[1] | ||||
|     return None | ||||
|  | ||||
| # Salted SHA storage | ||||
| def gensaltedsha(logins): | ||||
|     db = [] | ||||
|     for i in logins: | ||||
|         salt = str(random.randint(0,65535)) | ||||
|         csum = hashlib.sha256((i[1]+salt).encode('utf-8')).hexdigest() | ||||
|         db.append((i[0],csum,salt)) | ||||
|     return db | ||||
|  | ||||
| def authsaltedsha(login, passwd, database): | ||||
|     for i in database: | ||||
|         if i[0] == login: | ||||
|             current = i[1] | ||||
|             salt = i[2] | ||||
|     return (current == hashlib.sha256((passwd+salt).encode('utf-8')).hexdigest()) | ||||
|  | ||||
| def salthash(password,salt): | ||||
|     return hashlib.sha256((password+str(salt)).encode('utf-8')).hexdigest() | ||||
|  | ||||
| # PBKDF2 storage | ||||
| def genpbkdf2(logins,nbiterations): | ||||
|     db = [] | ||||
|     for i in logins: | ||||
|         salt = str(random.randint(0,65535)) | ||||
|         csum = base64.b64encode(hashlib.pbkdf2_hmac('sha256',i[1].encode('utf-8'),str(salt).encode('utf-8'),nbiterations)).decode('utf-8') | ||||
|         db.append((i[0],csum,salt,str(nbiterations))) | ||||
|     return db | ||||
|  | ||||
| def authpbkdf2(login, passwd, database): | ||||
|     for i in database: | ||||
|         if i[0] == login: | ||||
|             current = i[1] | ||||
|             salt = i[2] | ||||
|             nbiterations = int(i[3]) | ||||
|     return (base64.b64decode(current) == hashlib.pbkdf2_hmac('sha256',passwd.encode('utf-8'),str(salt).encode('utf-8'),nbiterations)) | ||||
|  | ||||
| def pbkdf2(password,salt,nbiterations): | ||||
|     nbiterations = int(nbiterations) | ||||
|     return base64.b64encode(hashlib.pbkdf2_hmac('sha256',password.encode('utf-8'),str(salt).encode('utf-8'),nbiterations)).decode('utf-8') | ||||
|  | ||||
|  | ||||
| # Generate shadow-style files | ||||
| def initworkspace(nblogins,nbpasswords,nbiterations): | ||||
|     print("Generating " + str(nblogins) + " logins and " + str(nbpasswords) + " passwords") | ||||
|     try : | ||||
|         os.mkdir("files") | ||||
|     except FileExistsError: | ||||
|         pass | ||||
|     plaindb = genplain(nblogins,nbpasswords) | ||||
|     writeFile("plain", plaindb) | ||||
|     encdb = genencrypted(plaindb) | ||||
|     writeFile("enc", encdb) | ||||
|     shadb = gensha(plaindb) | ||||
|     writeFile("sha", shadb) | ||||
|     saltedshadb = gensaltedsha(plaindb) | ||||
|     writeFile("saltedsha", saltedshadb) | ||||
|     pbkdf2db = genpbkdf2(plaindb,nbiterations) | ||||
|     writeFile("pbkdf2", pbkdf2db) | ||||
|  | ||||
|  | ||||
|  | ||||
| # Unit tests | ||||
| if __name__ == '__main__': | ||||
|     # create shadow files | ||||
|     initworkspace(10,100,1000) | ||||
|  | ||||
|     print("======\nUnit tests of the toolbox, you must work in skeleton.py\n=========") | ||||
|  | ||||
|     # test plain DB | ||||
|     print("\n============\nPlain storage:") | ||||
|     plaindb = readfile("plain") | ||||
|     print("Plain DB is : " + str(plaindb)) | ||||
|     print("Authenticating with plain DB : " + str(authplain(plaindb[0][0],plaindb[0][1],plaindb))) | ||||
|  | ||||
|     #test encrypted db | ||||
|     print("\n============\nEncrypted storage:") | ||||
|     encdb = readfile("enc") | ||||
|     print("Encrypted DB is " + str(encdb)) | ||||
|     print("Authenticating with encrypted DB : " + str(authencrypted(plaindb[1][0],plaindb[1][1],encdb))) | ||||
|  | ||||
|     #test SHA db | ||||
|     print("\n============\nSHA storage:") | ||||
|     shadb = readfile("sha") | ||||
|     print("SHA DB is " + str(shadb)) | ||||
|     print("Authenticating with SHA DB : " + str(authsha(plaindb[0][0],plaindb[0][1],shadb))) | ||||
|  | ||||
|     #test Salted SHA db | ||||
|     print("\n============\nSalted SHA storage:") | ||||
|     saltedshadb = readfile("saltedsha") | ||||
|     print("Salted SHA DB is " + str(saltedshadb)) | ||||
|     print("Authenticating with Salted SHA DB : " + str(authsaltedsha(plaindb[0][0],plaindb[0][1],saltedshadb))) | ||||
|  | ||||
|     # test PBKDF2 DB | ||||
|     print("\n============\nPBKDF2 storage:") | ||||
|     pbkdf2db = readfile("pbkdf2") | ||||
|     print("PBKDF2 DB is " + str(pbkdf2db)) | ||||
|     print("Authenticating with PBKDF2 DB : " + str(authpbkdf2(plaindb[0][0],plaindb[0][1],pbkdf2db))) | ||||
|  | ||||
|     print("\n======\nUnit tests of the toolbox, you must work in skeleton.py\n=========") | ||||
		Reference in New Issue
	
	Block a user