限制Linux应用程序的系统调用访问

限制Linux应用程序的系统调用访问,linux,security,linux-kernel,hook,system-calls,Linux,Security,Linux Kernel,Hook,System Calls,假设一个Linux二进制foobar,它有两种不同的操作模式: 模式A:一种性能良好的模式,其中使用系统调用A、b和c 模式B:一种出错模式,其中使用系统调用A、B、c和d 系统调用a、b和c是无害的,而系统调用d是潜在的危险,可能会导致机器不稳定 进一步假设应用程序运行的两种模式中的哪一种是随机的:应用程序以95%的概率在模式A中运行,以5%的概率在模式B中运行。应用程序没有源代码,因此无法修改,只能按原样运行 我想确保应用程序不能执行syscalld。执行syscalld时,结果应该是N

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

  • 模式A:一种性能良好的模式,其中使用系统调用
    A
    b
    c
  • 模式B:一种出错模式,其中使用系统调用
    A
    B
    c
    d
系统调用
a
b
c
是无害的,而系统调用
d
是潜在的危险,可能会导致机器不稳定

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

我想确保应用程序不能执行syscall
d
。执行syscall
d
时,结果应该是NOOP或立即终止应用程序


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

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


您必须确保与您希望允许流程执行的操作相对应。

应用程序是否静态链接

如果没有,您可以覆盖某些符号,例如,让我们重新定义
套接字

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中定义的符号进行重写。因此,在C库中定义的符号之上。

这似乎正是您所需要的。从:

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


这正是为什么。请参阅。

如果您的问题中存在误解,您能否澄清一下“概率”的含义?帕斯卡:当然!用澄清后编辑。对于这个问题,“模式选择”是随机的。这当然是SELinux的用例。其他沙箱技术也可用。@stband我将您的评论合并到了一起。您可能对上一版本中的“声明”做出了部分反应……我这样说是因为听到一些人说SELinux在实践中不太实用,正是因为需要适当的政策。没有尝试过,我没有任何意见,所以从这个角度来看,新版本可能更好。这实际上不符合安全要求吗?很容易让代码在
eax
或任何CPU约定中加载适当的系统调用号,然后将控制权转移到“a”、“b”或“c”系统调用的末尾。更改每个进程的系统调用表和加载程序更改(如SELinux)是阻止用户空间损坏的唯一方法。例如,见。至少这个答案假设系统中有几件事情是无法妥协的。