热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Capabilities入门教程:基础实战篇

该系列文章总共分为三篇:LinuxCapabilities入门教程:概念篇LinuxCapabilities入门教程:基础实战篇待续上篇文章介绍了Linuxcapabilit

该系列文章总共分为三篇:



  • Linux Capabilities 入门教程:概念篇



  • Linux Capabilities 入门教程:基础实战篇



  • 待续...



上篇文章介绍了 Linux capabilities 的诞生背景和基本原理,本文将会通过具体的示例来展示如何查看和设置文件的 capabilities。

Linux 系统中主要提供了两种工具来管理 capabilities:libcap 和 libcap-nglibcap 提供了 getcap 和 setcap 两个命令来分别查看和设置文件的 capabilities,同时还提供了 capsh 来查看当前 shell 进程的 capabilities。libcap-ng 更易于使用,使用同一个命令 filecap 来查看和设置 capabilities。


1. libcap

安装很简单,以 CentOS 为例,可以通过以下命令安装:

$ yum install -y libcap

如果想查看当前 shell 进程的 capabilities,可以用 capsh 命令。下面是 CentOS 系统中的 root 用户执行 capsh 的输出:

$ capsh --print
Current: = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read+ep
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read
Securebits: 00/0x0/1'b0
secure-noroot: no (unlocked)
secure-no-suid-fixup: no (unlocked)
secure-keep-caps: no (unlocked)
uid=0(root)
gid=0(root)
groups=0(root)

解释一下:



  • Current : 表示当前 shell 进程的 Effective capabilities 和 Permitted capabilities。可以包含多个分组,每一个分组的表示形式为 capability[,capability…]+(e|i|p),其中 e 表示 effective,i 表示 inheritable,p 表示 permitted。不同的分组之间通过空格隔开,例如:Current: = cap_sys_chroot+ep cap_net_bind_service+eip。再举一个例子,cap_net_bind_service+e cap_net_bind_service+ip 和 cap_net_bind_service+eip 等价。



  • Bounding set : 这里仅仅表示 Bounding 集合中的 capabilities,不包括其他集合,所以分组的末尾不用加上 +... 。



  • Securebits : 我也没搞清楚这是个什么鬼。



这个命令输出的信息比较有限,完整的信息可以查看 /proc 文件系统,比如当前 shell 进程就可以查看 /proc/$$/status。其中一个重要的状态就是 NoNewPrivs,可以通过以下命令查看:

grep NoNewPrivs /proc/$$/status
NoNewPrivs: 0

根据 prctl(2) 中的描述,自从 Linux 4.10 开始,/proc/[pid]/status 中的 NoNewPrivs 值表示了线程的 no_new_privs 属性。至于 no_new_privs究竟是干嘛的,下面我单独解释一下。


no_new_privs

一般情况下,execve() 系统调用能够赋予新启动的进程其父进程没有的权限,最常见的例子就是通过 setuid 和 setgid 来设置程序进程的 uid 和 gid 以及文件的访问权限。这就给不怀好意者钻了不少空子,可以直接通过 fork 来提升进程的权限,从而达到不可告人的目的。

为了解决这个问题,Linux 内核从 3.5 版本开始,引入了 no_new_privs 属性(实际上就是一个 bit,可以开启和关闭),提供给进程一种能够在 execve() 调用整个阶段都能持续有效且安全的方法。



  • 开启了 no_new_privs 之后,execve 函数可以确保所有操作都必须调用 execve() 判断并赋予权限后才能被执行。这就确保了线程及子线程都无法获得额外的权限,因为无法执行 setuid 和 setgid,也不能设置文件的权限。



  • 一旦当前线程的 no_new_privs 被置位后,不论通过 fork,clone 或 execve 生成的子线程都无法将该位清零。



Docker 中可以通过参数 --security-opt 来开启 no_new_privs 属性,例如:docker run --security-opt=no_new_privs busybox。下面通过一个例子来体会一下 no_new_privs 属性的作用。

首先撸一段 C 代码,显示当前进程的有效用户 id:

$ cat testnnp.c
#include
#include
#include
int main(int argc, char *argv[])
{
printf("Effective uid: %d\n", geteuid());
return 0;
}

$ make testnnp
cc testnnp.c -o testnnp

将可执行文件打入 docker 镜像中:

FROM fedora:latest
ADD testnnp /root/testnnp
RUN chmod +s /root/testnnp
ENTRYPOINT /root/testnnp

构建镜像:

$ docker build -t testnnp .
Step 1 : FROM fedora:latest
---> 760a896a323f
Step 2 : ADD testnnp /root/testnnp
---> 6c700f277948
Removing intermediate container 0981144fe404
Step 3 : RUN chmod +s /root/testnnp
---> Running in c1215bfbe825
---> f1f07d05a691
Removing intermediate container c1215bfbe825
Step 4 : ENTRYPOINT /root/testnnp
---> Running in 5a4d324d54fa
---> 44f767c67e30
Removing intermediate container 5a4d324d54fa
Successfully built 44f767c67e30

