2 điểm bởi GN⁺ 2023-12-16 | 1 bình luận | Chia sẻ qua WhatsApp
  • Trong quá trình đảo ngược để tích hợp đèn LED Bluetooth LE giá rẻ với Home Assistant, tác giả thử các giá trị hiệu ứng ẩn của dây đèn LED địa chỉ hóa dài 10 m và khiến bộ điều khiển ngừng hoạt động
  • Dùng Bluetooth HCI snoop trên Android cùng Wireshark/tshark để bắt các gói BLE mà ứng dụng gửi tới đèn, rồi lần theo các byte điều khiển trong yêu cầu ghi btatt.opcode.method==0x12
  • Các gói của ứng dụng iDeal LED không giống những giá trị bật/tắt đơn giản, nên tác giả giải nén APK và tham khảo bài phân tích có sẵn để giải mã bằng khóa AES cố định trong libAES.so
  • Gói bật/tắt sau khi giải mã có header cố định và chỉ khác nhau ở byte thứ 5 là 1/0; sau đó tác giả lặp lại các chức năng màu sắc, độ sáng và hiệu ứng để ghi lại mẫu byte
  • Khi gửi trực tiếp giá trị 8 bit vượt quá phạm vi 5 bit 0x1F mà ứng dụng dùng cho RGB, có thể tạo màu sáng hơn; nhưng ngay khi gửi hiệu ứng số 12, đèn tắt hẳn và Bluetooth advertising cũng biến mất

Điểm khởi đầu: tích hợp đèn BLE giá rẻ vào tự động hóa nhà

  • Từ giả định rằng các thiết bị giao tiếp qua Bluetooth LE và có ứng dụng riêng có thể được tích hợp vào hệ thống tự động hóa nhà, tác giả đã đảo ngược nhiều dải LED giá rẻ
  • Trước đó, tác giả đã kết nối dải LED 5 m không địa chỉ hóa điều khiển bằng Bluetooth LE giá £2.38 với Home Assistant chỉ trong vài giờ, và công bố mã liên quan tại bj_led
  • Công việc đảo ngược BLE cho bộ điều khiển LEDnetWF cũng có tại lednetwf_ble
  • Mục tiêu lần này là dây đèn địa chỉ hóa 10 m trên bàn làm việc, được điều khiển bằng ứng dụng “iDeal LED”
    • Ứng dụng có nhiều tính năng và hoạt động khá tốt
    • LED có thể là WS2812 hoặc sản phẩm tương tự
    • Sản phẩm là bộ đèn mua trên AliExpress

Bắt các byte BLE mà ứng dụng gửi đi

  • Để điều khiển thiết bị bằng phần mềm tự viết, trước tiên cần xem chuỗi byte mà ứng dụng gửi tới thiết bị qua Bluetooth
  • Giao thức đèn thông thường có thể gồm header, byte lệnh như bật/tắt hoặc đổi màu, và footer có thể là checksum
  • Trên Android, việc bắt gói được thực hiện theo các bước sau
    • Bật chế độ nhà phát triển
    • Cài ứng dụng điều khiển đèn
    • Kích hoạt Bluetooth HCI snoop trong cài đặt nhà phát triển
    • Thực hiện các thao tác như bật và tắt đèn trong ứng dụng
    • Sao chép log sang máy tính bằng adb pull sdcard/btsnoop_hci.log .
  • Khi mở log trong Wireshark, có thể xem các byte được gửi tới đèn
    • Ví dụ bộ lọc: bluetooth.dst == ff:ff:ff:ff:ff:ff && btatt.opcode.method==0x12
    • Cần thay địa chỉ MAC bằng MAC thực của đèn
    • btatt.opcode.method==0x12 nghĩa là có thao tác ghi từ thiết bị Android tới đèn
  • Nếu dùng tshark, có thể trích giá trị gói ngay trong terminal
    • tshark -r <filename> -T fields -e btatt.value sẽ in ra payload được ghi vào bộ điều khiển LED

