Created
August 31, 2017 08:36
-
-
Save filviu/65177c3f49039e4947bf9e99410ab6a6 to your computer and use it in GitHub Desktop.
Python script to recover freeotp tokens. Not mine, but can't remember where I got it...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
from __future__ import print_function | |
import base64 | |
import ctypes | |
import json | |
import subprocess | |
import sys | |
import xml.etree.ElementTree as ET | |
from urllib.parse import urlencode | |
def main(): | |
tree = ET.parse(sys.argv[1]) | |
root = tree.getroot() | |
assert root.tag == 'map' | |
num = 1 | |
for child in root: | |
assert child.tag == 'string' | |
name = child.attrib['name'] | |
if name == 'tokenOrder': | |
continue | |
if ':' in name: | |
service, user = name.split(':', 1) | |
else: | |
user = name | |
service = 'Unknown' | |
info = json.loads(child.text) | |
#print("Info for %s: %r" % (name, info)) | |
# Ensure that we only have unsigned values, then get secret | |
secret_bytes = [ctypes.c_ubyte(x).value for x in info['secret']] | |
secret_hex = ''.join('%02X' % (x,) for x in secret_bytes) | |
secret = bytes.fromhex(secret_hex) | |
secret_b32 = base64.b32encode(secret) | |
# Make fancy URL. | |
params = { | |
'secret': secret_b32, | |
'issuer': service, | |
'counter': info['counter'], | |
'digits': info['digits'], | |
'period': info['period'], | |
'algorithm': info['algo'], | |
} | |
tmpl = 'otpauth://{type}/{service}:{user}?{params}' | |
url = tmpl.format( | |
type=info['type'].lower(), | |
service=service, | |
user=user, | |
params=urlencode(params), | |
) | |
print(url) | |
print("Displaying: {0}".format(name)) | |
process_qrencode = subprocess.Popen(['qrencode', '-s 12', '-o', '%d.png' % num , url], | |
stdout=subprocess.PIPE) | |
num = num + 1 | |
# process_display = subprocess.Popen([''], | |
# stdin=process_qrencode.stdout) | |
# Allow the qrencode to recieve a SIGPIPE if display exits | |
process_qrencode.stdout.close() | |
# process_display.communicate() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment