来研究一个可视化采耳棒

如题,之前碰上美团上罗森搞活动,买零食的时候发现了这个只要 30 块的可视化采耳棒,没玩过的东西自然是非常好奇,明天就要离校了,趁着工具仪器啥的基本都在宿舍,于是把它拆开研究了下。本文大概分成两个部分,前半部分是抓包研究它如何传输视频的,并演示了用 ffmpeg 来截获视频;后半部分把它拆开研究了下硬件,并 dump 了 flash 里的固件,简单浏览了一下固件。

1. 受害者介绍

如图,就是这么个东西:

前端是个可以拿下来的盖子,揭开之后就是挖耳勺的部分:

可以看到有个很小的镜头,上面一圈的贴片元件是 LED 灯。

使用方法很简单,长按机身上唯一的那个按键之后启动,它会作为 WiFi AP 广播一个无需密码的开放 SSID,图里的那个 Cooleer_d88835 就是:

我的手机几乎是贴着它测试的,可以看到信号强度 -50dBm,并不是很强,远距离使用估计不行。手机需要连接这个 WiFi,然后安装一个叫 YW tool 的 app,打开这个 app 就可以看到画面了

2. 数据流分析

这玩意既然是用 wifi 传输的数据,那肯定是采用一套基于 IP 协议的应用层协议,得益于以太网协议家族成熟的工具链,我们可以很容易抓取数据包来分析。

2.1. 初步探测

首先要搞清楚这个东西作为一个 AP,在连接上一个 STA 之后的行为是什么,为此我们直接用电脑普通地连接到那个 Cooleer_d88835 wifi,我们即刻被分配了 IP 地址:

这证明它运行着 DHCP 服务器。

并且,采耳棒自身的 IP 是 192.168.1.1,我们作为第一个连接上来的 STA,被分配了 192.168.1.100. 此时若尝试再接入一个 STA,例如尝试用手机连接,是根本连不上去的,也就是说这玩意只允许一台设备在同一时刻连接。

连接上之后,标准流程,先启动 wireshark 抓包看看有什么东西,发现它并没有主动发送任何数据包。当然,它会正常地响应 ARP 查询请求和 ICMP echo 请求(ping):


这是一个好的迹象,至少证明它运行着一个较为完整的 IP 协议栈。而且有趣的是,若给它发一个 DNS 请求,它会给出一个 refuse 回应。

2.2. 监听流量

鉴于它使用开放性 wifi,我们采用无线网卡监听模式,在旁信道抓包是最方便的,这是综合以下几种考量的结果:

  • 若直接在手机上抓包: 我手机没 root,tcpdump 用不了,而像 PCAPdroid 这样的工具总是给我一些奇怪的结果,所以这个方案基本否决;
  • 若安插一个工作在二层协议的中间人: 基本思路是让一个拥有两个无线网卡的电脑,一边作为 wifi STA(相当于手机等一般客户端)连接到采耳棒,另一边同时充当 AP(相当于路由器)发射一个新的 wifi,用手机连接这个新 wifi,然后我们就可以在中间截胡所有的数据包。然而这其实带来一个新问题,要实现二层转发最方便的方法就是把两个网卡都连接到内核网桥,但是市面上绝大部分 wifi 网卡,在作为 STA 模式时是不能被挂到网桥上的(要做到这一点,你需要支持所谓 WDS 功能的网卡)。因此整个实现下来就非常麻烦,且我手头上的硬件不支持,否决。

关于无线网卡的监听模式: 这是一个特殊的模式,在该模式下,无线网卡将保持静默(不向外发送数据包),但是会接收指定信道上的所有合法的 IEEE 802.11 数据包,也就是尽可能地捕获空气中的有效 WiFi 数据包。因为无线电波(电磁场)在空气中四散传播,所以这是可行的。

利用这一点,我们可以让手机和采耳棒正常地通过 wifi 连接,而电脑将扮演一个监听者,它绝不出手干扰二者之间的通讯,而是悄悄收集二者通讯的内容

要将网卡设置为监听模式,有很多工具都可以做到这一点,比如专用于无线攻击和渗透的 aircrack-ng,但是这里我们使用最原始的 ipiw 命令,要用来监听的网卡是 wlp108s0.

由于我使用 NetworkManager 来管理网络,为此首先要让 NetworkManager 先暂时性忽略这块网卡,防止等会它自动进行扫描 wifi 之类的操作而干扰我们的监听:

$ nmcli device set wlp108s0 managed no

接下来先 down 掉网卡,将其设为 monitor (监听)模式,再 up 网卡:

$ sudo ip link set wlp108s0 down
$ sudo iw dev wlp108s0 set type monitor
$ sudo ip link set wlp108s0 up

最后最好指定一个监听信道,排除那些你不感兴趣的信道的干扰。这个采耳棒使用 2.4GHz 频段的信道 1,设置即可:

$ sudo iw dev wlp108s0 set channel

接下来普通地通过 wireshark 在 wlp108s0 上进行抓包即可。

