SUID特权进程
# SUID,SGID
set user ID
设置用户 ID
set group Id
设置组 ID
[root@jb51 process]# ls -al demo1.c
-rw-r--r-- 1 root root 239 Mar 31 22:26 demo1.c
2
-
:代表是普通文件rw-
:代表是root
用户的可读可写后面只有读权限
当特殊标志
s
这个字符出现在文件拥有者的x
权限位的时候就叫set UID
,简称SUID
,或是叫SUID
特权如果出现在组的权限位的时候就叫
SGID
一个特殊的文件
[root@jb51 process]# ls -al /bin/passwd
-rwsr-xr-x 1 root root 27856 Apr 1 2020 /bin/passwd
2
这个文件是ELF
可执行文件
[root@jb51 process]# file /bin/passwd
/bin/passwd: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=dee1b9ab6618c6bfb84a14f85ba258c742cf4aec, stripped
2
# SUID,SGID 的用途
一般来说,以
root
用户启动的程序都是超级进程,它这种进程权限特别大,一般来说都是一些重要的服务程序,有时候我们经常是以普通用户来执行程序的,比如:web
目录一般是以www
用户。但有时候普通进程需要访问一些特殊的资源,这个时候就需要提升权限来访问,比如修改密码之后普通用户来查看密码文件。
[root@jb51 process]# ls -al /etc/shadow
---------- 1 root root 842 Apr 8 12:53 /etc/shadow
2
这里可以看出普通用户是没有任何权限的。但是普通用户是可以通过/bin/passwd
这个ELF
可执行文件来修改/etc/shadow
文件以达到修改密码,但不可以直接去修改密码文件。
这个程序你之所以可以使用,是因为有一个s
在x
权限位,特权,你才能进行修改。
如何设置SUID
:
就在可执行文件的权限
x
位上设置chmod u/g/o + s (elf file 即ELF文件)
我们可以使用root
用户创建一个pwd.txt
文件,切换普通用户去测试。
这里我们还写了一个可执行文件,使用c
语言写一个文件的设置特权的代码。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
char *fileName = "pwd.txt";
int uid = getuid();
int euid = geteuid();
printf("uid: %d, euid: %d\n", uid, euid);
setuid(euid)
seteuid(euid);
uid = getuid();
euid = geteuid();
printf("uid=%d, euid=%d\n", uid, euid);
if (access(fileName, W_OK) == 0)
{
printf("我能修改此文件\n");
}
else
{
printf("我不能修改此文件\n");
}
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
然后对其进行编译得到可执行文件pwd
,然后使用linux
创建一个新的用户,切换,使用pwd
可执行文件来运行即可。
我们来使用php
来重写一下:
<?php
$file = "pwd.txt";
$uid = posix_getuid();
$euid = posix_geteuid();
fprintf(STDOUT, "uid: %d, euid: %d\n", $uid, $euid);
// 这样设置是不行的
posix_setuid($euid);
posix_seteuid($euid);
// 判断是否可以写
if (posix_access($file, POSIX_W_OK)) {
fprintf(STDOUT, "File %s is writable\n", $file);
} else {
fprintf(STDOUT, "File %s is not writable\n", $file);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@jb51 process]# php demo_12.php
uid: 0, euid: 0
File pwd.txt is writable
2
3
现在demo12.php
并不是可执行文件,只是一个普通的文本文件,是无法直接执行的。如果直接使用chmod u+s demo12.php
是不行的,权限位会变成大写的S
,毫无意义,所以还是需要改回来,chmod u-s demo12.php
,所以说,我们应该在php
的解释器的可执行文件,chmod u+s /usr/bin/php
设置SUID
,然后以普通用户执行php demo12.php
即可修改。
我们可以加上一段代码来进行测试
<?php
$file = "pwd.txt";
// 当前账号uid
$uid = posix_getuid();
$euid = posix_geteuid();
fprintf(STDOUT, "uid: %d, euid: %d\n", $uid, $euid);
// 这样设置是不行的
posix_setuid($euid);
posix_seteuid($euid);
// 提权,【修改权限以便能访问特殊资源】
$uid = posix_getuid();
$euid = posix_geteuid();
fprintf(STDOUT, "uid: %d, euid: %d\n", $uid, $euid);
// 判断是否可以写
if (posix_access($file, POSIX_W_OK)) {
fprintf(STDOUT, "File %s is writable\n", $file);
$fd = fopen($file, "a");
fwrite($fd, "php is the best!\n");
fclose($fd);
} else {
fprintf(STDOUT, "File %s is not writable\n", $file);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
然后进行查看文件是否真得改了。
[root@jb51 process]# php demo_12.php
uid: 1001, euid: 0
File pwd.txt is writable
[root@jb51 process]# cat pwd.txt
hello world
php is the best!
2
3
4
5
6
注意
平常开发,程序一般是以普通用户启动的进程,它是无法访问需要权限的资源的,所以我们通过SUID
提权以便能访问需要权限的资源。
注意:提权访问完之后,一定要改回来,改回普通用户,后果可能会很严重!在编写特权进程时,提权访问资源之后一定要改回来!