forked from steadfasterX/lglaf
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathauth.py
78 lines (66 loc) · 2.89 KB
/
auth.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
#!/usr/bin/env python
#
# Challenge/Response for communication with LG devices in download mode (LAF).
#
# Copyright (C) 2015 Peter Wu <peter@lekensteyn.nl>
# Licensed under the MIT license <http://opensource.org/licenses/MIT>.
from Crypto.Cipher import AES
from contextlib import closing, contextmanager
import lglaf,argparse,logging,struct
_logger = logging.getLogger("auth")
parser = argparse.ArgumentParser()
parser = argparse.ArgumentParser(description='LG LAF Download Mode utility')
parser.add_argument("--auth", action="store_true", help="auth LAF")
parser.add_argument("--debug", action='store_true', help="Enable debug messages")
parser.add_argument("--skip-hello", action="store_true", help="Immediately send commands, skip HELO message")
def key_transform(old_key):
new_key = ''
for x in range(32,0,-1):
new_key += chr(ord(old_key[x-1]) - (x % 0x0C))
return new_key
def key_xoring(key2_t, kilo_challenge):
key2_t_xor = ''
i = 0
while i <= 28:
key2_t_xor += chr(ord(key2_t[i]) ^ ord(kilo_challenge[3]))
key2_t_xor += chr(ord(key2_t[i+1]) ^ ord(kilo_challenge[2]))
key2_t_xor += chr(ord(key2_t[i+2]) ^ ord(kilo_challenge[1]))
key2_t_xor += chr(ord(key2_t[i+3]) ^ ord(kilo_challenge[0]))
i = i + 4
return key2_t_xor
def do_aes_encrypt(key2_t_xor):
plaintext = b''
for k in range(0,16):
plaintext += chr(k)
obj = AES.new(key2_t_xor, AES.MODE_ECB)
return obj.encrypt(plaintext)
def do_challenge_response(comm):
request_kilo = lglaf.make_request(b'KILO', args=[b'CENT', b'\0\0\0\0', b'\0\0\0\0', b'\0\0\0\0'])
kilo_header, kilo_response = comm.call(request_kilo)
kilo_challenge = kilo_header[8:12]
chalstring = ":".join("{:02x}".format(ord(k)) for k in kilo_challenge)
_logger.debug("Challenge: %s" %chalstring)
print("Challenge: %s" %chalstring)
key2 = b'qndiakxxuiemdklseqid~a~niq,zjuxl' # if this doesnt work try 'lgowvqnltpvtgogwswqn~n~mtjjjqxro'
kilo_response = do_aes_encrypt(key_xoring(key_transform(key2), kilo_challenge))
respstring = ":".join("{:02x}".format(ord(m)) for m in kilo_response)
#_logger.debug("Response: %s" %respstring)
print("Response: %s" %respstring)
request_kilo_metr = lglaf.make_request(b'KILO', args=[b'METR', b'\0\0\0\0', b'\x02\0\0\0', b'\0\0\0\0'], body=bytes(kilo_response))
metr_header, metr_response = comm.call(request_kilo_metr)
def main():
args = parser.parse_args()
logging.basicConfig(format='%(name)s: %(levelname)s: %(message)s',
level=logging.DEBUG if args.debug else logging.INFO)
comm = lglaf.autodetect_device()
with closing(comm):
do_challenge_response(comm)
if not args.skip_hello:
lglaf.try_hello(comm)
if __name__ == '__main__':
try:
main()
except OSError as e:
# Ignore when stdout is closed in a pipe
if e.errno != 32:
raise