特别注意: 对于一个开放性网络(连接 wifi 时不需要密码的),二层数据包是明文在空中传输的,因此抓包之后可以直接解读内容,直到遇到应用层加密协议层(如 https)。对于有密码的 WPA 认证网络(这是大部分 wifi 的情况),传输是加密的,要解密抓到的数据包,需要两个前置条件:(1) 抓到某个 STA 最开始接入时,和 AP 的握手包,这样的包一般有四个,STA 和 AP 通过这些握手包进行密钥交换;(2) 知道该 wifi 的密码。

由于这个采耳棒发射的是开放性网络,对于有密码的情况我们就不展开说了。

2.3. 分析流量

用 wireshark 抓包完成后,可以看到这些包全部是明文传输的,我们可以直接看到 IP 层甚至 TCP/UDP 层:

ip.addr == 192.168.1.1 这个条件过滤一下抓到的包,就可以看到手机和采耳棒之间的通讯过程了:

经过一些观察,可以发现如下的初步通讯过程:

我们把采耳棒记为 A,手机记为 S

  1. 手机上一旦打开 YW tools app,S 向 A 的 7099 端口发送一个纯 UDP 报文,真正的载荷只有两个字节,为 01 01
  2. 上述报文重复发送了两次,然后 A 开始向 S 不断发送 UDP 报文,载荷长度为 8,内容 00 a9 50 5f 00 00 00 00

这种情况持续了一会,期间 S 还尝试往 A 的 5000 端口发起一条 TCP 连接,但是都被 A 给 reset 了。直到 S 向 A 的 7070 端口发起 TCP 连接,这时 A accept 了这个连接,不过这回是 S 马上就 reset 连接了。然而紧接着 S 再次发起同样的连接,这次双方完成了 TCP 握手,连接建立:

追踪这条 TCP 连接可以看到(红色着色的是 S 到 A,蓝色着色的是 A 到 S):

好嘛,竟然是 RTSP 协议!

可以看到二者商量了一下 RTSP 流的端口和其它细节,然后就开始通过 UDP 传输视频了:

非常好啊,没有私有协议也没有加密,纯 RTSP 流来的。那根据刚才从 RTSP 握手包里得到的信息,它的流地址是 rtsp://192.168.1.1:7070/webcam,我们应该可以直接使用 ffmpeg 来播放这个流

2.4. 直接播放 RTSP 流

现在断开手机,再次把电脑连到采耳棒的 wifi 上,尝试用 ffplay 直接播放流:

$ ffplay 'rtsp://192.168.1.1:7070/webcam'

我们得到了:

非常地成功啊

