AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 562260
Accepted
Karthik Nedunchezhiyan
Karthik Nedunchezhiyan
Asked: 2020-01-16 06:24:26 +0800 CST2020-01-16 06:24:26 +0800 CST 2020-01-16 06:24:26 +0800 CST

为什么我们需要在调用 SECCOMP_MODE_FILTER 之前设置 no_new_privs?

  • 772

在手册页上,我阅读了以下行:

导致尝试使用 setuid(2) 将调用者的用户 ID 设置为非零值,而不是在不实际进行系统调用的情况下返回 0

我不明白他们想说什么。谁能给我解释一下?

谢谢。

linux security
  • 1 1 个回答
  • 764 Views

1 个回答

  • Voted
  1. Best Answer
    Danila Kiver
    2020-01-20T08:37:44+08:002020-01-20T08:37:44+08:00

    首先,请注意seccomp(2)手册页中的以下段落:

    SECCOMP_RET_ERRNO

    该值导致过滤器返回值的 SECCOMP_RET_DATA 部分作为 errno 值传递给用户空间,而不执行系统调用。

    因此,seccomp 过滤器可能会使内核跳过真正的系统调用执行,而是返回一些值来假装系统调用已执行并产生了指定的结果。如果返回值设置为零,这也包括成功的结果。

    这是libseccomp基于示例的程序 ( sec.c),它显示了它是如何工作的(为简洁起见,省略了所有错误检查):

    #include <stdio.h>
    #include <seccomp.h>
    
    int main() {
        scmp_filter_ctx seccomp;
    
        seccomp = seccomp_init(SCMP_ACT_ALLOW);
    
        // Make the `openat(2)` syscall always "succeed".
        seccomp_rule_add(seccomp, SCMP_ACT_ERRNO(0), SCMP_SYS(openat), 0);
    
        // Install the filter.
        seccomp_load(seccomp);
    
        FILE *file = fopen("/non-existent-file", "r");
    
        // Do something with the file and then perform the cleanup.
        // <...>
    
        return 0;
    }
    

    在跟踪执行的同时编译和运行这个程序表明openat(2)系统调用返回零(即“执行”成功),尽管/non-existent-file文件系统中不存在该文件:

    $ gcc sec.c -lseccomp -o sec
    
    # Run the program showing the openat(2) invocations and their results.
    $ strace -e trace=openat ./sec
    ...
    openat(AT_FDCWD, "/non-existent-file", O_RDONLY) = 0
    ...
    
    # Ensure that the file does not exist.
    $ stat /non-existent-file
    stat: cannot stat '/non-existent-file': No such file or directory
    

    好了,现在我们了解了 seccomp 过滤器的功能。让我们更接近您在问题中引用的段落的要点。想两件事:

    • 非特权进程可能会使用一些内核机制来提升其特权;
    • 有一些工具使用这种机制来临时授予权限,并且仅用于有限数量的操作。

    典型的例子是sudo(8)实用程序,它是root–owned SUID 二进制文件。在非特权进程的上下文中执行它会授予调用进程完全的超级用户权限(除了沙盒和容器等一些特殊情况),然后sudo(8)检查/etc/sudoers文件以了解是否允许调用用户执行请求的操作。如果是,则sudo(8)继续执行,如果不是,则拒绝执行。此外,sudo(8)允许代表任意用户执行 - 在这种情况下,它将在执行请求的操作之前设置适当的凭据。

    例如,假设/etc/sudoers文件包含以下记录

    testuser ALL=(anotheruser) NOPASSWD: /bin/bash
    

    用户testuser将能够anotheruser使用以下命令代表运行 shell:

    sudo -u anotheruser -i /bin/bash
    

    现在,我们更接近正题了:如果testuser–owned 进程安装了 seccomp 过滤器,这使得内核在setuid(2)没有实际执行的情况下返回,然后运行sudo -u anotheruser -i /bin/bash呢?好吧,走着瞧:

    • 内核看到二进制文件中的 SUID 位sudo(8)并适当地提升调用进程的权限;
    • sudo(8)检查/etc/sudoers并确保testuser允许运行/bin/bash为anotheruser;
    • 然后sudo(8)调用setuid(2)适当地更改进程的凭据并“降级”其权限;
    • 用户安装的seccomp过滤器静默报告成功,假装“降级”完成;
    • sudo(8)相信该过程现在代表……anotheruser执行并继续执行/bin/bash……
    • 实际上以超级用户权限运行它,因为setuid(2)被过滤器跳过并且没有真正执行!

    因此,允许非特权用户安装 seccomp 过滤器还允许该用户通过捕获调用来“劫持”特权凭据,setuid(2)同时以升级的权限临时运行,因此在手册页中指定了限制:

    调用线程必须在其用户命名空间中具有 CAP_SYS_ADMIN 功能,或者该线程必须已经设置了 no_new_privs 位。

    很清楚这句话的第一部分是什么意思:CAP_SYS_ADMIN是一种授予进程大量特权的能力,因此可以安全地假设拥有它的进程已经足够强大,可以对系统造成严重破坏。第二部分呢?

    该no_new_privs位是进程的一个属性,如果设置,它会告诉内核不要使用像 SUID 位这样的特权升级机制(因此,调用类似的东西sudo(8)根本不起作用),因此允许使用该位的非特权进程是安全的设置为使用 seccomp 过滤器:即使是暂时的,这个进程也没有任何可能提升权限,因此,将无法“劫持”这些权限。

    • 6

相关问题

  • 使用键盘快捷键启动/停止 systemd 服务 [关闭]

  • 需要一些系统调用

  • astyle 不会更改源文件格式

  • 通过标签将根文件系统传递给linux内核

  • 是否有实现 RFC 5848“签名系统日志消息”的系统日志守护程序?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve