把信号App变成一个粗略的跟踪器

2020-05-21 04:50:06

2020年5月20日更新:博客帖子已更新,以反映Google Play Store和Apple App Store上更新版本的Signal的可用性。

Signal Private Messenger的易用性、多平台支持以及对文本和呼叫的端到端加密每天都吸引了数百万用户。就连美国著名的泄密者爱德华·斯诺登(Edward Snowden)也声称“我每天都在使用Signal。”

因此,本月,当我披露了一种简单地通过振铃用户的信号号码(CVE-2020-5753)就可以泄露用户DNS服务器的方法时,我很高兴地看到他们修补它的速度如此之快。泄露信号用户的DNS服务器可能会泄露信号用户的粗略位置,但正如我们稍后将看到的,在Google Public DNS(8.8.8.8/8.8.4.4)等实例中,由于使用EDNS客户端子网,此攻击可以将位置缩小到信号用户所在的城市。

Signal团队告诉我们Android和iOS的更新版本将会推出。Signal是一个开源应用程序,由于我们的披露政策,一旦任何补丁或有关漏洞的信息公开,我们就会披露问题,例如本例。根据我们的调查,受影响的Android版本是Signal v4.59.0及更高版本,而对于iOS,受影响的WebRTC更新是在3.8.0.34中引入的。

对于某些信号用户,这个问题可能相当严重,而普通用户不太可能受到影响。值得一提的是,这不是Signal代码中的问题,而是由于WebRTC执行DNS请求。其他即时通讯应用程序也可能容易受到这一点的影响。Signal已经通知了Chromium团队,并提交了一个建议的补丁。这些讨论正在进行中。

Signal使用自己的WebRTC分支与远程对等点进行语音/视频呼叫。为了使WebRTC与远程对等方连接,它必须发现本地和远程对等方进行通信的有效连接路径。WebRTC为此利用了“信令”,这涉及到使用一个中间信令服务器来交换每个对等点的公共/私有IP地址(ICE候选地址),以便每个对等点能够彼此发现并最终建立最佳连接。

作为保护,如果用户接到非联系人的来电,Signal将不会发送您的公有/私有IP地址。此外,如果信号用户希望对来电的联系人隐藏其私有/公共IP地址,则其隐私选项中有一个选项“Always Relay Calls”(始终中继呼叫),该选项永远不会将您的公共/私有IP包含在ICE候选地址中。取而代之的是,它将只发送附近信号转向服务器的IP,以便主叫对等体连接到该服务器并通过该服务器中继音频/视频呼叫。关于这个信令过程,我观察到的一件有趣的事情是,它发生在信号用户决定应答呼叫之前。我认为这可能会导致一个有趣的攻击面,目标是让一个完全未知的电话号码响起远程信号用户的电话,从而泄露某种网络信息,即使他们启用了“始终中继呼叫”。这是可以做到的吗?

Signal是开源的,这让我更容易弄清楚如何做到这一点。我提到了一些ICE候选人的保护措施。由于这些保护,我不得不找一些聪明的东西来绕过并以某种方式泄露信息。在阅读ICE的RFC时,我发现它支持ICE候选域名。

<;Connection-Address>;:取自RFC 4566[RFC4566]。它是候选者的IP地址,允许IPv4地址、IPv6地址和完全限定的域名(FQDN)。

在2018年,WebRTC增加了对此https://webrtc-review.googlesource.com/c/src/+/85540/16.的支持,因为Signal在幕后使用WebRTC,我想我们可以只滑入一个ICE候选的域名,这样当我振铃电话(并触发ICE候选交换)时,被叫方将别无选择,只能解析我提供的域名。如果我拥有我提供的域名的权威域名服务器,我可以记录试图查询我的域名服务器的IP。该IP地址将是远程信号用户正在使用的DNS服务器,其通常在地理上接近(ISH)用户。同样,被呼叫者将在呼叫被应答之前执行域查询。事实上,我发现我可以很容易地在电话“响铃”之前强制DNS查找,然后关闭呼叫,这样被呼叫者看到的只有“未接来电”通知-没有振铃。同时,在我的名称服务器端,我们看到来自远程信号用户的当前DNS解析器的传入DNS查询。

为了实现这一点,我简单地修改了Signal中的这个例程,并将Signal App编译为我的“攻击者”电话。https://github.com/signalapp/Signal-Android/blob/3f7d0688fc76fd56ef0a562ae5293d91a67d6500/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.java#L1688。