Giao thức iDeal LED không thể chỉ replay đơn giản

  • Một số loại đèn cho thấy mẫu gần như đọc được trực tiếp trong thao tác bật/tắt
    • Ví dụ là dạng lặp như 69 96 02 01 0169 96 02 01 00
    • Byte cuối đổi giữa 10 để biểu thị bật/tắt
  • Nhưng với đèn iDeal LED lần này, chuỗi byte dài hơn nhiều lặp lại, và dù có thể phân biệt hai loại gói tương ứng bật/tắt, các giá trị trông như nhiễu
  • Nếu chỉ cần mục đích bật tắt đơn giản, replay lại nguyên chuỗi byte đã bắt có thể là đủ
    • Có thể dùng gatttool để kết nối tới thiết bị BLE và gửi byte
    • Handle cần gửi phải được xác định trong Wireshark
  • Để điều khiển nhiều hơn, cần hiểu cấu trúc gói, nên tác giả chuyển sang phân tích chính ứng dụng Android

Giải nén APK và tìm khóa AES

  • Tải APK về, mở bằng jadx và xem mã ứng dụng
  • Trong mã nguồn xuất hiện tham chiếu tới AES, cho thấy giao thức có thể đã được mã hóa
  • Với dữ liệu mã hóa, tác giả giả định các điều kiện sau
    • Bản mã cho cùng một thao tác không thay đổi mỗi lần, nên có thể tồn tại khóa nhất quán
    • Cần giải mã nhanh trên MCU công suất thấp, nên khóa ngắn sẽ có lợi
    • Khóa có thể không là duy nhất cho từng thiết bị mà là khóa cố định
  • Ứng dụng chứa thư viện AES biên dịch sẵn tên libAES.so, nên không thể chỉ dùng jadx để phân tích
  • Tác giả tìm thấy một bài phân tích của người khác, trong đó họ giải biên dịch thư viện AES bằng ida free và tìm ra khóa nhúng, rồi tác giả đem khóa đó đi thử
  • Khi giải mã bằng AES ECB mode trong Crypto.Cipher, các gói bật/tắt chuyển thành dạng có ý nghĩa
    • Giá trị sau giải mã hiện ra như 05 54 55 52 4E 01 ...05 54 55 52 4E 00 ...
    • Sau header cố định, byte thứ 5 đổi giữa 10 để biểu thị bật/tắt
    • Phần còn lại được đệm bằng 0
  • Từ bước này, tác giả có thể giải mã các gói mà ứng dụng gửi đi và tái hiện cùng cách điều khiển trong mã của mình

Ghi lại mẫu byte theo từng chức năng

  • Phạm vi giao thức được mở rộng bằng cách chạy từng chức năng trong ứng dụng rồi ghi lại các byte được truyền
  • Mỗi thao tác được lặp lại nhiều lần, và xen kẽ mẫu tắt/bật đèn để dễ phân tách các đoạn trong log bắt gói
    • Đổi màu theo thứ tự red, green, blue nhiều lần
    • Đổi độ sáng theo 100%, 50%, 10%, 50%, 100%
    • Chèn off/on giữa các nhóm để dễ tìm ranh giới trong log bắt gói
  • Bằng cách này, có thể xác định byte nào thay đổi theo từng thao tác và đối chiếu hành động đã ghi với các gói đã bắt

Hiệu ứng số 12 đã biến bộ điều khiển thành cục gạch

  • Trong lúc phân tích thay đổi màu, tác giả xác nhận ứng dụng không gửi giá trị lớn hơn 0x1F cho các giá trị red, green, blue
    • 0x1F là phạm vi 5 bit
    • Khi tự gửi giá trị 8 bit, màu sáng hơn vẫn hoạt động
  • Để kiểm tra xem ngoài 10 hiệu ứng mà ứng dụng dùng còn hiệu ứng nào khác không, tác giả chạy vòng lặp range(20) để gửi lần lượt các số hiệu ứng
    • Từ 1 đến 10 hoạt động bình thường
    • Ở 11 phát hiện hành vi trông như một chế độ ẩn
    • Sang 12 thì đèn tắt
  • Sau đó đèn không bao giờ bật lại được nữa
    • Không còn phát Bluetooth advertising
    • Cũng không kết nối được
    • Giữ nút khi cấp nguồn cũng không khôi phục được
    • Rút điện qua đêm vẫn không trở lại
  • Tác giả suy đoán firmware có thể đã bị hỏng do tràn bộ đệm, nhưng không xác định được nguyên nhân chính xác
  • Bản thân LED là loại LED địa chỉ hóa tiêu chuẩn, nên vẫn có thể nối với một vi điều khiển khác để tái sử dụng cả dây đèn

