【问题标题】:Android binder securityAndroid活页夹安全
【发布时间】:2011-10-04 22:15:06
【问题描述】:

Android 中 Binder 提供的进程间通信是否可以防止中间人攻击?是否有提供此信息的文档?

【问题讨论】:

    标签: android security android-binder


    【解决方案1】:

    Binder 使用基于能力的安全模型。每个 binder 对象代表一个能力;将该对象交给另一个进程会授予该进程对该功能的访问权限。从这个角度来看,您可以通过不将重要的活页夹对象交给中间人来防止中间人攻击。如果一个进程没有得到一个 binder 对象,它就不能以任何方式访问它。

    关于论文中讨论的“跨绑定器引用伪造”问题,如果我理解他们所谈论的具体场景,我认为他们关于用户空间的附录比我同意的要弱一些。他们犯了我认为查看为 ServiceManager 编写的特殊 C 代码的错误。形式上,我认为 C++ 用户空间代码(特别是 Parcel)是 Binder 架构的一部分。当您调用其 readBinder() 和相关方法时,此代码特别确保处理此类欺骗尝试。

    我不同意内核没有完全确保数据完整性是一个缺陷的说法。我能想象到的唯一方法是为绑定事务定义标准类型的数据结构,以便它可以读取和验证包裹的内容。在我看来,这将太多的知识放在内核中,并没有真正的好处。无论你放了多少,用户空间都需要对传入的交易进行某种验证,以确保它符合预期。今天,这是在验证 Parcel 上的原始数据读取操作(readBinder()、readString16()、readInt() 等)是为了避免攻击而编写的。向内核推送更多验证仍然需要在用户空间验证数据类型是否正确,现在您实际上已经将一些攻击机会(由于此代码中的错误)从用户空间转移到了内核。

    关于 binder 安全性的最后一件事是,重要的是要意识到在平台级别,在 binder 基础架构之上实现了另一个重要的安全模型。这是基于权限/uid 的系统,服务可以检查传入呼叫的​​ uid 以验证它们是否符合其允许的权限。

    此安全模型有另一个必须处理的欺骗漏洞。一个典型的场景是应用程序接收活动管理器服务的 IBinder(因为每个人都可以得到它)。 Activity Manager Service 的 API 深度基于检查传入调用的 uid 以确定允许的内容——例如,如果调用了 bindService(),它将检查该 uid 是否有权绑定到给定的服务。恶意应用程序可以通过将活动管理器 IBinder 交给另一个系统服务来尝试在这里玩游戏,例如作为窗口管理器的 IWindow。如果它知道第二个系统服务将进行的事务,它可以进行设置,以便进行它认为是 resizeWindow() 的调用,但实际上最终成为对 bindService() 的调用,当它进入活动时manager(如果这两个调用映射到相同的事务 ID)。

    存在此漏洞是因为绑定系统没有以任何方式键入,“方法”调用只是使用整数事务代码和数据缓冲区发送的事务。

    为了防止这种情况发生,aidl 生成的用户空间类型接口总是将它们打算调用的接口的名称放在其事务缓冲区的开头,并且事务的接收代码检查前面的接口名称缓冲区以确保它与自己的交互匹配。这样,当活动管理器看到它有一个接口是窗口的来电时,上面场景中的欺骗者就会被捕获。

    无论如何,对于 Android 开发人员的大多数实际应用,基于 uid 的安全性与核心绑定器功能模型一样重要。在某些情况下,您将通过限制哪些进程可以访问活页夹来加强安全性。一个例子是如何有一个 IBinder 代表每个活动,只有系统进程和运行活动的进程共享。

    在其他情况下,IBinder 对象将与任何感兴趣的进程共享,但在基于 uid 的调用点强制执行安全性。如果您使用aidl 来提供此类接口的标准实现,那么您可以根据要应用于uid 的含义来完成您自己的此类安全性实现。例如,您可以使用标准工具将权限与 uid 关联,并询问包管理器传入的 uid 是否具有权限。

    【讨论】:

    • 感谢@hackbod,这是关于 Android 的 Binder 机制的非常有用的深入文档。这应该附加到 Binder 的 JavaDoc 或其他比目前提供的更全面的东西:-)
    • 这是一个非常深入的解释,但是我不明白这一段:aidl生成的用户空间类型接口总是在他们的事务缓冲区的开头放他们是接口的名称打算调用,事务的接收代码检查缓冲区前面的接口名称,以确保它与自己的接口匹配。我在生成的文件中找不到该缓冲区。你能再解释一下吗?非常感谢。
    • @TranSonHai:在 AIDL 生成的 Java 文件的代理(发送者)部分,您会在每个方法的开头看到 _data.writeInterfaceToken(DESCRIPTOR)DESCRIPTOR 是接口名称,_datamRemote.transact 使用的事务缓冲区。在同一文件的存根(接收方)端,您会在每个事务案例的开头看到对enforceInterface(DESCRIPTOR) 的调用。这是完成上述检查的地方。 _datadataandroid.os.Parcel 类的对象,mRemoteandroid.os.IBinder 类的对象。
    【解决方案2】:

    Binder 有一个已识别的安全漏洞,可能使其容易受到 MITM 攻击:http://crypto.hyperlink.cz/files/xbinder.pdf。引用 TFA:

    攻击者可以管理目标以进一步传递或调用其“受保护”绑定器(攻击者不被邀请直接调用)。我们称之为跨绑定器参考伪造(XBRF)

    作者接着说,Android 中有针对这种攻击的防御措施,但是

    在某些情况下,对攻击进程准备的交易数据进行仔细操作仍可能导致成功的 XBRF 漏洞利用

    给人的印象是,对于精心编写的代码,Binder 似乎相对安全,但存在一些风险。

    【讨论】:

    • 这是原始问题的一个很好的答案。但是,它没有回答如何验证活页夹通信的两个端点。
    • 根据 TFA,Android 代码中有一些缓解措施,但不一定足够。因此,留给开发人员的剩余措施是在通信进程之间使用数字签名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    相关资源
    最近更新 更多