首页 >> 网络安全 >>极客新闻 >> 大疆无人机漏洞研究分析
详细内容

大疆无人机漏洞研究分析

在最近的调查中,Check Point Research发现了一个漏洞,一旦被利用,该漏洞将使攻击者可以访问用户的DJI帐户,而无需用户意识到。这本可以提供访问:

  • 如果DJI用户已将其与DJI的云服务器同步,则在无人机飞行期间生成的飞行日志,照片和视频。(飞行日志会显示无人机在整个飞行过程中的确切位置,以及飞行过程中拍摄的照片和视频的预览。)

  • 如果DJI用户正在使用DJI的FlightHub飞行管理软件,则可以在无人机飞行期间进行实时摄像头视图和地图视图。

  • 与DJI用户帐户相关的信息,包括用户个人资料信息。

该漏洞是通过DJI论坛访问的,DJI论坛是一个在线论坛,旨在讨论其产品。登录DJI论坛并单击特制的恶意链接的用户可能已经窃取了登录凭据,以允许访问其他DJI在线资产:

  • DJI的网络平台(账户,商店,论坛)

  • 从DJI GO或GO 4试用版应用同步的云服务器数据

  • 大疆创新的FlightHub(集中式无人机运营管理平台)

  • 我们已于2018年3月通知DJI此漏洞,DJI做出了负责任的回应。此漏洞已得到修补。DJI将此漏洞归类为高风险但可能性很小,并表示没有证据表明该漏洞曾被Check Point研究人员利用。

2.jpg

图:  三种潜在攻击流程的简化视图。


技术分析

以下我们的研究说明了我们如何通过网站,移动应用程序和FlightHub的所有三个DJI平台访问敏感的DJI无人机飞行信息以及敏感的用户数据。

不过,首先,我们将解释漏洞的位置以及其工作方式。


漏洞

简而言之,该漏洞位于DJI识别过程中。

DJI使用cookie,攻击者可以获得该cookie来识别用户并创建令牌或票证以访问其平台。通过使用此cookie,攻击者可以简单地劫持任何用户的帐户,并完全控制该用户的DJI Mobile Apps,Web帐户或DJI FlightHub帐户。

我们通过调查DJI网站的登录过程来开始研究,因为我们首先想了解DJI后端如何识别用户以及哪些参数或cookie对登录过程很重要。因此,我们了解了通过客户端(浏览器)和DJI后端的所有流量。


我们很快注意到DJI为它提供的服务使用了几个子域:

  • forum.dji.com

  • account.dji.com

  • store.dji.com

此外,这些域之间的登录使用OAuth框架。结果,我们开始研究这些子域之间的流量。

通过分析,我们发现对mobile.php URL 的请求向我们提供了有关DJI测试用户的敏感信息,其中包含诸如username,member_uid,token等数据。

这很有趣,因为它促使我们调查DJI后端如何识别我们的用户以及它是否使用相同的标识符ID。因此,我们查看了那里使用的cookie,发现其中一个特别是名为“ meta-key”的cookie是负责用户识别的cookie。

3.png

图1 : mobile.php请求

由于我们现在的目标是通过任何可能的方式获取此“元密钥” cookie,因此我们必须找到一个不受纯http属性保护的子域,因为这将防止JavaScript泄漏cookie。

满足我们需求的子域是forum.dji.com,因此我们开始在该平台中寻找漏洞。


发现漏洞

经过一番搜索后,我们偶然发现了以下GET请求:https : //forum.dji.com/forum.php?mod = ajax &action = downremoteimg &message =

在这里,我们看到message参数反映在响应中。但是有两个障碍:

  • 有一个“ addslashes”功能,可以在以下字符“'/ /

  • XSS有效负载注入发生在一个名为“ updateDownImageList”的未定义函数中,该函数是从上下文中没有的其他JavaScript代码中导入的。

我们假定对GET请求的响应类似于以下伪代码:

4.jpg

因此,从函数转义开始,我们以反斜杠和单引号开始,如下所示:

parent.updateDownImageList(' \' ');

然后,“ addslahes”还将添加一个反斜杠,该反斜杠将转义我们的反斜杠并将其更改为如下所示的字符串:

parent.updateDownImageList(' \\'  ');

因此,我们现在不得不处理其余的字符');。以及身份不明的函数“ updateDownImageList”。

为了处理其余字符,我们添加了一个简单的html注释,例如<!–,它创建了以下有效负载:

parent.updateDownImageList(' \'<!–  ');

现在我们剩下的就是处理未知功能了。为了克服该函数未定义的事实,我们必须自己定义它。

因此,我们的有效负载最终看起来像这样:

\'alert(document.cookie); 函数updateDownImageList(数据){} <!– 

5.png

图3 :使用有效负载收到的Cookie。

然后,攻击者可以创建有效载荷,该有效载荷会将该元密钥cookie发送到他的网站。这种XSS不会被任何XSS Auditor阻止,因为它驻留在JavaScript本身中,并且不包含脚本或事件。


要触发此XSS攻击,攻击者所需要做的就是在DJI论坛中写一个简单的帖子,其中包含指向有效负载的链接。毕竟,DJI将链接限制在论坛本身中的内容,因此无法通过这种方式将链接发送到恶意网站。

6.png

图4: DJI论坛中潜在攻击者发帖链接的恶意站点示例。

由于我们的XSS驻留在论坛本身中,因此我们能够绕过链接限制。此外,由于有成千上万的用户在与DJI论坛进行交流,攻击者甚至不需要共享恶意链接,因为这是由用户自己在消息和链接上转发时由用户自己完成的。


获取元密钥后,我们将继续检查登录过程并测试DJI后端如何从DJI网站开始在每个DJI平台中处理登录。


大疆创新网站

要访问DJI网站上的任何用户帐户,我们需要的是他们的“元密钥”,在子域account.dji.com上称为“ mck” 。

我们首先创建一个DJI帐户并登录。通过分析登录过程,我们发现它使用OAuth来在子域之间(例如,accounts.dji.com与Forum.dji.com之间以及回到dji.com之间)对用户进行身份验证。

因此,每当DJI想要验证用户身份时,它都会使用“ mck” cookie发送initData.do,并且响应将是带有票据的回调URL。

通过导航到url,用户将因此得到认证而无需凭据。

因此,为了劫持帐户,我们需要:

  1. 以攻击者身份登录dji.com,然后单击DJI.COM,这会将我们重定向到dji.com。

  2. 在initData.do请求中,将“ mck” cookie值替换为受害者的“ mck”(这是我们从XSS漏洞获得的)。

  3. 继续登录过程并访问受害者的帐户。

以下是initData.do请求:

7.png

图5: initData.do请求


DJI App

为了劫持DJI移动应用程序中的帐户,我们必须绕过一些在应用程序本身中实现的缓解措施。

为了调查登录过程,我们必须拦截从应用程序到DJI后端的请求。但是在这里,我们遇到了SSL固定机制,该机制阻止了我们拦截应用程序流量并进行调查。

因此,我们尝试对应用程序进行反编译,以了解如何绕过SSL固定机制。不幸的是,由于DJI的移动应用程序使用了SecNeo(移动应用程序安全公司)保护,因此无法完成反升级。

根据SecNeo,提供了以下保护:

  • 源代码可逆预防和敏感数据保护。

  • 具有防钩挂功能的应用篡改,重新打包和调试预防。

  • 动态代码注入和反编译/反汇编预防。

因此,我们尝试使用Frida绕过这些限制。实际上,我们尝试附加到dji.go.v4应用程序,但没有成功。

然后,我们检查为什么无法附加到dji.go.v4进程,并从命令“ frida-ps –U”开始,以获取在移动设备上运行的所有进程的列表。

运行此命令后,我们注意到只有一个dji.go.v4进程。但是,几秒钟后,我们看到了另一个dji.go.v4进程出现了。

通过查看/ proc / 11194 / status,我们可以看到新产生的进程已附加到第一个进程并进行实际调试。这就是为什么我们无法使用Frida调试过程的原因-该过程已被调试。

8.jpg

图6:在第一个dji.go.v4进程中附加的新生成的进程,如Frida中所示。


我们发现,启动的第一个进程不是调试器,而是实际的应用程序。调试器实际上已附加到实际应用程序并开始对其进行保护。这意味着存在一种竞争条件,我们可以在调试器进程启动之前利用钩子将钩子附加到应用程序进程并分离它。


为了避免这种情况,我们将Burp Suit证书复制到了手机中,并亲自生成了DJI应用程序。这将以挂起模式启动应用程序(在调试器初始化之前)。


然后,我们创建了一个使用以下逻辑的Frida脚本:

  • 打开我们的打Suit西装证书,并将其转换为X509Certificate。

  • 加载密钥库并将证书放入其中。

  • 创建TrustManagerFactory并使用我们刚刚创建的包含我们的Burp Suit证书的KeyStore对其进行初始化。

  • 重载SSLContext并将TrustManager与我们的TrustManager挂钩。


挂钩完成后,我们恢复了挂起的应用程序并从其分离。现在,当我们完成所有钩子之后,调试器就可以开始保护了。

这样,我们绕过了SSL固定,流量随后出现在了Burp Suit中。

9.png

图7:  绕过SSL固定后在Burp Suit中看到的流量。


绕过SSL固定后,我们然后设置了一个代理,该代理使我们能够拦截Mobile应用程序的通信。

通过分析Web应用程序的登录过程,我们发现,一旦用户插入其凭据,移动应用程序就会向/ apis / apprest / v1 / email_login发送请求。收到的响应如下所示:

{“代码”:0,“消息”:“确定”,“数据”:{“昵称”:“ XXXXXXXXX”,“ cookie_name”:“ _ meta_key”,“ cookie_key ”:“” NTUxNjM2ZTXXXXXXXXXXXXXXXXXNmI2NjhmYTQ5NGMz “,”活动”:false, “电子邮件”:“ XXXXXXXX@gmail.com”,“ 令牌 ”:“ XXXXXXXXX2139 ”,“有效性”:15275XXXXX,“ user_id”:“ 9629807625XXXXXX”,“ register_phone”:“”,“区号”:“”,“ inner_email “:假的,”订阅”:假的,” vipLevel”:空,” vipInfos”:[]}}


这里要注意的两个重要参数是:

  • “ cookie_key” –这是我们到目前为止在DJI论坛上已经熟悉的meta-key / mck。

  • “令牌” –该参数可以从我们在本研究出版物开头描述的请求mobile.php中获得。


帐户劫持过程

劫持帐户的过程是:

  1. 首先,攻击者需要一个元密钥和一个令牌来替换为自己的密钥。因此,他将要破解的元密钥发送到mobile.php并接收到相应的令牌。

  2. 然后,攻击者输入他的凭据,并发送登录请求。

  3. 收到步骤2的响应后,攻击者将cookie_key值替换为受害者的meta-key,并将其令牌替换为步骤1中的令牌。

  4. 攻击者现在可以完全访问受害者的帐户。


如上所述,通过利用DJI漏洞,攻击者可以接管受害者的帐户,并访问其所有已同步记录的航班,无人机照片等。

我们还进行了进一步的研究,发现通过解析飞行日志文件,我们可以获得更多信息,例如在无人机飞行过程中拍摄的每张照片的位置和角度,无人机的原位,最后一次知道的位置等等。

为了访问飞行日志文件,攻击者需要做的就是将飞行记录与手机同步,所有手动上传到DJI云服务器的飞行日志都将保存在手机上。然后,他可以简单地浏览至文件夹“ DJI / dji.go.v4 / FlightRecord”并找到航班的所有文件,将其上传到站点并查看有关用户航班数据的大量信息。

10.png

11.png

12.png

13.png

(请注意:上面的飞行路线和图像的屏幕截图是由Airdata拍摄的  ,他没有参与这项研究,也不受此漏洞的影响。)

DJI-FlightHub

14.png

DJI-FlightHub是基于Web的应用程序,旨在为企业用户提供有关无人机操作的完整视觉和管理。实际上,它通过包括地图视图,实时摄像头视图(具有听到声音的能力)以及允许用户在空中查看其每架无人机的确切位置,从而允许用户从世界任何地方实时查看其无人机操作。为了协调任务。


DJI-FlightHub有一个用于访问管理控制面板的桌面应用程序,一个用于驾驶无人机的试点应用程序以及对我们幸运的是一个用于访问管理控件的Web门户。可以在以下URL上找到Web门户:www.dji-flighthub.com。


在DJI-FlightHub中,有一名管理员,上尉和一名飞行员。管理员负责DJI-FlightHub帐户,并访问DJI-FlightHub平台,查看航班数据并创建新的机长或飞行员。机长还可以登录DJI-FlightHub平台并创建新飞行员。飞行员是使用飞行员应用程序飞行无人机并将无人机绑定到DJI-FlightHub帐户的人。


考虑到这一点,如果我们能够访问管理员或机长帐户,我们将能够实时查看无人机的操作。为了劫持管理员或机长的DJI帐号,我们需要了解DJI-FlightHub的登录过程。

15.png

图8: DJI-FlightHub登录页面

我们发现,当您单击“登录”时,发送了一个initData.do请求,但在响应中未收到票证(类似于在account.dji.com门户中收到的票证)。相反,当用户输入其凭据时,我们仅在login.do响应中收到票证。由于这与我们通过门户网站劫持帐户所使用的常规account.dji.com不同,我们不得不考虑另一种劫持DJI-FlightHub中帐户的方法。


尽管我们知道可以通过initData.do请求生成票证,但由于某种原因,DJI-FlightHub并非如此。因此,我们查看了该请求以了解原因,并注意到在DJI-FlightHub中,initData.do请求的appId为DJI-FlightHub,这就是为什么我们在响应中未获得故障单的原因。考虑到这一点,我们认为我们可以将appId替换为我们知道可以用来获取票证的东西。收到票证后,我们现在要做的就是检查另一个appid的票证是否也可以在这里工作。


然后需要采取的步骤是:

  1. 发送一个appId = store的initdata.do请求,其中管理员的mck旨在被劫持,并在响应中获取票证。

  2. 登录FlightHub时,拦截请求,将login.do请求中的mck更改,并将响应开关中的mck更改为inidata.do请求中收到的相应票证。然后,攻击者将被重定向到管理员/受害者的帐户。

此外,管理员不会收到有关攻击者已访问其帐户的任何通知。同时,攻击者将可以完全不受禁止地访问当前正在进行的任何航班的实时操作期间的登录并查看无人机的摄像头,或者下载先前记录的已上传到FlightHub平台的航班的记录。

《转spr——原文:DJI无人漏洞

技术支持: 建站ABC | 管理登录