【问题标题】:Limiting syscall access for a Linux application限制 Linux 应用程序的系统调用访问
【发布时间】:2011-01-09 21:41:49
【问题描述】:

假设一个 Linux 二进制文件 foobar 有两种不同的操作模式:

  • 模式 A:使用系统调用 abc 的行为良好的模式。
  • 模式 B:使用系统调用 abcd 的错误模式。

系统调用abc 是无害的,而系统调用d 具有潜在危险,可能导致机器不稳定。

进一步假设应用程序运行的两种模式中的哪一种是随机的:应用程序以 95% 的概率以模式 A 运行,以 5% 的概率以模式 B 运行。该应用程序没有源代码,因此无法修改,只能按原样运行。

我想确保应用程序无法执行系统调用d。执行 syscall d 时,结果应该是 NOOP 或应用程序立即终止。

如何在 Linux 环境中实现这一点?

【问题讨论】:

  • 您能否澄清一下您的问题中“概率”的含义,以防有什么误解?
  • 帕斯卡:当然!帖子已编辑并进行了澄清。对于这个问题,“模式选择”是随机的。

标签: linux security linux-kernel hook system-calls


【解决方案1】:

应用程序是静态链接的吗?

如果没有,你可以覆盖一些符号,例如,让我们重新定义socket

int socket(int domain, int type, int protocol)
{
        write(1,"Error\n",6);
        return -1;
}

然后构建一个共享库:

gcc -fPIC -shared test.c -o libtest.so

我们跑吧:

nc -l -p 6000

好的。

现在:

$ LD_PRELOAD=./libtest.so nc -l -p 6000
Error
Can't get socket

当您使用变量LD_PRELOAD=./libtest.so 运行时会发生什么?它使用 libtest.so 中定义的符号覆盖 C 库中定义的符号。

【讨论】:

  • 这实际上不符合安全要求?获取代码以在eax 或任何 CPU 约定中加载适当的系统调用号,然后将控制权转移到“a”、“b”或“c”系统调用的尾部是相当容易的。更改每个进程的系统调用表和加载程序更改(如 SELinux)是阻止用户空间损坏的唯一方法。参见例如ROP at wikipedia。至少这个答案假设系统中有几件事是无法妥协的。
【解决方案2】:

看来systrace 完全符合您的需要。来自Wikipedia page

仅允许应用程序进行策略中指定的系统调用。如果应用程序尝试执行未明确允许的系统调用,则会引发警报。

【讨论】:

    【解决方案3】:

    这是sandboxing 的一种可能应用(特别是基于规则的执行)。一种流行的实现是SELinux

    您必须write the policy 对应于您希望允许该进程执行的操作。

    【讨论】:

    • 这当然是 SELinux 的用例。其他沙盒技术也可用。
    • @stsquad 我采纳了你的评论。您可能对以前版本中的“声明”做出了部分反应……我这样说是因为听说有些人 SELinux 在实践中不太好用,正是因为需要适当的策略。没有尝试过,我没有任何意见,所以从这个角度来看,也许新版本更好。
    【解决方案4】:

    这正是seccomp-bpf 的用途。请参阅example how to restrict access to syscalls

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-06
      • 2012-11-19
      • 2013-04-01
      • 2015-10-04
      • 2013-12-18
      • 1970-01-01
      • 2012-10-24
      • 1970-01-01
      相关资源
      最近更新 更多