下面来做两个实验,先在没有开启 no-new-privileges 的情况下启动容器:

$ docker run -it --rm --user=1000 testnnp
Effective uid: 0

从输出结果来看,只要给可执行文件设置了 SUID 标识,即使我们使用普通用户(UID=1000)来运行容器,进程的有效用户也会变成 root。

接着在开启 no-new-privileges 的前提下启动容器,以防止执行设置了 SUID 标识的可执行文件进行 UID 转换:

$ docker run -it --rm --user=1000 --security-opt=no-new-privileges testnnp
Effective uid: 1000

可以看到,开启了 no_new_privs 属性之后,即使可执行文件设置了 SUID 标识,线程的有效用户 ID 也不会变成 root。这样即使镜像中的代码有安全风险,仍然可以通过防止其提升权限来避免受到攻击。

Kubernetes 也可以开启 no_new_privs,不过逻辑稍微复杂一点。当 Pod 的 SecurityContext 定义下的 allowPrivilegeEscalation 字段值为 false 时(默认就是 false),如果不满足以下任何一个条件,就会开启 no_new_privs 属性:



  • 设置了 privileged=true



  • 增加了 CAP_SYS_ADMIN capabilities,即 capAdd=CAP_SYS_ADMIN



  • 以 root 用户运行,即 UID=0



例如,当设置了 privileged=true 和 allowPrivilegeEscalation=false 时,就不会开启 no_new_privs 属性。同理,设置了 capAdd=CAP_SYS_ADMIN 和 allowPrivilegeEscalation=false 也不会开启 no_new_privs 属性。


管理 capabilities

可以通过 getcap 来查看文件的 capabilities,例如:

$ getcap /bin/ping /usr/sbin/arping
/bin/ping = cap_net_admin,cap_net_raw+p
/usr/sbin/arping = cap_net_raw+p

也可以使用 -r 参数来递归查询:

$ getcap -r /usr 2>/dev/null
/usr/bin/ping = cap_net_admin,cap_net_raw+p
/usr/bin/newgidmap = cap_setgid+ep
/usr/bin/newuidmap = cap_setuid+ep
/usr/sbin/arping = cap_net_raw+p
/usr/sbin/clockdiff = cap_net_raw+p

如果想查看某个进程的 capabilities,可以直接使用 getpcaps,后面跟上进程的 PID:

$ getpcaps 1234

如果想查看一组相互关联的线程的 capabilities(比如 nginx),可以这么来看:

$ getpcaps $(pgrep nginx)

这里你会看到只有主线程才有 capabilities,子线程和其他 workers 都没有 capabilities,这是因为只有 master 才需要特殊权限,例如监听网络端口,其他线程只需要响应请求就好了。

设置文件的 capabilities 可以使用 setcap,语法如下:

$ setcap CAP+set filename

例如,将 CAP_CHOWN 和 CAP_DAC_OVERRIDE capabilities 添加到 permitted 和 effective 集合:

$ setcap CAP_CHOWN,CAP_DAC_OVERRIDE+ep file1

如果想移除某个文件的 capabilities,可以使用 -r 参数:

$ setcap -r filename

2. libcap-ng

安装也很简单,以 CentOS 为例:

$ yum install libcap-ng-utils

用法

libcap-ng 使用 filecap 命令来管理文件的 capabilities。有几个需要注意的地方:



  • filecap 添加删除或查看 capabilities 时,capabilities 的名字不需要带 CAP_ 前缀(例如,使用 NET_ADMIN 代替 CAP_NET_ADMIN);



  • filecap 不支持相对路径,只支持绝对路径;



  • filecap 不允许指定 capabilities 作用的集合,capabilities 只会被添加到 permitted 和 effective 集合。



查看文件的 capabilities:

$ filecap /full/path/to/file

递归查看某个目录下所有文件的 capabilities:

$ filecap /full/path/to/dir

例如:

$ filecap /usr/bin
file capabilities
/usr/bin/newgidmap setgid
/usr/bin/newuidmap setuid

注意: filecap 只会显示“capabilities 被添加到 permitted 和 effective 集合中”的文件。所以这里没有显示 ping 和 arping。


递归查看整个系统所有文件的 capabilities:

$ filecap /
# or
$ filecap -a

设置文件的 capabilities 语法如下:

$ filecap /full/path/to/file cap_name

例如:

$ filecap /usr/bin/tac dac_override

移除某个文件的 capabilities:

$ filecap /full/path/to/file none

3. 总结

本文通过两种工具演示了如何对可执行文件的 capabilities 进行管理,并以 docker 为例,展现了 no_new_privs 的强大之处。如果条件允许,推荐大家以后尽量用 capabilities 来替代完整的 root 权限或者设置 SUID 标识。

