In this video, I'll show you a few techniques to crack passwords using Python. There are a lot of tools out there that can help you to decrypt passwords, such as Hydra, John The Ripper, and many others. We will build a simple python script that will help you understand how those more complicated tools work.
Let's get started. First, create a hack_password.py file. Through the video, I will copy-paste some code between files just to make it easier to follow.
importhashlibfromurllib.requestimporturlopendefhash(password):result=hashlib.sha256(password.encode())returnresult.hexdigest()defget_wordlist(url):try:withurlopen(url)asf:wordlist=f.read().decode('utf-8').splitlines()returnwordlistexceptExceptionase:print(f'failed to get wordlist: {e}')exit(1)defbruteforce(wordlist,password):password_hash=hash(password)forguess_passwordinwordlist:ifhash(guess_password)==password_hash:returnguess_passwordif__name__=='__main__':WORDLIST_URL='https://raw.githubusercontent.com/berzerk0/Probable-Wordlists/2df55facf06c7742f2038a8f6607ea9071596128/Real-Passwords/Top1575-probable-v2.txt'MY_PASSWORD='123123'wordlist=get_wordlist(WORDLIST_URL)print(f'wordlist contains {len(wordlist)} items')password=bruteforce(wordlist,MY_PASSWORD)ifpasswordisnotNone:print('your password is:',password)else:print('your password is not in the wordlist')
Since we don't rely on any third-party modules, we don't need to create a virtual environment and install those libraries. We can execute the script right away.
importcsvimporthashlibfromurllib.requestimporturlopendefhash(password):result=hashlib.sha256(password.encode())returnresult.hexdigest()defget_wordlist(url):try:withurlopen(url)asf:wordlist=f.read().decode('utf-8').splitlines()returnwordlistexceptExceptionase:print(f'failed to get wordlist: {e}')exit(1)defget_users(path):try:result=[]withopen(path)asf:reader=csv.DictReader(f,delimiter=',')forrowinreader:result.append(dict(row))returnresultexceptExceptionase:print(f'failed to get users: {e}')exit(1)defbruteforce(wordlist,password):password_hash=hash(password)forguess_passwordinwordlist:ifhash(guess_password)==password_hash:returnguess_passwordif__name__=='__main__':WORDLIST_URL='https://raw.githubusercontent.com/berzerk0/Probable-Wordlists/2df55facf06c7742f2038a8f6607ea9071596128/Real-Passwords/Top12Thousand-probable-v2.txt'DATABASE_PATH='database.csv'wordlist=get_wordlist(WORDLIST_URL)print(f'wordlist contains {len(wordlist)} items')users=get_users(DATABASE_PATH)foruserinusers:password=bruteforce(wordlist,user['password'])ifpasswordisnotNone:print(f'username: {user["username"]}, password: {password}')
To improve our script, we can use rainbow tables. A rainbow table is a database that is used to gain authentication by cracking the password hash. It is a precomputed dictionary of plaintext passwords and their corresponding hash values that can be used to find out what plaintext password produces a particular hash.
Create a script to create a rainbow table out of wordlist, which we usually use.
importcsvimporthashlibfromurllib.requestimporturlopendefget_wordlist(url):try:withurlopen(url)asf:wordlist=f.read().decode('utf-8').splitlines()returnwordlistexceptExceptionase:print(f'failed to get wordlist: {e}')exit(1)defhash(password):result=hashlib.sha256(password.encode())returnresult.hexdigest()defcreate_rainbow_table(wordlist_url,rainbow_table_path):wordlist=get_wordlist(wordlist_url)try:withopen(rainbow_table_path,'w')asf:writer=csv.writer(f,delimiter=',')writer.writerow(['password','hash'])forwordinwordlist:writer.writerow([word,hash(word)])exceptExceptionase:print(f'failed to create rainbow table: {e}')exit(1)if__name__=='__main__':WORDLIST_URL='https://raw.githubusercontent.com/berzerk0/Probable-Wordlists/2df55facf06c7742f2038a8f6607ea9071596128/Real-Passwords/Top1575-probable-v2.txt'RAINBOW_TABLE_PATH='rainbow_table.csv'create_rainbow_table(WORDLIST_URL,RAINBOW_TABLE_PATH)
Let's create our last script, hack_database_v2.py. This script is no exception. We will reuse a lot of methods from previous examples.
importcsvimporthashlibfromurllib.requestimporturlopendefhash(password):result=hashlib.sha256(password.encode())returnresult.hexdigest()defget_wordlist(url):try:withurlopen(url)asf:wordlist=f.read().decode('utf-8').splitlines()returnwordlistexceptExceptionase:print(f'failed to get wordlist: {e}')exit(1)defget_users(path):try:result=[]withopen(path)asf:reader=csv.DictReader(f,delimiter=',')forrowinreader:result.append(dict(row))returnresultexceptExceptionase:print(f'failed to get users: {e}')exit(1)defget_rainbow_table(path):try:result=[]withopen(path)asf:reader=csv.DictReader(f,delimiter=',')forrowinreader:result.append(dict(row))returnresultexceptExceptionase:print(f'failed to get rainbow table: {e}')exit(1)defmatch_hash(users,rainbow_table):foruserinusers:password_hash=hash(user['password'])forrowinrainbow_table:ifpassword_hash==row['hash']:print(f'username: {user["username"]}, password {row["password"]}')if__name__=='__main__':WORDLIST_URL='https://raw.githubusercontent.com/berzerk0/Probable-Wordlists/2df55facf06c7742f2038a8f6607ea9071596128/Real-Passwords/Top12Thousand-probable-v2.txt'DATABASE_PATH='database.csv'RAINBOW_TABLE_PATH='rainbow_table.csv'users=get_users(DATABASE_PATH)rainbow_table=get_rainbow_table(RAINBOW_TABLE_PATH)match_hash(users,rainbow_table)
Run the script
python3hack_database_v2.py
These days, more and more systems use proper password storage algorithms such as Bcrypt, Scrypt, or Argon2. Those algorithms are no longer "vulnerable" to rainbow tables: since each hash is unique, even if the passwords are equal, rainbow tables no longer work.
That's why rainbow tables are unpopular today.