Linux权限提升

SUID提权

Linux组管理

linux中的每个用户必须属于一个组,不能独立于组外,在linux中的每个文件都有所有者、所在组、其它组的概念。

  • 所有者

    一般为文件的创建者,谁创建了该文件,就自然的成为该文件的所有者

  • 所在组

    当某个用户创建了一个文件后,这个文件的所在组就是该用户所在的组

  • 其它组

    除文件的所有者和所在组的用户外,系统的其它用户都是文件的其它组

一共有三个用户,jack用户、lisa用户、tom用户,其中jack属于组1、lisa和tom属于组2,tom用户创建了a.txt文件,则a.txt这个文件的所有者、所在组、其它组关系如下:

1619242323291-da2d93ad-826e-49d5-b1e6-9b58066bfd93.png

Linux权限控制

ls -l命令的结果如下:
-rwxrw-r-- 1 root root 1213 Feb 2 09:39 abc
权限 链接数 所有者 所有组 文件大小 文件最后被修改的时间 文件名
-rwxrw-r– 1 root root 1213k Feb 2 09:39 abc
详解-rwxrw-r--

image.png

  • 编号0的含义:第0位确定文件类型(d,-,l,c,b)

    • - 代表普通文件
    • d 是目录,相当于windows文件夹
    • l 是链接,相当于Windows快捷方式
    • c 是字符设备文件,鼠标,键盘
    • b 是块设备文件,比如硬盘
  • 编号1~3含义:确定了该 文件/目录 所有者拥有该 文件/目录 的权限

    • rwx代表文件abc的所有者root对该文件有可读(r)可写(w)可执行(x)的权限
  • 编号4~6含义:确定了该文件所属组对该文件的权限

    • 编号4~6为 rw-

      image.png

      说明组root对文件有可读(r),可写(w),但是没有可执行权限 ( 用 “-” 表示没有权限)

  • 编号7~9含义:代表其它组的用户对该文件的权限

    • image.png

      r--,说其它组对文件abc只是有可读(r)的权限,没有可写和可执行权限

  • 注意:linux下面除了用rwx表示权限之外,还可以用数字表示:r代表4,w代表2,x代表1。如果文件拥有rwx权限就等价于4+2+1=7

UID

在Linux中,经常会遇到各种用户ID(user identifier, UID)和组ID(group identifier, GID),Linux也是通过对这些ID的管理实现的自主访问控制(discretionary access control, DAC)

用户ID(英语:user identifier,一般缩写为User ID或UID),全称用户标识符,在类UNIX系统中是内核用来辨识用户的一个无符号整型数值,亦是UNIX文件系统与进程的必要组成部分之一

虽然我们登录Linux主机时使用的是账户,但是对于Linux系统而言,它只认识ID。而ID与账户的对应就记录在/etc/passwd文件中。可以通过命令id查看各个id与账户名的对应关系:

image-20221129202908954

分类

值得注意的是,以下的分类都是针对进程而言的,只有进程才会有下述几种ID

中文 英文
真实用户ID Real UID(RUID)
有效用户ID Effective UID(EUID)
暂存用户ID Saved UID(SUID)
  • RUID

    对于进程而言,创建该进程的用户的UID为此进程的RUID,比如:这里以lisa用户执行./exp创建了进程exp,所以进程exp的RUID即为lisa用户的UID,即执行id命令后得到uid值

  • EUID

    主要用于二进制可执行文件的权限检查,对于一个可执行的二进制文件,文件能否执行就是取决于EUID,一般情况下,EUID=RUID

  • SUID

    一般情况下,SUID=EUID,设置SUID后,可以让文件以文件所有者的权限来执行

RUID、EUID、SUID的深入理解

以lisa用户创建文件exp.c,来输出进程的ruid、euid、suid的值,内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(){
	int ruid,euid,suid;
	getresuid(&ruid,&euid,&suid);
	printf("ruid=%d,euid=%d,suid=%d\n",ruid,euid,suid);
    pause();	//暂停,为了进程一直运行
	return;
}

然后用gcc编译并执行,发现了进程exp的ruid、euid、suid都是1001,如下:

image-20221129220223207

注意:查看正在运行的进程的ruid、euid、suid还可以用ps -ax -o ruid -o euid -o suid -o pid -o fname,如下:

image-20221129220945269

为文件exp设置suid,如下:

image-20221129221204398

然后让用户tom运行,发现ruid是tom用户的uid,而euid和suid是lisa用户的uid,如下:

image-20221129221455047

SUID实例分析

/etc/passwd文件用来存储所有的用户信息,任何用户都可以修改自己的密码。显然,其它用户在执行/usr/bin/passwd命令时修改了/etc/passwd文件。但是,查看/etc/passwd文件的权限,发现root用户对该文件有写入权限,而普通用户对该文件仅有读的权限,那么具体是什么原因导致用户可以修改/etc/passwd文件呢 ?

