登录
  • 人们都希望被别人需要 却往往事与愿违
  • 软件设计就像做爱, 一次犯错, 你要用余下的一生来维护 @Michael Sinz

如何控制德业 DYD E12A3

编程 Benny 小土豆 4864 次浏览 5178 字 4 个评论
文章目录 [显示]

8 月份的时候买了个除湿器,这东西可以联网,用他们自己的 APP 进行控制。当然也可以直接按实体按钮控制,说好听点叫没网也能用😂

我一直不喜欢用装这种 APP,那么既然如此,就要搞一波这个德业智能 APP 了。

思路

  1. 先拿到除湿器的 IP 地址, 先 nmap 一波看看,也许有什么隐藏的接口
  2. 在路由器上用 tcpdump 抓这个 IP 地址的包,又回到了我搞小米摄像头的时候(这个也许以后会写文章讲讲我都做了哪些奇葩的事情)
  3. 在 iOS 上抓包,看看都发了什么请求控制开启和关闭,也许是简单的 http

除湿器 IP

在路由器的 DHCP 分配记录中可以看到我有一个叫 MiCO 的设备,IP 地址是192.168.7.119。全部 TCP 65535 端口都扫了一波,发现只开了一个 53 端口。难道这东西是 DNS?咱也不知道,因为所有的 DNS 请求都会被拦截到路由器,因此也没有进行进一步测试。

路由器抓包

有点懒,还要先搞 tcpdump,再加上好像不太会用 tcpdump,嗯先不管这个

iOS 抓包

在 iOS 上抓包,有很多选择,比较简单的用 stream,在 APP 里设置一下就可以解密 HTTPS 了。不过缺点是 stream 只能抓 https 和 http 的,其他协议看不到

抓包之后可以分享 har 文件,其实就是个 json。抓包结果中有这样几个关键信息:

随手拿浏览器打开这个 api 看了一下,令人痴呆惊呆的事情发生了

如何控制德业DYD E12A3

这竟然是个 Django WebApp,并且还开启了 DEBUG 模式,这……😓

简单整理了下有这么几个接口比较管用

登录接口

https://api.deye.com.cn/v3/enduser/login/

body 里提交 loginnamepasswordappid(任意字符串就可以)、extend(json string),POST 方法,会在返回的数据中拿到tokenclientid

  1. {
  2. "meta": {
  3. "code": 0,
  4. "message": "signup ok."
  5. },
  6. "data": {
  7. "token": "xxxxx",
  8. "clientid": "123456"
  9. }
  10. }

这个TOKEN就是后续的 JWT TOKEN

注意这个登录是单点登录的!但是 TOKEN 一直有效就是了。

获取设备列表

https://api.deye.com.cn/v3/enduser/deviceList/?app=new

GET 请求,携带 JWT TOKEN,会返回当前帐号绑定的所有设备

  1. {
  2. "meta": {
  3. "code": 0,
  4. "message": "device list by user."
  5. },
  6. "data": [
  7. {
  8. "online": true,
  9. "product_icon": "https://deye-cloud.oss-cn-shanghai.aliyuncs.com/profile/1597889707825.png",
  10. "product_id": "c2c34567df",
  11. "product_name": "DYD-E12A3",
  12. "device_id": "609",
  13. "mac": "04xxxx",
  14. "payload": "1411xxxxxhiddenxxxx",
  15. "role": 1,
  16. "gatewaytype": 0,
  17. "device_name": "不再潮湿",
  18. "product_type": "dehumidifier",
  19. "is_combo": false,
  20. "protocol_version": "wifi_V2.4"
  21. }
  22. ]
  23. }

比较关键的信息有product_id,product_name,device_id等。Payload还不知道是个啥看起来像是一段 hex

MQTT info

https://api.deye.com.cn/v3/enduser/mqttInfo/

同样是 GET 请求,会返回如下数据

  1. {
  2. "meta": {
  3. "code": 0,
  4. "message": "mqtt info"
  5. },
  6. "data": {
  7. "loginname": "ff123/123abc",
  8. "clientid": "app_123abc",
  9. "endpoint": "ff123",
  10. "password": "123456",
  11. "mqtthost": "ff123.mqtt.iot.gz.baidubce.com",
  12. "mqttport": 1883,
  13. "sslport": 1884
  14. }
  15. }

看来用户名和密码都有了,并且用的是 MQTT 协议,这是个啥?

