add: ai generated SW/HW component overview
This commit is contained in:
@@ -11,8 +11,145 @@ TODO:
|
||||
|
||||
## 0.1 Services Running on the Device
|
||||
|
||||
The system consists of four parts that expose services: the lock (inner/motor module), the outer touch module, the bridge, and the cloud backends used by the LOQED and Shelly apps.
|
||||
|
||||
### Lock
|
||||
|
||||
Its only wireless interface is BLE.
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| Advertising name | `Loqed Inside` |
|
||||
| Address | `FF:EC:EE:E7:32:E5`, type PUBLIC (fixed, does not rotate) |
|
||||
| Advertising | Undirected, connectable |
|
||||
| Manufacturer data | Company ID `0xFFFF` (reserved/test ID), payload `0000` |
|
||||
|
||||
The GATT table could be enumerated without pairing and contains three services:
|
||||
|
||||
| Service | Characteristic | Properties | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| Generic Access (`0x1800`) | Device Name (`0x2A00`) | READ, WRITE | Value `Loqed Inside`. Declared writable. |
|
||||
| | Appearance (`0x2A01`) | READ | `0x0000` (unknown) |
|
||||
| | Peripheral Preferred Connection Parameters (`0x2A04`) | READ | `ffffffff0000ffff` (no preference) |
|
||||
| | Central Address Resolution (`0x2AA6`) | READ | `0x01` (privacy supported, although a public address is used) |
|
||||
| Generic Attribute (`0x1801`) | Service Changed (`0x2A05`) | INDICATE | |
|
||||
| Custom (`bdce0001-e90d-4685-b89d-5578cd199a9f`) | `bdce0101-…` | WRITE | Accepted unauthenticated writes (ToothFairy WRLS-GATT-004) |
|
||||
| | `bdce0102-…` | READ, INDICATE | 33 bytes: `0x01` + 32 high-entropy bytes |
|
||||
| | `bdce0103-…` | WRITE | Accepted unauthenticated writes (ToothFairy WRLS-GATT-004) |
|
||||
| | `bdce0104-…` | READ, INDICATE | 97 bytes: `0x01` + 96 high-entropy bytes |
|
||||
|
||||
The custom service appears to consist of two request/response channels.
|
||||
The readable values look random, which suggests they are encrypted or cryptographic material rather than plaintext state.
|
||||
|
||||
> This is an assumption based on the data, not yet verified.
|
||||
|
||||
According to the bridge firmware analysis, the lock receives commands (lock state changes, time sync, firmware updates in parts) from the bridge over this BLE link.
|
||||
|
||||
#### Wired interfaces
|
||||
|
||||
- UART (115200 8N1): internal link to the touch module carrying a framed binary protocol with display text
|
||||
- SWD: debug port of the nRF52840; no connection could be established
|
||||
|
||||
### Outer Module (Touch)
|
||||
|
||||
No wireless services.
|
||||
|
||||
Connected to the motor module by cable and receives display content over the UART link described above.
|
||||
|
||||
### Bridge (ESP32)
|
||||
|
||||
The bridge connects to WiFi as a client and relays between the cloud and the lock.
|
||||
|
||||
| Service / Connection | Direction | Details |
|
||||
| --- | --- | --- |
|
||||
| BLE central (GATT client) | Bridge → Lock | Scans for, pairs/bonds with and controls the lock |
|
||||
| MQTT over TLS | Bridge → Cloud | `mqtts://mqtt.production.loqed.com:8883` / `production.loqed.com:8883`, topics `locks/<id>/to_lock`, `locks/<id>/to_backend`, `…/state`, `…/status` |
|
||||
| HTTPS | Bridge → Cloud | `gateway.production.loqed.com:443`, `production.loqed.com:8080` |
|
||||
| HTTPS OTA | Bridge → Cloud | `firmware.loqed.com` (firmware for bridge and lock) |
|
||||
| Core dump upload | Bridge → Cloud | `https://app.loqed.com/Bridge-core-dump/bridge-core-dump2.php` |
|
||||
| HTTP (port 80, clear text) | LAN → Bridge | Likely: `10.12.2.17` (MAC `8c:4b:14:6a:1a:cc`, Espressif OUI) answered `GET /shelly` from the app in the init capture, matches the Shelly local device API and the app's mDNS queries for `_shelly._tcp.local` |
|
||||
| UART console (115200) | Physical | Boot log, firmware contains format strings that print tokens and WiFi credentials in clear text |
|
||||
|
||||
Endpoints are taken from the firmware analysis unless stated otherwise.
|
||||
|
||||
### Cloud Backends
|
||||
|
||||
> Observed during initial setup.
|
||||
|
||||
From the PreTester report of the init capture and the nmap scans:
|
||||
|
||||
| Host | IP | Ports observed in capture | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| `control.shelly.cloud` | `34.95.90.149` | 443 (TLS 1.3) | |
|
||||
| `shelly-101-eu.shelly.cloud` | `34.79.5.199` | 31234 (TLS 1.3) | [nmap](network/nmap/shelly-101-eu-shelly-cloud.nmap): 22 (OpenSSH 9.6p1 Ubuntu), 80 + 443 (nginx 1.24.0, Ubuntu); 443 returns `401` without `WWW-Authenticate` header; 31234 filtered |
|
||||
| `shelly-120-eu.shelly.cloud` | `104.155.32.247` | 443, 6113 (TLS 1.3) | Rescan pending (see 2.6) |
|
||||
| `shelly-infra1-eu.shelly.cloud`, `app-ratings.shelly.cloud`, `paypal.shelly.cloud` | `35.205.173.252` | 443, 9443 (TLS 1.2) | |
|
||||
| `changelog-backend.shelly.cloud` | `34.62.47.252` | 443 (TLS 1.2) | |
|
||||
| `repo.shelly.cloud` | `35.241.201.25` | 443 | |
|
||||
| `integrations.loqed.com` | `34.155.200.196` | 443, 8883 (MQTTS) | |
|
||||
|
||||
All cloud connections in the capture were encrypted (TLS 1.2/1.3 with AEAD cipher suites)
|
||||
|
||||
The only clear-text HTTP flows were captive-portal checks and the local request to `10.12.2.17:80`.
|
||||
|
||||
### Apps
|
||||
|
||||
| App | Package |
|
||||
| --- | --- |
|
||||
| LOQED | `com.loqed.keychain` |
|
||||
| Shelly | `cloud.shelly.smartcontrol` |
|
||||
|
||||
## 0.2 Hardware and Software Specifications
|
||||
|
||||
| Component | Main chip | Firmware | Interfaces |
|
||||
| --- | --- | --- | --- |
|
||||
| Lock (inner/motor module) | Nordic nRF52840 | Unknown (not extracted) | BLE, UART, SWD, I²C |
|
||||
| Outer module (touch) | Unknown (not opened, glued) | Unknown | Cable to motor module (UART) |
|
||||
| Bridge | ESP32-WROVER-B | `LoqedBridge`, ESP-IDF v4.4.1 | WiFi, BLE, UART |
|
||||
|
||||
Power supply: 8× AA batteries (lock).
|
||||
|
||||
The bridge has its own mains power supply beneath the PCB.
|
||||
|
||||
### Lock (Inner/Motor Module)
|
||||
|
||||
| Item | Details |
|
||||
| --- | --- |
|
||||
| SoC | Nordic nRF52840 |
|
||||
| CPU / memory | Arm Cortex-M4F @ 64 MHz, 1 MB internal flash, 256 KB RAM, BLE 5 radio (datasheet values) |
|
||||
| External flash | Macronix MX25R3235F, 4 MB SPI NOR, ultra-low-power, WSON-8 package (U6) |
|
||||
| PCB markings | `LOQED IM31201218 PT2256A4 13Jul2022`, manufacturer marking `HT-M E327182`, `94V0` (flammability rating) |
|
||||
| U7 (`H451`) | SOP-8 next to a 0.22 Ω shunt resistor (`R220`) and the motor/power connectors, likely part of the motor driver or power stage (unverified) |
|
||||
| U4 | Sensor on I²C (SDA/SCL pads), function unverified |
|
||||
| Other components | Buzzer, push button (S1), LED, motor terminals (M1/M2), battery terminals (+/−), connectors for touch module, power supply and motor |
|
||||
| Debug / test points | SWD (`CLK`, `DIO`, `3V3`), 2×5 pad header (likely factory programming), UART (`Rx`, `Tx`, `VCC`, J2: `GND`, `3V3`, `RX`, `TX`, `VEXT`) |
|
||||
| Mechanics | DC gear motor driving a brass worm wheel with a hexagonal shaft for the cylinder |
|
||||
| Firmware | Not extracted, per the bridge firmware, lock updates are downloaded by the bridge from `firmware.loqed.com` and streamed to the lock over BLE in parts |
|
||||
| Lock states (from bridge firmware) | Positions: open / latch / night lock, Triggers: twist assist, touch-to-lock, outside module button/PIN, BLE, remote |
|
||||
|
||||
### Outer Module (Touch)
|
||||
|
||||
| Item | Details |
|
||||
| --- | --- |
|
||||
| Construction | Plastic shell, three screws, additionally glued, not opened to avoid damage |
|
||||
| Function | Touch sensor and display (shows e.g.: "Touch to Lock", "Locking") |
|
||||
| Connection | Cable to the motor module, display content is sent over UART |
|
||||
|
||||
### Bridge
|
||||
|
||||
| Item | Details |
|
||||
| --- | --- |
|
||||
| Module | Espressif ESP32-WROVER-B (ESP32-D0WD, 64 Mbit PSRAM), WiFi 2.4 GHz + Bluetooth/BLE |
|
||||
| Flash | 4 MB, MD5 `847d4795ee64714d3b02e2bdb3d20266` |
|
||||
| Framework | ESP-IDF v4.4.1, project `LoqedBridge` |
|
||||
| Build | Git commit `33beadfc1ba5d4d3b0cb6a6ee673535a1d12972c`, version string `33beadf-dirty` (built from an uncommitted working tree) |
|
||||
| Security features | `secure_boot_v1` (per boot log), NVS encryption (`nvs_key` partition) |
|
||||
| Partitions | `nvs` (16K), `nvs_key` (4K), `otadata` (8K), `phy_init` (4K), `factory` / `ota_0` / `ota_1` (1280K each), `coredump` (64K) |
|
||||
| Update mechanism | HTTPS OTA with A/B partitions and rollback, for both bridge and lock |
|
||||
| Crypto library | mbedTLS (AES, RSA, EC, SHA-1/SHA-256), standard CA trust store bundled, no embedded private keys |
|
||||
| Debug interface | UART (115200), used for boot log and firmware read-out via `esptool` |
|
||||
| Other | Reset button, developer paths leaked in strings (`/home/pierre/bridge/…`, `/root/bridge/…`) |
|
||||
|
||||
## 0.3 Known Vulnerabilities / Problems / Hacks
|
||||
|
||||
No known vulnerabilities or hacks were found during research or on CVE.
|
||||
|
||||
Reference in New Issue
Block a user