好久没有写文章了,再不整点新东西,友台们该以为我嘎了。
今年海能达发布了PDC690对讲机,逗老师觉得不错顺手整了一个,这一下子打开了新世界的大门,海能达PDC系列安卓对讲机可玩性高啊。
最近围绕着海能达PDC系列安卓对讲机做了很多分析,也入手了PDC690 PDC760多台设备。
今天咱们先分享一下海能达的MDM接口。
先看看我做出来的效果,我让我的两个海能达手台的信息注册到自己搭建的FakeMDM上,然后进行展示。
目录
一、海能达MDM介绍
1、整体功能
Smart MDM 是海能达专为专业对讲终端(如多模智能对讲机、PoC对讲机、执法记录仪等)开发的移动设备管理系统,支持通过有线或无线方式(WLAN / LTE)进行远程批量配置和管理
兼容窄带终端与宽带设备,支持集中管理不同型号与批次的设备
2、MDM主要组件功能
到现在为止,逗老师并没有部署任何一台真实的SmartMDM服务器。
纯抓包,通过抓包内容分析推测,SmartMDM主要存在以下组件:
下面,我们对与抓包抓到的MDM注册和上报等动作进行分析
二、接口协议分析
对讲机与MDM的整体通信逻辑为
1、对讲机与MDM数据承载服务首次通信,上报SN
2、MDM数据承载服务返回登录服务器信息,设备与登录服务器进行认证鉴权
3、登录服务器给出ses服务器信息,设备与ses建立通信,维持心跳和获取任务
4、根据获取的任务,对讲机向MDM数据承载服务器上传信息,下载固件,下载配置等。
以下的分析说明中所使用的端口,均以上图的接口为例。
1、首次注册
服务:MDM数据承载服务 HTTP 8081
API PATH:POST HTTP 8081 /nrm/androidTask/checkDeviceSn
设备请求:
{
"deviceId": "00861067070143638",
"sn": "Z1AASA0600",
"versionCode": "400",
"pushModel": "0",
"terminalType": 2,
"modelNumber": "60P90000-1S0DDDUpU1C000S0A0DDV00012001000-1Q0DDCB1D1GGPBA0DD0BCABIEC000900-00000008",
"modelName": "PDC690 U1"
}
响应:
Content-Type: application/json
{
"code": "0",
"success": "true",
"msg": "",
"data": {
"sesPort": "8082",
"mdmCertMd5": "470af1bd61ae8be30ac5b5ee61e487c7",
"netDiskUrl": "http://192.168.31.221:8080/NetDiskWeb",
"usageMode": "0",
"mdmPort": "8081",
"sesIp": "192.168.31.221",
"checkResult": "0",
"mdmScheme": "http",
"isMasterSlaveModel": "0",
"umcMode": "0"
}
}
关键逻辑:MDM在这一步校验SN和设备ID,如果允许设备注册,MDM返回成功信息。如果认证成功,以下两条关键信息将引导对讲机寻找login认证服务器进行鉴权
1、“sesIp”: “192.168.31.221” login鉴权服务器IP地址
2、“sesPort”: “8082” login鉴权服务器HTTP 端口
其他信息实测无所吊谓
2、Login登录
基于上一步获取的信息,对讲机继续进行鉴权认证登录操作
服务:login鉴权服务 HTTP 8082
API PATH:POST HTTP 8082 /login/login
设备请求:
{
"deviceId": "00861067070143638",
"deviceType": "0",
"password": "077A7C98232FF38A0784BB89690BA91D",
"cerMd5": "1304A3DDC35079E3F63D88C8B51D625A"
}
响应:
Content-Type: application/json
Transfer-Encoding: chunked
{
"msg": "",
"code": "",
"data": {
"ip": "192.168.31.221",
"port": "8083",
"sslPort": "8084",
"channelId": "",
"token": "9d8d6205a63d437781419c6ed2a194b6",
"updateMd5": "true"
},
"success": "true"
}
关键逻辑:
1、登录PASSWORD使用MD5加盐认证。
2、返回数据中包含以下关键信息:
- ses任务服务器IP地址
- ses任务服务器TCP端口
- ses任务服务器SSL端口
- token令牌
- updateMd5,布尔值,如果设备false会触发设备端证书更新。更新证书后影响请求体中cerMd5字段。
3、Ses任务服务器
基于上一步获取的信息,对讲机继续与ses任务服务器通信。
服务:login鉴权服务 TCP 8083
测试发现,如果TCP端口可用,设备优先使用TCP明文进行通信。如果TCP端口不通,会尝试使用SSL进行通信。
注意,这一步使用TCP Socket通信,不是HTTP REST API
3.1、登录Ses任务服务器
设备提供设备ID,password,之前获取的token
设备请求:"msgType":5
{"msgContent":"{"name":"00861067070143638","password":"077A7C98232FF38A0784BB89690BA91D","token":"9d8d6205a63d437781419c6ed2a194b6","type":"0"}","msgType":5}
响应:"msgType":6
{"msgType":6,"msgContent":"{"result":"true","reason":""}"}
3.2、心跳+获取任务清单
设备请求:"msgType":4
{"msgContent":"{"name":"00861067070143638"}","msgId":"","msgType":4}
响应:"msgType":9
{"msgType":9,"msgContent":"{"UserName":"00861067070143638","content":"{"CommandUUID":"e117fc8fd54c484d939c0cb157987ee1","body":{"msgType":"deviceControlMsg","reExecuteTimes":0,"msgDate":"2025-07-29 21:01:15","RequestType":"MultipleCommad"},"type":"HyteraCommand"}","fromName":"push","CommandUUID":"e117fc8fd54c484d939c0cb157987ee1"}"}
设备ACK响应:"msgType":8
{"msgContent":"{"CommandUUID":"e117fc8fd54c484d939c0cb157987ee1","ACK_Result":"0","UserName":"00861067070143638","deviceType":"0"}","msgType":8}
这一段的响应比较有趣。测试发现:
- 1、如果下发的任务为deviceControlMsg-MultipleCommad。设备会上报通信录,APP List,GPS定位等信息。其他指令没有抓到
- 2、CommandUUID为任务ID,设备端在执行任务后对于再次获取到相同任务ID的任务不再重复执行。控制服务端CommandUUID的生成时间,例如10分钟更新,可以控制设备端上报的时间间隔。
- 3、设备端每分钟发送一次
"msgType":4
作为心跳,同时查看是否有新任务。 - 4、时间无所吊谓,不影响设备执行任务。但是影响设备内日志记录
4、上报数据
4.1、getDeviceInfoFromAndroid
服务:MDM数据承载服务 HTTP 8081
API PATH:POST HTTP 8081 /nrm/androidTask/getDeviceInfoFromAndroid
上报对讲机基本信息
期待返回:
{"code": "0","success": "true","msg": ""}
4.2、getAppInfoFromAndroid
服务:MDM数据承载服务 HTTP 8081
API PATH:POST HTTP 8081 /nrm/androidTask/getAppInfoFromAndroid
上报对讲机APP安装列表
期待返回:
Content-Type: application/json
Transfer-Encoding: chunked
{"code": "0","success": "true","msg": ""}
4.3、uploadContact
服务:MDM数据承载服务 HTTP 8081
API PATH:POST HTTP 8081 /nrm/androidTask/uploadContact
上报对讲机通信录列表
期待返回:
Content-Type: application/json
Transfer-Encoding: chunked
{"code": "0","success": "true","msg": ""}
4.4、appMd5Check
服务:MDM数据承载服务 HTTP 8081
API PATH:POST HTTP 8081 /nrm/androidTask/appMd5Check
上报对讲机APP MD5校验
期待返回:
Content-Type: application/json
Transfer-Encoding: chunked
{"code": "0","success": "true","msg": "","data": []}
4.5、uploadWorkInterfaceInfo
服务:MDM数据承载服务 HTTP 8081
API PATH:POST HTTP 8081 /nrm/androidTask/uploadWorkInterfaceInfo
没看出来上报的是啥
期待返回:
Content-Type: application/json
Transfer-Encoding: chunked
{"code": "0","success": "true","msg": "","data": None}
4.6、getAndroidCommand
服务:MDM数据承载服务 HTTP 8081
API PATH:POST HTTP 8081 /nrm/androidTask/getAndroidCommand
没看出来上报的是啥
{"id":"0ed5335ef8aa4633a7105452c050685e","deviceId":"00861067070143638","operStatus":"3","execResult":"999"}
期待返回:
Content-Type: application/json
Transfer-Encoding: chunked
{"code": "0","success": "true","msg": "","data": None}
4.7、uploadLocationInfo
服务:MDM数据承载服务 HTTP 8081
API PATH:POST HTTP 8081 /nrm/androidTask/uploadLocationInfo
上报GPS定位信息
{"deviceId":"00861067070143638","latitude":"-23.56723","longitude":"-46.65941","altitude":"862.2"}
期待返回:
Content-Type: application/json
Transfer-Encoding: chunked
{"code":"0","success":"true","msg":"","data":null}
以上,我就抓到了这些
三、Python实现MDM的可行性
分析完上述的动作之后,其实我们只要按照设备期待的返回,就可以一步步的引导设备注册到我们自己待见的MDM服务上。
开发的时候特别注意几点
1、token,password,MD5等关乎到认证,取决于开发者是否需要进行设备端鉴权。不鉴权的话直接全过
2、部分接口反馈内容Transfer-Encoding: chunked,需要注意
3、ses TCP端口编码的时候采用字符串编码json结构体,json内嵌json需要现对内嵌的json进行json.dumps()。
四、FakeMDM Github项目
Fake_Hytera_MDM
已经搭建好了一个测试站点,为HAM们进行交流服务,非商业用途。
http://mdm.ctsdn.com:2232/,扫码登录MDM
http://mdm.ctsdn.com:2232/dashboard 查看注册设备状态
五、狗头保命
免责声明
本项目或文档中所涉及的 Hytera SmartMDM 系统协议分析内容,均基于海能达 PDC 系列对讲机(如 PDC680、PDC760)与 SmartMDM 服务器之间通过网络通信所产生的未加密数据抓包所得。
所有分析工作完全基于合法拥有的设备和网络环境中进行的数据观察,未涉及对海能达任何软硬件产品的逆向工程、反编译、破解或其他形式的逆向分析。
本项目的目的仅限于:
- 网络通信协议学习;
- 无线通信设备行为理解;
- 提高个人或业余无线电爱好者对现代通信设备工作机制的认知;
- 网络与设备之间交互行为的透明化研究。
本项目不涉及:
- 破解海能达产品授权机制;
- 复制、模仿或绕过其商业逻辑;
- 未经授权地接入其生产环境;
- 任何形式的商业或营利用途。
请注意:
- 本文档或项目中所述的所有品牌、产品名称及相关协议均归其原厂商(海能达通信股份有限公司)所有;
- 所有技术内容和结论仅供学习交流使用;
- 任何组织或个人不得利用本文档或项目中提供的信息从事违反《中华人民共和国著作权法》《中华人民共和国计算机软件保护条例》或其他相关法律法规的行为;
- 本项目作者不承担因使用本文档内容所引起的任何法律责任或纠纷。
若您是相关厂商或权利方,并对本项目内容有任何疑问或异议,欢迎及时联系项目作者,我们将积极配合处理。