在 Mac 上记录“open”系统调用

Jas*_*eth 5 c macos bash dtrace system-calls

我想知道open(2)bash 脚本中进行了哪些调用。

我编写了以下拦截系统调用的程序:

#include <fcntl.h>
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>

#define DYLD_INTERPOSE(_replacment,_replacee) \
__attribute__((used)) static struct{ const void* replacment; const void* replacee; } _interpose_##_replacee \
__attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacment, (const void*)(unsigned long)&_replacee };

static
int
my_open(const char *filename, int oflag, mode_t mode)
{
    printf("$jason$ open: %s\n", filename);
    return open(filename, oflag, mode);
}
DYLD_INTERPOSE(my_open, open)
Run Code Online (Sandbox Code Playgroud)

然后我使用以下命令运行:

clang -dynamiclib libfile.c -o libfile.dylib
export DYLD_INSERT_LIBRARIES=libfile.dylib
touch /tmp/testingtesting
Run Code Online (Sandbox Code Playgroud)

这不起作用。

我用自己编译的程序尝试了一下,效果很好。我用brew编译的程序尝试了一下,效果很好。我阅读了touch.c的源代码。它调用open(2).

然后我禁用了 SIP,效果很好。因此,我得出的结论是 SIP 导致了问题。但我不想禁用 SIP。

我应该怎么办?我正在考虑只允许 dtrace: csrutil enable --without dtrace。因为我认为 dtrace 可以跟踪系统调用,但我不确定这是否是一个安全的选择。

pmd*_*mdj 6

最新版本的 macOS 基本上不支持常规库注入。

\n

然而,您确实可以按照dtrace您的怀疑,特别是dtruss脚本来执行此操作。不幸的是,macOS 附带的此脚本的版本相当陈旧,因此我建议使用我的更新版本dtruss\xc2\xb9,因为这将让您跟踪所有子进程,如果您是跟踪 shell 脚本。它还避免了必须运行您尝试使用 跟踪的命令sudo,这可能会使其行为不同。

\n

这个命令\xe2\x80\xa6

\n

path/to/dtruss -d -e -f -t open touch /tmp/testingtesting

\n

\xe2\x80\xa6 应该可以与链接版本一起正常工作。命令行解释:

\n
    \n
  • -d-e显示通话时间。(选修的)
  • \n
  • -f启用“跟随”模式来跟踪生成的子进程 - 这对于命令来说并不是很有趣touch,但您可能需要它来跟踪 bash 脚本。
  • \n
  • -t open限制对open系统调用的跟踪。(保留此选项以跟踪所有系统调用。警告:这可能会产生大量输出。)
  • \n
\n

使用 的库存版本dtruss,您可以退回到:

\n
    \n
  • sudo dtruss -d -e -t open touch /tmp/testingtesting- 但请注意,touch在这种情况下将以 root 用户身份运行,并且不支持跟踪子进程。
  • \n
  • sudo dtruss -d -e -t open -n touch,然后touch /tmp/testingtesting在另一个终端中运行。这可以避免touch以 root 身份运行,但它会跟踪所有名为 的进程touch
  • \n
\n

使用原始版本时,跟踪的系统调用的输出可能也不太清晰,dtruss因为更新版本在格式化系统调用参数(尤其是字符串)方面做得更好。(open()具体来说,更新版本将创建的文件权限的“mode”参数打印为八进制,这通常是您想要的。)

\n

是的,您需要禁用 SIP 的 dtrace 部分才能使 dtrace 的所有功能正常工作,这可能确实会带来一个小安全风险,但我还没有听说有任何恶意软件试图利用这一点。

\n

脚注:

\n

\xc2\xb9 我并不是想自我推销我的代码。我只是不知道更好的解决方案 - 我遇到了与提问者非常相似的问题,并且内置工具不够好,所以我修复了它。

\n


Art*_*iev 2

你所做的就是所谓的库注入,Apple 正在努力从他们的系统中删除这种能力。

由于他们的努力,在启用 SIP 的情况下,您只能对未强化的应用程序(或在几个特定的​​例外情况下强化)执行 DYLD_INSERT 魔法,我认为这些应用程序是您构建和酿造的应用程序。Apple 二进制文件(其中之一是 touch)通常通过其他方式进行强化或保护。

这里没有太多选择:

  1. 禁用SIP并注入你想要的东西
  2. 部分禁用 SIP,您可能会实现一些目标(dtrace 可能会有所帮助)
  3. 编写一个内核扩展来进行注入,并以某种方式从 Apple 获取 kext 签名 - 它可以在启用 SIP 的情况下工作。

所有这些选项都适用于基于 Intel 的 Mac,对于 m1 来说可能更难。

关于安全性:将禁用 SIP 的机器与外部数据源(互联网、USB 驱动器等)断开,进行研究,然后重新启用 SIP 并再次将 mac 连接到世界。