153 lines
6.0 KiB
Python
153 lines
6.0 KiB
Python
import hashlib
|
|
import random
|
|
import tkinter as tk
|
|
from tkinter import font as tkfont
|
|
from urllib.parse import urlencode
|
|
from urllib.request import urlopen
|
|
|
|
URL_FULL = "https://www.home.daprogs.net/pwn/indexapi.php"
|
|
URL_ZERO = "https://www.home.daprogs.net/pwn/zerotrust.php"
|
|
|
|
|
|
def compute_sha1(text: str) -> str:
|
|
return hashlib.sha1(text.encode("utf-8")).hexdigest()
|
|
|
|
|
|
def fetch(url: str, params: dict) -> str:
|
|
try:
|
|
with urlopen(f"{url}?{urlencode(params)}") as resp:
|
|
return resp.read().decode("utf-8")
|
|
except Exception as e:
|
|
return f"Request exception: {e}"
|
|
|
|
|
|
class App:
|
|
def __init__(self, root: tk.Tk):
|
|
self.root = root
|
|
root.title("Password Checker")
|
|
mono = tkfont.Font(family="Consolas", size=10)
|
|
|
|
tk.Label(root, text="Enter String").grid(row=0, column=0, columnspan=2, sticky="w")
|
|
self.txt_input = tk.Entry(root, font=mono, width=40)
|
|
self.txt_input.grid(row=1, column=0, sticky="we")
|
|
self.btn_hash = tk.Button(root, text="Hash", command=self.on_hash)
|
|
self.btn_hash.grid(row=1, column=1, sticky="we")
|
|
self.txt_output = tk.Entry(root, font=mono, width=40)
|
|
self.txt_output.grid(row=2, column=0, sticky="we")
|
|
self.btn_zero = tk.Button(root, text="ZeroTrust", command=self.on_zero_trust)
|
|
self.btn_zero.grid(row=2, column=1, sticky="we")
|
|
self.lbl_status = tk.Label(root, text="...")
|
|
self.lbl_status.grid(row=3, column=0, columnspan=2, sticky="w")
|
|
self.txt_result = tk.Entry(root, font=mono, width=50)
|
|
self.txt_result.grid(row=4, column=0, columnspan=2, sticky="we")
|
|
self.txt_desc = tk.Text(root, font=mono, width=50, height=12)
|
|
self.txt_desc.grid(row=5, column=0, columnspan=2, sticky="we")
|
|
self.btn_report = tk.Button(root, text="Create Report", command=self.on_create_report)
|
|
self.btn_report.grid(row=6, column=0, columnspan=2, sticky="we")
|
|
root.columnconfigure(0, weight=1)
|
|
root.bind("<Return>", lambda e: self.on_hash())
|
|
self.txt_input.focus_set()
|
|
|
|
def clear_fields(self):
|
|
self.txt_desc.delete("1.0", "end")
|
|
self.txt_output.delete(0, "end")
|
|
self.txt_result.delete(0, "end")
|
|
self.root_update()
|
|
|
|
def select_all_input(self):
|
|
self.txt_input.focus_set()
|
|
self.txt_input.selection_range(0, "end")
|
|
|
|
def root_update(self):
|
|
self.root.update()
|
|
|
|
def on_hash(self):
|
|
self.clear_fields()
|
|
h = compute_sha1(self.txt_input.get())
|
|
self.txt_output.insert(0, h)
|
|
self.lbl_status.config(text="web request...")
|
|
self.root_update()
|
|
ret = fetch(URL_FULL, {"sha1": h})
|
|
self.lbl_status.config(text="response...")
|
|
self.root_update()
|
|
self.txt_result.insert(0, ret)
|
|
self.lbl_status.config(text="...")
|
|
self.root_update()
|
|
if "BAD" in ret:
|
|
count = ret.split(":")[1].replace("\r\n", "")
|
|
self.txt_desc.insert("1.0",
|
|
"This password is in the master list.\r\n"
|
|
f"It has been seen {count} times\r\n"
|
|
"Even a value of 1 is bad.\r\n"
|
|
"You need to change this password ASAP!\r\n")
|
|
self.select_all_input()
|
|
|
|
def on_zero_trust(self):
|
|
self.clear_fields()
|
|
h = compute_sha1(self.txt_input.get())
|
|
self.txt_output.insert(0, h)
|
|
sha5 = h[:5]
|
|
start = random.randrange(6, 36)
|
|
sha6 = h[start:start + 3]
|
|
r_hash = h[5:]
|
|
self.txt_output.delete(0, "end")
|
|
self.txt_output.insert(0, r_hash)
|
|
self.lbl_status.config(text="web request...")
|
|
self.root_update()
|
|
ret = fetch(URL_ZERO, {"sha5": sha5, "sha6": sha6})
|
|
self.lbl_status.config(text="response...")
|
|
self.root_update()
|
|
self.lbl_status.config(text=f"request sent: {sha5}-{sha6}")
|
|
self.root_update()
|
|
if "BAD" in ret:
|
|
if r_hash.lower() in ret.lower():
|
|
self.txt_result.insert(0, "BAD - Your password is listed")
|
|
desc = ret.replace("BAD:\r\n", "")
|
|
self.txt_desc.insert("1.0", desc)
|
|
pos = desc.find(r_hash.upper())
|
|
if pos >= 0:
|
|
self.txt_desc.tag_add("sel", f"1.0+{pos}", f"1.0+{pos + 35}")
|
|
self.txt_desc.see(pos)
|
|
else:
|
|
self.txt_result.insert(0, "OK - Not in list")
|
|
else:
|
|
self.txt_result.insert(0, ret)
|
|
self.select_all_input()
|
|
|
|
def on_create_report(self):
|
|
self.clear_fields()
|
|
with open("passList-tci.csv", encoding="utf-8", errors="replace") as f:
|
|
pass_list = f.read().split("\r\n")
|
|
total = len(pass_list)
|
|
count = 0
|
|
with open("userReport-tci.txt", "w", encoding="utf-8") as out:
|
|
for item in pass_list:
|
|
if "," in item:
|
|
items = item.split(",")
|
|
email = items[0].split(";")[0] + "@" + items[2]
|
|
password = items[1]
|
|
if len(password) > 0:
|
|
h = compute_sha1(password)
|
|
self.txt_output.delete(0, "end")
|
|
self.txt_output.insert(0, h)
|
|
self.txt_result.delete(0, "end")
|
|
self.txt_result.insert(0, f"{count}/{total}")
|
|
self.lbl_status.config(text="web request...")
|
|
self.root_update()
|
|
ret = fetch(URL_FULL, {"sha1": h})
|
|
self.lbl_status.config(text="response...")
|
|
self.root_update()
|
|
if "BAD" in ret:
|
|
out.write(f"{email},Password is hacked!({ret.split(':')[1].replace(chr(13) + chr(10), '')})\n")
|
|
count += 1
|
|
self.txt_output.delete(0, "end")
|
|
self.txt_output.insert(0, "Complete.")
|
|
self.lbl_status.config(text="Complete.")
|
|
self.root_update()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
root = tk.Tk()
|
|
App(root)
|
|
root.mainloop()
|