开头

有这么一款摄像头,不支持ovif协议,不支持rtsp/rtmp。仅能通过云服务器进行查看/控制,开源的HA库明确表明不会支持本地视频流浏览(为了卖云存储),转存到NAS也得折腾一大圈。产品宣称使用金融级加密,实际上…
起源于某次抓包,让我对其有了全新的认识。

三种视频查看方式:

PixPin_2025-11-04_17-41-48.png

抓包

初显端倪

通过PCAPdroid抓取目标应用的数据包,然后在应用中进行播放视频。
过滤UDP数据包,可以发现同时向6个ip地址的32100端口发送了数据包

Pasted_image_20251104225550.png

相关IPList:(xxx.p2psy2.mijia.tech和xxx.p2psy2.io.mi.com域名)
42.157.165.184
42.157.165.251
110.43.39.73
110.43.68.126
110.43.39.53
110.43.68.154

发送的数据包为f1000000f1200024584d5359434e530000021fa14c424a4e5a0000000002082b000000000000000000000000 分别为4字节和40字节。像是某种握手包(Hello Packet)
同时发现也向局域网广播4字节的数据包,但是使用32108端口

Pasted_image_20251104231118.png

接下来云IP返回了20字节的响应f1010010000231bbf562009d0000000000000000和8字节的响应f121000400000000
通过对比发现数据包都是以f1开头。
Pasted_image_20251104233509.png

通过互联网搜索f100得到一个线索:PPPP协议

PPPP Protocol

这是CS2 network公司(尚云互连)http://www.cs2-network.com/ 开发的P2P Camera协议,宣称存在四道安全防护

Pasted_image_20251104234229.png

根据深入的了解,也对上面的3210032108端口有了了解。
https://github.com/Ankermgmt/ankermake-m5-protocol/blob/c12eb79a3f0bf87091fa9daf4feb062c5e8727d7/libflagship/ppppapi.py

image_2025-11-05_22-19-25.png

可以粗略的看作WAN请求使用32100端口,在局域网下使用32108端口发送广播消息。
PPPP协议可以大概视为TCP的简化版,其中数据在MSG_DRW类型中传递。
wireshak解密插件可使用https://github.com/pmarrapese/iot/tree/master/p2p/dissector

以下是研究中引用的网站
https://github.com/DavidVentura/cam-reverse
https://re-ws.pl/2018/05/pppp-api-what-i-know/
https://palant.info/2025/09/08/a-look-at-a-p2p-camera-lookcam-app/
https://hacked.camera/cves/#cs2
到这里可以把摄像头禁止联网了,有概率通过互联网匿名浏览。

PPPP Protocol Parse

根据某个使用了PPPP协议的产品,找到了该协议的解析库。
https://github.com/Ankermgmt/ankermake-m5-protocol/blob/c12eb79a3f0bf87091fa9daf4feb062c5e8727d7/documentation/developer-docs/libflagship.md
使用python进行简单的解析

import libflagship.pppp as pppp
from rich import print

# binary message to parse
input = bytes.fromhex('f1000000')
print(f"input:   {input}")

# parsing a message into structured data
msg, tail = pppp.Message.parse(input)
print(f"decoded: {msg}")

# packing a structured message into binary output
output = msg.pack()
print(f"encoded: {output}")

# the output must match our original input
assert input == output

可以解析出握手包信息

image_2025-11-05_22-46-03.png

P2PReq信息
image_2025-11-05_22-48-06.png

P2P握手成功后局域网开放的临时端口信息
image_2025-11-05_22-50-10.png

甚至贴心的给出了P2P NAT后的端口信息
image_2025-11-05_22-52-25.png

防止P2P失败,给出的云端中转信息
image_2025-11-05_22-54-07.png

当然,由于不是适配的库,某些握手包会解析失败,如下:

Pasted_image_20251105225656.png

当视频流开始传输时,可以看到数据包长度会明显变大
image_2025-11-05_22-58-10.png

这时解析数据包会显示一堆乱码数据
image_2025-11-05_22-59-46.png

这是MSG_DRW的消息经过了某种加密/混淆处理(看so库,应该是AES-CBC)。