image-20221129223641514

查看/usr/bin/passwd文件的权限,发现该文件被设置了suid位,如下:

image-20221129223817192

那么普通用户在执行/usr/bin/passwd时,就拥有了等同于文件"/usr/bin/passwd"的拥有者root的权限,而root用户对/etc/passwd文件有写权限,因此普通用户也具有了写权限,进而可以通过/usr/bin/passwd来修改/etc/passwd文件的内容。

我们查看当前正在进行进程passwd,发现其euid和suid都是0,也就是root用户的uid,如下:

image-20221129224714505

如果清除掉/usr/bin/passwd的suid权限位,普通用户就无法修改自己的密码,如下:

image-20221129225741298

对于常用函数setuid(0)的说明

setuid()用来重新设置执行目前进程的用户识别码。不过,要让此函数有作用,其有效的用户识别码必须为0(root)

在Linux下,当root 使用setuid()来变换成其他用户识别码时,root权限会被抛弃,完全转换成该用户身份,也就是说,该进程往后将不再具有可setuid()的权 利,如果只是向暂时抛弃root 权限,稍后想重新取回权限,则必须使用seteuid()

image-20221202172119886

劫持环境变量提权

变量是计算机系统用于保存可变值的数据类型,我们可以直接通过变量名称来提取到对应的变量值。在 Linux 系统中,环境变量是用来定义系统运行环境的一些参数

环境变量的分类如下:

  • 按生命周期分:

    • 永久的:在环境变量脚本文件中配置,用户每次登录时会自动执行这些脚本,相当于永久生效
    • 临时的:用户利用export命令,在当前终端下声明环境变量,关闭Shell终端失效
  • 按作用域分:

    • 系统环境变量:公共的,对全部的用户都生效
    • 用户环境变量:用户私有的、自定义的个性化设置,只对该用户生效

环境变量相关的常用命令如下:

1
2
3
4
5
6
env:查看当前用户全部的环境变量
env|grep 环境变量名:筛选包含的环境变量
export:显示当前系统定义的所有环境变量
printenv 环境变量名:查看指定环境变量的值
echo $环境变量名:查看指定环境变量的值
unset 环境变量名:清除指定环境变量

常用环境变量 PATH

PATH是Linux和类Unix操作系统中的环境变量,它指定存储可执行程序的所有bin和sbin目录。当用户在终端上执行任何命令时,它会通过PATH变量来响应用户执行的命令,并向shell发送请求以搜索可执行文件。超级用户通常还具有/sbin和/usr/sbin条目,以便于系统管理命令的执行

1
2
3
4
5
[lisa@XXYhost ~]$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/lisa/.local/bin:/home/lisa/bin

# 说明:
# 冒号为分隔符,在Windows上的PATH环境变量用分号做分隔符
PATH提权Demo

查找具有SUID权限 的二进制可执行文件,发现可以shell文件

image-20221202172738385

然后用xxd或strings来分析该文件,执行xxd shell后,发现了ps命令

image-20221202173407658

然后进行提权

image-20221202173708354

注意:其实二进制文件shell是由shell.c编译而来,shell.c源码如下:

1
2
3
4
5
6
7
8
9
#include<unistd.h>
#include<stdio.h>
void main()
{
    setuid(0);
    setgid(0);
    system("ps");
    return;
}

Sudo提权

参考:sudo提权—Vir-k

sudo是linux系统管理指令,是允许系统管理员让普通用户执行一些或者全部的root命令的一个工具

并非每个用户都可以使用sudo命令,如下:

image-20221202210419397

要想让一个用户能够执行sudo命令,需要让root用户把这个用户的名字、可以执行的特定命令、按照哪种用户或用户组的身份执行等信息注册到/etc/sudoers文件中,即完成对该用户的授权(此时该用户称为suoder)才可以

查看sudoers文件的内容,如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[root@XXYhost ~]# vim /etc/sudoers
/sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool
Defaults   !visiblepw
Defaults    always_set_home
Defaults    match_group_by_gid
Defaults    always_query_group_plugin
Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
root	ALL=(ALL) 	ALL
%wheel	ALL=(ALL)	ALL

在sudoers文件中添加如下内容,给予lisa用户全部root权限,让lisa用户能够通过sudo以root用户权限执行任何命令

在sudoers文件的root ALL=(ALL) ALL下添加
lisa ALL(ALL:ALL) ALL
image-20221203191316709.png

在sudoers文件中添加如下内容,给予lisa用户部分root权限,让lisa用户能够通过sudo以root用户权限执行部分命令

在sudoers文件的root ALL=(ALL) ALL下添加

lisa ALL=(root) NOPASSWD: /usr/bin/find

