【问题标题】:How to defeat framework injections?如何击败框架注入?
【发布时间】:2012-08-30 13:00:06
【问题描述】:

是否有人强化他们的代码以尝试检测注入?例如,如果有人试图通过 NSUrlConnection 拦截用户名/密码,他们可以使用 LD_PRELOAD/DYLD_LIBRARY_PATH,为我的调用提供导出到 NSUrlConnection,然后将调用转发到真正的 NSUrlConnection。

Ali 在下面提供了极好的信息,但我正在尝试确定应对恶劣环境采取哪些措施,手机可能会被越狱。大多数应用程序不必关心,但一类应用程序需要关心 - 高完整性软件。

如果您正在强化,您使用什么方法?是否有一种标准方法可以检测 Mac 和 iPhone 上的注入?你是如何战胜框架注入的?

【问题讨论】:

  • 您可以应用许多运行时保护。我曾在应用程序上工作过,我们应用链接器标志来停止加载 [unexpected] dylib,我们停止了应用程序重新打包(以阻止人们添加恶意库),我们加载了反调试检测,我们检查了系统库调用是否被钩住 &我们屏蔽了最新的逆向工程工具库。但是,如果您没有同样强大的 at-restin-transit 控件,那又有什么意义呢?

标签: cocoa cocoa-touch code-injection ld-preload


【解决方案1】:

对于 iOS / CocoaTouch,不允许加载动态库*(系统框架除外)。要通过 AppStore 构建和分发应用程序,您只能链接静态库和系统框架,不能链接动态库。

因此,在 iOS 上,您不能将其用于代码注入,当然也不能使用 LD_PRELOAD(因为您在 iOS 上无权访问此类环境变量)。

可能除了越狱的 iPhone,但越狱 iPhone 的人应该自己承担越狱的定义是解除 iOS 提供的所有证券以避免注入等事情(所以你不能指望解除锁定你的门,以避免不得不使用你的钥匙......并且仍然期望你仍然受到保护,免受小偷抢劫你的房子;-))

这就是 iOS 上 Sandboxing + CodeSigning + No dylib 约束的优势。无法进行代码注入。

(在 OSX 上仍然可以,尤其是使用 LD_PRELOAD)


[编辑] 从 iOS8 开始,iOS 也允许动态框架。但由于这仍然是沙盒(您只能加载应用程序包内的代码签名框架,而不能加载来自应用程序包外的框架)注入仍然是不可能的*

*除非用户越狱了手机,但这意味着他/她选择摆脱所有保护和目的,从而将手机置于危险之中——我们无法破解手机安全并仍然期待它提供这些证券提供的所有保护

【讨论】:

  • 谢谢阿里。我应该更具体。我正在查看越狱设备(并且我已经看到了注入库 - 我有资源)。所以这个想法是在敌对环境中强化可执行文件。
  • @uchuugaka 是的,但只有嵌入在你的包中的框架,然后只能从你的包中的二进制文件加载(即:你的应用程序和你的应用程序“扩展”),所以它仍然捆绑在应用程序沙箱和注入仍然无法发生。进行动态注入的唯一方法是将代码注入您自己嵌入到应用程序包中的框架中,但它无法加载位于您的包之外的第三方框架,只能加载您包含的框架您构建并签署了您的应用程序。
  • 阅读frida.re。此外,没有什么能阻止您重新签署应用程序包并重新安装。当然,它会丢失应用商店的加密,但谁在乎呢?查看node-applesign
  • 嗨@AliSoftware 能否请您也提供信息的来源,这将是一个很大的帮助。提前致谢
【解决方案2】:

这是一个特定于类 UNIX 操作系统的答案,如果它对您的问题没有意义,但我不太了解您的平台,我深表歉意。不要创建动态链接的可执行文件。

我可以想到两种方法来做到这一点。方法#2 可能最适合您。他们都很相似。

重要,可执行文件必须在构建时使用-static 静态编译

  1. 方法 1 - 静态 exe,通过受信任的完整路径手动加载共享库

通过完整路径手动dlopen每个您需要的库,然后在运行时通过dlsym获取函数地址,并将它们分配给函数指针以使用它们。您需要为要使用的每个外部函数执行此操作。我相信可重入的不安全函数不会喜欢这样,所以对于那些使用静态变量的函数 - 你需要使用可重入的安全版本,这些版本以“_r”结尾,即使用 strtok_r 而不是 strtok

这将是困难或简单取决于您的应用程序做什么以及您正在使用多少功能。

  1. 方法 2 - 静态链接可执行文件,句号

您可以通过仅链接静态可执行文件来完全避免使用动态库来解决您的颠覆问题。这将生成比dlopen()/dlsym() 方法大得多的exe。使用-static 编译标志而不是使用,例如gcc bah.c -o bah lssl 使用gcc -static bah.c -o bah /usr/lib/libssl.a 来使用您需要的库的静态编译版本而不是动态共享库。换句话说,在构建时使用-static,不要使用-l

对于任一方法:

  1. 构建后,使用file bah 确认可执行文件是静态链接的。或者通过运行ldd 来确认
  2. 请注意,您将需要系统中存在的所有要链接的库的静态编译版本。这些文件以.a 结尾,而不是.so)
  3. 另请注意,升级系统库不会更新您的可执行文件。如果 OpenSSL 中有新的安全漏洞,您需要获取最新的 libssl.a 并重新编译它。如果您使用dlopen()/dlsym() 方法,则不会出现此问题,但如果符号在不同版本中发生更改,则会出现可移植性问题

根据您的需要,每种方法都有其优缺点。

采用方法 1 dlopendlsym 方法会使您的代码更加“模糊”且更小,但在大多数情况下会牺牲可移植性,因此可能不是您想要的。好处是,当安全漏洞在系统范围内得到修复时,它可能会受益。

【讨论】:

    猜你喜欢
    • 2020-08-08
    • 1970-01-01
    • 2010-11-16
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 2010-09-14
    • 1970-01-01
    相关资源
    最近更新 更多