http://market.szonline.net/amaz/23467.html
http://market.szonline.net/amaz/23466.html
http://market.szonline.net/amaz/23465.html
http://market.szonline.net/amaz/23464.html
http://market.szonline.net/amaz/23463.html
http://market.szonline.net/amaz/23462.html
http://market.szonline.net/amaz/23461.html
http://market.szonline.net/amaz/23460.html
http://market.szonline.net/amaz/23459.html
http://market.szonline.net/amaz/23458.html
http://market.szonline.net/amaz/23457.html
http://market.szonline.net/amaz/23456.html
http://market.szonline.net/amaz/23455.html
http://market.szonline.net/amaz/23454.html
http://market.szonline.net/amaz/23453.html
http://market.szonline.net/amaz/23452.html
http://market.szonline.net/amaz/23451.html
http://market.szonline.net/amaz/23450.html
http://market.szonline.net/amaz/23449.html
http://market.szonline.net/amaz/23448.html
http://market.szonline.net/amaz/23447.html
http://market.szonline.net/amaz/23446.html
http://market.szonline.net/amaz/23445.html
http://market.szonline.net/amaz/23444.html



推荐阅读
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • Mono为何能跨平台
    概念JIT编译(JITcompilation),运行时需要代码时,将Microsoft中间语言(MSIL)转换为机器码的编译。CLR(CommonLa ... [详细]
  • Linux系统高级网络配置:链路聚合
    链路聚合网卡的链路聚合就是将多块网卡连接起来,当一块网卡损坏,网络依旧可以正常运行,可以有效的防止因为网卡损坏带来的损失,同 ... [详细]
  • uboot与linux驱动1.uboot本身是裸机程序(1)在裸机中本来是没有驱动概念的(狭义的驱动概念是指在操作系统中用来具体操控硬 ... [详细]
  • Linux线程的同步和互斥
    目录1、线程的互斥2、可重入VS线程安全3、线程的同步1、线程的互斥 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 【shell】网络处理:判断IP是否在网段、两个ip是否同网段、IP地址范围、网段包含关系
    本文介绍了使用shell脚本判断IP是否在同一网段、判断IP地址是否在某个范围内、计算IP地址范围、判断网段之间的包含关系的方法和原理。通过对IP和掩码进行与计算,可以判断两个IP是否在同一网段。同时,还提供了一段用于验证IP地址的正则表达式和判断特殊IP地址的方法。 ... [详细]
  • 腾讯安全平台部招聘安全工程师和数据分析工程师
    腾讯安全平台部正在招聘安全工程师和数据分析工程师。安全工程师负责安全问题和安全事件的跟踪和分析,提供安全测试技术支持;数据分析工程师负责安全产品相关系统数据统计和分析挖掘,通过用户行为数据建模为业务决策提供参考。招聘要求包括熟悉渗透测试和常见安全工具原理,精通Web漏洞,熟练使用多门编程语言等。有相关工作经验和在安全站点发表作品的候选人优先考虑。 ... [详细]
  • Centos7搭建ELK(Elasticsearch、Logstash、Kibana)教程及注意事项
    本文介绍了在Centos7上搭建ELK(Elasticsearch、Logstash、Kibana)的详细步骤,包括下载安装包、安装Elasticsearch、创建用户、修改配置文件等。同时提供了使用华为镜像站下载安装包的方法,并强调了保证版本一致的重要性。 ... [详细]
  • 解决Sharepoint 2013运行状况分析出现的“一个或多个服务器未响应”问题的方法
    本文介绍了解决Sharepoint 2013运行状况分析中出现的“一个或多个服务器未响应”问题的方法。对于有高要求的客户来说,系统检测问题的存在是不可接受的。文章详细描述了解决该问题的步骤,包括删除服务器、处理分布式缓存留下的记录以及使用代码等方法。同时还提供了相关关键词和错误提示信息,以帮助读者更好地理解和解决该问题。 ... [详细]
  • Apache Shiro 身份验证绕过漏洞 (CVE202011989) 详细解析及防范措施
    本文详细解析了Apache Shiro 身份验证绕过漏洞 (CVE202011989) 的原理和影响,并提供了相应的防范措施。Apache Shiro 是一个强大且易用的Java安全框架,常用于执行身份验证、授权、密码和会话管理。在Apache Shiro 1.5.3之前的版本中,与Spring控制器一起使用时,存在特制请求可能导致身份验证绕过的漏洞。本文还介绍了该漏洞的具体细节,并给出了防范该漏洞的建议措施。 ... [详细]
  • 本文介绍了使用readlink命令获取文件的完整路径的简单方法,并提供了一个示例命令来打印文件的完整路径。共有28种解决方案可供选择。 ... [详细]
  • const限定符全解一、const修饰普通变量  intconsta500;  constinta600;  上述两种情况相同,都是声明一个const型的变量,它们 ... [详细]
author-avatar
linlidai911_729
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有