lisa ALL=(root) NOPASSWD: /usr/bin/awk

lisa ALL=(root) NOPASSWD: /usr/bin/git

image-20221203192851221

find提权

1
2
[lisa@XXYhost ~]$ sudo find /home -exec /bin/bash \;
[root@XXYhost lisa]# 

awk提权

1
2
[lisa@XXYhost ~]$ sudo awk 'BEGIN{system("/bin/bash")}'
[root@XXYhost lisa]# 

git提权

1
2
3
[lisa@XXYhost ~]$ sudo git help add
#然后回车输入 !/bin/bash 再次回车即可完成提权
[root@XXYhost man]# 

可sudo提权的命令

wget、find、cat、apt、zip、xxd、time、taskset、git、sed、pip、ed、tmux、scp、perl、bash、less、awk、man、vi、env、ftp、ed、screen

Ssh密钥提权

运维人员如果在服务器上使用ssh-keygen命令生成密钥对(id_rsa、id_rsa.pub),然后采用此密钥对进行远程登录,那么当他忘记把私钥(id_rsa)删除,且文件权限可读,黑客就可以使用这个私钥进行用户登录,达到用户水平越权或者权限提升到 root

Ssh 登陆的大致流程:

  • ServerA
    • 在 ServerA 上生成一对密钥 id_rsa、id_rsa.pub
    • 将公钥(id_rsa.pub)拷贝给 ServerB,并且重命名为 authorized_keys
    • ServerA 向 ServerB 发送一个连接请求
  • ServerB
    • ServerB 收到 ServerA 的请求后,ServerB 会随机生成一个字符串,假如这个字符串是 asdf
    • ServerB 使用公钥 authorized_keys 对字符串 asdf 进行加密,然后发送给 ServerA
  • ServerA
    • ServerA 收到 ServerB 发来的加密字符串后,会使用私钥 id_rsa 对字符串进行解密,然后将解密后的字符串再发送给 B
  • ServerB
    • 接受到解密后的字符串后,会与先前随机生成的字符串 asdf 进行对比,如果一致,就允许免密登陆

如果我们能够拿到 root 用户对应密钥对,就可通过 ssh 登陆到 root 用户

可写的Passwd提权

参考:https://blog.csdn.net/tomyyyyyy/article/details/115714221

/etc/passwd 中一行记录对应着一个用户, 其文件格式和具体文件如下:

  • 用户名 : 口令 : 用户标识号 : 组标识号 : 注释性描述 : 主目录 : 登录Shell

    详情见:https://www.yuque.com/xxxws/hudb8d/rceums

提权步骤:

  1. 普通用户对于 passwd 文件必须有可写的权限

    image-20230302100041540

  2. 将带有加密字符的信息

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    #利用openssl生成加密的密码, 语法:openssl passwd-1-salt[salt value]password
    openssl passwd -1 -salt user3 pass123
    
    #mkpasswd类似于openssl passwd,它将生成指定密码字符串的哈希值。
    mkpasswd -m SHA-512 pass
    
    #利用python中的crypt库生成
    python -c 'import crypt; print crypt.crypt("pass", "$6$salt")'
    
    #利用Perl和crypt来使用salt值为我们的密码生成哈希值
    perl -le 'print crypt("pass123", "abc")'
    
    #php语言
    php -r "print(crypt('aarti','123') . " ");"

    image-20230302100239073

  3. 然后将生成的密码按照一定格式添加到 /etc/passwd

    image-20230302100344628

  4. 然后通过用户名 test、密码 password@123 登陆主机后,即为 root 权限

计划任务提权

定时任务(cron job)可以用来设置周期执行的命令,提权的原理为计划任务以root权限运行,计划任务中的脚本其他用户有写入的权限,或者脚本所属组为其他用户,则可以进行计划任务提权

crond 任务调度

在 linux 下面有一个叫 crond 的后台程序,它可以定时去调度我们设置的任务

任务调度:是指系统在某个时间执行特定的命令或者程序

任务调度分类:

  • 系统工作:有些重要的工作必须周而复始地执行,如病毒扫描
  • 个别用户工作:个别用户可能希望执行某些程序,比如对mysql数据库的备份

注意:crond是工具,是linux的一个定时执行的服务项,可以通过crontab 命令添加或者编辑需要定时执行的任务

基本语法如下:

  • crontab 【选项】

    -e:编辑 crontab 定时任务

    -l:查询 crontab 任务

    -r:删除当前用户所有的 crontab 任务

第三方 组件/服务 提权

NFS提权

MOF提权

启动项提权

反弹端口提权

Mysql提权

CVE-2016-6663、CVE-2016-6664提权

Docker提权

内核漏洞提权

DirtyCow(CVE-2016-5195)

DirtyPipe(CVE-2022-0847))

Polkit提权

 微信 微信
0%