内容简介:在最近进行的一项调查中,
DJI (大疆)一直都是民用无人机和航空成像技术行业的全球 领导者 。除个人消费者外,它在企业市场也占有很大的份额,这些用户涵盖了关键基础设施、制造业、农业、建筑业、应急管理产业等领域。由于 DJI 无人机在全球拥有众多用户,因此无论是个人消费者还是企业用户,都可以从广泛的视角和题材中获取数据和图像。
在最近进行的一项调查中, Check Point 的研究人员发现了一个安全漏洞。如果被利用,攻击者可以在用户完全不知情的情况下访问其 DJI 账户,并提供了对大量敏感数据的访问:
l 如果 DJI 用户已经与 DJI 的云服务器同步,那么能够被访问的数据则包括在无人机飞行期间生成的飞行日志、照片和视频。(飞行日志包含无人机在整个飞行过程中的确切位置,以及在飞行过程中拍摄的照片和视频的预览。)
l 如果 DJI 用户正在使用 DJI 的 FlightHub 飞行管理软件,那么能够被访问的数据则包括无人机飞行期间的实时摄像头视图和地图视图。
l 与 DJI 用户帐户相关的信息,包括用户个人资料信息。
对于此漏洞的利用开始于 DJI 论坛( DJI Forum ),这是由 DJI 运营的一个在线论坛,用于讨论其产品。登录 DJI Forum ,然后点击一个由攻击者植入的恶意链接,用户的登录凭证就可能会被窃取,并允许攻击者访问用户的其他 DJI 在线资产:
l DJI 的 Web 平台(账户、商店、论坛)
l 从 DJI GO 或 DJI GO 4 应用程序同步的云服务器数据
l DJI 的 FlightHub (集中式无人机操作管理平台)
我们在 2018 年 3 月就此漏洞通知了 DJI , DJI 也负责任地进行了回应。目前,此漏洞已经被修复。 DJI 将此漏洞分类为“高风险,低概率”,并表示没有证据表明此漏洞曾被 Check Point 研究人员以外的任何人利用。
三种潜在攻击流的简化视图
视频地址: https://youtu.be/dFDA9dYTkzQ
漏洞利用演示视频
技术分析
以下内容解释了我们如何能够通过网站、移动应用程序和 FlightHub 这三个 DJI 平台访问到敏感的 DJI 无人机飞行信息以及敏感的用户数据。
首先,我们将解释漏洞位于何处以及它是如何工作的。
漏洞
简单来说,此漏洞存在于 DJI 的识别过程中。
DJI 使用 cookie 来识别访问其平台的用户,而这个 cookie 存在被攻击者捕获的风险。通过使用这个 cookie ,攻击者可以很容易地劫持任何用户的帐户,并完全控制用户的 DJI 移动应用程序、 Web 帐户或 DJI FlightHub 帐户。
我们首先研究了 DJI 网站的登录过程,因为我们首先想了解 DJI 后端是如何识别用户的,以及哪些参数或 cookie 对登录过程来说是足够重要的。因此,我们查看了所有通过客户端(浏览器)和 DJI 后端的流量。
我们很快注意到, DJI 为其提供的服务使用了一些子域:
l forum.dji.com
l account.dji.com
l store.dji.com
此外,这些域之间的登录使用的是 OAuth 框架。接下来,我们开始检查这些子域的流量。
我们发现,一个发送给 mobile.php URL 的请求向我们提供了 DJI 测试用户的敏感信息,包括 username 、 member_uid 、 token 等数据。
这一个发现很重要,因为它促使我们想要弄清楚 DJI 后端是如何识别我们的用户,以及它是否使用的是相同的标识符 ID 。为此,我们查看了在那里使用的 cookie ,并发现其中一个名为“ meta-key ”的 cookie 被用于识别用户。
mobile.php 请求
于是,我们接下来的目标就成了通过任何可能的方式获得这个“ meta-key ” cookie 。为此,我们必须找到一个不受 http-only 属性保护的子域,因为这会阻止 JavaScript 泄漏 cookie 。
最终,符合我们需求的子域被确认为 forum.dji.com 。接下来,我们开始在这平台上查找漏洞。
发现漏洞
经过一番查找,我们偶然间发现了以下 GET 请求:
https://forum.dji.com/forum.php?mod=ajax&action=downremoteimg&message=
在这里,我们看到消息参数已经反映在了响应中。但存在两个障碍:
1. 这里还有一个“ addslashes ”函数,它为后面的字符添加了一个斜杠“ / ”;
2. XSS payload 注入发生在一个名为“ updateDownImageList ”的未定义函数中,它是从其他一些 JavaScript 代码中导入的,而我们的上下文中没有这些代码。
我们假设对 GET 请求的响应类似于以下伪代码:
于是,从函数转义开始,我们开始使用反斜杠和单引号,如下所示:
parent.updateDownImageList(‘ \’ ‘);
然后,“ addslahes ”也会添加一个反斜杠,它会转义我们的反斜杠,并将它更改为这样的字符串:
parent.updateDownImageList(‘ \\ ‘ ‘);
接下来,我们不得不处理剩下的字符,以及未定义的函数“ updateDownImageList ”。
为了处理剩下的字符,我们添加了一个简单的 html 注释,比如“ <!– ”,它创建了以下 payload :
parent.updateDownImageList(‘ \'<!– ‘);
现在,我们剩下的就是处理这个未定义函数了。为了搞定这个函数,我们必须自己定义它。
于是,我们的 payload 最终看起来像是这样的:
\’ alert(document.cookie); function updateDownImageList (data) {} <!–
使用我们的 payload接 收到的 Cookie
然后,攻击者可以创建一个 payload ,将该 meta-key cookie 发送到他的网站。任何 XSS Auditor 都不会阻止这种 XSS ,因为它驻留在 JavaScript 本身,而不是脚本或事件中。
想要触发这种 XSS 攻击,攻击者所需要做的就是在 DJI 论坛上编写一个简单的帖子,并将包含 payload 的链接插入其中。不过,由于 DJI 限制链接到论坛本身的内容,因此想要以这种方式来发送链接到恶意网站是不可能的。
DJI 论坛中潜在攻击者通过帖子链接的恶意站点示例
但由于我们的 XSS 驻留在论坛本身,因此我们能够绕过这种链接限制。此外,由于有数十万用户在 DJI 论坛上进行交流,因此攻击者甚至不需要共享恶意链接,因为这会在用户转发消息和链接时自动完成。
在获得 meta-key 之后,我们继续检查了登录过程,并测试了 DJI 后端是如何处理每个 DJI 平台的登录的。首先,我们从 DJI 网站开始。
DJI网站
想要获得对 DJI 网站上任何用户帐户的访问权限,我们所需要的只是他们的“ meta-key ”,在子域 account.dji.com 上称被为“ mck ” 。
我们首先创建了一个 DJI 帐户并登录上去。通过分析登录过程,我们发现它使用 OAuth 在子域之间对用户进行身份验证。例如,从 accounts.dji.com 到 forum.dji.com ,或者返回 dji.com 。
因此,每当 DJI 想要对用户进行身份验证时,它都会发送带有一个“ mck ” cookie 的 initData.do 请求,并且响应将是带有 ticket 的回调 URL 。
通过导航到 URL ,用户能够在不需要凭证的情况下进行身份验证。
因此,为了劫持一个帐户,我们需要进行以下操作:
l 以攻击者的身份登录 dji.com ,然后点击 DJI.COM ,将我们重定向到 dji.com 。
l 在 initData.do 请求中,将“ mck ” cookie 值替换为受害者的“ mck ”(我们通过 XSS 漏洞获取)。
l 继续登录过程,并访问受害者的帐户。
以下是 initData.do 请求:
initData.do 请求
DJI App
想要劫持 DJI 移动应用程序中的帐户,我们必须绕过应用程序本身采取的一些缓解措施。
为此,我们不得不拦截从应用程序到 DJI 后端的请求,以便研究其登录过程。但是在这里我们遇到了一个 SSL pining 机制,它阻止我们拦截应用程序流量并对其进行研究。
因此,我们尝试对应用程序进行反编译,以了解如何绕过 SSL pining 机制。不幸的是,由于 DJI 的移动应用程序得到了 SecNeo (一家移动应用程序安全公司)的保护,因此反编译没有取得成功。
根据 SecNeo 的描述,它提供了以下保护:
l 源代码逆向预防和敏感数据保护。
l 应用程序篡改、再包装和调试预防,以及 anti-hooking 检测功能。
l 动态代码注入和反编译 / 反汇编预防。
因此,我们试图通过使用 Frida 来绕过这些限制。事实上,我们试图搞定 dji.go.v4 应用程序,但没有取得任何成功。
然后,我们检查了一下为什么我们无法连接到 dji.go.v4 进程,并使用了“ frida-ps –U ” 命令来获取在我们的移动设备上运行的所有进程的列表。
在运行此命令后,我们注意到只有一个 dji.go.v4 进程。然而,在几秒钟之后,我们发现出现了另一个 dji.go.v4 进程。
通过查看 /proc/11194/status ,我们可以看到新生成的进程被附加到了第一个进程,并实际调试它。这也就解释了为什么我们无法使用 Frida 调试进程的原因——它已经被调试过了。
附加到第一个 dji.go.v4 进程的新进程
我们发现,启动的第一个进程并不是调试程序,而是实际应用程序。调试程序实际上已经附加到了实际应用程序,并开始保护它。这意味着,我们可以利用竞争条件并将我们的 hook 附加到应用程序进程,并在调试程序进程启动之前将其分离。
为了绕过这个问题,我们将 Burp Suit 证书复制到手机上并自行生成了 DJI 应用程序,这将使得应用程序以挂起模式启动(在调试程序初始化之前)。
然后,我们创建了一个使用以下逻辑的 Frida 脚本:
1. 打开我们的 Burp Suit 证书,并生成 X509Certificate 。
2. 加载 KeyStore ,并将证书放入其中。
3. 创建 TrustManagerFactory ,并使用我们刚刚创建的包含 Burp Suit 证书的 KeyStore 对其进行初始化。
4. 重载 SSLContext ,并将 TrustManager 与我们的 TrustManager 挂钩。
在挂钩完成后,我们恢复了挂起的应用程序并从中脱离。现在,调试程序就可以在我们完成所有挂钩之后才开始保护了。
通过这种方式,我们绕过了 SSL pinning ,然后流量开始出现在我们的 Burp Suit 中。
绕过 SSL pinning 后在 Burp Suit 中看到的流量
在绕过 SSL pining 之后,我们设置了一个代理,允许我们拦截移动应用程序的流量。
通过分析 Web 应用程序的登录过程,我们发现一旦用户插入其凭证,移动应用程序就会向 /apis/apprest/v1/email_login 发送一个请求,收到的响应如下:
{“code”:0,”message”:”ok”,”data”:{“nick_name”:”XXXXXXXXX”,”cookie_name”:”_meta_key”,”cookie_key“:”NTUxNjM2ZTXXXXXXXXXXXXXXNmI2NjhmYTQ5NGMz“,”active”:false,”email”:”XXXXXXXX@gmail.com”,”token“:”XXXXXXXXX2139“,”validity”:15275XXXXX,”user_id”:”9629807625XXXXXX”,”register_phone”:””,”area_code”:””,”inner_email”:false,”subscription”:false,”vipLevel”:null,”vipInfos”:[]}}
在这里,我们注意到两个重要参数:
l “ cookie_key ” – 这是我们现在已经熟悉了的 DJI 论坛的 meta-key/ mck 。
l “ token ” – 我们可以从本文一开始描述的 mobile.php 请求中获取此参数。
帐户劫持过程
劫持帐户的过程如下:
1. 首先,我们需要一个 meta-key 和一个 token 来替换我们自己的。因此,我们需要将想要破解的 meta-key 发送到 mobile.php ,并接收相应的 token 。
2. 然后输入自己的凭证,并发送登录请求。
3. 收到步骤 2 的响应后,使用受害者的 meta-key 替换 cookie_key 值,并使用步骤 1 中的 token 替换我们自己的 token 。
4. 这样,我们就可以访问受害者的帐户了。
通过利用 DJI 漏洞,攻击者可以接管受害者的帐户,并访问他们所有同步的飞行记录、无人机拍摄的照片等。
我们还进行了进一步的研究,发现通过解析飞行日志文件,我们可以获得更多的信息。例如,无人机飞行期间拍摄的每一张照片的位置和角度、无人机的标识位置、最后的已知位置等等。
为了能够访问飞行日志文件,攻击者所需要做的就是将飞行记录与他的手机同步。这样,所有手动上传到 DJI 云服务器上的飞行日志都将会保存到他的手机上。然后,他可以直接浏览到“ DJI/dji.go.v4/FlightRecord ”文件夹,找出所有的飞行记录文件,将它们上传到网站,并查看各种有关无人机飞行的信息。
DJI-FlightHub
DJI-FlightHub 是一个基于 Web 的应用程序,用于为企业用户提供完整的摄像头视图和对无人机的管理。实际上,它可以让用户在世界任何地方实时查看他们的无人机活动,包括一个地图视图、一个能够听到声音的实时摄像头视图,并且允许用户查看每台无人机的确切位置,以便协调任务。
DJI-FlightHub 包含一个用于访问管理控制面板的桌面应用程序和一个用于操纵无人机的应用程序。幸运的是,我们还找到了一个可访问管理控制的 Web 门户,你可以通过这个 URL 找到它: www.dji-flighthub.com 。
DJI-FlightHub 包含一个 admin 账户、一个 captain 账户和一个 pilot 账户。 admin 账户可以管理 DJI-FlightHub 帐户并访问 DJI-FlightHub 平台、查看飞行数据,并可以创建新的 captain 或 pilot 。 Captain 账户则可以登录 DJI-FlightHub 平台,并创建新的 pilot 。 Pilot 账户则可以通过无人机操纵应用程序来操纵无人机,并将无人机绑定到 DJI-FlightHub 帐户。
基于此,如果我们能够访问 admin 或 captain 帐户,那么我们就能够实时查看无人机的操作。为了劫持 admin 或 captain 的 DJI 帐户,我们需要了解 DJI-FlightHub 的登录过程。
DJI-FlightHub 登录页面
我们发现,当我们单击“ login ”时, initData.do 请求确实是发送了,但在响应中没有接收到 ticket (类似于我们通过 account.dji.com 门户接收到的 ticket )。相反,只有在输入凭证时,我们才会在 login.do 响应中接收到 ticket 。由于这与我们之前通过 account.dji.com 门户劫持帐户不同,因此我们不得不考虑另一种在 DJI-FlightHub 中劫持帐户的方法。
虽然我们知道可以通过 initData.do 请求来生成 ticket ,但由于某种原因,在 DJI-FlightHub 中并非如此。因此,我们查看了请求,以便理解其中的原因。我们注意到,在 DJI-FlightHub 中, initData.do 请求包含一个 DJI-FlightHub 的 appId ,这应该就是我们没有在响应中接收到 ticket 的原因。考虑到这一点,我们认为我们可以将 appId 替换我们所熟悉的东西来获得 ticket 。一旦获取到 ticket ,我们要做的就是检查另一个 appid 的 ticket 是否也适用于此。
需要采取的步骤如下:
1. 发送一个带有“ appId = store ”的 initdata.do 请求,其中 admin 的 mck 旨在被劫持并在响应中获取 ticket 。
2. 登录到 FlightHub 时,拦截请求,将 login.do 请求中的 mck 和响应切换中的 mck 替换为在 inidata.do 请求中接收到的 ticket 。然后,我们就将会被重定向到管理员 / 受害者的帐户。
此外,管理员将不会收到任何有关攻击者访问其帐户的通知。与此同时,在当前正在进行的任何飞行的实时操作期间,攻击者登录并查看无人机摄像头拍摄画面将完全不受限制,并且可以下载之前所有已经上传到 FlightHub 平台的飞行记录。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 大疆无人机爆安全漏洞
- 大疆网站及应用存在安全漏洞,攻击者可获取无人机实时视频画面
- Soar(腾飞计划)分布式无人机平台
- RF工业设备可用无人机轻松入侵
- 如何将深度学习应用于无人机图像的目标检测
- DroneOS 0.10 发布,开源无人机航空操作系统
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。