diff --git a/CSCI262Assignment.py b/CSCI262Assignment.py new file mode 100644 index 0000000..5ed6493 --- /dev/null +++ b/CSCI262Assignment.py @@ -0,0 +1,296 @@ +#!/usr/bin/env python3 +import hashlib +import pandas as pd +from pathlib import Path +import numpy as np +import sys +import os +from passlib.hash import lmhash + + +class RainbowTable(): + # 初始化方法或构造函数 + + def __init__(self, table, chain, pw, collisionchecklist, hashingfunction, rainbow): + self.table = table + self.chain = chain + self.pw = pw + self.collisionchecklist = collisionchecklist + self.hashingfunction = hashingfunction + self.rainbow = rainbow + + def progressbar(self, it, prefix="", size=60, out=sys.stdout): # Python3.6+方法用于显示生成彩虹表的进度条 + count = len(it) + + def show(j): + x = int(size * j / count) + print(f"{prefix}[{u'█' * x}{('.' * (size - x))}] {j}/{count}", end='\r', file=out, flush=True) + + show(0) + for i, item in enumerate(it): + yield item + show(i + 1) + print("\n", flush=True, file=out) + + # simple normal binary search二分查找 + def binary_search(self, arr, x): + low = 0 + high = len(arr) - 1 + mid = 0 + + while low <= high: + + mid = (high + low) // 2 + + if arr[mid] < x: + low = mid + 1 + + elif arr[mid] > x: + high = mid - 1 + + else: + return mid + + # If we reach here, then the element was not present如果到达这里,元素就不存在了 + return 'notfound' + + def transversechain(self, reduction, chainhead): # 生成彩虹链 + for i in range(0, self.chain - 1): + passwords = self.pw[0][reduction] + # 将它转成字符串并将其用十六进制表示 + passwordhash = self.hashingfunction(str(passwords)) + reduction = int(passwordhash, 16) % len(self.pw) + self.rainbow.append([chainhead, passwordhash]) + return self.rainbow.sort(key=lambda x: int(x[1], 16)) + + def generate(self): # 生成彩虹表 + for i in self.progressbar(range(len(self.pw)), "Computing: ", 70): + passwords = self.pw[0][i] + if (self.pw[0][i][-4:] != 'used'): + self.pw[0][i] = self.pw[0][i] + 'used' + elif (self.pw[0][i][-4:] == 'used'): + passwords = self.pw[0][i][:-4] + passwordhash = self.hashingfunction(passwords) + reduction = int(passwordhash, 16) % len(self.pw) + chaintail = self.transversechain(reduction, passwords) + + # save tables so we dont have to run the creation everytime保存表,这样我们就不必每次都运行创建 + def saveandsorttables(self): # 保存和排序彩虹表 + # df1 = pd.DataFrame(self.table) + df2 = pd.DataFrame(self.rainbow) + np.savetxt(r'Rainbow.txt', df2.values, fmt='%s') + with open('Passwords.txt', 'w') as sortedbooks: + for i in range(len(self.pw)): + sortedbooks.writelines(str(self.pw[0][i]) + '\n') + + # np.savetxt(r'passhash.txt', df1.values, fmt='%s') + # df1.to_excel("output1.xlsx") + + # df2.to_excel("output2.xlsx") + + def loopchain(self, i, readpasswordhash, password): # 遍历彩虹表 + for x in range(self.chain): + passwordhash = self.hashingfunction(str(readpasswordhash.iloc[i][0])) + reduction = int(passwordhash, 16) % len(self.pw) + if (self.hashingfunction(self.pw[0][reduction]) == password): + # print(type(self.hashingfunction(self.pw[0][reduction].encode('utf8')).hexdigest())) + # print('\n找到了 : : ' + self.pw[0][reduction] + '\n') + + return 'found' + else: + return 'notfound' + + def crack(self, hash, readpasswordhash): # 破解hash函数,hash为目标的hash函数,readpasswordhash是从表中找到相关数值 + password = hash + # 查找彩虹表找到密码 + index = self.binary_search([int(i, 16) for i in readpasswordhash['passwordhash']], int(password, 16)) + if (index != 'notfound'): + stoploop = self.loopchain(index, readpasswordhash, password) + # print(readpasswordhash.iloc[0][index]) + else: + for i in range(len(self.pw)): + if (i == len(self.pw) - 2): + print('\n在表中无法找到相应的 password \n\n') + break + elif (self.hashingfunction(str(readpasswordhash.iloc[i][0])) == password): + print('\n找到了想找到的password : ' + str(readpasswordhash.iloc[i][0]) + '\n') + break + else: + pointer = self.loopchain(i, readpasswordhash, password) + if (pointer == 'found'): + break + +def main(): + passwordFileArg = '' + + def createList(r1, r2): + # Testing if range r1 and r2测试r1、r2的范围 + if (r1 == r2): + return r1 + else: + #建立空列表 + res = [] + #循环将后继程序追加到list,直到到达r2为止。 + while (r1 < r2 + 1): + res.append(r1) + r1 += 1 + return res + + if (len(sys.argv) > 1): + passwordFileArg = str(sys.argv[1]) + if (passwordFileArg[-4:] != '.txt'): + passwordFileArg = passwordFileArg + '.txt' + while True: + if (passwordFileArg[-4:] != '.txt'): + passwordFileArg = passwordFileArg + '.txt' + file = Path(str(passwordFileArg)) + if (file.exists()): + print("\n\n密码可以被找到 !\n\n") + break + else: + passwordFileArg = input("没有找到密码参考文件(ARGUMENT),请输入另一个文件名\n") + else: + while True: + if (len(passwordFileArg) == 0): + passwordFileArg = input("请输入参考密码文件名\n") + if (passwordFileArg[-4:] != '.txt'): + passwordFileArg = passwordFileArg + '.txt' + file = Path(str(passwordFileArg)) + if (file.exists()): + print("\n\n已找到密码文件 !\n\n") + break + else: + passwordFileArg = input("没有找到文件,请输入另一个文件名\n") + else: + if (passwordFileArg[-4:] != '.txt'): + passwordFileArg = passwordFileArg + '.txt' + file = Path(str(passwordFileArg)) + if (file.exists()): + print("\n\n已找到密码文件 !\n\n") + break + else: + passwordFileArg = input("没有找到文件,请输入另一个文件名\n") + + print("彩虹表操作流程,请选择操作流程") + print( + "//请注意,相关的文件,如密码文件和生成的彩虹表文件将在同一目录下//") + print("1 . 生成彩虹表") + print("2 . 破解哈希函数") + print("3 . 刷新参考文件(删除参考文件中密码上所有已使用的标记)") + print("4 . 退出程序") + while True: + try: + chioce = float(input()) + if chioce < 1 or chioce > 4: + raise ValueError + elif (chioce == 1): + while True: + file = Path(str(passwordFileArg)) + if file.exists(): + df = pd.read_csv(passwordFileArg, header=None) + df = df.replace(np.nan, 'null', regex=True) + instance = RainbowTable([], 5, df, createList(0, len(df) - 1), lmhash.hash, []) + print("Reading") + print(len(df)) + print("rows of password") + instance.generate() + instance.saveandsorttables() + print('已在当前目录中创建彩虹表Rainbow.txt') + print("1 . 生成彩虹表") + print("2 . 破解哈希函数") + print("3 . 刷新参考文件(删除参考文件中密码上所有已使用的标记)") + print("4 . 退出程序") + break + else: + print("文件名不存在,请输入另一个文件") + pass + + + elif (chioce == 2): + filename = 'Rainbow.txt' + if (Path(str(filename)).exists()): + readpasswordhash = pd.read_csv(filename, sep=' ', names=['password', 'passwordhash']) + unused = [] + df = pd.read_csv(passwordFileArg, header=None) + df = df.replace(np.nan, 'null', regex=True) + while True: + hash = input("请输入有效的哈希值进行破解 \n") + if (len(hash) == 32): + print( + "----------------------------------------------------------------------------------------------------------------------") + print("不支持彩虹表的重新哈希和追加功能") + print( + "\n请注意以下密码未被散列(错误)或未在参考文件中进行标记 : ") + df2 = df + df = [x[:-4] if x[-4:] == 'used' else x for x in df[0]] + dfreport = [x[:-4] if x[-4:] == 'used' else unused.append(x) for x in df2[0]] + if (len(unused) != 0 and len(unused) != len(df)): + for i in range(len(unused)): + print(unused[i]) + elif (len(unused) == len(df)): + print("参考文件密码已取消标记。请考虑重新设置密码") + else: + print('参考文件散列中的所有密码都已被标记使用') + print( + "----------------------------------------------------------------------------------------------------------------------") + instance = RainbowTable([], 5, pd.DataFrame(df), createList(0, len(df) - 1), lmhash.hash, + []) + instance.crack(hash, readpasswordhash) + print("1 . 生成彩虹表") + print("2 . 破解哈希函数") + print( + "3 . 刷新参考文件(删除参考文件中密码上所有已使用的标记)") + print("4 . 退出程序") + break + else: + print("WARNING: 输入的不是32位hash") + pass + else: + print("***************彩虹表不存在,请生成彩虹表") + print("1 . 生成彩虹表") + print("2 . 破解哈希函数") + print("3 . 刷新参考文件(删除参考文件中密码上所有已使用的标记)") + print("4 . 退出程序") + pass + elif (chioce == 3): + while True: + if (Path(str(passwordFileArg)).exists()): + df = pd.read_csv(passwordFileArg, header=None) + df = df.replace(np.nan, 'null', regex=True) + df = [str(x[:-4]) if str(x[-4:]) == 'used' else str(x) for x in df[0]] + df = pd.DataFrame(df) + instance = RainbowTable([], 5, df, createList(0, len(df) - 1), lmhash.hash, []) + with open(passwordFileArg, 'w') as sortedbooks: + for i in instance.progressbar(range(len(df)), "Computing: ", 60): + sortedbooks.writelines(str(df[0][i]) + '\n') + print("1 . 生成彩虹表") + print("2 . 破解哈希函数") + print("3 . 刷新参考文件(删除参考文件中密码上所有已使用的标记)") + print("4 . 退出程序") + + break + else: + print("没有找到密码参考文件") + passwordFileArg = input("请再次输入密码文件名") + pass + else: + break + + except ValueError: + print('Please enter a valid chioce//输入有效选择.') + + +if __name__ == "__main__": + main() + + + + + + + + + + + +