-
Notifications
You must be signed in to change notification settings - Fork 42
/
pwn_search.py
109 lines (88 loc) · 3.57 KB
/
pwn_search.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
"""Search online for pwned passwords."""
from machine import Pin, SPI
from hashlib import sha1
from ubinascii import hexlify
from urequests2 import get
from network import STA_IF, WLAN
import gc
from xpt2046 import Touch
from ili9341 import Display, color565
from xglcd_font import XglcdFont
from touch_keyboard import TouchKeyboard
from time import sleep
class PwnLookup(object):
"""Checks if password is pwned."""
def __init__(self, spi1, spi2, dc=4, cs1=16, rst=17, cs2=5, rotation=270):
"""Initialize PwnLookup."""
# Set up display
self.display = Display(spi1, dc=Pin(dc), cs=Pin(cs1), rst=Pin(rst),
width=320, height=240, rotation=rotation)
# Load font
self.unispace = XglcdFont('fonts/Unispace12x24.c', 12, 24)
# Set up Keyboard
self.keyboard = TouchKeyboard(self.display, self.unispace)
# Set up touchscreen
self.xpt = Touch(spi2, cs=Pin(cs2), int_pin=Pin(0),
int_handler=self.touchscreen_press)
self.wlan = WLAN(STA_IF)
def lookup(self, pwd):
"""Return the number of times password found in pwned database.
Args:
pwd: password to check
Returns:
integer: password hits from online pwned database.
Raises:
IOError: if there was an error due to WiFi network.
RuntimeError: if there was an error trying to fetch data from dB.
UnicodeError: if there was an error UTF_encoding the password.
"""
sha1pwd = sha1(pwd.encode('utf-8')).digest()
sha1pwd = hexlify(sha1pwd).upper().decode('utf-8')
head, tail = sha1pwd[:5], sha1pwd[5:]
if not self.wlan.isconnected():
raise IOError('WiFi network error')
hits = 0
gc.collect()
with get('https://api.pwnedpasswords.com/range/' + head) as response:
for line in response.iter_lines():
l = line.decode(response.encoding).split(":")
if l[0] == tail:
hits = int(l[1])
break
gc.collect()
return hits
def touchscreen_press(self, x, y):
"""Process touchscreen press events."""
if self.keyboard.handle_keypress(x, y, debug=False) is True:
self.keyboard.locked = True
pwd = self.keyboard.kb_text
self.keyboard.show_message("Searching...", color565(0, 0, 255))
try:
hits = self.lookup(pwd)
if hits:
# Password found
msg = "PASSWORD HITS: {0}".format(hits)
self.keyboard.show_message(msg, color565(255, 0, 0))
else:
# Password not found
msg = "PASSWORD NOT FOUND"
self.keyboard.show_message(msg, color565(0, 255, 0))
except Exception as e:
if hasattr(e, 'message'):
self.keyboard.show_message(e.message[:22],
color565(255, 255, 255))
else:
self.keyboard.show_message(str(e)[:22],
color565(255, 255, 255))
self.keyboard.waiting = True
self.keyboard.locked = False
def main():
"""Start PwnLookup."""
spi1 = SPI(1, baudrate=51200000,
sck=Pin(14), mosi=Pin(13), miso=Pin(12))
spi2 = SPI(2, baudrate=1000000,
sck=Pin(18), mosi=Pin(23), miso=Pin(19))
PwnLookup(spi1, spi2)
while True:
sleep(.1)
main()