commit a29ae1f57d40ec8f7e9f857eca06ead8bf0be9d5 Author: Shreyas Kapur Date: Mon May 15 08:54:22 2017 -0400 Init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e99e36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..4bb4818 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +## Duo One Time Password Generator + +This is a little script I put together after I reverse engineered the Duo 2FA Mobile App and figured out how their auth flow works. This can be ported into probably a useful desktop app or chrome extention and can probably be used to write bots for MIT Services that require auth. + +### Usage + +Install stuff, + +``` +pip install -r requirements.txt +``` + +Just grab the QR Code URL that starts with `duo://` and execute, + +``` +python duo_bypass.py duo://urlhere +``` + +### How does this work? + +It's pretty simple so I won't explain. The hard part was to read DUO's obfuscated code, because obfuscation makes things so secure. + +Why didn't I sniff? Because HTTPS and because they apparantly ignore trusted CA's on the Android Device and also the fact that I was too lazy to get a USB cable from my room and also that I didn't want to download a gigabyte of emulator. + +When I almost got all of it I realized I could have probably decompiled their Windows app, coz .NET and and coz they didn't obfuscate that. rip me. + +Anyway, it's 9 AM and I should sleep. \ No newline at end of file diff --git a/duo_bypass.py b/duo_bypass.py new file mode 100644 index 0000000..e758742 --- /dev/null +++ b/duo_bypass.py @@ -0,0 +1,29 @@ +import pyotp +import requests +import base64 +import json +import sys +from urllib2 import unquote + +if len(sys.argv) < 2: + print "Usage: python duo_bypass.py "; exit() + +qr_url = sys.argv[1] +data = unquote(qr_url.split('=')[1]) + +hostb64 = data.split('-')[1] + +host = base64.b64decode(hostb64 + '='*(-len(hostb64) % 4)) +code = data.split('-')[0].replace('duo://', '') + +url = 'https://{host}/push/v2/activation/{code}'.format(host=host, code=code) +r = requests.post(url) +response = json.loads(r.text) + +secret = base64.b32encode(response['response']['hotp_secret']) + +print "10 Next OneTime Passwords!" +# Generate 10 Otps! +hotp = pyotp.HOTP(secret) +for _ in xrange(10): + print hotp.at(_) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..b353458 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pyotp +requests \ No newline at end of file