简介
linux是一种安全的操作系统,将系统权限都赋予了一个单一root,只给普通用户保留需要的权限,root可以安装、修改等服务、管理用户等
作为普通用户如果需要执行某些只有管理员才能进行的操作时,有两种方法可以实现:sudo或SUID管控,sudo比较常规
SUID,如passwd,修改密码时候是需要root的权限,但普通用户却可以通过这个来修改密码,这是因为/bin/passwd被设置了SUID标识所以普通用户执行passwd时,进程的owner就是passwd的所有者也就是root,运行周期内有root权限,一旦被漏洞利用将直接导致权限获取
此处SUID通常只需要一部分特权,但SUID提供了所有的root权限,所以SUID就存在了较大安全隐患,为了更加细颗粒度的进行控制,linux在内核2.2引入了一种叫做capabilities机制
将之前与root(uid=0)关联的特权细化分成为不同的功能组,本身作为线程的属性存在,每个功能组都可以独立启用和禁用,本质是将内核调用分门别类,具备相同功能的内核调用被放到同个组中
这么一来权限检查就变成了:如果身份不是root,就去检查是否具备该特权对应的Capabilities查看cap_effective对应位是否有效,以此决定是否可以执行特权操作,而不是单独检查进程的有效UID是否为0;Capabilities可以在进程执行时赋予,也可以从父进程去继承
Capabilities表
CAP_AUDIT_CONTROL |
启用和禁用内核审计;改变审计过滤规则;检索审计状态和过滤规则 |
CAP_AUDIT_READ |
允许通过 multicast netlink 套接字读取审计日志 |
CAP_AUDIT_WRITE |
将记录写入内核审计日志 |
CAP_BLOCK_SUSPEND |
使用可以阻止系统挂起的特性 |
CAP_BPF (5.8) |
从CAP_SYS_ADMIN分离一部分BFP功能,控制了一些BPF特定的操作,包括创建BPF maps、使用一些高级的BPF程序功能、访问BPF type format(BTF)数据等 |
CAP_CHECKPOINT_RESTORE (5.9) |
允许更新/proc/sys/kernel/ns_last_pid,使用set_tid特性,读其他进程的/proc/[pid]/map_files |
CAP_CHOWN |
修改文件所有者的权限 |
CAP_DAC_OVERRIDE |
忽略文件的 DAC 访问限制 |
CAP_DAC_READ_SEARCH |
忽略文件读及目录搜索的 DAC 访问限制 |
CAP_FOWNER |
忽略文件属主 ID 必须和进程用户 ID 相匹配的限制 |
CAP_FSETID |
允许设置文件的 setuid 位 |
CAP_IPC_LOCK |
允许锁定共享内存片段 |
CAP_IPC_OWNER |
忽略 IPC 所有权检查 |
CAP_KILL |
允许对不属于自己的进程发送信号 |
CAP_LEASE |
允许修改文件锁的 FL_LEASE 标志 |
CAP_LINUX_IMMUTABLE |
允许修改文件的 IMMUTABLE 和 APPEND 属性标志 |
CAP_MAC_ADMIN |
允许 MAC 配置或状态更改 |
CAP_MAC_OVERRIDE |
忽略文件的 DAC 访问限制 |
CAP_MKNOD |
允许使用 mknod() 系统调用 |
CAP_NET_ADMIN |
允许执行网络管理任务 |
CAP_NET_BIND_SERVICE |
允许绑定到小于 1024 的端口 |
CAP_NET_BROADCAST |
允许网络广播和多播访问 |
CAP_NET_RAW |
允许使用原始套接字 |
CAP_PERFMON (5.8) |
管理性能监控task |
CAP_SETGID |
允许改变进程的 GID |
CAP_SETFCAP |
允许为文件设置任意的 capabilities |
CAP_SETPCAP |
允许设置其他进程的 capabilities |
CAP_SETUID |
允许改变进程的 UID |
CAP_SYS_ADMIN |
允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等 |
CAP_SYS_BOOT |
允许重新启动系统 |
CAP_SYS_CHROOT |
允许使用 chroot() 系统调用 |
CAP_SYS_MODULE |
允许插入和删除内核模块 |
CAP_SYS_NICE |
允许提升优先级及设置其他进程的优先级 |
CAP_SYS_PACCT |
允许执行进程的 BSD 式审计 |
CAP_SYS_PTRACE |
允许跟踪任何进程 |
CAP_SYS_RAWIO |
允许直接访问 /devport、/dev/mem、/dev/kmem 及原始块设备 |
CAP_SYS_RESOURCE |
忽略资源限制 |
CAP_SYS_TIME |
允许改变系统时钟 |
CAP_SYS_TTY_CONFIG |
允许配置 TTY 设备 |
CAP_SYSLOG |
允许使用 syslog() 系统调用 |
CAP_WAKE_ALARM |
允许触发一些能唤醒系统的东西(比如 CLOCK_BOOTTIME_ALARM 计时器) |
Capabilities的赋予和继承
linux的Capabilities分为进程Capabilities和文件Capabilities,对于进程来说,Capabilities是细分到了线程的,每个线程都可以有自己的Capabilities,对文件来说,Capabilities保存在文件的扩展属性
线程Capabilities
每个线程都有5个Capabilities集合,集合使用64位掩码,显示16进制格式,5个Capabilities集合分别是:
Permitted
Effective
Inheritable
Bounding
Ambient
Permitted
定义了线程能够使用的Capabilities上限。
线程可以通过系统调用 capset 来从Effective或Inheritable集合中添加或删除Capabilities,前提是添加或删除的Capabilities必须在Permitted集合中
如果某个线程想向Inheritable集合中添加或删除Capabilities,首先他的Effective必须包含CAP_SETPCAP这个Capability
Effective
内核检查线程是否可以进行特权操作时,检查的对象是Effective集合
已知Permitted定义了上线,线程可以删除Effective集合中的某Capabilities,随后在需要的时候在从Permitted集合中恢复该Capabilities,以此达到临时禁用的目的
Inheritable
当执行 exec 系统调用的时候,能够被新的可执行文件集成的Capabilities被包含在Inheritable集合中
包含在该集合中的Capabilities并不会自动集成给信的可执行文件,不会添加到新线程的Effective中,只会影响线程的Permitted集合
Bounding
Bounding集合是Inheritable集合的超集,如果某个Capabilities不在Bounding集合中,即使它在Permitted集合中,线程也不能将该Capabilities添加到它的Inheritable集合中
Bounding集合的Capabilities在执行 fork 系统调用时会传递给子进程的Bounding 集合,并且在执行 exec 系统调用后保持不变
当某个线程运行时候不能向Bounding集合中添加Capabilities
一旦某个Capabilities被从Bounding集合中删除,则无法被添加回来
将Capabilities从Bounding删除后,之前Inherited集合如果包含该Capabilities则将继续保留,如果后续从Inheritable集合删除了该Capabilities则不能添加回来
Ambient
在4.3的内核新增的集合,用来弥补Inheritabl
Permitted和Inheritable未设置的Capabilities,Ambient也不能设置
当Permitted和Inheritable关闭某权限(比如 CAP_SYS_BOOT)后,Ambient也随之关闭对应权限,这样就确保了降低权限后子进程也会降低权限
非特权用户如果在Permitted集合中有一个Capabilities,那么可以添加到 Ambient集合中,这样它的子进程便可以在Ambient、Permitted和Effective集合中获取这个Capabilities
Ambient优势:将CAP_NET_ADMIN添加到当前进程的Ambient集合中,它便可以通过 fork 和 exec 调用shell脚本来执行网络管理任务,因为CAP_NET_ADMIN会自动继承下去
文件Capabilities
保存在文件的扩展属性中,要想修改需要有CAP_SETFCAP权限,文件和线程的Capabilities共同决定了通过 exec 调用运行该文件后线程的Capabilities
注意如果不支持文件系统支持,如系统文件使用了nouuid进行挂载,那么Capabilities会被忽略
3个集合:
Permitted
Inheritable
Effective
Permitted
会与线程的Bounding集合计算交集,然后添加到线程Permitted集合中
Inheritable
与线程的Inheritable集合的交集,会被添加到执行完 exec 后的线程的Permitted 集合中
Effective
这不是一个集合,仅仅是一个标志位。如果设置开启,那么在执行完 exec 后,线程 Permitted集合中的Capabilities会自动添加到它的Effective集合中
对于一些旧的可执行文件,由于其不会调用Capabilities相关函数设置自身的 Effective集合,所以可以将可执行文件的Effective bit开启,从而可以将Permitted集合中的Capabilities自动添加到Effective集合中
使用Capabilities
查看文件的capabilities
getcap /bin/ping
也可以使用-r参数来递归查询
getcap -r /usr
直接查看进程Capabilities,可以如下直接加pid
getpcaps 71431
设置文件的Capabilities,使用setcap
添加cap_net_admin到permitted、effective集合中
setcap cap_net_admin+ep 2
移除文件的Capabilities
setcap -r 2