2018 年 5 月

第 33 卷,第 5 期

安全性 - 从 Xamarin 应用中检测和响应取得 root 权限的 Android 设备

通过Joe Sewell

在最后一年 11 月的问题,我阐释如何使用运行时检查,代码注入附带 Visual Studio 2017 来保护你的.NET Framework 应用,从未经授权的使用调试程序,以及不被篡改的功能 (msdn.com/magazine/ mt845626)。从那时起,新的检查类型已变得可用。在"根"的设备上运行一个 Xamarin.Android 应用程序时,根检查检测-允许普通的应用能够使用管理员权限 (根访问权限)。

在后续本文中,我将说明为何取得 root 权限的设备会造成所有 Android 开发人员必须了解; 风险详细介绍如何 Xamarin.Android 开发人员可以使用根检查来检测和响应该风险;并演示的示例方案的最佳方法。

为何需要防止定位

Xamarin 平台可以有效地创建用于 Android、 iOS 和 Windows 设备的移动应用程序。熟悉 C# 之类的.NET 语言的开发人员可以采取这一知识,并将其应用到移动的空间。Xamarin.Forms 等技术抽象远多平台,可降低复杂性,成本和风险的开发跨平台应用之间的差异。通过保留最新的 Xamarin 工具,你可以继续以支持新版本和每个平台的功能。

但是,移动开发的某些特定于平台的方面值得开发人员关注。此类的一个方面是安全的。每个平台都有唯一的安全风险和唯一的安全模型,解决这些风险。例如,权限系统不同在平台之间,有时甚至相同的平台的版本。

对于 Android 应用程序,取得 root 权限的设备是特别重要的安全隐患。此类设备已经修改以允许应用将中断 OS 有一定的常规安全沙盒。这可以公开到很多风险,如恶意软件和密码窃取击键记录程序设备。通常情况下,用户根其设备来解决某个问题 — 例如了所需的应用程序通常不可为其设备的版本-却没有意识到这些威胁的严重级别。在其他情况下,用户可能甚至无法感知设备已取得 root 权限并且因此易受攻击。

最后一年 9 月,支付卡行业安全标准委员会 (PCI SSC) 颁发开发人员移动付款接受安全指导原则的 2.0 的版。为了对抗取得 root 权限的设备与关联的安全风险,准则建议移动应用程序开发人员实现根检测和隔离应用程序的响应机制 (bit.ly/2H5ymge)。下面是部分 4.3 (着重强调) 中的相关文本:

[T] 他设备应进行监视的抵消操作系统安全 controls—e.g。、 jailbreaking 或定位的活动-和设备时检测到,应隔离的一种解决方案,将其从网络中删除时,删除付款验收应用程序从该设备,或禁用付款应用程序。脱机越狱和根检测和自动隔离是键,因为某些攻击者可能会尝试将设备置于脱机状态以进一步避开检测。

除了合法用户操作取得 root 权限的环境中的应用程序与关联的风险,这种环境下也可能表示恶意用户尝试进行反向工程应用程序。攻击者经常使用取得 root 权限的设备来研究并创建篡改过的应用,它们然后填充恶意软件的版本。打开 Web 应用程序安全性项目 (OWASP) 列出为前 10 移动风险之一篡改的代码 (bit.ly/2GNbd4o) 和专门调出根检测和响应作为一种方式来应对这种风险。不执行此操作,根据 OWASP,可能导致声誉损害和利润损失。

根检查

检测取得 root 权限的设备会很困难。可以使用多种不同方法,为设备的根并的一组可用的方法更改一段时间内和跨 Android 版本。因此,根检测代码必须不断发展和调整。这是变得更复杂,因为一些恶意根技术尝试掩盖其使用,因此很好的根检测代码还必须解决这些对策。维护最新的根检测代码比较棘手,并且不可能要花费有限的资源。

幸运的是,你无需编写自己的代码来检测根。PreEmptive 保护-Dotfuscator Community Edition (CE),它又包括在适用于 Windows 的 Visual Studio 2017,可以插入到你的 Xamarin.Android 应用中根检查。根检查检测取得 root 权限的环境,即使设备处于脱机状态。除了标准的"退出应用程序"操作,还可以配置检查响应定位通过调用自定义应用程序代码。

一样本身的 Xamarin,根检查降低复杂性、 成本和风险相比滚动您自己的实现。使 Dotfuscator 保持最新,并让它处理根检测-获取恢复你的应用程序更快的有趣部分上工作。

示例方案

为了演示根检查,我提供了调用受保护 TodoAzureAuth 的示例应用程序。基于现有 Xamarin.Forms 示例 TodoAzureAuth (bit.ly/2InvU48)、 由 David Britch 最初写入。

此文章的剩余部分说明应用程序中,我给它,以及如何应用该策略与根检查应用的保护策略。你可以使用此案例研究,以及包含示例的 GitHub 存储库中的其他方案 (bit.ly/2GQutOv),以了解到根检查你可以随后可应用到你自己的 Xamarin.Android 应用程序的方法。

原始示例: TodoAzureAuth 连接到 Microsoft Azure 移动应用程序实例,使用户能够查看和修改共享的待办事项列表。为了演示如何在 Xamarin 应用程序中执行身份验证,此示例要求用户在访问待办事项列表之前使用 Google 帐户登录。

应用程序开始在登录页上,它具有字段,只需登录按钮。当用户选择此按钮时,应用程序将委派到 Google OAuth 系统,这可能需要用户输入凭据,包括密码登录过程。因此,在应用程序不处理凭据。用户已登录后,应用将显示 Todo 列表页中,允许用户访问共享的待办事项列表。用户可以注销,然后通过选择注销按钮返回到登录页。

保护策略:有关本文中,我视为 TodoAzureAuth Android 项目,TodoAzure.Droid,如同它已处理敏感数据,像使用 PCI 合规的应用程序一样。我实现适当的保护策略通过使用 Dotfuscator CE 注入根检查应用程序中,生成应用程序中,受保护 TodoAzureAuth 的受保护的版本。

在受保护的应用中,当用户选择登录按钮,根检查激活。如果应用程序正在取得 root 权限的设备上运行,突然,退出并运行应用程序的所有进一步尝试后面的简短的错误消息,还将进行退出,即使不再为根设备。图 1显示受此策略应用程序的概述。

受保护 TodoAzureAuth 示例应用程序的概述
图 1 的受保护 TodoAzureAuth 示例应用程序概述

此策略将对齐的带引号的更早版本的 PCI 准则所做的建议:

  • 应用程序监视的设备以进行定位。
  • 应用程序隔离通过禁用本身,如果检测到根,则该设备。
  • 此安全控制操作甚至当设备处于脱机状态时。

当应用程序禁用其自身,错误消息通知用户设备是不安全。未使用时在此示例中,应用程序使用这种情况下无法还"phone 主页"分析平台,如 Visual Studio 应用中心 (bit.ly/2pYMuk5)。

除了按照 PCI 准则,此策略还可以让与 OWASP 建议关闭的应用程序中取得 root 权限的环境,从而防止反向工程。我配置根检查激活代码,而不仅仅是在登录过程中的其他部件以便如果攻击者生成删除的登录过程根检测篡改的版本的应用程序,应用程序的其他部分可仍反映定位。Dotfuscator 也经过模糊处理代码中,将另一层保护添加到应用程序和根检查。

并非所有应用都具有相同的安全要求,并因此不是所有的应用程序应做出响应定位的方式相同。我选择了此示例中,提供严格的方法,但更宽松的策略可能导致应用程序以在某些情况下取得 root 权限的设备上运行。有关示例,请参阅"使用备用保护策略。"

受保护的示例:你可以查看受保护 TodoAzureAuth 示例使用前面提供的 GitHub 链接。上默认主分支,我已配置 Dotfuscator CE 来保护与根检查 TodoAzure.Droid,以便应用程序符合前面所述的策略。你可以按照 Git 历史记录,开头之前检查分支,若要查看如何我的示例应用这篇文章中的步骤。

请有关如何设置、 生成和运行示例,参阅示例的自述文件,了解详细信息。自述文件还包括存储库中存在的演示不同的保护策略比本文中,如"备用保护策略。"中详述的策略用于其他分支的详细信息

将 Dotfuscator 集成到 Xamarin 生成

Dotfuscator 对.NET 程序集 (.dll 和.exe 文件),因为不移动平台格式如 Android 包 (.apk 文件),必须将 Dotfuscator 集成到 Xamarin 生成过程。设置的集成需要安装和注册 Dotfuscator CE、 下载的专用的 MSBuild 目标文件和修改项目文件以包括这些目标。我如何执行这些集成步骤 Xamarin 博客,因此编写这些说明,请参阅bit.ly/2w9em6c

重要注意事项:根检查需要 Visual Studio 2017 Dotfuscator CE 5.35 或更高版本。你可以随时获取最新版本在bit.ly/2fuUeow

我按照保护 TodoAzure.Droid 项目文件的版本的 Xamarin 博客说明 |AnyCPU 生成配置。因为根检查是特定于 Android 的功能,但你也可以按照 Xamarin 博客说明可保护 iOS 和通用 Windows 平台 (UWP) 项目与代码混淆处理,本文只涉及此 Android 项目。

配置 Dotfuscator 保护

一旦我 Dotfuscator 集成到 TodoAzure.Droid 项目的生成过程中时,我配置通过 Dotfuscator CE UI 的保护。在生成集成将添加到你的项目生成的第一个时间专用 Dotfuscator 配置文件中保存项目的保护设置。

正在创建 Dotfuscator 配置文件:使用 Visual Studio 2017,生成 TodoAzure.Droid 发行版中的项目生成为 AnyCPU 平台,这是我已设置为使用 Dotfuscator 的配置的配置。这产生了中的新 Dotfuscator 配置文件,DotfuscatorConfig.xml,项目的目录。因此我更高版本无法自定义并重新应用基于该自定义的保护到源代码管理添加此新文件。

此外在我的项目目录中,这是集成的一部分运行时 Dotfuscator 写入各种报表文件的位置创建了一个 DotfuscatorReports 目录生成。由于此目录的内容更新每次生成,我遇到了以下我忽略此目录的源控件。

打开 Dotfuscator:要自定义 Dotfuscator 配置文件,我打开 Dotfuscator CE UI 从 Visual Studio 2017 通过选择工具 |PreEmptive 保护-Dotfuscator。在 Dotfuscator UI 中出现,我选择文件 |打开项目中,导航到 TodoAzure.Droid 项目的目录并选择 DotfuscatorConfig.xml,Dotfuscator 配置文件。Dotfuscator UI 更新以显示此 Dotfuscator 配置文件保护的两个程序集:TodoAzure.Droid.dll 本身和可移植类库 (PCL) 程序集 TodoAzure.dll。

请记住 Dotfuscator UI 中的生成项目选项不会执行 Xamarin 打包步骤。若要确保 Android 包包含受保护的程序集,而是请从 Visual Studio 或 MSBuild 中生成项目。

启用注入的代码:检查是 Dotfuscator 代码注入功能的一部分。若要启用注入代码,我用鼠标右键单击 Dotfuscator 导航栏中的注入节点并选中启用选项。从灰色更改为黑色,,指示注入已启用的注入节点的文本颜色。

查看配置检查:Dotfuscator 检查页显示这种情况下 DotfuscatorConfig.xml 在 TodoAzure.Droid 项目中的所有配置加载的配置文件,检查列表。若要查看此页,我选择注入节点,并切换到检查选项卡。

当我首次访问此列表时,它为空。我配置新根检查,如在下一部分中,我介绍后更新列表,以便为该检查,包括行中所示图 2。我无法通过双击该行查看检查的配置。

Dotfuscator 检查页上,显示根检查
图 2 Dotfuscator 检查页上,显示根检查

请注意,你可以配置根检查多个单个 Dotfuscator 配置文件中,但我未为此项目执行此操作。由多个检查受保护的应用程序示例,请参阅有关最后一个年 11 月我编写 AdventureWorksSalesClient.NET Framework 应用程序。

添加根检查

在检查页面中,我添加根检查通过单击添加根检查按钮。当我这样做时,Dotfuscator 显示配置新的检查的新窗口。图 3显示完成的配置; 本部分介绍每个设置和选择这些设置的原因的含义。

配置根检查的-隐藏的折叠 TodoAzure.dll 节点的其他位置
图 3 配置根检查的-隐藏的折叠 TodoAzure.dll 节点的其他位置

位置:每个检查都与一个或多个方法在应用中,调用位置相关联。当应用程序调用这样的方法时,根检查激活,如果设备似乎取得 root 权限,在该时刻检测。执行所有配置报告和响应功能,这些度量值未退出应用程序中,假定后检查将控制权返回给方法的顶部。

对于此方案检查,我选择多个位置。第一次使用应用程序中的位置是 TodoAzure.Droid.MainActivity.AuthenticateAsync,协调登录请求。使用此位置意味着根检查将其检测和响应每次执行登录过程开始。

每个保护策略中,取得 root 权限的设备上运行的应用程序退出时首先到达的 AuthenticateAsync 方法。因此为什么未添加发生其他方法更高版本中应用的生命周期作为其他位置?这是为了帮助抵御反向工程应用程序。如果攻击者创建的应用程序绕过,或者移除 AuthenticateAsync 的根检查代码的篡改的版本,这些其他位置将仍将能够应对取得 root 权限的环境。

这些其他的位置的一些 TodoAzure.dll 中定义。这可以是令人惊讶,因为该程序集包含逻辑通用于所有 Xamarin 平台,不只是 Android。如何可以 Dotfuscator 插入根检查-其中检测到取得 root 权限的 Android 设备-为平台不可知的程序集?记住,此 Dotfuscator 配置文件是特定于 TodoAzure.Droid 项目,即在引用 TodoAzure 项目。当 Dotfuscator 修改 TodoAzure.dll 时,它将修改 Visual Studio 或 MSBuild 副本使用在当前项目中,TodoAzure.Droid 的程序集。原始 TodoAzure 项目的程序集保持不变。

应用程序通知:检查可以报告其检测到的应用代码的结果。这允许您已自定义报告和响应行为时检测工作将具有检查插入的由 Dotfuscator 句柄。收到检测结果的应用程序代码调用应用程序通知接收器。

为了满足在此方案中的保护策略,我需要安装应用程序禁用本身,以便以后用来运行应用程序退出时出现一条错误消息。我选择要添加此禁用逻辑在方法中,TodoAzure.App.DisableIfCompromised,并将其用作检查的接收器通过设置以下检查属性:

  • ApplicationNotificationSinkElement:类型的代码元素,则在这种情况下,一种方法。
  • ApplicationNotificationSinkName:代码元素中; 的简单名称在此情况下,DisableIfCompromised。
  • ApplicationNotificationSinkOwner:包含的代码元素; 的类型在此情况下,TodoAzure.App。

检查的位置的任何可以调用此接收器方法,因为它是公共和静态。若要通过检查兼容,方法是同步的 (非异步)、 采用单个 bool 自变量和具有 void 返回类型。

当激活,检查调用的方法,如果设备已取得 root 权限传递自变量 true 和 false 否则。当此参数设为 true-即,当检测到根-该方法将值保存到本地存储,,该值指示应用程序现已禁用。随附的属性,IsDisabled,公开的已保存的值:

// Definitions in TodoAzure.App
private const string DisabledPropertyKey = "AppStatus";
public static void DisableIfCompromised(bool wasCompromised)
{
  if (!wasCompromised) { return; }
  Current.Properties[DisabledPropertyKey] = new Random().Next();
  SavePropertiesNow();
}
public static bool IsDisabled =>
  Current.Properties.ContainsKey(DisabledPropertyKey);

禁用应用程序后,以后用来运行需要显示错误消息和退出。为此,我会忽略 TodoAzure.LoginPage.OnAppearing,当启动该应用程序,将显示登录页之前,正确调用。如果应用程序处于禁用状态,此方法将隐藏登录页,显示错误对话框,然后退出。

// Definition in TodoAzure.LoginPage
protected override async void OnAppearing()
{
  if (App.IsDisabled)
  {
    IsVisible = false;
    var message = "The security of this device has been compromised. "
      + " The app will exit.";
    await DisplayAlert("App deactivated", message, "Exit App");
    App.Exit(); // Delegates to platform-specific exit logic
  }
  base.OnAppearing();
}

我还希望抵御反向工程,因为我用时更多措施,确保应用会更具弹性到这样的攻击。我使用的已保存的值,AppStatus 的模糊名称,并将值设置为一个随机数遮盖的值的含义。我还配置 Dotfuscator 进行模糊处理应用程序中,重命名 DisableIfCompromised,如标识符,因此攻击者查看反编译的代码将不会轻松地识别为感兴趣的此方法。有关如何配置重命名模糊处理的详细信息,请参阅示例的自述文件。

操作:虽然接收器 (DisableIfCompromised 方法) 设置一个属性,以确保将来运行的应用程序退出,它不本身退出该应用时首次检测到根。相反,我配置来自动执行此操作通过操作检查属性设置为退出的检查。

当检查检测到取得 root 权限的设备时,则会通知接收器,并随后立即退出应用程序。通过让这项检查,而不是接收器,执行此初始退出,我分布通过应用程序的退出逻辑的多个副本。就像使用多个位置,退出逻辑的多个副本将允许应用程序以更好地保护自身时攻击者已删除的根检查一些。

生成和测试应用程序

在配置根检查后,我退出检查的窗口通过选择确定,然后我将我的更改保存到 Dotfuscator 配置文件通过选择文件 |保存项目。我生成 TodoAzure.Droid Visual Studio 测试受保护应用程序,以验证我正确配置根检查以强制实施的预期的保护策略中。

测试应用非取得 root 权限的设备上、 取得 root 权限的设备和仿真程序的消息。非取得 root 权限,在设备中,应用程序工作正常,并让我地登录以查看待办事项列表。但是,在取得 root 权限的设备上以及在仿真程序中,选择登录按钮后应用程序突然关闭。重新启动后应用程序,该应用将显示错误对话框中所示图 4; 在关闭对话框中,一次更退出该应用程序后。若要查看登录页同样,我必须卸载并重新安装应用程序。

受保护的 TodoAzure.Droid 在模拟器中运行
图 4 受保护的 TodoAzure.Droid 在模拟器中运行

总结

我希望本文促进了当地照亮有效地检测和响应附带 Visual Studio 以使用可用的工具的 Android 设备取得 root 权限的方法。尽管作为引用,我使用众所周知的示例应用程序,你可以应用到所有类型的 Xamarin.Android 应用程序和各种其他保护策略,这篇文章中引入的想法。

如果你感兴趣学习有关检查的详细信息,建议阅读我以前的 MSDN 杂志文章的地方。其中,我介绍了其他类型的检查,你可以将应用于.NET Framework 应用程序和如何使用检查可以防止数据泄露。

你还可能对感兴趣的 Dotfuscator Professional Edition 高级的检查和模糊处理功能 (bit.ly/2xgEZcs) 或 Java 和传统 Android 应用,PreEmptive 保护-DashO 的配套工具 (bit.ly/2ffHTrN)。你可以跟踪的最新检查和 PreEmptive 保护中的所有开发在 Twitter 上按照 PreEmptive Solutions (twitter.com/preemptive) 和通过访问我们的博客 (preemptive.com/blog).

备用保护策略

此文章提供了一种策略检测和响应取得 root 权限的设备,但也可能其他策略。你选择应该适用于你的应用的策略,在其中使用您的应用程序和安全风险的上下文待解决。你可以随后可应用根进行检查,以实现选的策略。例如,如果你的应用程序必须在任何情况下退出,则可配置根选中以禁用检测到根时,某些功能,而不是退出应用。

一个单应用甚至可能需要对定位根据在运行时识别的信息以不同方式做出响应。请考虑多个地理区域中可用的应用。定位到的应用程序的响应可能需要因区域以符合当地的法律和法规,尤其是在该响应包括将事件报告发送回给开发人员 ("传回 home")。

在开发时保护策略,你还必须考虑你的策略将对具有有意取得 root 权限的高诚信其设备应用程序的用户的影响。这些"power users"可能是您的客户群的重要部分,并禁止取得 root 权限的设备无法控制离开你的应用程序。您必须权衡取得 root 权限的设备免受与 alienating 的此类设备的合法用户关联的业务风险与关联的安全风险。

对于本文中,我将假定 TodoAzure.Droid 处理敏感数据,并因此,若要防止数据窃取,反向工程的影响,取得 root 权限的设备应完全禁止。如果我已改为将数据视为非敏感,我无法已实现的保护策略,在某些情况下,允许取得 root 权限的设备,使应用程序更易于访问到超级用户。在此备用策略,而不是应用程序禁用本身,应用程序将检测到取得 root 权限的设备时,警告用户。此警告可确保用户可以知道的不安全状态的设备和关联的风险喜欢凭据被盗。用户可以选择要取消的登录尝试,或以接受的风险并继续登录。

在受保护 TodoAzureAuth GitHub 存储库的警告用户分支,我已配置 Dotfuscator CE,以防 TodoAzure.Droid 为实现此备用保护策略根检查。在该分支上的自述文件说明配置的细节。

请注意此备用策略使到超级用户的可访问性和反向工程的威胁之间进行权衡。在此策略下,不良参与方可以仍设备上安装应用取得 root 权限为了进行反向工程;警告对话框不会将其停止。我仍使用 Dotfuscator 进行模糊处理应用程序中,提供一定程度的保护进行反向工程。实际的应用程序可以实现其他控件,如要求特殊身份验证可取得 root 权限的设备上使用应用程序。

图 A显示取得 root 权限的设备上运行时应用显示该警告。

TodoAzure.Droid,受此备用策略,在用户选择登录按钮后,在模拟器中,运行
图 TodoAzure.Droid,受此备用策略,在用户选择登录按钮后,在模拟器中,运行


Joe Sewell是一种软件工程师和技术的 PreEmptive Solutions Dotfuscator 团队的编写器。他以前曾为 MSDN 杂志和正式的 Xamarin 博客。

衷心感谢以下 Microsoft 技术专家对本文的审阅:David Britch
David Britch 在 Microsoft 的 Xamarin 文档组工作。他写的软件开发发布包括丛书、 指南文档、 参考实现、 白皮书、 视频和讲师培训课程范围