tags: [网络安全, Android, 逆向] title: 某社区网络门禁协议解析 slug: lianxiangjia-protocol redirect_from:
首先用 HttpCanary 抓包,过滤掉无用域名后,定位到一个 UDP 连接,在明文数据中可以明显看到 UNLOCK 字样,并得知采用 SIP 协议通信
逆向,根据 SIP 服务器地址找到相关类,使用 Frida 对该类 hook,可以得到该协议使用的用户名与密码
安全问题1:该协议使用的密码与 App 账户密码相同,因此可断定后端为明文存储密码
安全问题2:该 App 保留了调试用的 log 输出,只是通过两处 bool 值判断是否输出,存在暴露 log 的问题
开源问题1:该协议用到了开源库pjsip,但没有遵循 GPL 2 协议(就连署名都没有,你脸呢?)
<del>然后就是踩坑环节了</del>
由于这个协议不算罕见,开始时想到的是去找轮子,却发现没有支持 Python 3 的轮子,所以卡了一段时间,最后决定不用轮子直接当 UDP 协议来写,请求头之类的全部复制过来(面向过程😆)
其中一个比较麻烦的点就是 Digest 认证,虽然严格按照规范写一遍也不算难
首次发送后,没有像预期一样收到响应,看着每次请求都不同的 OperateId
,我<del>又走了一条死路</del>想,这个 UUID 会不会是与时间相关的哈希之类的东西?
回到逆向那边,搜索,最终找到的却只有randomUUID
看回模拟的代码,这个 ID 用的是硬编码的固定值,那是不是——随机才行?
改成 uuid.uuid4()
,发送,五秒后——门开了
🤔
由于这个 App 可以打开多处的门禁,下一个问题就是如何指定目标门禁
之前看 logcat 的时候,偶然发现了含有“lock number”的一行,对应的就是 SIP 协议中的号码(这个本来也是硬编码的固定值),又发现对于不同的门禁,该号码也不同
去翻/data/data/包名/databases
,在某一个数据库里找到了完整的对应列表,复制,运行时读取,第二个问题也解决了
用termux-api
里的UI.radio
装饰一下,搞个还过得去的用户界面,就能拿来用了
顺便吐槽下这个 App,肉眼可见的 SDK 就有至少十个,一半的内容都是购物,6KiB 就能实现的功能搞成了一个 60+ MiB 的软件
走了一大堆弯路,但还是挺有意思的经历就是了
大概就是,抓住每一处细节,多去翻databases
这类有敏感信息的文件,别在一些随机的东西上纠结太久
以及,没有轮子可以不用轮子,轮子不是用来给你制造麻烦的👎