Kết quả còn lại và lưu ý

  • Dù thất bại, tác giả vẫn tài liệu hóa được phần lớn giao thức và tạo một dự án GitHub có kèm Home Assistant custom component
  • Component hoạt động được, nhưng các thử nghiệm theo cách tương tự có thể làm hỏng bộ điều khiển đèn, nên ai làm thì tự chịu rủi ro

1 bình luận

 
GN⁺ 2023-12-16
Ý kiến trên Hacker News
  • Có vẻ không hẳn là “header cố định” của FTA, mà là dạng có byte độ dài (“lệnh là 5 byte”), lệnh TURN, tham số 0/1, rồi phần còn lại được điền 0 cho đủ 16 byte

    • 54 55 52 4E nổi bật ngay vì đó là chữ in hoa TURN
      Nếu biết chữ số bắt đầu từ 0x30, chữ hoa từ 0x41, chữ thường từ 0x61, thì rất dễ tìm các mẫu chữ-số trong dump thập lục phân
      Kiến thức kiểu này hữu ích với chuỗi ngắn, nhưng khi xem packet hoặc dump bộ nhớ thì định dạng hexdump chuẩn là tốt nhất
    • Nhận xét đúng. 0x54 55 52 4E thực ra là T U R N
    • Phát hiện hay. Tôi sẽ kiểm tra các lệnh khác để xem giả thuyết byte độ dài có đúng không; có vẻ khả thi
    • Nhiều khả năng đó không phải padding mà chỉ là uint
    • Trong trường hợp này, xét theo độ dài và điểm bắt đầu thì header coi như là cố định
  • Có thể là vấn đề nguồn điện. Dòng WS281x có thể sáng rất mạnh, và ghép nhiều cái lại thì ngốn dòng điện khủng khiếp
    Với strip 100 bóng và bộ nguồn 12V 3A thì chỉ vừa đủ bật toàn bộ ở màu trắng độ sáng tối đa, và sẽ rất chói
    Vì vậy có lẽ tôi sẽ kiểm tra cầu chì bị đứt trước. Việc firmware chỉ dùng tới 31 trên mức sáng tối đa 255 cũng là một manh mối

    • Thấy độ sáng bị giới hạn ở 0x1f thì ban đầu tôi cũng nghĩ vậy. Nếu may mắn, bộ nguồn có cầu chì và có thể chỉ cầu chì bị cháy
      Dù không cứu được, chuỗi LED WS281x chuẩn vẫn có thể nối với Raspberry Pi, và cũng có thể dùng bộ điều khiển LED định địa chỉ mã nguồn mở của tôi :) https://github.com/mbevand/ledthemfight
      Nó có các hiệu ứng tích hợp, được thiết kế rất mô-đun cho DIY, nên chỉ với hai dòng Python là có thể tạo một mô-đun hiệu ứng LED tùy chỉnh đơn giản. Demo ở đây: https://youtu.be/qpd2rILsnM4
    • Ý hay. Tôi sẽ lấy đồng hồ vạn năng ra đo thử
    • Cái này trông không giống WS2812. Nhìn link Ali đã đăng thì trên strip có bốn dây 12V, đỏ, xanh lá, xanh dương
      Có vẻ là strip RGB analog, cả strip sáng cùng một màu, chứ không định địa chỉ từng LED
      https://www.aliexpress.com/item/1005005485885067.html
      Ai muốn vọc đèn LED thì nhất định nên xem WLED. Nó có nhiều hiệu ứng tích hợp, có GUI web, dùng ESP32 hoặc ESP8266 rất rẻ làm controller, và còn có thể phản ứng theo âm thanh. Tôi đang chạy WLED cho đèn Giáng sinh trong nhà, trông rất đẹp
    • Cảm ơn mẹo. Tôi đã cập nhật mã bằng cách dịch phải 3 bit để đưa nó trở lại thành số 5 bit
      Đây là một cách gọn gàng để giới hạn mức tiêu thụ điện
  • Bài hay. Tôi nhớ có lần thử reverse engineering bộ đèn mình có thì phát hiện nó được mã hóa
    Một cái là amaran 60d, còn lại là vài đèn LED chạy pin SmallRig RM75; tôi muốn bật/tắt tất cả bằng một script thay vì phải thao tác hai ứng dụng riêng
    Tôi đã tốn khá nhiều thời gian reverse engineering ứng dụng và giao thức, và cả hai đèn có vẻ dùng cùng một thủ tục thương lượng nhưng được triển khai bằng các thư viện khác nhau
    Tôi đã cố mô phỏng trao đổi khóa Diffie-Hellman khi kết nối nhưng cuối cùng bỏ cuộc. Theo trí nhớ thì sau đó còn một hoặc hai bước nữa, và sau khi gửi khóa đầu tiên, nó lại gửi một con số trông như ngẫu nhiên (một khóa khác?) mà tôi không hiểu nó muốn gì
    Đọc bài này làm tôi nghĩ có lẽ nên thử nhét một khóa hard-code vào xem có chạy không

    • Nếu làm được với đèn Amaran thì quá tuyệt. Như vậy có lẽ có thể dẫn tới việc reverse engineering toàn bộ dòng sản phẩm Aputure
      Nếu có tích hợp mã nguồn mở cho Elgato Stream Deck hoặc Home Assistant thì sẽ là một ví dụ thành công lớn. Với những người làm YouTube quay video talking-head tại bàn, nó sẽ tốt hơn nhiều so với điều khiển đèn bằng app điện thoại
  • Tôi đã cố tự động hóa đèn Giáng sinh kết nối BLE và tạo ra rác điện tử. Giờ bạn cũng có thể làm vậy

    • Không biết cụ thể bạn làm thế nào, nhưng tôi từng thấy một số loại SmartTrash như vậy có thể hard reset bằng một chuỗi thao tác kỳ diệu kiểu bật tắt nhanh 5 lần
    • Nếu muốn sniff packet BLE theo hướng GUI hơn, hãy thử dùng app nRF Connect
      Tôi không rõ với iPhone, nhưng trên Android, nếu để nó chạy nền, bạn có thể bắt hoạt động BLE qua GUI gọn gàng trên điện thoại. Tôi dùng hằng ngày
    • Nếu bỏ qua controller, bạn vẫn có thể dùng nó như đèn ngu/đèn cổ điển
  • Làm tôi nhớ tới các MCU bàn phím bị brick khi nhận một lệnh đèn nhất định
    OpenRGB cuối cùng đã phải vô hiệu hóa để mô-đun đó không tự chạy trên phần cứng liên quan. Đôi khi phần mềm của nhà sản xuất cũng kích hoạt cùng lỗi đó
    Đáng tiếc là thông thường muốn vào chế độ lập trình trong hệ thống thì phải gửi USB HID report, nhưng các thiết bị bị ảnh hưởng thậm chí không còn enumerate nữa
    Việc đó thực sự là hỏng firmware hay phần cứng hỏng vì một hành vi không xác định khác lại là chuyện khác

  • “Gửi plaintext qua không dây thì không an toàn mà”
    “Đừng lo, tôi đã thêm mã hóa AES rồi”

    • Tuya thật sự rất buồn cười ở điểm này. Giao thức chỉ là TLS chạy trên TCP, nhưng mỗi khi app thêm thiết bị mới, nó lại rải mật khẩu Wi-Fi cho mọi STA xung quanh
      Vì cơ chế ghép đôi là vậy. App broadcast packet bừa bãi tới 255.255.255.255, còn thiết bị đích (bóng đèn, ổ cắm, v.v.) chờ ở chế độ promiscuous
      Nội dung packet được bảo vệ bằng WPA2 hoặc tương tự, nhưng độ dài packet thì không, nên nó gửi rất nhiều packet cực nhỏ, trong đó độ dài mỗi packet được đặt thành giá trị byte ASCII của ký tự tiếp theo trong handshake cấu hình. Có lẽ nó còn gửi lặp lại nhiều lần
      Vì vậy quá trình ghép đôi mất 2 phút rồi luôn đột ngột dừng trước khi bộ đếm chạm 0
    • Chắc là mã hóa dành cho không khí
  • Đây chính là điều năm ngoái tôi thực sự lo lắng khi reverse engineering bộ điều khiển BLE của lò sưởi nhà mình
    Đặc biệt là lệnh “Set password” nhận đầu vào byte thô, trong khi ứng dụng OEM chỉ gửi dữ liệu số có giới hạn độ dài
    May là có vẻ chỉ cần mất điện chốc lát là nó quên sạch mọi thứ đã xảy ra trước đó
    Vì vậy có vẻ phần lớn bộ điều khiển BLE cùng thương hiệu vẫn giữ nguyên mật khẩu mặc định 0000. Chỉ cần mất điện một lần là cuối cùng lại quay về trạng thái đó. Nếu thật sự rảnh rỗi thì đây sẽ là đề tài khá hay để BLE wardriving
    Tôi cũng đã biến kết quả reverse engineering thành tích hợp Home Assistant (https://github.com/kaechele/napoleon-efire), và cũng viết tài liệu về hệ thống cùng giao thức (https://bonaparte.readthedocs.io/en/latest/index.html)

  • Tôi đang tìm đèn linh hoạt và bền để gắn lên giá nóc ô tô
    Dùng pin, phù hợp ngoài trời/mọi thời tiết, và nếu hộp pin có thể dễ dàng buộc bằng dây rút lên bề mặt thì càng tốt
    Nếu có thể thì tôi muốn loại form factor “mini” T5, RGB và lập trình được để dùng theo mùa, chẳng hạn đỏ/xanh lá vào Giáng sinh, tím/cam vào Halloween
    Không biết có ai biết sản phẩm nào đáp ứng các điều kiện này không. Ba điều kiện đầu có thể tìm được ở Walmart hoặc Home Depot, nhưng rất khó tìm loại đáp ứng điều kiện cuối
    Tìm kiếm thì toàn ra nhiễu
    [1] https://cdn.christmaslightsetc.com/images/CategoryDetail/788...

    • Có lẽ hướng đi sẽ khác nhau tùy bạn sẵn sàng DIY đến mức nào
      Ví dụ, loại dải LED 12V chống nước IP67 (dạng nằm trong ống silicone) rất dễ mua [0], và vì có số LED nhiều hơn hẳn so với dây đèn kiểu Giáng sinh nên hiệu ứng cũng sẽ mạnh hơn
      Tuy nhiên bạn sẽ phải mua rồi lập trình một vi điều khiển như Arduino, ESP32, ESP8266, và tự giải quyết cách lấy điện từ ắc quy ô tô [1]
      Cũng có thể đặt linh kiện điện tử trong xe, chỉ luồn dây ra ngoài cốp, rồi trông chờ gioăng cốp hiện có giúp chống nước
      [0] https://www.aliexpress.com/item/1005004289391906.html
      [1] https://www.aliexpress.com/item/1005005977505151.html
    • Bạn cũng có thể xem loại WS2811 kiểu “bullet string”. Nếu định nối vào 12V của xe thì nó là 12V native, thường là sản phẩm chống nước có đuôi nối xConnect, dễ gắn và linh hoạt
      Cũng dễ hàn lại bằng dây nối dài hoặc nối chuỗi
      https://www.aliexpress.com/item/4000105913323.html
      Theo những gì tôi đọc được, các sản phẩm như vậy hoặc đèn 5V tương tự dường như được dùng gần như chuẩn trong các màn trình diễn đèn Giáng sinh ngoài trời
    • Hãy vào Discord của WLED và xem các kênh #projects#showcase. Có rất nhiều dự án gắn đèn RGB LED lên xe
      Nhưng hãy cẩn thận, mảng này rất dễ cuốn vào
      Link mời: https://discord.gg/eVhhh2Wh
  • Có thể xem cảnh tháo rời bộ đèn Giáng sinh bị hỏng không?
    Nếu biết bên trong có chip gì thì có thể có manh mối xem nó có bộ nhớ flash hay không, và có dễ dump không