现在这玩意也不再神秘了,本质上就是个 RTSP 推流,加上了一些自定义的 UDP 握手包而已。不过这玩意还有个陀螺仪,用来处理画面旋转,这部分是如何实现的我就懒得研究了(

3. 更深入一点

都到这里了不妨直接拆开看看吧。这玩意是一个非常坑的卡扣结构,第一次拆基本上不可能无损拆开。

总之拆开之后是这样的:

主板前面有一个 FPC 软排线,连接到前面的摄像头。前面电池的部分:

拆出主板,主板正面是几个电源管理的 IC,还有按键,没什么好说的:

但是主板正面暴露出的几个测试点上,写着 TCLK, TMS, EN, AB(还是 A8?)这些字样,TCLK 和 TMS 看着像是 JTAG 端口,然而后面几个完全对不上。我完全看不出这是啥端口,有头绪的大佬请务必联系我!

背面就看到了主控,主控左上角是重力加速度计(陀螺仪),它的左边那个银色的是有源晶振,那根焊上去的导线是非常粗犷的 wifi 天线:

这个主控主打一个神秘,丝印 KL-908我搜遍全网都查不到任何资料,连淘宝上都没有卖的。 另一个在 reddit 上的老哥在无人机上也遇到了这个芯片,那个似乎也是一个相机+WiFi 的应用,这芯片应该是专门做这个的。

不过它右边的那个 8pin 芯片看着像是个 flash,里面肯定存着这个主控的固件。我想着不妨把它拆下来,把固件读出来看看。

3.1. 读 flash

这个 8pin 芯片的丝印 MK25D40,也是搜遍全网搜不到任何资料,真讨厌。不过这个 25D40 的命名方式看着确实像是某种 flash,顺着这个方向我找到了许多疑似是它的孪生兄弟,其中这个 A25D40 算是非常像的一个:

说到底,按照命名惯例, MK25D40 前面的 MK 应该是厂商之类代号,那 MK25D40A25D40 应该只是不同厂商生产的同一种器件,应该可以代换。

无论如何,从 A25D40 的 datasheet 来看,这玩意是个 512KB 的标准 SPI flash,手边没有编程器,我干脆直接把它拆下来,焊了一个搭棚,然后接到树莓派上去读:

在树莓派上,flashrom 根本不认它,大悲:

不过根据前面的经验,先找个应该兼容它的兄弟姐妹型号试试:

额……继 A25D40 之后还有 ZD25D40,不管了就用它吧,没想到还真成功读出来了:

有了固件文件 flash.bin,我们可以干一些更进一步的事情了。

3.2. 初步分析一下固件

对于一个完全没有资料的主控,连它的指令集架构都不知道,内存布局也不知道,要展开逆向工程是很难的。我的能力也有限,没有对其展开更深入的分析,不过还是可以做一些常规的手段的。

首先是 binwalk,毫无用处,什么都没分析出来:

然后是熵分析,没有出现大段数据熵接近 1 的情况,基本可以确定没有压缩和加密。中间相对高熵的一段应该是代码段,后面稍微低一些的应该是符号表、字符串区一类:

接下来可以提取字符串+搜索关键词看看,这里我们可以看到一些有趣的东西了:

可以搜索到 task 之类的关键词,还有 PID、CPU time 之类的东西,说明它应该运行着某种 RTOS,而不是裸机在跑程序:

还可以发现包含图像处理、IEEE 802.11 部分的大量代码符号:

不过很可惜,以上这些并没有给我们关于 CPU 架构或内存布局的更多线索。

目前我就探索到这里了,之后有新的进展我会继续更新(不过想必是悬了)。
我把提取出的 flash 文件放到了 github(GitHub - wait1210day/ryevi-hack: RYEVi 可视化采耳棒(主控丝印 KL-908)固件逆向实验 ),有感兴趣的大佬如果分析出什么结果了请务必和我交流!哦内该!

4. 写在最后:关于安全性的思考

如你所见,这个小小的采耳棒,在使用开放性 wifi 的情况下,我们可以通过监听的方式,在完全不产生物理接触的情况下,就得到它传输的视频内容。虽然对于一个 30 元的玩意不可能要求太多,但是它在加密方面的缺失仍然是足以引发担忧的

试想一下,如果你无意间将它在开启、连接的状态下,随意地放置到了桌上,而它的摄像头正好拍到了手机或电脑屏幕上的隐私信息,那这足以构成隐私泄漏。本质上,它是通过这个未加密的开放 wifi,向你四周大大方方地广播它所拍摄到的所有东西。

对于一个物联网产品来说,安全是用户看不到的部分,又是至关重要的部分。这个采耳棒在功能和效果方面做的已经挺不错,这是用户能看到的部分,然而在用户看不到的部分偷懒,不是一个负责任的制造商应有的态度。

2 个赞

诶 这个截图里面是什么APP

Cellular-Z,分析无线电环境挺好用的,可以分析蜂窝移动网络,wifi,和 GPS/北斗 之类的

那个kl-908会不会是 KY908系列无人机 Wi-Fi 图传模组的一个换皮?


好奇reddit怎么搜出来这个的,好像帖子里面也没有KL-908的关键字,但是就是能搜出来,好神奇
感觉应该是对每张图片生成了caption,或者做了OCR

google 搜关键词 kl-908 chip,可以搜到这个帖子,然后会发现一张在原帖里不存在的图片(原帖里的板子是红色的,这个图里的板子是黑色的):

原帖里的那个(红色板子的)图非常模糊,放大之后根本看不清丝印,没法做 OCR。感觉应该是对这个黑色板子的图做了 OCR 或者有 caption,但是这图到底哪来的???反正就是很神奇(

原帖里面有的,要往后翻,第三张图片

wow 没注意到

更新一下进度,目前取得了显著的进展:我已经搞清楚了主控的真面目(并非完全确定,但有非常大把握),找到了 UART 接口,并下载到了对应的开发套件和工具链(SDK 和编译环境)

5. KL-908 的真面目

前面已经提到过,在网络上直接搜索 KL-908 没有任何有价值的结果,这意味着两种可能:

  • 这颗 SoC 太过小众,是某厂商专门研发的专用芯片,且对外不公开资料;
  • 这是别的什么芯片的换皮,即,将原来芯片的丝印磨掉之后,重新打标。这种手段在国内非常常见,其主要意图是防止破解。

第一种可能性其实非常小,因为这样做成本很高,小公司承担不起,第二种情况的可能性很大。

不过猜测归猜测,还是得拿出证据才行。一切的起点是,今天我在 flash.bin 里一通乱搜的时候,一个疑似 SDK 名称的东西出现了(ps:之前和群里大佬交流的时候,也提到过要注意这个):

hgSDK 想必就是开发这东西固件的 SDK 平台了,以它为关键词,在网上四处搜刮一下,我先是找到了 GitHub 上一个叫 T-Halow 的仓库里,有个目录是 hgSDK

这是一个 WiFi HaLow 的项目,使用了泰芯的 TXW830x 芯片。WiFi HaLow 也即 IEEE 802.11ah,这是一个工作在 1GHz 频率以下的、专为物联网设备设计的 WiFi 协议。和我这个采耳棒看起来好像没什么关系,毕竟它的 wifi 工作在 2.4GHz 频段。

继续搜索 hgSDK 关键词,经过一上午的翻找后,真正破局的是这个帖子的出现:Mini 1080p wifi camera from Aliexpress, how to use without app (FtyCamPro)?

该帖的楼主在全球速卖通上买了个便宜的 wifi 摄像头,拆开看发现是 BK7252 主控。不过最关键的是 6 楼有人给出了一个很类似的摄像头, 但是芯片是泰芯 TXW817-810 层主提供了一张非常高清的近照:

这张图中可以看清楚主控的一些引脚和外围电路之间的连接。有几个关键的引脚值得注意:

  • 图中主控 48 脚(照片最下面那一排引脚的最右侧那个)经历了一个简单的 LC 射频前端电路后连接到了 PCB 上的天线;
  • 45,46,47 脚被连接在一起,然后经过一个电容连接到 GND;
  • 43,44 脚似乎是接到了 40MHz 外部晶振(右下银白色的那个);
  • 1-24 脚大多是细长的并列连线,推测为数字信号连线,这意味着该主控的 GPIO 和大部分 peripherals 可能在这些引脚上引出。

对比这些特征,和我这个采耳棒上的 KL-908 与外围电路的连接方式完全一致由此怀疑 KL-908 就是 TXW817-810,或其同系列相似型号。

另一个非常激动人心的事情是,该帖子中层主还成功地找到了 UART 接口,并从 UART 读到了它的 boot log,我复制一部分过来:

<... 上面省略>
[0]00 00 00 00 00 10 e4 00
[0]f0 3c 0f
[0]validity: 1678e00d

** hgSDK-v2.5.1.7-26745, app-0, build time:Jan 18 2024 21:55:13 **
**   libcore v2.5.1.7-26745, build time:Dec 18 2023 11:05:53
**   libnetutils v2.5.1.7-26745, build time:Dec 18 2023 11:06:10
**   libcommon v2.5.1.7-26745, build time:Dec 18 2023 11:05:58
<下面省略...>

可以看到,其中明确地出现了 hgSDK 字样,且格式和我们在固件里找到的完全一致,更加确定了这个推测,即,KL-908 很可能就是 TXW817-810.

6. 找到 UART 并读出内容

经过一些观察和尝试,发现 UART 接口在板子上一个非常隐蔽的位置:

在画圈处,有一个很小的空焊盘,直接连接到芯片的 25 脚,除此之外没有和任何其它东西相连,并且甚至还写了个 T 标记在旁边。。。经过一些测试,这里确实就是 UART 的 TX 接口,至于 RX 接口我并没有找到,而且应该没有什么用,所以我就不关心它了。

接下来要确定 UART 的波特率,逻辑分析仪或示波器都可以做到这一点,我就用示波器了。把示波器挂在 TX 和 GND 之间,然后寻找一个持续时间最小的高电平来观察(除了空闲电平外,所有的高电平持续时间都是这个最小时间的整数倍,所以这个最小的高电平还是很好找的)

如图,用 Measure 或 Cursor 功能测量一下这个高电平的持续时间,这里是 1.07us,考虑误差,与之对应的可能有两个常见的波特率,1000000 (1us 显性电平)或 921600(1.085us 显性电平),两个都试一下,看看哪个能得到有意义的输出就行了。

测试之后发现 921600 可以得到有意义的输出(更准确地说,它采用 UART 921600 8N1,即921600 波特率,8 位数据位,无奇偶校验,1 位停止位),启动过程中 UART 输出如下:

[0]40 00 57 00 a3 44 12 a0
[0]28 f2 00 00 00 00 00 00
[0]00 00 00 00 00 00 00 00
[0]47 87 81 16 88 35 66 a6
[0]8a a5 89 88 9e 57 00 00
[0]80 00 bc 02 a0 ca 00 00
[0]00 1d 00 00 0e 0a 00 00
[0]00 00 00 00 09 30 03 00
[0]00 00 00 00 08 84 40 08
[0]84 40 08 84 40 08 84 03
[0]08 3f 1e e8 81 5e f8 c4
[0]3f f8 83 0f f8 f5 fe f6
[0]ff 00 f8 f7 0f 00 ee fe
[0]ee 00 00 f0 ea 00 00 1d
[0]00 03 b2 00 00 00 00 07
[0]00 00 00 00 00 73 0a 00
[0]78 50 00
[0]cpu   clk: 120 
[0]flash clk: 80 
[0]psram clk: 0 
[0]validity: 1579e00d
[0][OTA_MSG] OTA_NUM:0  ota_version:31060       run_addr:0

** hgSDK-v2.5.0.7-31060, app-0, build time:Oct 25 2024 15:55:12 **
**   libcore v2.5.0.7-31060, build time:Oct 21 2024 15:49:37
**   libnetutils v2.5.0.7-31060, build time:Oct 21 2024 15:49:52
**   libcommon v2.5.0.7-31060, build time:Oct 21 2024 15:49:43
**   libosal v2.5.0.7-31060, build time:Oct 21 2024 15:49:36
**   libatcmd v2.5.0.7-31060, build time:Oct 21 2024 15:49:43
**   liblmac v2.5.0.7-31060, build time:Oct 21 2024 15:50:08
**   libwifi v2.5.0.7-31060, build time:Oct 21 2024 15:50:18
------------------------------------------------------------------
[0] ------- system restart fault -----------
[0] ---------------------------------------
[1]freemem:160596
[1]custom_mem_init:2000d258
[2]custom mem sram:61440
[2]skbpool init, total:45656 (0x200389a8~0x20043c00), max per:80%
[3]syscfg_read OK!
[3]old cfg_ver:259
[6]lmac rx info size:36
[6]GAP0 : 200345a8
[6]GAP1 : 200389a0
[6]lmac rx buff:200345b0, size:17392, hw rx buff size:11368, ampdu:7, max subfrm:3
[7]lmac priv: 2001d268
[8]lmac tx  : 2001d628
[8]lmac rx  : 2001e7f4
[8]lmac ble rx: 00000000
[9]pack:7, bios_id:3
[9]use AMPM DPD!
[9]verf:0x6, ibpt:0xa, ibct:0xa, iref:0x6
[10]verfvco_trim:0x8, verfcp_trim:0x6, verfdiv_trim:0x5
[10]verfdsm_trim:0x4, verfvcc25_trim:0x1
[11]da cap:7, da gain:1
[14]txdcoc from:1, i:14, q:10
[14]tx imb from:1, pm:51, gm:9
[15]rx dcoc from:1
[15]g:0, ana:2048, i:2, q:0
[15]g:1, ana:2112, i:4, q:2
[16]g:2, ana:2112, i:4, q:2
[16]g:3, ana:2112, i:8, q:6
[16]g:4, ana:2112, i:7, q:7
[17]g:5, ana:2112, i:6, q:6
[17]g:6, ana:2112, i:6, q:6
[17]g:7, ana:2112, i:3, q:8
[18]rx imb from:1
[18]g:0, 8174, 4077
[18]g:1, 8190, 4086
[19]g:2, 8174, 4078
[19]g:3, 0, 4087
[19]g:4, 0, 4088
[19]g:5, 8176, 4080
[20]g:6, 8170, 4079
[20]g:7, 0, 4088
[20]time offset:0, 29
[20]!!! rf pack err !!!
[21]lmac test: 2001efa0
[21]lmac_bgn_lo_freq_set: 2432
[23]set rts_threshold =2304
[23]lmac set mac0 addr:46:87:81:35:88:d8
[24]*** open ADC success!
[24]*** add success: ADC channel cnt = 1, name:257
[25]*** add success: ADC channel cnt = 2, name:258
[25]*** add success: ADC channel cnt = 3, name:262
[26]*** delete success: ADC channel cnt = 2
[29]lmac_bgn_lo_freq_set: 2412
[31]lmac_bgn_lo_freq_set: 2412
[32]set rts_threshold =1600
[32]set ac= 0 aifs= 2 cw_min= 15 cwmax= 1023 txop= 79
[33]set ac= 1 aifs= 6 cw_min= 15 cwmax= 1023 txop= 79
[34]set ac= 2 aifs= 1 cw_min= 7 cwmax= 15 txop= 128
[34]set ac= 3 aifs= 1 cw_min= 3 cwmax= 7 txop= 65
[35]set ac= 0 aifs= 2 cw_min= 15 cwmax= 1023 txop= 79
[36]set ac= 1 aifs= 6 cw_min= 15 cwmax= 1023 txop= 79
[36]set ac= 2 aifs= 1 cw_min= 7 cwmax= 15 txop= 128
[37]set ac= 3 aifs= 1 cw_min= 3 cwmax= 7 txop= 65
[38]lmac_bgn_lo_freq_set: 2437
[39]inteface1: start scanning ...
[40]vif1 state WPA_DISCONNECTED -> WPA_SCANNING
[41]lmac dbg!!!mac addr err:00:00:00:00:00:00
[41]Func:lmac_bgn_tx_check Line:784 LR=0x1802b0c4
[240]lmac dbg!!!mac addr err:00:00:00:00:00:00
[240]Func:lmac_bgn_tx_check Line:784 LR=0x1802b0c4
[2117]lmac set mac0 addr:46:87:81:35:88:d8
[2118]lmac_bgn_lo_freq_set: 2412
[2120]lmac set mac0 addr:46:87:81:35:88:d8
[2120]lmac_bgn_lo_freq_set: 2412
[2122]ieee80211_ap_ioctl:164::set channel 1
[2122]set ac= 0 aifs= 1 cw_min= 1 cwmax= 3 txop= 0
[2123]set ac= 1 aifs= 1 cw_min= 1 cwmax= 3 txop= 0
[2123]set ac= 2 aifs= 1 cw_min= 1 cwmax= 3 txop= 0
[2124]set ac= 3 aifs= 1 cw_min= 1 cwmax= 3 txop= 0
[2125]vif2 state WPA_DISCONNECTED -> WPA_COMPLETED
[2127]add w0 interface!
JPG start
[2128]csi_test start,iic init
[2129]iic init finish,sensor reset & set sensor clk into 6M
hgdvp_set_baudrate:clock:480000000
[2133]set sensor finish ,Auto Check sensor id
[2133]SID: ff, a0, 42, 43,0
[2134]SID: ff, bb, 66, 67,f0
[2135]SID: ff, 10, 42, 43,f1
[2136]SID: ff, 9d, 42, 43,f0
[2136]preset table num:2
[2137]SID: ff, c0, 62, 63,0
[2138]SID: 20, 3a, dc, dd,fc
[2138]SID: 20, 37, dc, dd,fc
[2139]SID: 20, 38, dc, dd,fc
[2140]SID: a6, a6, dc, dd,fd
[2140]id =a6 num:8 
[2140]Auto Check sensor id finish
[2141]mclk:24000000MHz
hgdvp_set_baudrate:clock:480000000
[2141]init:1804f340 u8Addrbytnum:1,u8Databytnum:1
[2142]SENSER....init
[2182]init table num:308
[2183]SENSR ident ok:480*480
[2183]csi init start  --
[2183]csi set size ====>480*480
[2184]csi dvp_size_set
[2184]csi IRQ init
[2184]dvpirq_register:1 1801a4e0  1801a4e0
[2185]dvpirq_register:0 1801a4cc  1801a4cc
[2185]vppirq_register:0 1801a2fc  1801a2fc
[2186]vppirq_register:1 1801a640  1801a640
[2186]vppirq_register:2 1801a2f8  1801a2f8
[2187]vppirq_register:3 1801a49c  1801a49c
[2187]vppirq_register:4 1801a4b0  1801a4b0
[2188]vppirq_register:5 1801a2e8  1801a2e8
[2188]vppirq_register:6 1801a2d8  1801a2d8
[2189]vppirq_register:7 1801a2c8  1801a2c8
[2189]csi IRQ init finish,start get data
eloop_init:287::start
user_eloop_run:309::run
[2193]dns sock :2
[test] init tcp server: port: 5007
[2194]ota num:0 version:31060
g_sensor_init start,iic init:200004a0
init g_sensor,check id
SID: ff, 13, 4e, 4f,1
SID: 26, 26, 32, 33,70
id =26 num:1 
init table num:22
gsensor_ok
adc_open_ok
[2202]*** add success: ADC channel cnt = 3, name:2
adc_add_channel_ok
> udp_user_data_init
                    udp port:7099
enter usr_udp_create_server_test
udp server ok:4
port:7070       fd:5
[2207]set_video_track:364
[2207]set_video_track source->track[t]:0        rtp:200290B0
[2208]set_video_track:364
[2208]set_video_track source->track[t]:0        rtp:200296D4
[2209]no this event(20005)...
[2209]scan down.......

前面的方括号里的看起来应该是时间戳,代表了从启动开始的毫秒数。启动完成后,它开始周期性地输出这些内容(此时没有手机连接):

vol_f:3652 
vol_f:3652 
vol_f:3650 
vol_f:3650 
[3209]custom mem sram:61440
[3209]freemem:42824
vol_f:3650 
vol_f:3650 
vol_f:3650 
vol_f:3650 
[4209]custom mem sram:61440
[4209]freemem:42824
vol_f:3648 
vol_f:3648 
vol_f:3648 
--------------------
local:46:87:81:35:88:d8
    !!! chip pack err !!!
    bios:3, pack:7 
    pwr idx: 0
    chip-temperature: 36
    freq:2412, bg_rssi:-83
    cca: -70, -60, -62
    tx: txq:0, ps:0, tx_stat_q:0,
                                         tx dma:1, total tx:0, retry:0, tx lost:0, tx err:0
    rx: frms:41, data:0
    throughput: tx: 0 bps, rx: 0 bps
    max gain:7
--------------------

上面这段内容被不断重复,(那个 vol_f 的值是不断变化的,还有一些诸如温度和 RSSI(wifi 信号强度)也是在变化的),当有手机连接上它的热点时,输出开始有变化:

[49557]lmac_bgn_add_sta: if:1, aid1, addr:32:ec:a9:e6:9e:fb[49558]rc_init: type= 2 mcs_mask= 0x3cc

[49558]inteface2: sta 32:ec:a9:e6:9e:fb connected
[49559]user_sta_add:32 ec a9 e6 9e fb
[49693]send DHCP_OFFER ...
[49694]Next IP: 192.168.1.101
[49694]Assign IP 192.168.1.100 for 32:ec:a9:e6:9e:fb, flags=0 (next:192.168.1.101)
vol_f:3618 
[49708]send DHCP_ACK ...
[49709]Assign IP 192.168.1.100 for 32:ec:a9:e6:9e:fb, flags=0 (next:192.168.1.101)
[49711]IP Pool:
[49712]    ip:192.168.1.100 - 32:ec:a9:e6:9e:fb

这印证我们之前关于它内置 DHCP server 的猜测。

接下来在手机上打开 YW tool,开始查看摄像头,输出又有变化:

do_accept  477
do_accept c:2002A124
do_read:372
===========OPTIONS=============
RTSP/1.0 200 OK
CSeq: 1
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE


do_read:372
===========DESCRIBE=============
[53363]live_get_sdp:88  path:/webcam
[53363]live_get_sdp:95
[53364]À source->track[t]:200290B0      rtp:200292A8
[53364]live_get_sdp:119
RTSP/1.0 200 OK
CSeq: 2
Content-Base: rtsp://192.168.1.1:7070/webcam/
Content-Type: application/sdp
Content-Length: 122


rtsp_teardown:147
rtsp_release_event:132
del_session session:2002A794
do_read:372
===========SETUP=============
[53381]jpeg_stream_init:713
[53382]opcode_func:270
[53383]src:2002A890
[53383]src open_ref:1
RTSP/1.0 200 OK
CSeq: 3
Transport: RTP/AVP;unicast;client_port=20318-20319;server_port=53796-53797
Session: 82838485868788898A8B8C8D8E8F90


[53392]rtsp_live_thread:23
do_read:372
===========PLAY=============
RTSP/1.0 200 OK
CSeq: 4
Session: 82838485868788898A8B8C8D8E8F90

可以看到是在处理 RTSP 协议。

以上是在 UART 上观察的全部内容了。 UART 内容和上文提到的那个帖子里的 UART 内容几乎一致,于是进一步肯定了这块主控就是 TXW817 的猜测。

7. Dive into TXW817-810

这个芯片的 datasheet 可以在网上找到,也可以看泰芯官网的介绍

它是一个集成了很多常见外设的物联网 SoC,还带有 WiFi, BLE,以及 mjpeg 硬件编解码单元,其核心是一个 国产自研 CSKY 指令集架构的 CK803 CPU

CK803 是一颗具有 3 级 pipeline,32KB cache 的 32 位 RISC CPU 核心:

我之前对这个 CSKY 架构是闻所未闻的,不过据网上介绍,其出货量相当大,想必应该是已经渗透进我们生活中的各种产品了。

8. SDK 和 Toolchain

据官网介绍,该芯片要使用 CDK 开发环境(也是一个自研 IDE,用 wxWidgets 写的,仅支持 windows 平台),搭配官方的 SDK. 感兴趣的读者可以去官网下载 linux 的 toolchain 来研究(基于 gcc):csky-elf-noneabiv2-tools-x86_64-newlib-20210423.tar.gz

这次更新的进展主要是硬件方面的。目前我正在根据 SDK 的代码来进一步研究,如果有新的进展会保持更新。

我目前搜集到的资料已经上传到 github,包含 flash 全量 dump,txw817 的 datasheet,还有官方的 software design doc.

2 个赞

@Murasame 突然想到 好像网上有黑产就是有关 IP Cam 的监控的)是不是他们有一套类似的自动 scan+hack 的系统,把家庭里面防护很弱的 IP Cam 都 hack 了

有点好奇这个技术是怎么发展的,比如怎么扫描网络里面的 IP Cam

问了一下Gemini,似乎没有这么简单)

