视频会议的开发与探索(三):WhatsApp的世界更加狂野

WhatsApp是另一个支持视频会议的App,核心实现思路没有使用WebRTC。而是使用了PJSIP,包含有一些WebRTC代码,也包含大量的其它代码,并且先于WebRTC开展。我模糊化了这个实现,来观察它是否与WebRTC和FaceTime结果一样。

模糊化准备

PJSIP是开源的,所以在Android WhatsApp binary可以轻易见到PJSIP代码。因为PJSIP使用了开源的libsrtp,我在IDA里打开binary,查找srtp_protect,它是libsrtp用来加密的函数名称。Binary中只有一个函数可以调用它,被称为memcpy。一些日志记录包含srtp_transport.c文件名,它存在于PJSIP目录中。WhatsApp binary中的登录日志表明被调用的函数是transport_send_rtp2,PSJIP只有一个叫做transport_send_rtp的函数,但是它和WhatsApp中调用 srtp_protect的函数相似,因为在memcpy前后具有相同的调用次数。假设WhatsApp中的代码稍作了修改,memcpy在被加密之前拷贝全部未加密的数据。

Hook memcpy看起来像是模糊化WhatsApp视频通话的一种方式。我使用了一个工具,它叫Frida。它可以轻易hook Android App的原始功能,我可以短时间内看到从WhatsApp到memcpy的通话。然而视频会议是性能敏感的,信息的延时传递实际上影响了后面信息的内容,所以hook每一个memcpy调用看起来不切实际。我决定将memcpy指向我写的函数。

我写了一个函数,使用dlopen从文件系统载入library,通过调用dlsym恢复记录。Frida在这里可以将dlopen和dlsym的通话连接起来,确保正确通话。我使用这个函数在WhatsApp GIF转码器里重写了一个函数,它仅仅在发送短信息时被使用。接着我让memcpy调用指向这个函数,使用在线ARM分支查找

sub_2F8CC
MOV             X21, X30
MOV             X22, X0
MOV             X23, X1
MOV             X20, X2
MOV             X1, #1
ADRP            X0, #aDataDataCom_wh@PAGE ; "/data/data/com.whatsapp/libn.so"
ADD             X0, X0, #aDataDataCom_wh@PAGEOFF ; "/data/data/com.whatsapp/libn.so"
BL              .dlopen
ADRP            X1, #aApthread@PAGE ; "apthread"
ADD             X1, X1, #aApthread@PAGEOFF ; "apthread"
BL              .dlsym
MOV             X8, X0
MOV             X0, X22
MOV             X1, X23
MOV             X2, X20
NOP
BLR             X8
MOV             X30, X21
RET

 

我还为Andorid重写了一个library,与memcpy具有相同参数,但是同时将buffer模糊化和拷贝,而不是单纯拷贝,并且将它放在文件系统中,被dlopen载入。我接着建立了WhatsApp通话。视频通话看起来在15分钟内被模糊化,最终崩溃。

重现

为了重现,我向library加入了日志,每一个被改变的buffer都会被保存到文件中。接着我创建了第二个library,它拷贝日志信息到buffer中。这需要轻微改变WhatsApp binary,因为日志信息通常和被发送的信息大小不同。我改变了被hook的memcpy的长度,通过地址传递,接着使library将长度变为日志信息的长度。这改变了长度的值,在向srtp_protect通话时会正确通过。幸运的是,buffer是固定长度的,所以不需要担心一个有效的信息会溢出buffer长度。这是RTP处理中的一个通常设计模式,通过减少长度检验提高性能。它还能改变FaceTime重现可变长度的信息,就像之前讨论的那样。

但是这样不能正常工作,观察日志信息,发现WhatsApp使用四条流,具有不同的SSRC。每条流都只有一个payload类型,它们完全不同,所以将每个SSRC指向对应的流很容易。我改变了重放library,基于输入信息的payload类型决定当前流的SSRC。这样就能可靠的重现WhatsApp通话。我接着模糊化,复制了WhatsApp中的崩溃。

结果

我发现了WhatsApp中的一个堆损坏问题,CVE-2018-6344。后来它被修复了。模糊化不再会产生任何崩溃,我们开始研究另一种方法。在第四部分我们会描述查找WhatsApp易受攻击点的其它尝试(未成功)。

原文标题:Adventures in Video Conferencing Part 3: The Even Wilder World of WhatsApp
链接:https://googleprojectzero.blogspot.com/2018/12/adventures-in-video-conferencing-part-3.html

WebRTC 中文社区由

运营