diff --git a/Document0-Initial_Information_Gathering.md b/Document0-Initial_Information_Gathering.md index be1202b..00c554e 100644 --- a/Document0-Initial_Information_Gathering.md +++ b/Document0-Initial_Information_Gathering.md @@ -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//to_lock`, `locks//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.