您提到的这种方法是过去几年里一种常见的Wi-Fi密码破解技术,它针对的是使用WPA/WPA2-Personal (PSK) 安全协议的无线网络。

这个过程的核心是捕获“四次握手”数据包。这个“四次握手”是客户端设备(比如您的手机或笔记本电脑,通常被称为STA)在连接到无线接入点(AP,也就是您的路由器)时,为了验证彼此身份并生成加密密钥而进行的一个必要过程。

需要明确的是:抓到这四个握手包本身并不能直接“看到”Wi-Fi密码。

这个方法的完整流程是这样的:

  1. 开启监听模式:攻击者需要一张支持监听模式(Monitor Mode)的无线网卡。这种模式允许网卡捕获其通信范围内所有的Wi-Fi数据包,而不仅仅是发往自己的数据包。
  2. 捕获握手包:当一个设备尝试连接到目标Wi-Fi网络时,攻击者会使用专门的软件(如Aircrack-ng套件中的airodump-ng)来监听并捕获这个设备与路由器之间交换的四个EAPOL(Extensible Authentication Protocol over LAN)数据包。这就是所谓的“四次握手”包。如果目标设备已经连接,攻击者还可以发送一个“反认证”(deauthentication)包,强制该设备断开连接然后重新连接,从而触发一次新的“四次握手”过程,以便进行捕获。
  3. 离线暴力破解:捕获到的握手包中包含了验证密码正确性所必需的加密信息,但并不包含明文密码本身。密码是以一种经过哈希(Hash)计算的形式存在的,称为PMK (Pairwise Master Key)。攻击者接下来会使用破解软件(如aircrack-ng),在自己的计算机上进行离线攻击。这个过程是:
  • 攻击者使用一个庞大的密码字典(一个包含成千上万个常用密码的列表)。
  • 软件会逐一尝试字典中的每一个密码,通过与SSID(Wi-Fi名称)结合,计算出对应的PMK。
  • 然后,软件会用这个计算出的PMK来模拟“四次握手”的加密过程,并将其结果与捕获到的握手包中的加密信息进行比对。
  • 如果比对结果一致,那就意味着字典中正在尝试的这个密码就是正确的Wi-Fi密码。

