diff --git a/Pipfile b/Pipfile index c50dea4..929a865 100644 --- a/Pipfile +++ b/Pipfile @@ -7,6 +7,7 @@ verify_ssl = true [packages] requests = "*" +pyinstaller = "*" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index 9fc69f7..1441cb1 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "bb57e0d7853b45999e47c163c46b95bc2fde31c527d8d7b5b5539dc979444a6d" + "sha256": "38e2af2d59158d85bb4d55eb3140a0745c9eb21635643df4b2192cdd0abc2074" }, "pipfile-spec": 6, "requires": { @@ -16,6 +16,13 @@ ] }, "default": { + "altgraph": { + "hashes": [ + "sha256:d6814989f242b2b43025cba7161fc1b8fb487a62cd49c49245d6fd01c18ac997", + "sha256:ddf5320017147ba7b810198e0b6619bd7b5563aa034da388cea8546b877f9b0c" + ], + "version": "==0.16.1" + }, "certifi": { "hashes": [ "sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5", @@ -30,6 +37,13 @@ ], "version": "==3.0.4" }, + "future": { + "hashes": [ + "sha256:1d73b8a1aab19cb8c2c961ba82bf93860e1fb7d361be21e7288691c068cd3cfc", + "sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8" + ], + "version": "==0.17.1" + }, "idna": { "hashes": [ "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", @@ -37,6 +51,33 @@ ], "version": "==2.8" }, + "macholib": { + "hashes": [ + "sha256:ac02d29898cf66f27510d8f39e9112ae00590adb4a48ec57b25028d6962b1ae1", + "sha256:c4180ffc6f909bf8db6cd81cff4b6f601d575568f4d5dee148c830e9851eb9db" + ], + "version": "==1.11" + }, + "pefile": { + "hashes": [ + "sha256:a5d6e8305c6b210849b47a6174ddf9c452b2888340b8177874b862ba6c207645" + ], + "version": "==2019.4.18" + }, + "pyinstaller": { + "hashes": [ + "sha256:a5a6e04a66abfcf8761e89a2ebad937919c6be33a7b8963e1a961b55cb35986b" + ], + "index": "pypi", + "version": "==3.4" + }, + "pywin32-ctypes": { + "hashes": [ + "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942", + "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98" + ], + "version": "==0.2.0" + }, "requests": { "hashes": [ "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", diff --git a/src/have_I_b33n_pwned.py b/src/have_I_b33n_pwned.py new file mode 100644 index 0000000..5f598ad --- /dev/null +++ b/src/have_I_b33n_pwned.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python + +# have_I_b33n_pwned.py +# Check if your password (hash) appears in the leaked password database +# of haveibeenpwned.com +# +# Copyright (C) 2019 willipink.eu +# Author Moritz Münch moritzmuench@mailbox.org +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# updater script for nextcloud +# +# TODO +# - add feature: also check for email breaches +# - add feature: keepass integration? isnt there something like this already? + + + +from sys import argv, stdout +from hashlib import sha1 +from getpass import getpass +from requests import get + +RED = "\033[1;31m" +GREEN = "\033[0;32m" +RESET = "\033[0;0m" +API = 'https://api.pwnedpasswords.com/range/' +ROW = '{:<30}{:<10}{:<45}' +HIDDEN = False + + +def header(): + print() + print(ROW.format('password', 'leaked', 'sha1')) + print('-' * 80) + + +def prompt_password(): + print() + password = getpass('Tell me your password: ') + global HIDDEN + HIDDEN = True + header() + query(password) + + +def query(password): + password_hash = sha1(password.encode('UTF-8')).hexdigest().upper() + request = password_hash[:5] + response = get(API + request).text + hash_searched = 'not yet' + for answer in response.splitlines(): + data = answer.split(':') + combined_hash = request + data[0] + if password_hash == combined_hash: + hash_searched = int(data[1]) + break + + if hash_searched == 'not yet': + stdout.write(GREEN) + else: + stdout.write(RED) + + if HIDDEN: + password = '*' * len(password) + + print(ROW.format(password, hash_searched, password_hash)) + stdout.write(RESET) + + if HIDDEN: + prompt_password() + + +if __name__ == '__main__': + if len(argv) < 2: + prompt_password() + else: + header() + for password in argv[1:]: + query(password) + print() + exit(0)