MQTT 协议


国内有一家做 MQTT 协议的公司,叫 EMQ,文档写的非常不错!

https://www.emqx.com/zh/blog/what-is-the-mqtt-protocol


简单的来说,MQTT 主要就是一种适合物联网等处理能力比较差、内存比较小、网络环境复杂不可靠的终端设备用的协议。

这东西简单的说有点像消息队列,属于 publish/subscribe 的模式,但是设计非常简单。盗个图是这样的

如何控制德业DYD E12A3

publisher 向 news 这个 topic 发送消息,所有订阅了 news 的用户都会收到消息。

当然了每个用户既可以是 publisher 也可以是 subscriber。

这个消息,图片中的 some msg 就是 payload,格式一般有 json,plaintext,base64 和 hex

那既然如此,肯定是我的 iPhone 发了 MQTT 协议的数据,看来只能继续抓包了

Wireshark 抓包 iOS

想要抓到 iOS 全部通信的数据,那最好的办法是用 Wireshark 了。当然我这里不是说在 iOS 上装 Wireshark,想啥呢,App Store 可没有 Wireshark。

具体来说其实很简单,让 iPhone 的全部流量走你的电脑,电脑抓包就可以了。Windows 本本的话,只能想办法开个热点,然后抓无线网卡了,这个操作过于简单,我就不说了。

macOS 的话,这样也行,但是还有一种更方便的、开发 iOS APP 时用到的办法🤔

获取 iPhone UDID

把 iPhone 用线连接到电脑,打开 Apple Music,就可以看到 UDID,一大长串,别认错了不是序列号。iPhone 记得解锁。

如何控制德业DYD E12A3

创建虚拟网卡

这一步需要rvictl这个命令,如果你不开发 iOS APP,那么大概率这个命令是找不到的,因为这个命令包含在 Xcode 之中。

当然这并不意味着我们要为了这么一点小事安装 10G + 的 Xcode。这就像你爸爸想要捶你并不需要拿出鸡毛掸子,他只要拎起拳头就够了。同理,我们只要 Xcode 的一小部分就可以了。当然了,整个 Xcode 还是要下载的,爸爸毕竟还要从箱子里拿出来鸡毛掸子吓唬吓唬你嘛。

在 Apple 官网下载适合你的版本的 Xcode 之后,解压缩,然后进到 Xcode.app 中(右键 - 显示包内容),找到这两个文件:

  1. Xcode.app/Contents/Resources/Packages/MobileDevice.pkg
  2. Xcode.app/Contents/Resources/Packages/MobileDeviceDevelopment.pkg

安装这两个就可以了。

如果你不想下载 10G + 的 Xcode 的话,那么也可以用我的,Catalina 10.15.7,Xcode 12.4

https://www.dropbox.com/sh/4sdl3zyx1m0sw08/AADNcp8WdFEBtNHdUjkiIQmIa?dl=0

安装完成后
sudo rvictl -s UDID即可看到 success

想要停止可以用sudo rvictl -x UDID

如果失败,可能需要先运行

  1. sudo launchctl load -w /Library/Apple/System/Library/LaunchDaemons/com.apple.rpmuxd.plist

之后会多出来一个rvi0的网卡,Wireshark 打开,开始吧!

分析 MQTT 协议

首先我们要在 wireshark 的设置中开启 MQTT 协议,这样 Wireshark 会解析出来,更方便我们看。然后需要过滤一下

  1. mqtt and ip.addr==192.168.7.116

connect

就像在教科书中说的一样,德业智能先是连接到了 MQTT 服务器

  • Cliend ID: 其实是任意一个随机尽量不可能重复的字符串就可以了,德业智能这里是 login 接口中的 clientid 和时间戳的拼接
  • username 可以从 mqttinfo 接口中获得,格式其实是endpoint/clientid
  • 密码从接口中获得
  • host 当然也是接口中获得了,看起来是百度云哦

如何控制德业DYD E12A3

subscribe

随后德业智能订阅了两条消息,分别为

status/hex

endpoint/product_id/device_id/status/hex

online/json

endpoint/product_id/device_id/online/json

  1. {
  2. "type": "online",
  3. "data": {
  4. "online": true
  5. }
  6. }

看起来是德业智能在获取当前除湿器的状态,然后 APP 动态显示按钮类别

publish

publish 证明德业智能向某个 topic 发布了消息,那么这非常有可能是在控制除湿器,这就需要一点点尝试了

publish online/json

德业智能向online/json发布了一条消息,内容是一串十六进制

如何控制德业DYD E12A3

7b2274797065223a226f6e6c696e65222c2264617461223a7b226f6e6c696e65223a747275657d7d 随便找个网站转换一下,发现竟然是如下结果

如何控制德业DYD E12A3

尝试在 MQTTX 中连接到这台设备的 MQTT 服务器,然后以 hex 格式发布消息到 topic,除湿器没有响应

publish command/hex

从名字上来看,这个非常像在控制除湿器

如何控制德业DYD E12A3

而且 message 是 16 进制的0001,会让人联想是不是0001是开,0000是关?

在 MQTTX 中设置一波,发送,除湿器并没有开……

再往下看,还有一串神奇的数字 080203403c0000000000,MQTTX 中尝试一下,奇迹出现了,除湿器开了。🧐

再抓个包,就会发现080202403c0000000000是关机代码。

尽管俺也不知道这神秘代码是什么,但是这就像是伏拉夫经常说的 “我爱中国”,“咱们中国真是太棒了” 一样,直接拿去用就能过上心想事成的生活。

Python 实现

已经知道了神秘代码和 topic,那么接下来封装一下就可以了。使用 paho.mqtt.python

  1. server.publish("endpoint/product_id/device_id/command/hex", "080203403c0000000000")

如何控制德业DYD E12A3

嗯??没开啊,咋回事?完全没效果。网络不好吗,再试一次,还是如此

莫非财富密码神秘代码失灵了?打开 MQTTX 订阅这个 topic,发现好像不对,怎么是那么一长串数字……

仔细想一下……

如何控制德业DYD E12A3

噢要 hex 格式,可是这个库并没有额外参数设置 payload 的格式啊

如何控制德业DYD E12A3

不慌不慌,经过我的摸着石头过河、然后搬起石头砸自己的脚的艰苦探索的经历,完全不用考虑struct.pack 什么的,直接发送这样的消息就可以啦

  1. codecs.decode(b"080203403c0000000000","hex")
  2. # 当然你也可以选择使用base64
  3. base64.b64decode("CAICQDwAAAAAAA==")

封装

那么要素已经齐全了,接下来就是上 click、requests 等,写个 setup.py,做成 console application,直接pip install deye然后就可以啦!包含登录功能,登录之后会把信息写到 ~/.deye.dbm

可以看下面这个视频

后续

  1. 这个 Python package 的 bug 很多!我知道!因为我不太会用 click
  2. 我并没有什么打算添加其他设备的想法,也不想添加更多的 command。因为既没有时间、也没有钱购入更多德业的设备,不过接口已经写好了就是…… 按照原本的想法,是想把这个接入米家的,可是一想这个工作量 ++
  3. 花了好几个小时,写完了,把不需要的文件丢到回收站,清空。发现写好的文章也被我顺带着删了……🤬想嘴自己

代码开源在这里 https://github.com/BennyThink/deye


文章版权归原作者所有丨本站默认采用 CC-BY-NC-SA 4.0 协议进行授权 |
转载必须包含本声明,并以超链接形式注明原作者和本文原始地址:
https://dmesg.app/dyd-e12a3.html
喜欢 (42)
分享:-)
关于作者:
If you have any further questions, feel free to contact me in English or Chinese.
发表我的评论
取消评论

                     

去你妹的实名制!

  • 昵称 (必填)
  • 邮箱 (必填,不要邮件提醒可以随便写)
  • 网址 (选填)
(4) 个小伙伴在吐槽
  1. 我重新封装了一个完成度比较高的德业插件 https://github.com/stackia/ha-deye-dehumidifier
    Stackia2023-03-19 21:16 回复
    • 你这个厉害👍
      -- 本评论由 Telegram Bot 回复~❤️
      Benny 小土豆 2023-03-19 21:17 回复
  2. 随便一搜就有,不需要自己 DIY 吧 https://xiking.win/2020/11/12/3-deye-dehumidifer-add-to-homeassistant/
    家明 2021-11-07 19:57 回复
    • 你和我随便一搜可能不太一样,我是没搜到。。。
      -- 本评论由 Telegram Bot 回复~❤️
      Benny 小土豆 2021-11-07 19:58 回复
您直接访问了本站! 莫非您记住了我的域名. 厉害~ 我倍感荣幸啊 嘿嘿