如果密码是自己设置的比较复杂就不行了

没有问题嘛。Gemini 给出的结果就是在说需要两个条件同时满足,一个是抓到四个 WPA2 握手包,一个是知道 wifi 的密码。我那段话的目的是解密在空气中捕获到的 wifi 流量,在 WPA2 的情况下(这是现如今大部分 wifi 的配置),如果你抓到了握手包,并知道了那个 wifi 的密码,就是可以解密流量的,这一点可以自己在 wireshark 中验证(在设置 => Protocols => IEEE 802.11 => wpa-psk 中设置解密密码)。

也就是说前提是你已经知道了密码,再利用四个握手包,这两个条件合在一起就可以解密之后的所有通信流量。不是说单独通过捕获握手包就可以知道密码,或者就可以解密流量。解密流量的前提之一是必须先知道密码

可能是我原帖的阐述造成了你的误解,我说“STA 和 AP 通过这四个包进行密钥交换”,这个密钥不是密码,是通过密码推导出来的一个值,具体来讲这个过程是这样的:

  • STA 和 AP 双方都基于密码和 SSID,经过协议规定的算法(PBKDF2)推导出一个成对主密钥(PMK),因为 STA 和 AP 都知道密码,所以它们都可以独立地推导出相同的 PMK
  • 接下来开始四次 EAPOL 握手:
  1. AP → STA: 第一次握手由 AP 发起,它先生成一个随机数,称为 ANouce,然后明文发给 STA;
  2. STA → AP: STA 收到 ANouce,接下来的流程比较复杂,要经过以下步骤:
  1. STA 自己再生成一个随机数,称为 SNouce
  2. STA 根据 PMK,ANouceSNouceSTA macAP mac 这 5 个参数生成一个成对临时密钥(PTK)
  3. PTK 比较长,它会被切分为几个部分:密钥加密密钥 (KEK)密钥确认密钥 (KCK) 和用于实际数据加密的临时密钥 (TK)
  4. STA 将 SNouce 包含在第二个握手包里,并将整个握手包内容和 KCK 一起,推导出一个消息完整性码(MIC)
  5. SNouce 和 MIC 一起发送给 AP
  1. AP → STA: 这个流程也比较复杂:
  1. AP 通过 STA 发来的第二次握手包,提取出 SNouce
  2. 现在 AP 已经有了生成 PTK 的所有材料,它使用和 STA 相同的流程生成 PTK
  3. AP 从 PTK 中切分出 KEK,KCK,TK
  4. AP 使用自己生成的 KCK,结合 STA 发来的第二次握手包,计算 MIC
  5. 将算出来的 MIC 和 STA 发来的 MIC 进行比较,若匹配,则可以宣告 STA 和自己拥有相同的 PMK,则显然 STA 的密码正确,现在 AP 成功验证了 STA 身份
  6. AP 还会提前生成一个组临时密钥(GTK),它用于加密广播和组播流量,这个密钥对于同一个 AP 下的所有 STA 都是一样的(PTK 则是每个 STA 都不同的)
  7. 使用 KEK 加密 GTK
  8. 将认证成功信息和加密的 GTK 一起发送给 STA,这是第三个握手包

(现在 STA AP 双方都互相证明了对方拥有相同的 PTK)

  1. STA → AP: 最后一次握手,这只是一个确认帧,用于向 AP 宣告正确的 GTK 和 PTK 已被安装,现在可以开始正常 wifi 通信了
  2. 正常 wifi 通信开始,现在所有的流量都将由 TK 加密

==============

至于 Gemini 说的则是攻击者如何在不知道你密码的情况下,通过捕获的握手包暴力穷举出密码(如果密码很简单的话),然后用破解出的这个密码再去解密数据包,也就是回到上面一段话所述的流程。

也就是说一个不知道你密码的攻击者,需要解密一个 WPA2-PSK wifi 流量的话,需要做:

  1. 前提:目标 wifi 使用 WPA2-PSK 加密
  2. 主动或被动捕获 EAPOL 握手包(主动捕获是指主动进行 de-auth 泛洪攻击,使得对方 STA 下线,STA 如果重连,攻击者可以立刻捕获到 EAPOL 握手包;被动捕获是指攻击者直接进行一个等待,等某个 STA 自己重连网络(比如谁离开家然后又回来了))
  3. 想办法知道你的 wifi 密码
  4. 开始解密

问题就在想办法知道你 wifi 密码这一步,他可以选择暴力破解(就像 gemini 说的那样),也可以利用一些社工方法,比如问邻居/亲戚/小孩什么的,那方法就很多了(

ipcam 那种估计得事先进到家里局域网,或者利用传输协议的漏洞吧,不知道他们怎么搞的

搜噶 了解了 感谢回复