Initial Commit
commit
f443485a6a
|
@ -0,0 +1,107 @@
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# celery beat schedule file
|
||||||
|
celerybeat-schedule
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
|
||||||
|
# Node
|
||||||
|
node_modules/
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 VTRUST
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,56 @@
|
||||||
|
# smarthome-smarthack
|
||||||
|
Here you can find scripts to upgrade certain IoT-devices using esp8266 to any firmware without soldering etc.
|
||||||
|
The devices and methods were analyzed and described at the 35c3 conference in Germany.
|
||||||
|
The talk "Smart home - Smart hack" from Michael Steigerwald can be viewed here:
|
||||||
|
https://media.ccc.de/v/35c3-9723-smart_home_-_smart_hack
|
||||||
|
|
||||||
|
!!! USE THIS SCRIPTS AT YOUR OWN RISK !!!
|
||||||
|
|
||||||
|
## REQUIREMENTS
|
||||||
|
These scripts were tested in
|
||||||
|
* Kali-Linux 2018.4 in VMWARE
|
||||||
|
* a Raspberry Pi 3B+ + USB-WIFI with this image from [here](https://www.offensive-security.com/kali-linux-arm-images/)
|
||||||
|
https://images.offensive-security.com/arm-images/kali-linux-2018.4a-rpi3-nexmon-64.img.xz
|
||||||
|
|
||||||
|
Any Linux with a Wifi which can act as an Access Point should work.
|
||||||
|
We did not succeed to use the built-in Wifi of a Raspberry Pi 3B+ or 3B
|
||||||
|
|
||||||
|
## PROCEDURE
|
||||||
|
### INSTALLATION
|
||||||
|
# git clone https://github.com/vtrust-de/smarthome-smarthack
|
||||||
|
# cd smarthome-smarthack
|
||||||
|
# ./install_prereq.sh
|
||||||
|
### FLASH loader firmware + backup
|
||||||
|
# ./start_flash.sh
|
||||||
|
|
||||||
|
Follow the instructions and our FLASH loader will be installed in the esp8266.
|
||||||
|
After it will connect with a static IP to the WIFI
|
||||||
|
|
||||||
|
WIFI: vtrust-flash
|
||||||
|
PASS: flashmeifyoucan
|
||||||
|
IP: 10.42.42.42
|
||||||
|
A backup of the original firmware will be created and stored locally
|
||||||
|
### Device information
|
||||||
|
During loading some information about your device will been shown.
|
||||||
|
You can see them in a browser or by using following command:
|
||||||
|
|
||||||
|
# curl http://10.42.42.42
|
||||||
|
### BACKUP only and UNDO
|
||||||
|
You can use the FLASH loader to create a backup only.
|
||||||
|
If you want to delete the FLASH loader out of the flash again and go back to the stock software just do following:
|
||||||
|
|
||||||
|
# curl http://10.42.42.42/undo
|
||||||
|
### FLASH loader to user2
|
||||||
|
The FLASH loader only allows flashing the thirdparty firmware, if the loader is running in the userspace user2 starting from 0x81000.
|
||||||
|
This will flash the FLASH loader in user2 if it is not already there.
|
||||||
|
It will destroy your ability to undo and go back to the original firmware
|
||||||
|
|
||||||
|
# curl http://10.42.42.42/flash2
|
||||||
|
### FLASH third-party firmware
|
||||||
|
BE SURE THE FIRMWARE FITS YOUR DEVICE!
|
||||||
|
Place or link your binary file to ./files/thirdparty.bin
|
||||||
|
|
||||||
|
# curl http://10.42.42.42/flash3
|
||||||
|
## EXAMPLE
|
||||||
|
Here you can see a recording of the full process:
|
||||||
|
https://asciinema.org/a/2aDZweVGfliwc9TjB1ncwmKvm
|
|
@ -0,0 +1,10 @@
|
||||||
|
# Please input the good wlan device (most of the time it is wlan0 or wlan1)
|
||||||
|
WLAN=wlan0
|
||||||
|
|
||||||
|
# The ETH device should be connected to the internet but it should also work if it is a local network only
|
||||||
|
ETH=eth0
|
||||||
|
|
||||||
|
# Here you could change the WIFI-name and password but most likely most scripts won't work after
|
||||||
|
# Because the WIFI-credentials are hardcoded in the esp8266-ota-flash-convert
|
||||||
|
AP=vtrust-flash
|
||||||
|
PASS=flashmeifyoucan
|
|
@ -0,0 +1 @@
|
||||||
|
esp8266-ota-flash-convert_upg.bin
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
Put_a_Link_To_a_File_You_Like_to_upload(with_OTA)_here
|
|
@ -0,0 +1 @@
|
||||||
|
esp8266-ota-flash-convert.ino-0x81000.bin
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
curl -sL https://deb.nodesource.com/setup_11.x | sudo -E bash -
|
||||||
|
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get upgrade -y
|
||||||
|
sudo apt-get install -y dnsmasq hostapd screen curl python-pip python-setuptools python-wheel mosquitto nodejs
|
||||||
|
|
||||||
|
sudo pip install paho-mqtt pyaes tornado http
|
||||||
|
|
||||||
|
pushd scripts/smartconfig
|
||||||
|
npm i
|
||||||
|
popd
|
||||||
|
|
||||||
|
echo "Ready to start upgrade"
|
|
@ -0,0 +1,44 @@
|
||||||
|
#!/usr/bin/python2
|
||||||
|
# encoding: utf-8
|
||||||
|
"""
|
||||||
|
backup.py
|
||||||
|
|
||||||
|
Created by nano on 2019-01-10.
|
||||||
|
Copyright (c) 2019 VTRUST GmbH. All rights reserved.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import http.client
|
||||||
|
from binascii import unhexlify
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
DEVICE_IP = "10.42.42.42"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("Create backup of entire FLASH from %s" % DEVICE_IP )
|
||||||
|
data = b""
|
||||||
|
conn = http.client.HTTPConnection(DEVICE_IP)
|
||||||
|
conn.request("GET","/flashsize")
|
||||||
|
flashsize = int(conn.getresponse().read())
|
||||||
|
print("Connected... Flashsize=",flashsize)
|
||||||
|
for address in range(0,flashsize,1024):
|
||||||
|
conn.request("GET", "/get?read=%X" % address )
|
||||||
|
r1 = conn.getresponse()
|
||||||
|
# print(r1.status, r1.reason)
|
||||||
|
block = r1.read().split(b'\n')
|
||||||
|
print(block[0])
|
||||||
|
data += block[1]
|
||||||
|
conn.close()
|
||||||
|
bindata = unhexlify(data)
|
||||||
|
f= open(datetime.datetime.now().strftime("../%Y-%m-%d_%H-%M-%S_readout.bin"),"wb")
|
||||||
|
f.write(bindata)
|
||||||
|
f.close
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
# encoding: utf-8
|
||||||
|
"""
|
||||||
|
mq_pub_15.py
|
||||||
|
Created by nano on 2018-11-22.
|
||||||
|
Copyright (c) 2018 VTRUST. All rights reserved.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import tornado.web
|
||||||
|
import os
|
||||||
|
import hashlib
|
||||||
|
def file_as_bytes(file):
|
||||||
|
with file:
|
||||||
|
return file.read()
|
||||||
|
|
||||||
|
from tornado.options import define, options, parse_command_line
|
||||||
|
|
||||||
|
define("port", default=80, help="run on the given port", type=int)
|
||||||
|
define("debug", default=True, help="run in debug mode")
|
||||||
|
|
||||||
|
class FilesHandler(tornado.web.StaticFileHandler):
|
||||||
|
def parse_url_path(self, url_path):
|
||||||
|
if not url_path or url_path.endswith('/'):
|
||||||
|
url_path = url_path + str('index.html')
|
||||||
|
return url_path
|
||||||
|
|
||||||
|
class MainHandler(tornado.web.RequestHandler):
|
||||||
|
def get(self):
|
||||||
|
self.write("Hello, world")
|
||||||
|
|
||||||
|
class JSONHandler(tornado.web.RequestHandler):
|
||||||
|
def get(self):
|
||||||
|
print('\n')
|
||||||
|
print('URI:'+str(self.request.uri))
|
||||||
|
self.write('Hello Human, Do you have IOT?')
|
||||||
|
def post(self):
|
||||||
|
print('\n')
|
||||||
|
uri = str(self.request.uri)
|
||||||
|
a = str(self.get_argument('a'))
|
||||||
|
print('URI:'+uri)
|
||||||
|
|
||||||
|
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'
|
||||||
|
)
|
||||||
|
|
||||||
|
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)
|
||||||
|
#os.system("killall smartconfig.js")
|
||||||
|
|
||||||
|
elif(".active" in a):
|
||||||
|
print("Answer s.gw.dev.pk.active")
|
||||||
|
index = uri.find("gwId=")+5
|
||||||
|
gwId = uri[index:index+20]
|
||||||
|
print("READ GW ID",gwId)
|
||||||
|
answer =(b'{"result":'
|
||||||
|
b'{'
|
||||||
|
b'"schema":"[{'
|
||||||
|
b'\\"mode\\":\\"rw\\",'
|
||||||
|
b'\\"property\\":{\\"type\\":\\"bool\\"},\\"id\\":1,\\"type\\":\\"obj\\"},'
|
||||||
|
b'{\\"mode\\":\\"rw\\",'
|
||||||
|
b'\\"property\\":{\\"min\\":0,\\"max\\":86400,\\"scale\\":0,\\"step\\":1,\\"type\\":\\"value\\"},'
|
||||||
|
b'\\"id\\":9,\\"type\\":\\"obj\\"'
|
||||||
|
b'}]",'
|
||||||
|
b'"uid":"00000000000000000000","devEtag":"0000000000","secKey":"0000000000000000","schemaId":"0000000000","localKey":"0000000000000000"'
|
||||||
|
b'},'
|
||||||
|
b'"t":7,"e":false,"success":true}\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
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(".upgrade" in a):
|
||||||
|
print("Answer s.gw.upgrade")
|
||||||
|
#Fixme
|
||||||
|
#Calculate MD5 and Filesize
|
||||||
|
file_md5 = hashlib.md5(file_as_bytes(open('../files/1.bin', 'rb'))).hexdigest()
|
||||||
|
file_len = os.path.getsize('../files/1.bin')
|
||||||
|
answer = b'{"result":{"auto":3,"fileSize":"%d","etag":"0000000000","version":"9.0.0","url":"http://10.42.42.1/files/1.bin","md5":"%s"},"t":100,"e":false,"success":true}' % (file_len,file_md5.encode('utf-8'))
|
||||||
|
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(".debug.log" in a):
|
||||||
|
print("Answer atop.online.debug.log")
|
||||||
|
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)
|
||||||
|
|
||||||
|
elif(".update" in a):
|
||||||
|
print("Answer s.gw.update")
|
||||||
|
answer =b'{"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)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("WARN: unknown request: {} ({})".format(a,uri))
|
||||||
|
self.write("WARN: unknown request: "+uri)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parse_command_line()
|
||||||
|
app = tornado.web.Application(
|
||||||
|
[
|
||||||
|
(r"/", MainHandler),
|
||||||
|
(r"/gw.json", JSONHandler),
|
||||||
|
('/files/(.*)', FilesHandler, {'path': str('../files/')}),
|
||||||
|
],
|
||||||
|
#template_path=os.path.join(os.path.dirname(__file__), "templates"),
|
||||||
|
#static_path=os.path.join(os.path.dirname(__file__), "static"),
|
||||||
|
debug=options.debug,
|
||||||
|
)
|
||||||
|
app.listen(options.port)
|
||||||
|
print("Listening on port "+str(options.port))
|
||||||
|
tornado.ioloop.IOLoop.current().start()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -0,0 +1,110 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
# encoding: utf-8
|
||||||
|
"""
|
||||||
|
mq_pub_15.py
|
||||||
|
Created by nano on 2018-11-22.
|
||||||
|
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
|
||||||
|
|
||||||
|
help_message = '''USAGE:
|
||||||
|
"-i"/"--deviceID"
|
||||||
|
"-l"/"--localKey" [default=0000000000000000]
|
||||||
|
"-b"/"--broker" [default=127.0.0.1]
|
||||||
|
iot:
|
||||||
|
%s -i 43511212112233445566 -l a1b2c3d4e5f67788''' % (sys.argv[0].split("/")[-1])
|
||||||
|
|
||||||
|
class iotAES(object):
|
||||||
|
def __init__(self, key):
|
||||||
|
self.bs = 16
|
||||||
|
self.key = key
|
||||||
|
def encrypt(self, raw):
|
||||||
|
_ = self._pad(raw)
|
||||||
|
cipher = pyaes.blockfeeder.Encrypter(pyaes.AESModeOfOperationECB(self.key))
|
||||||
|
crypted_text = cipher.feed(raw)
|
||||||
|
crypted_text += cipher.feed()
|
||||||
|
crypted_text_b64 = base64.b64encode(crypted_text)
|
||||||
|
return crypted_text_b64
|
||||||
|
def decrypt(self, enc):
|
||||||
|
enc = base64.b64decode(enc)
|
||||||
|
cipher = pyaes.blockfeeder.Decrypter(pyaes.AESModeOfOperationECB(self.key))
|
||||||
|
plain_text = cipher.feed(enc)
|
||||||
|
plain_text += cipher.feed()
|
||||||
|
return plain_text
|
||||||
|
def _pad(self, s):
|
||||||
|
padnum = self.bs - len(s) % self.bs
|
||||||
|
return s + padnum * chr(padnum).encode()
|
||||||
|
@staticmethod
|
||||||
|
def _unpad(s):
|
||||||
|
return s[:-ord(s[len(s)-1:])]
|
||||||
|
def iot_dec(message,local_key):
|
||||||
|
iot_aes = iotAES(local_key)
|
||||||
|
message_clear = iot_aes.decrypt(message[19:])
|
||||||
|
print (message_clear)
|
||||||
|
return message_clear
|
||||||
|
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
|
||||||
|
# print (preMd5String)
|
||||||
|
m.update(preMd5String)
|
||||||
|
md5sum = m.hexdigest()
|
||||||
|
print (md5sum) #ca2b66d33d3f50a1 #ca2b66d33d3f50a1
|
||||||
|
messge_enc = PROTOCOL_VERSION_BYTES + md5sum[8:][:16].encode('latin1') + messge_enc
|
||||||
|
print (messge_enc)
|
||||||
|
return messge_enc
|
||||||
|
|
||||||
|
class Usage(Exception):
|
||||||
|
def __init__(self, msg):
|
||||||
|
self.msg = msg
|
||||||
|
|
||||||
|
def main(argv=None):
|
||||||
|
broker='127.0.0.1'
|
||||||
|
localKey = "0000000000000000"
|
||||||
|
deviceID = ""
|
||||||
|
if argv is None:
|
||||||
|
argv = sys.argv
|
||||||
|
try: #getopt
|
||||||
|
try:
|
||||||
|
opts, args = getopt.getopt(argv[1:], "hl:i:vb:", ["help", "localKey=", "deviceID=", "broker="])
|
||||||
|
except:
|
||||||
|
raise Usage(help_message)
|
||||||
|
|
||||||
|
# option processing
|
||||||
|
for option, value in opts:
|
||||||
|
if option == "-v":
|
||||||
|
verbose = True
|
||||||
|
if option in ("-h", "--help"):
|
||||||
|
raise Usage(help_message)
|
||||||
|
if option in ("-l", "--localKey"):
|
||||||
|
localKey = value
|
||||||
|
if option in ("-i", "--deviceID"):
|
||||||
|
deviceID = value
|
||||||
|
if option in ("-b", "--broker"):
|
||||||
|
broker = value
|
||||||
|
|
||||||
|
if (len(localKey)<10):
|
||||||
|
raise Usage(help_message)
|
||||||
|
if (len(deviceID)<10):
|
||||||
|
raise Usage(help_message) #
|
||||||
|
except Usage:
|
||||||
|
print (sys.argv[0].split("/")[-1] + ": ")
|
||||||
|
print ("\t for help use --help")
|
||||||
|
print (help_message)
|
||||||
|
return 2
|
||||||
|
|
||||||
|
message = '{"data":{"gwId":"%s"},"protocol":15,"s":%d,"t":%d}' %(deviceID,1523715,time.time())
|
||||||
|
m1 = iot_enc(message,localKey)
|
||||||
|
|
||||||
|
client = mqtt.Client("P1")
|
||||||
|
client.connect(broker)
|
||||||
|
client.publish("smart/device/in/%s" % (deviceID),m1)
|
||||||
|
client.disconnect()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
|
@ -0,0 +1,94 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Source config
|
||||||
|
. ../config.txt
|
||||||
|
|
||||||
|
echo "Backing up NetworkManager.cfg..."
|
||||||
|
sudo cp /etc/NetworkManager/NetworkManager.conf /etc/NetworkManager/NetworkManager.conf.backup
|
||||||
|
|
||||||
|
cat <<- EOF > /etc/NetworkManager/NetworkManager.conf
|
||||||
|
[main]
|
||||||
|
plugins=keyfile
|
||||||
|
|
||||||
|
[keyfile]
|
||||||
|
unmanaged-devices=interface-name:$WLAN
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Restarting NetworkManager..."
|
||||||
|
sudo service network-manager restart
|
||||||
|
sudo ifconfig $WLAN up
|
||||||
|
|
||||||
|
echo "Backing up /etc/dnsmasq.conf..."
|
||||||
|
sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.backup
|
||||||
|
|
||||||
|
|
||||||
|
echo "Writing dnsmasq config file..."
|
||||||
|
echo "Creating new /etc/dnsmasq.conf..."
|
||||||
|
cat <<- EOF >/etc/dnsmasq.conf
|
||||||
|
# disables dnsmasq reading any other files like /etc/resolv.conf for nameservers
|
||||||
|
no-resolv
|
||||||
|
# Interface to bind to
|
||||||
|
interface=$WLAN
|
||||||
|
#Specify starting_range,end_range,lease_time
|
||||||
|
dhcp-range=10.42.42.10,10.42.42.40,12h
|
||||||
|
# dns addresses to send to the clients
|
||||||
|
server=9.9.9.9
|
||||||
|
server=1.1.1.1
|
||||||
|
address=/tuya.com/10.42.42.1
|
||||||
|
address=/tuyaeu.com/10.42.42.1
|
||||||
|
address=/tuyaus.com/10.42.42.1
|
||||||
|
address=/tuyacn.com/10.42.42.1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Writing hostapd config file..."
|
||||||
|
cat <<- EOF >/etc/hostapd/hostapd.conf
|
||||||
|
interface=$WLAN
|
||||||
|
driver=nl80211
|
||||||
|
ssid=$AP
|
||||||
|
hw_mode=g
|
||||||
|
channel=1
|
||||||
|
macaddr_acl=0
|
||||||
|
auth_algs=1
|
||||||
|
ignore_broadcast_ssid=0
|
||||||
|
wpa=2
|
||||||
|
wpa_passphrase=$PASS
|
||||||
|
wpa_key_mgmt=WPA-PSK
|
||||||
|
wpa_pairwise=TKIP
|
||||||
|
rsn_pairwise=CCMP
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Configuring AP interface..."
|
||||||
|
sudo ifconfig $WLAN up 10.42.42.1 netmask 255.255.255.0
|
||||||
|
echo "Applying iptables rules..."
|
||||||
|
sudo iptables --flush
|
||||||
|
sudo iptables --table nat --flush
|
||||||
|
sudo iptables --delete-chain
|
||||||
|
sudo iptables --table nat --delete-chain
|
||||||
|
sudo iptables --table nat --append POSTROUTING --out-interface $ETH -j MASQUERADE
|
||||||
|
sudo iptables --append FORWARD --in-interface $WLAN -j ACCEPT
|
||||||
|
|
||||||
|
echo "Starting DNSMASQ server..."
|
||||||
|
sudo /etc/init.d/dnsmasq stop > /dev/null 2>&1
|
||||||
|
sudo pkill dnsmasq
|
||||||
|
sudo dnsmasq
|
||||||
|
|
||||||
|
sudo sysctl -w net.ipv4.ip_forward=1 > /dev/null 2>&1
|
||||||
|
|
||||||
|
sudo ip route add 255.255.255.255 dev $WLAN
|
||||||
|
|
||||||
|
|
||||||
|
echo "Starting AP on $WLAN in screen terminal..."
|
||||||
|
sudo hostapd /etc/hostapd/hostapd.conf
|
||||||
|
|
||||||
|
sudo rm /etc/NetworkManager/NetworkManager.conf > /dev/null 2>&1
|
||||||
|
sudo mv /etc/NetworkManager/NetworkManager.conf.backup /etc/NetworkManager/NetworkManager.conf
|
||||||
|
sudo service network-manager restart
|
||||||
|
sudo /etc/init.d/dnsmasq stop > /dev/null 2>&1
|
||||||
|
sudo pkill dnsmasq
|
||||||
|
sudo rm /etc/dnsmasq.conf > /dev/null 2>&1
|
||||||
|
sudo mv /etc/dnsmasq.conf.backup /etc/dnsmasq.conf > /dev/null 2>&1
|
||||||
|
sudo rm /etc/dnsmasq.hosts > /dev/null 2>&1
|
||||||
|
sudo iptables --flush
|
||||||
|
sudo iptables --flush -t nat
|
||||||
|
sudo iptables --delete-chain
|
||||||
|
sudo iptables --table nat --delete-chain
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "tuya-helper",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Send Smartlink Packets to Devices",
|
||||||
|
"main": "smartconfig.js",
|
||||||
|
"keywords": [
|
||||||
|
"tuya",
|
||||||
|
"cli",
|
||||||
|
"iot"
|
||||||
|
],
|
||||||
|
"author": "Zimbo Boyd <zimbo.boyd@gmail.com> (https://vtrust.de)",
|
||||||
|
"license": "MIT",
|
||||||
|
"homepage": "https://github.com/vtrust-de/smarthack",
|
||||||
|
"dependencies": {
|
||||||
|
"@tuyapi/link": "^0.2.0",
|
||||||
|
"debug": "^4.1.1",
|
||||||
|
"ora": "^3.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"xo": "^0.21.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
//cmd = system("ip route add 255.255.255.255 dev wlan0")
|
||||||
|
// --> Broadcast must be routed over WIFI
|
||||||
|
// --> Any other WIFI device needs to be connected during pairing process!
|
||||||
|
|
||||||
|
const ssid = "vtrust-flash"
|
||||||
|
const passwd = "flashmeifyoucan"
|
||||||
|
const wait_time = 60; // seconds
|
||||||
|
|
||||||
|
function sleep(seconds){
|
||||||
|
var waitUntil = new Date().getTime() + seconds*1000;
|
||||||
|
while(new Date().getTime() < waitUntil) true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const debug = require('debug')('Main');
|
||||||
|
//const ora = require('ora');
|
||||||
|
|
||||||
|
const TuyaLink = require('@tuyapi/link');
|
||||||
|
const manual = new TuyaLink.manual();
|
||||||
|
|
||||||
|
console.log('Put Device in Learn Mode!, sending Smartlink Packets now');
|
||||||
|
|
||||||
|
manual.registerSmartLink({region: 'EU',
|
||||||
|
token: '00000000',
|
||||||
|
secret: '0101',
|
||||||
|
ssid: ssid,
|
||||||
|
wifiPassword: passwd});
|
||||||
|
|
||||||
|
console.log('Smartlink in progress');
|
||||||
|
console.log('Sending SSID '+ssid);
|
||||||
|
console.log('Sending wifiPassword '+passwd);
|
||||||
|
console.log('Sending Packets and wait '+wait_time+' seconds.');
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
echo "Trigger upgrade in 10 seconds"
|
||||||
|
sleep 10
|
||||||
|
python mq_pub_15.py -i $1
|
|
@ -0,0 +1,87 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
. ./config.txt
|
||||||
|
|
||||||
|
./stop_flash.sh >/dev/null
|
||||||
|
|
||||||
|
pushd scripts
|
||||||
|
|
||||||
|
echo "======================================================"
|
||||||
|
echo "SMARTHOME-SMARTHACK"
|
||||||
|
echo "https://github.com/vtrust-de/smarthome-smarthack"
|
||||||
|
echo "USE AT YOUR OWN RISK!!!"
|
||||||
|
echo "======================================================"
|
||||||
|
echo " Starting AP in a screen"
|
||||||
|
sudo screen -S smarthack-wifi -m -d ./setup_ap.sh
|
||||||
|
|
||||||
|
|
||||||
|
echo " Stopping any Webserver"
|
||||||
|
sudo service apache2 stop >/dev/null 2>&1
|
||||||
|
|
||||||
|
echo " Starting Websever in a screen"
|
||||||
|
sudo screen -S smarthack-web -m -d ./fake-registration-server.py
|
||||||
|
|
||||||
|
service mosquitto stop >/dev/null 2>&1
|
||||||
|
echo " Starting Mosquitto in a screen"
|
||||||
|
sudo screen -S smarthack-mqtt -m -d mosquitto -v
|
||||||
|
echo
|
||||||
|
echo "======================================================"
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo "USE AT YOUR OWN RISK!!!"
|
||||||
|
echo "IMPORTANT"
|
||||||
|
echo "1. Connect any another device (a smartphone or something) to the WIFI $AP"
|
||||||
|
echo " The wpa-password is $PASS"
|
||||||
|
echo " This step is IMPORTANT otherwise the smartconfig will not work!"
|
||||||
|
echo "2. Put your IoT device in autoconfig/smartconfig/paring mode (LED will blink fast)"
|
||||||
|
echo "3. Press ENTER to continue"
|
||||||
|
read x
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo "======================================================"
|
||||||
|
echo "Starting pairing procedure in screen"
|
||||||
|
sudo ip route add 255.255.255.255 dev $WLAN
|
||||||
|
sudo screen -S smarthack-smartconfig -m -d ./smartconfig/smartconfig.js
|
||||||
|
|
||||||
|
|
||||||
|
echo "Waiting for the upgraded device to appear"
|
||||||
|
|
||||||
|
while ! timeout 0.2 ping -c 1 -n 10.42.42.42 &> /dev/null
|
||||||
|
do
|
||||||
|
printf "."
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "IoT-device is online with ip 10.42.42.42"
|
||||||
|
echo "Fetching firmware backup"
|
||||||
|
sleep 2
|
||||||
|
./backup.py
|
||||||
|
|
||||||
|
popd
|
||||||
|
|
||||||
|
echo "======================================================"
|
||||||
|
echo "Getting Info from IoT-device"
|
||||||
|
curl http://10.42.42.42 2> /dev/null | tee device-info.txt
|
||||||
|
echo
|
||||||
|
echo "======================================================"
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo "Next steps:"
|
||||||
|
echo "1. To go back to the orginal software"
|
||||||
|
echo " # curl http://10.42.42.42/undo"
|
||||||
|
echo
|
||||||
|
echo "2. Be sure the conversion software runs in user2"
|
||||||
|
echo " # curl http://10.42.42.42/flash2"
|
||||||
|
echo
|
||||||
|
echo "3. Flash a third party firmware to the device"
|
||||||
|
echo "BE SURE THE FIRMWARE FITS TO THE DEVICE"
|
||||||
|
echo "MAXIMUM SIZE IS 512KB"
|
||||||
|
echo "put or link it to ./files/thirdparty.bin"
|
||||||
|
echo " # curl http://10.42.42.42/flash3"
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo "HAVE FUN!"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Stopping AP in a screen"
|
||||||
|
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'
|
Loading…
Reference in New Issue