mirror of
https://github.com/ct-Open-Source/tuya-convert.git
synced 2026-03-07 08:57:03 +01:00
Circumvent new tuya sdk protection
This commit is contained in:
@@ -9,6 +9,8 @@ Copyright (c) 2018 VTRUST. All rights reserved.
|
||||
import tornado.web
|
||||
import os
|
||||
import hashlib
|
||||
import hmac
|
||||
import binascii
|
||||
def file_as_bytes(file):
|
||||
with file:
|
||||
return file.read()
|
||||
@@ -32,7 +34,8 @@ class JSONHandler(tornado.web.RequestHandler):
|
||||
def get(self):
|
||||
print('\n')
|
||||
print('URI:'+str(self.request.uri))
|
||||
self.write('Hello Human, Do you have IOT?')
|
||||
#self.write('Hello Human, Do you have IOT?')
|
||||
self.post()
|
||||
def post(self):
|
||||
print('\n')
|
||||
uri = str(self.request.uri)
|
||||
@@ -42,7 +45,7 @@ class JSONHandler(tornado.web.RequestHandler):
|
||||
if(a == "s.gw.token.get"):
|
||||
print("Answer s.gw.token.get")
|
||||
answer =(b'{"result":{"gwApiUrl":"http://10.42.42.1/gw.json","stdTimeZone":"-05:00","mqttRanges":"","timeZone":"-05:00",'
|
||||
b'"httpsPSKUrl":"https://10.42.42.1/gw.json","mediaMqttUrl":"10.42.42.1","gwMqttUrl":"10.42.42.1","dstIntervals":[]},"t":7,"e":false,"success":true}\n'
|
||||
b'"httpsPSKUrl":"https://10.42.42.1/gw.json","mediaMqttUrl":"10.42.42.1","mqttsUrl":"10.42.42.1","gwMqttUrl":"10.42.42.1","dstIntervals":[]},"t":7,"e":false,"success":true}\n'
|
||||
)
|
||||
|
||||
self.set_header("Content-Type", "application/json;charset=UTF-8")
|
||||
@@ -71,22 +74,47 @@ class JSONHandler(tornado.web.RequestHandler):
|
||||
self.set_header('Content-Length', str(len(answer)))
|
||||
self.set_header('Content-Language', 'zh-CN')
|
||||
self.write(answer)
|
||||
print("TRIGGER UPGRADE IN 10 SECONDS")
|
||||
os.system("./trigger_upgrade.sh %s &" % str(gwId))
|
||||
elif(".dynamic.config.get" in a):
|
||||
print("Answer tuya.device.dynamic.config.get")
|
||||
index = uri.find("gwId=")+5
|
||||
gwId = uri[index:index+20]
|
||||
print("READ GW ID",gwId)
|
||||
answer = (b'{"result":'
|
||||
b'{'
|
||||
b'"ackId":"1234567", "time":"1", "validTime":"1",'
|
||||
b'"config":{"stdTimeZone":"UTC", "dstIntervals":"0"}'
|
||||
b'},'
|
||||
b'"t":9, "e":false,"success":true}')
|
||||
self.set_header("Content-Type", "application/json;charset=UTF-8")
|
||||
self.set_header('Content-Length', str(len(answer)))
|
||||
self.set_header('Content-Language', 'zh-CN')
|
||||
self.write(answer)
|
||||
|
||||
elif(".upgrade" in a):
|
||||
print("Answer s.gw.upgrade")
|
||||
elif(".upgrade.get" in a) or ('.upgrade.silent.get' in a):
|
||||
print("Answer s.gw.upgrade.get")
|
||||
#Fixme
|
||||
#Calculate MD5 and Filesize
|
||||
file_md5 = hashlib.md5(file_as_bytes(open('../files/upgrade.bin', 'rb'))).hexdigest()
|
||||
file_len = os.path.getsize('../files/upgrade.bin')
|
||||
answer = b'{"result":{"auto":3,"fileSize":"%d","etag":"0000000000","version":"9.0.0","url":"http://10.42.42.1/files/upgrade.bin","md5":"%s"},"t":100,"e":false,"success":true}' % (file_len,file_md5.encode('utf-8'))
|
||||
file_sha256 = hashlib.sha256(file_as_bytes(open('../files/upgrade.bin', 'rb'))).hexdigest().upper()
|
||||
file_hmac = hmac.HMAC(b'0000000000000000', file_sha256.encode(), 'sha256').hexdigest().upper()
|
||||
answer = b'{"result":{"auto":3,"size":"%d","type":9,"pskUrl":"https://10.42.42.1/files/upgrade.bin","hmac":"%s","version":"9.0.0"},"t":10,"e":false,"success":true}'%(file_len, file_hmac.encode())
|
||||
print(answer)
|
||||
self.set_header("Content-Type", "application/json;charset=UTF-8")
|
||||
self.set_header('Content-Length', str(len(answer)))
|
||||
self.set_header('Content-Language', 'zh-CN')
|
||||
self.write(answer)
|
||||
|
||||
elif(".dynamic.config.ack" in a):
|
||||
print("Answer tuya.device.dynamic.config.ack")
|
||||
answer =b'{"result":true,"t":7,"e":false,"success":true}'
|
||||
self.set_header("Content-Type", "application/json;charset=UTF-8")
|
||||
self.set_header('Content-Length', str(len(answer)))
|
||||
self.set_header('Content-Language', 'zh-CN')
|
||||
self.write(answer)
|
||||
print("TRIGGER UPGRADE IN 10 SECONDS")
|
||||
os.system("./trigger_upgrade.sh %s &" % str(gwId))
|
||||
|
||||
|
||||
elif(".debug.log" in a):
|
||||
print("Answer atop.online.debug.log")
|
||||
answer =b'{"result":true,"t":7,"e":false,"success":true}'
|
||||
|
||||
@@ -8,6 +8,7 @@ Copyright (c) 2018 VTRUST. All rights reserved.
|
||||
import sys, getopt, time, pyaes, base64
|
||||
import paho.mqtt.client as mqtt #pip install paho-mqtt
|
||||
from hashlib import md5
|
||||
import binascii
|
||||
|
||||
help_message = '''USAGE:
|
||||
"-i"/"--deviceID"
|
||||
@@ -25,8 +26,7 @@ class iotAES(object):
|
||||
cipher = pyaes.blockfeeder.Encrypter(pyaes.AESModeOfOperationECB(self.key.encode()))
|
||||
crypted_text = cipher.feed(raw)
|
||||
crypted_text += cipher.feed()
|
||||
crypted_text_b64 = base64.b64encode(crypted_text)
|
||||
return crypted_text_b64
|
||||
return crypted_text
|
||||
def decrypt(self, enc):
|
||||
enc = base64.b64decode(enc)
|
||||
cipher = pyaes.blockfeeder.Decrypter(pyaes.AESModeOfOperationECB(self.key))
|
||||
@@ -47,15 +47,11 @@ def iot_dec(message, local_key):
|
||||
def iot_enc(message, local_key):
|
||||
iot_aes = iotAES(local_key)
|
||||
messge_enc = iot_aes.encrypt(message)
|
||||
m = md5()
|
||||
PROTOCOL_VERSION_BYTES = b'2.1'
|
||||
# preMd5String = b'data=' + messge_enc + b'||lpv=' + PROTOCOL_VERSION_BYTES + b'||' + local_key
|
||||
preMd5String = b'data=' + messge_enc + b'||pv=' + PROTOCOL_VERSION_BYTES + b'||' + local_key.encode()
|
||||
# print (preMd5String)
|
||||
m.update(preMd5String)
|
||||
md5sum = m.hexdigest()
|
||||
print (md5sum) #ca2b66d33d3f50a1 #ca2b66d33d3f50a1
|
||||
messge_enc = PROTOCOL_VERSION_BYTES + md5sum[8:][:16].encode('latin1') + messge_enc
|
||||
message = b'%08d'%((int(time.time()*100)%100000000)) + messge_enc
|
||||
c = binascii.crc32(message)
|
||||
PROTOCOL_VERSION_BYTES = b'2.2'
|
||||
messge_enc = PROTOCOL_VERSION_BYTES + (c).to_bytes(4, byteorder='big') +message
|
||||
|
||||
print (messge_enc)
|
||||
return messge_enc
|
||||
|
||||
@@ -98,7 +94,8 @@ def main(argv=None):
|
||||
print (help_message)
|
||||
return 2
|
||||
|
||||
message = '{"data":{"gwId":"%s"},"protocol":15,"s":%d,"t":%d}' %(deviceID, 1523715, time.time())
|
||||
|
||||
message = '{"data":{"gwId":"%s"},"protocol":15,"s":"%d","t":"%d"}' %(deviceID, 1523715, time.time())
|
||||
m1 = iot_enc(message, localKey)
|
||||
|
||||
client = mqtt.Client("P1")
|
||||
|
||||
117
scripts/psk-frontend.py
Executable file
117
scripts/psk-frontend.py
Executable file
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import socket
|
||||
import select
|
||||
import ssl
|
||||
import sslpsk
|
||||
|
||||
from Crypto.Cipher import AES
|
||||
import hashlib
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
server_hint_hex = "316448527363324e6a62486c74624778336557683530303030303030303030303030303030"
|
||||
server_hint = unhexlify(server_hint_hex)
|
||||
|
||||
|
||||
def listener(host, port):
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sock.bind((host, port))
|
||||
sock.listen(1)
|
||||
return sock
|
||||
|
||||
def client(host, port):
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.connect((host, port))
|
||||
return sock
|
||||
|
||||
|
||||
def get_psk(identity):
|
||||
id = identity
|
||||
server_hint = unhexlify(server_hint_hex)
|
||||
|
||||
md5_uuid = id[17:(17+16)]
|
||||
source = id[1:50]
|
||||
|
||||
rand = server_hint[21:21+16]
|
||||
|
||||
key = hashlib.md5(rand).digest()
|
||||
to_encode = id[1:33]
|
||||
iv = hashlib.md5(source).digest()
|
||||
cipher = AES.new(key ,AES.MODE_CBC, iv)
|
||||
|
||||
c = cipher.encrypt(to_encode)
|
||||
print("PSK: %r"%(hexlify(c)))
|
||||
return c
|
||||
|
||||
|
||||
class PskFrontend():
|
||||
def __init__(self, listening_host, listening_port, host, port):
|
||||
self.listening_port = listening_port
|
||||
self.listening_host = listening_host
|
||||
self.host = host
|
||||
self.port = port
|
||||
|
||||
self.server_sock = listener(listening_host, listening_port)
|
||||
self.sessions = []
|
||||
self.hint = '1dHRsc2NjbHltbGx3eWh50000000000000000'
|
||||
|
||||
|
||||
|
||||
def readables(self):
|
||||
readables = [self.server_sock]
|
||||
for (s1, s2) in self.sessions:
|
||||
readables.append(s1)
|
||||
readables.append(s2)
|
||||
return readables
|
||||
|
||||
def new_client(self, s1):
|
||||
try:
|
||||
ssl_sock = sslpsk.wrap_socket(s1,
|
||||
server_side = True,
|
||||
ssl_version=ssl.PROTOCOL_TLSv1_2,
|
||||
ciphers='PSK-AES128-CBC-SHA256',
|
||||
psk=get_psk,
|
||||
hint=self.hint)
|
||||
|
||||
s2 = client(self.host, self.port)
|
||||
self.sessions.append((ssl_sock, s2))
|
||||
except:
|
||||
pass
|
||||
def data_ready_cb(self, s):
|
||||
if s == self.server_sock:
|
||||
_s, frm = s.accept()
|
||||
print("new client on port %d from %r"%(self.listening_port, frm))
|
||||
self.new_client(_s)
|
||||
|
||||
for (s1, s2) in self.sessions:
|
||||
if s == s1 or s == s2:
|
||||
c = s1 if s == s2 else s2
|
||||
try:
|
||||
buf = s.recv(4096)
|
||||
if len(buf) > 0:
|
||||
c.send(buf)
|
||||
else:
|
||||
s1.shutdown(socket.SHUT_RDWR)
|
||||
s2.shutdown(socket.SHUT_RDWR)
|
||||
self.sessions.remove((s1,s2))
|
||||
except:
|
||||
self.sessions.remove((s1,s2))
|
||||
|
||||
|
||||
def main():
|
||||
proxies = [PskFrontend('', 443, '127.0.0.1', 80), PskFrontend('', 8886, '127.0.0.1', 1883)]
|
||||
|
||||
|
||||
while True:
|
||||
readables = []
|
||||
for p in proxies:
|
||||
readables = readables + p.readables()
|
||||
r,_,_ = select.select(readables, [], [])
|
||||
for s in r:
|
||||
for p in proxies:
|
||||
p.data_ready_cb(s)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -44,6 +44,8 @@ $screen_with_log smarthack-web.log -S smarthack-web -m -d ./fake-registration-se
|
||||
echo " Starting Mosquitto in a screen"
|
||||
sudo service mosquitto stop >/dev/null 2>&1
|
||||
$screen_with_log smarthack-mqtt.log -S smarthack-mqtt -m -d mosquitto -v
|
||||
echo " Starting PSK frontend in a screen"
|
||||
$screen_with_log smarthack-psk.log -S smarthack-psk -m -d ./psk-frontend.py -v
|
||||
echo
|
||||
echo "======================================================"
|
||||
echo
|
||||
|
||||
@@ -5,3 +5,4 @@ sudo screen -S smarthack-wifi -X stuff '^C'
|
||||
sudo screen -S smarthack-web -X stuff '^C'
|
||||
sudo screen -S smarthack-smartconfig -X stuff '^C'
|
||||
sudo screen -S smarthack-mqtt -X stuff '^C'
|
||||
sudo screen -S smarthack-psk -X stuff '^C'
|
||||
|
||||
Reference in New Issue
Block a user