米家 LED 智能台灯简单分析
2018-6-15 13:39:16 Author: mp.weixin.qq.com(查看原文) 阅读量:2 收藏

网上看了一些台灯,最后选了这一款,据说得了2017 iF 设计金奖,不过最主要是价格还合适。小米和飞利浦有合作的智能台灯,不过评价都不是很好,价格也高,也就没选。这个台灯很多人说不喜欢红线裸露,也有人说这个是亮点,产品设计者说这是故意裸露出来的。我觉得价格合适,控制方便,外观设计也过得去,也就它了。

可以通过手机App来控制,调节亮度色温,响应速度很快。

使用IoT安全测试环境来简单的分析下通信过程。

域名解析

台灯打开后,通过dhcp获取IP地址,然后解析了一个域名地址ot.io.mi.com,这个就是米家的云端。

可以看到这个域名的A记录有很多IP地址,后面与云端通讯时会选择其中一个,开始不间断的与云端进行通信,所有通讯都是UDP的。一般设备断电重启会重新选择一个云端地址。

心跳

每隔几秒,台灯会向云端发送一个报文,Len=32。同时云端也会发送一个报文,可以看到两个报文Data部分都是一样的。网上说这是UDP打洞机制,这样才可以实时判断设备是否在线,App对设备控制时反应很快,应该也是基于此。关灯后心跳包也一直存在,这样才能随时通过手机App控制。UDP打洞参考:

https://en.wikipedia.org/wiki/UDP_hole_punching

控制命令下发

通过手机App端控制灯泡,调节亮度和色温(这部分没抓包),可以看到云端向台灯发送了很多UDP数据包。

测试发现,直接重放云端发送给设备的UDP数据包,比如开灯、关灯、调节亮度和色温操作这些,在一段时间内(大概40秒左右),都是可以重放的。但是过了一段时间,重放数据包就不能控制了。这个我不确定是不是在数据Data部分做了控制,有了解的可以说下(对协议不是很了解^_^)。

OTA升级

台灯升级时,手机App端确定升级,设备会向云端服务器下载更新包。

升级使用http,把升级包下载下来看看,使用文本查看下bin文件里都有什么内容。

现在智能设备基本都开启了UPnP。

这里有个向cloud.yeelight.com发送统计信息的请求,不过我没抓到,估计要等待一段时间。不过这有句话很有意思哈:

sometimes, we don't want to be loved as much to be understood.

IDLE ゥゥゥゥゥゥゥゥゥゥTmr Svc 8.8.8.8               tiT 
ot.netif_change Oct 12 2017 17:15:57    ot_config   psm_model   _miap   
network.ssid    network.password    _miio   %u  network.configured  
stationTimer    {   ?????  %s.%s   _psm_object_open    (NULL)  %02X%c  
%02x%c  %02X    %02x    0123456789abcdef    0123456789ABCDEF    
NOTCONNECTED    CONNECTING  unknown CONNECTED   ONLINE  
{"result":{"state":"%s","auth_fail_count":%d,"conn_succes_count":%d,"conn_fail_count":%d,"dhcp_fail_count":%d  
 }}  no mem  ot_config.uid   %d  ot_config.gmt_offset    
ot_config.enauth    enauth  Invalid json.   Invalid param.  otn OTd not 
available.  ot_config.psm_model ot_config.mcu_ver   ot_config.psm_token 
country_domain  esp8266 
%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x    
%d.%d.%d.%d "%s":   "%s %s  {"localIp":"    ","mask":"  ","gw":"    "}  
"%s":"  "%s"    {"rssi":%hd,"ssid":"%s","bssid":"   "life":%u,  
"token":"   mac "hw_ver":"%s",  ESP8266 "uid":%s,   "channel":"%s", 
mcu_fw_ver  wifi_fw_ver ap  "}, netif   "mmfree":%u {"result":{ Mem 
error.  network ap2staTmr   rebootTimer Config router fail  passwd  
channel uid gmt_offset  miio_default    0x82562647  MIIO_net_change uap 
MIIO_net_change unprov  MIIO_net_change updating    MIIO_net_change 
cloud   MIIO_net_change local   MIIO_net_change offline config_JsDlgt   
reboot_JsDlgt   restore_JsDlgt  stop_diag_mode_JsDlgt   
wifi_assoc_state_JsDlgt config_router_JsDlgt    info_JsDlgt 
{"result":[%s]} reboot_timer    get_down    result "ready"  down 
update_fw
 error
  ok
 ota_progress    20  ota failed  app_url mcu_url ota_state   ota_reboot  "idle"  "downloading"   "downloaded"    "installing"    "installed" "failed"    ota_install_JsDlgt  ota_JsDlgt  get_ota_state_JsDlgt    get_ota_progress_JsDlgt ?$@0    $@4$@,$@?$@0    $@

用的esp8266芯片,标红部分应该是与云端通信时传递的一些参数,标绿部分是OTA升级的一些状态吧。

 HTTP resps:%s Content-Length: Content-Length err. Header err. Open 
error. Write. HTTP resps: http://   渞%@爎%@|$@?$@T$@?$@Invalid json. 
Busy.  {"id":%u,"error":{"code":%d,"message":"%s"}} Resp general error. 
Resp invalid json. ip result otc_list Try out.  Method not found. 
ot.online method from sid params Req object invalid. _JsDlgtS _JsDlgt 
ot.offline "ott_stat": [%u, %u, %u, %u] ,"otstat":{ 
"timestamp":%u,"proto":1,"otip":" ","otport":80, "sendcnt":%u, 
"ackcnt":%u, "costtime":%u} {"method":"_otc.info","params":{   
竢%@紃%@p$@(*$@?$@?$@{"id":%u,"result":0} otc_test R. error model retry 
timeout "method": ,"params": ,"sid": ,"model": ,"from":"%s" "result": 
"error": ,"id":%u} nbl.%u not sync. {"method":"_otc.login","params":{ 
DnFull. LocalOnly. K@%c. Invalid param. redirect failed. _otd.redirect 
host _otd.neighbor token did NeighborAckProbErrIP. LanPktHdrErrDID. 
NeighborAckErrIP. LanPktErrDID. WanPktHdrErrDID. WanPktErrDID. 
WanPktNotFromHost. KPstop. KPTstop. "otu_stat": [%u,%u,%u,%u,%u,%u] 
"timestamp":%u,"proto":0,"otip":" ","otport":8053, ,"err":"%s"}}   
s%@s%@hP$@user    miIO    user    ot.online   true    false   up_task 
_otc.log    _async.store    null    
{"retry":0,"timeout":2000,"method":"props","params":{   "%s":%s "ota_   
"method":   {%s
   {"retry":%u,"timeout":2000,"method":"event.%s","params":[%s]}   {"retry":0,"method":"%s","params":{"%s":%s}}

这里也可以看到云端通讯使用的8053端口,设备端使用固定的端口54321,应该都是为了满足UDP打洞要求。

简单分析就到这,网上有人专门拆解了小米的扫地机器人、智能灯泡等,感兴趣的可以去看看。


文章来源: https://mp.weixin.qq.com/s?__biz=MzI5NzAzMDg0NA==&mid=2650697913&idx=1&sn=a22027c9a904d915d2f74ea3ee1d7091&chksm=f4b1956ac3c61c7c5cd40499e2bbd2dacfbe3cd1cb97c6365a1a56f9e83d59743fbf20951634&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh