在Mac OS X上编译二进制免疫库重定向

时间:2015-04-16 04:31:54

标签: macos g++ static-libraries static-linking setuid

我注意到,在我调用 g ++ (甚至 gcc 对于那个问题)使用 -static 选项,二进制文件的链接失败 - 总是由于某些库或其他库未成功找到。因此,我只能生成使用共享库的二进制文件。

这是一个问题,因为我有一种情况,如果没有编写使用Setuid Root权限安装的程序,我无法解决。我需要编写的这个程序将检查环境变量以确保它们没有任何恶意(并且它会以更好的安全而不是抱歉的态度这样做)然后它会降级它的用户ID使用 exec()的形式调用另一个程序之前之前的常规用户

对环境的这些安全检查将确保其他程序可以在关键环境变量(例如 DYLD_LIBRARY_PATH )未损坏的保证下安全运行。但是这个程序本身可以在任何这样的保证下运行 - 因为它是执行这项检查的一部分。 第一个的地方。

那么如何保护这个C ++程序免受这样的安全漏洞的影响呢?我的第一个想法是使用 -static 选项编译它 - 但由于这在OS X上不起作用,是否有人有其他想法?

感谢。

1 个答案:

答案 0 :(得分:1)

编辑:只要可执行文件是setuid,加载程序就会杀死所有DYLD_ *环境变量。来自the source code for dyld.cpp

// For security, setuid programs ignore DYLD_* environment variables.
// Additionally, the DYLD_* enviroment variables are removed
// from the environment, so that any child processes don't see them.

[原始答案:]根据this post by Sam Marshall,您可以通过在名为" __ RESTRICT"的二进制标题中添加新的部分,并使用名为" __ restrict"的部分。 。您可以在Xcode中将其添加到"其他链接器标志"中来执行此操作:

-Wl,-sectcreate,__RESTRICT,__restrict,/dev/null

忽略DYLD_LIBRARY_PATH的其他可能方法是将可执行文件设置为setuid或setgid,或使用权利签名。来自the source code for dyld.cpp

dyld::log("dyld: DYLD_ environment variables being ignored because ");
switch (sRestrictedReason) {
    case restrictedNot:
        break;
    case restrictedBySetGUid:
        dyld::log("main executable (%s) is setuid or setgid\n", sExecPath);
        break;
    case restrictedBySegment:
        dyld::log("main executable (%s) has __RESTRICT/__restrict section\n", sExecPath);
        break;
    case restrictedByEntitlements:
        dyld::log("main executable (%s) is code signed with entitlements\n", sExecPath);
        break;
}