在它中,我向iceCandidateParcels列表中添加了其他ICE候选对象。这些额外的ICE候选人在他们里面有我的域名(我拥有一个权威的域名服务器)。

对于每个ICE候选(以及每个呼叫),我都会生成一个唯一的子域,原因有两个:

确保它将绕过任何DNS缓存,这样我总是强制被调用者的DNS服务器查询我的名称服务器。

在不同地点进行多次测试后,我发现DNS定位精度通常在约400英里半径内准确,具体取决于ISP/DNS配置,并且可以回答诸如某人当前所在的国家或地区等问题。需要考虑的另一件事不仅是通过DNS服务器识别位置,还包括通过ISP交换机识别位置。例如,我现在在家里,…。用燃烧器信号电话…剥削我自己。我泄漏了我的电话当前在我的家庭网络上使用的DNS服务器,我看到它是来自南加州…的Cox ISP的DNS服务器。这是正确的,因为我住在南加州,使用COX ISP。

我现在走到外面,走到街对面的星巴克,当我离开房子,现在正在使用4G,我再次利用自己的另一个神秘的未接来电泄露了我正在使用的新…域名服务器

好的…。看起来像是圣何塞的Verizon DNS服务器,这表明我可能远离移动运营商上任何已知的Wi-Fi网络。

然后我连接到星巴克Wi-Fi。我对自己进行了另一次信号DNS泄漏电话,发现了南加州地区的一个OpenDNS服务器IP地址。

有了这些信息,攻击者就知道我此时不在家。如果攻击者更关心,他们甚至可以建立我经常使用的DNS服务器的配置文件,以标明我通常使用的位置,如“在办公室”、“在家里”、“在咖啡馆”、“在朋友家”等。

我还与其他几个地点和网络进行了测试。这是一位自愿参加这次考试的同事。本例中的DNS服务器来自宾夕法尼亚州,这与我进行测试时他所在的州相同。

确实来了几个奇怪的DNS曲线球。例如,有一次我在加利福尼亚州连接到一家餐厅的Wi-Fi网络,它让我解析来自…的查询。佛罗里达州迈阿密。在宾夕法尼亚州与另一位同事进行的另一项测试从多伦多解决了其中一项网络测试,虽然仍有大约400英里远,但肯定会推动这一进程。

在这些情况下,一周内的重复攻击可以更好地缩小位置范围,因为将有更多的DNS服务器泄露,以便更好地使用多个数据点来更好地绘制一般位置。另外,如果整个攻击过程中这些DNS服务器中的一个最终使用EDNS客户端子网(例如Google Public DNS),那么我们可以泄露更精细的位置信息…。

一些DNS服务器,例如常用的Google Public DNS(8.8.8.8/8.8.4.4),使用EDNS客户端子网。这会将始发客户端的部分IP地址(前3个二进制八位数)转发到名称服务器。这使得缩小位置更好地适应了这次攻击。下面我们看到解释EDNS客户端子网的一段代码。

这允许解析程序将客户端IP地址的一部分(IPv4/IPv6的前24/56位或更少)作为DNS消息中的源IP进行传递,以便名称服务器可以根据用户的位置(而不是解析程序的位置)返回优化结果。

让我们来看一些例子。在此场景中,我们将泄漏中西部使用EDNS客户端子网的志愿者DNS服务器。我们的命名服务器在请求的Additional Records/Client Subnet字段中转发用户实际IP地址的前3个八位字节(模糊的最后两个八位字节)。

查找这个IP子网,它缩小了距离他的实际位置只有几英里远的位置。

然后我在自己身上测试了这一点,因为我碰巧在使用Google公共DNS的网络上。在用一次性电话拨打我的号码后,在查找这个转发的客户端子网后,我们最终显示了我所在的确切城市。

这样做最大的问题之一是,你无法阻止一些未知的信号号码响起你的手机,并试图泄露你的位置/ISP信息。在正常电话使用中的某个时刻,使用EDNS客户端子网的网络也很常见,我们已经看到它可以精确定位您所在城市的位置。如果您担心这个问题,我建议您将Signal Android更新到4.59.11版本,或者将Signal iOS更新到3.8.4版本。如果您无法更新到这些版本,我建议您使用可传输DNS流量的移动VPN应用程序。在我的测试中,我发现专用互联网接入和Psiphon VPN应用程序就能做到这一点,并防止泄漏。