Linux 파일 속성 및 특수 권한에 대한 자세한 설명

파일 속성 구조는 아래와 같습니다. 이 그림을 통해 우리는 Unix 계열 운영 체제의 파일 속성 구조를 전반적으로 파악할 수 있습니다. 이 블로그에서는 일반적으로 사용되는 몇 가지 속성을 소개할 뿐만 아니라 쉽게 사용할 수 있는 몇 가지 특수 권한도 소개합니다. 간과.

여기에 이미지 설명을 삽입하세요.

0x10 파일 형식

Linux 첫 번째 문자는 파일 형식을 나타냅니다.

  • [ d ] -> 디렉토리, 디렉토리
  • [ - ] -> 일반 파일
  • [ l ] -> 링크, 링크 파일
  • [ b ] -> 블록, 하드디스크, 메모리 등 블록 장치
  • [ c ] -> 장, 키보드, 마우스 등의 문자장치
  • [ s ] -> 소켓, 소켓, 네트워크 스트림

0x20 파일 권한

3개의 그룹이 이어지며, 각 그룹은 파일 권한을 나타내는 [rwx]의 조합입니다 . 즉 read/write/execute, 권한이 없으면 [-]입니다. 파일 유형과 파일 속성은 10자로 식별됩니다.

Linux/Unix 파일 호출 권한은 파일 소유자(Owner), 사용자 그룹(Group), 기타 사용자(Other Users)의 세 가지 수준으로 구분됩니다.
여기에 이미지 설명을 삽입하세요.

파일 소유자와 수퍼유저만 파일이나 디렉토리의 권한을 수정할 수 있습니다 . 절대 모드(8진수 모드)와 기호 모드를 사용하여 파일 권한을 지정할 수 있습니다.

여기에 이미지 설명을 삽입하세요.

0x21 파일 권한을 수정하는 명령줄

1개의 옥탈 마스크

역사적으로 3자리 이진수는 아래와 같이 권한 rwx를 나타내는 데 사용되었습니다. 이는 모든 권한 집합 |r|w|x|를 나타낼 수 있으며 위치는 1이며 권한이 있음을 나타냅니다.

# 권한 rwx 바이너리
7 읽기+쓰기+실행 rwx 111
6 읽기 + 쓰기 rw- 110
5 읽기+실행 RX 101
4 읽기 전용 아르 자형- 100
쓰기 + 실행 -wx 011
2 그냥 써 -w- 010
1 실행만 -엑스 001
0 없음 000

따라서 chmod는 간단한 8진수 마스크를 사용하여 파일 권한을 수정할 수 있습니다.

chmod 777 test.txt		# -rwxrwxrwx,所有人可读可写可执行
chmod 666 test.txt		# -rw-rw-rw-
2 기호 모드

초보자가 기억하기 쉬운 기호 모드는 누구(사용자 유형), 운영자(운영자), 권한(허가) 등 여러 항목을 설정할 수 있으며, 각 항목에 대한 설정은 쉼표로 구분할 수 있습니다.

who에 대한 기호 패턴 테이블은 다음과 같습니다.

WHO 사용자 유형 설명하다
u 사용자 파일 소유자
g 그룹 파일 소유자 그룹
o 다른 사람 다른 모든 사용자
a 모두 사용된 사용자는 ugo 와 동일합니다.

연산자에 대한 기호 패턴 테이블:

운영자 설명하다
+ 지정된 사용자 유형에 권한 추가
- 지정된 사용자 유형에서 권한 제거
= 지정된 사용자 권한에 대한 설정을 지정합니다. 즉, 사용자 유형에 대한 모든 권한을 재설정합니다.

심볼 패턴 허가표:

모델 이름 설명하다
r 읽다 읽기 권한으로 설정
w 쓰다 쓰기 가능한 권한으로 설정
x 실행 권한 실행 권한으로 설정
X 특별 실행 권한 파일이 디렉터리 파일이거나 다른 유형의 사용자에게 실행 권한이 있는 경우에만 파일 권한을 실행 가능으로 설정합니다.
s setuid/gid 파일이 실행되면 who 매개변수에 지정된 사용자 유형에 따라 파일의 setuid 또는 setgid 권한이 설정됩니다.
t 비트 붙여넣기 붙여넣기 비트를 설정하세요. 슈퍼유저만 이 비트를 설정할 수 있습니다. 파일 소유자만 이 비트를 사용할 수 있습니다.

chmod 명령 예

chmod ugo+r test.txt	# -rwxrwxrwx,所有人可读可写可执行

0x22 코드 수정 파일 권한

Linux에서는 파일 권한 수정을 위한 시스템 호출을 제공합니다 chmod(Linux 프로그래밍 매뉴얼 참조 man 2 chmod).권한 수정을 위해 제공되는 기능은 다음과 같습니다.

#include <sys/stat.h>

int chmod(const char *pathname, mode_t mode);
int fchmod(int fd, mode_t mode);

#include <fcntl.h>           /* Definition of AT_* constants */
#include <sys/stat.h>

int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags);

chmod이 함수는 파일 이름과 수정 권한만 제공하면 되며, fchmod사용하기 전에 먼저 파일을 열고 파일 핸들을 얻어야 합니다. 시스템 보안에 따라 실행 파일에 데이터를 쓰려고 하고 실행 파일에 S_ISUID 또는 S_ISGID 권한이 있는 경우 이 두 비트가 지워집니다. 디렉터리에 S_ISUID 비트 권한이 있으면 이 디렉터리에 있는 파일의 소유자나 루트만 파일을 삭제할 수 있음을 의미합니다.

chmod("/testdir/aaa.txt", S_IRUSR|S_IWUSR|S_IRGRP|S_IRGRP|S_IROTH|S_IWOTH);	// 666o

매개변수 모드에는 다음과 같은 조합이 있습니다.

  • S_ISUID 04000 파일(실행 시 사용자 ID 설정) 비트
  • S_ISGID 02000 파일(실행 시 그룹 ID 설정) 비트
  • S_ISVTX 01000 파일의 고정 비트
  • S_IRUSR (S_IREAD) 00400 파일 소유자에게 읽기 권한이 있습니다.
  • S_IWUSR (S_IWRITE)00200 파일 소유자에게 쓰기 권한이 있습니다
  • S_IXUSR (S_IEXEC) 00100 파일 소유자에게 실행 권한이 있습니다
  • S_IRGRP 00040 사용자 그룹에 읽기 권한이 있습니다.
  • S_IWGRP 00020 사용자 그룹에 쓰기 권한이 있습니다.
  • S_IXGRP 00010 사용자 그룹에 실행 권한이 있습니다.
  • S_IROTH 00004 다른 사용자에게 읽기 권한이 있습니다.
  • S_IWOTH 00002 다른 사용자에게 쓰기 권한이 있습니다.
  • S_IXOTH 00001 다른 사용자에게 실행 권한이 있습니다.

예를 들어 IDA를 되돌릴 때 mode매개변수를 8진수 표현으로 수정해야 해당 권한을 쉽게 확인할 수 있습니다.

여기에 이미지 설명을 삽입하세요.

0x30 파일 소유자

Linux/Unix는 다중 사용자, 다중 작업 운영 체제이며 모든 파일에는 소유자가 있습니다. chown을 사용하여 지정된 파일의 소유자를 지정된 사용자 또는 그룹으로 변경합니다. 사용자는 사용자 이름 또는 사용자 ID( UID )일 수 있습니다. 그룹은 그룹 이름 또는 그룹 ID( GID )일 수 있습니다. 파일은 다음으로 구분됩니다. 권한을 변경하기 위한 공백 파일 목록, 와일드카드 문자 지원

1. chgrp: 파일 그룹 변경

chgrp [OPTION]... GROUP FILE...

공통 매개변수

  • -R, 파일 그룹을 재귀적으로 변경합니다. 디렉토리의 그룹을 변경하면 해당 디렉토리에 있는 모든 파일의 그룹이 변경됩니다. 이 매개변수는 다른 Linux 명령에서도 자주 사용됩니다.

2. chown: 파일 소유자/그룹 변경

chown [OPTION]... [OWNER][:[GROUP]] FILE...

0x40 특별 권한

우리 모두 알고 있듯이, 리눅스 파일 권한은 777, 666 등과 같습니다. 실제로 해당 파일에 UID 권한만 추가하면 해당 파일은 권한을 추가한 사람으로 실행할 수 있습니다. 따라서 bash를 다른 위치에 복사한 다음 루트를 사용하여 UID 권한을 추가하면 됩니다. 사용자가 이 셸을 실행하는 한 루트로 모든 파일을 실행할 수 있습니다.

이 방법은 권한을 승격하는 데 사용될 수 있습니다.

0x41 setuid/setgid(rws)

일반적으로 파일을 호출하는 사람은 파일 소유자의 권한 만 갖습니다 . 이는 파일 속성에 지정되어 있습니다. 예를 들어, 일반 사용자가 자신의 비밀번호를 변경하려고 하는데 비밀번호 구성을 저장하는 파일이 일반 사용자가 쓸 수 없다는 것을 알게 되면 이론적으로 일반 사용자는 자신의 비밀번호도 변경할 수 없습니까?

$ ls -lh /etc/passwd
-rw-r--r-- 1 root root 3.2K Jan 14 11:30 /etc/passwd

그리고 setuid/ 는 이 설정을 변경할 수 있습니다. 이는 프로그램이 실행 중일 때 파일 소유자를 변경하는setgid 것과 같습니다 . 비밀번호 변경에 사용되는 바이너리를 살펴보겠습니다.

$ ls -lh /usr/bin/passwd
-rwsr-xr-x 1 root root 63K Feb  7  2020 /usr/bin/passwd

用户属主的权限位 x 是 s,这里的 s 意思是其他用户运行此命令时,会临时具有 root 用户的权限运行此文件

  • setuid:让普通用户可以以 root 用户的角色运行只有 root 帐号才能运行的程序或命令
  • setgid:该权限只对目录有效。目录被设置该位后,任何用户在此目录下创建的文件都具有和该目录所属的组相同的组

0x42 Sticky Bit (rwt)

In Unix-like operating systems, a sticky bit is a permission bit which is set on a file or folder, thereby permitting only the owner or root user of the file or folder to modify, rename or delete the concerned directory or file. No other user would be permitted to have these privileges on a file which has a sticky bit. In Unix-like systems, without the sticky bit on, any user can modify, rename or delete the directory or file regardless of the owner of the file or folder.

类 Unix 操作系统中的文件权限,读写可执行,其中的写和执行权限,就代表了重命名、删除文件的权限。而设置了 Sticky Bit 的文件,只有文件、目录所有者或者 root 才能够有权限重命名或删除该文件。

例如 Linux 文件系统根目录下的 tmp 目录

$ ls -lh / | grep tmp 
drwxrwxrwt  13 root root  12K Feb  8 15:09 tmp

如果本来该位上有 x,则特殊位显示小写字母(s, s, t),否则显示大写字母(S,S,T)。即 rws/rwS

0x43 延伸:具有写权限却不能写入文件

某天在测试某个设备时,突然发现一个问题,明明对该文件具有写的权限,但是却不能写入信息

$ ls -lh /tmp/my.log 
-rw-rw-rw- 1 lys  lys     0 28 15:48 my.log

我们是以 jerry 的身份修改 my.log ,代码如下

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>

int main(int argc, char const *argv[])
{
    
    
	char *name = "/tmp/my.log";
	FILE *fp = fopen(name, "a+");
	if(fp == NULL) {
    
    
		fprintf(stderr, "Couldn't open: %s: %s\n", name, strerror(errno));
	}
	else
		fclose(fp);
	return 0;
}

运行该程序

$ ./test
Couldn't open: /tmp/my.log: Permission denied

这个问题来源于在 Linux 4.19 内核引入的一个内核参数 this commitfs.protected_regular,用于禁止在全局可写 Sticky Bit 目录中打开不属于用户的 FIFO 或常规文件。相关文档位于 Documentation/sysctl/fs.txt

protected_fifos:

The intent of this protection is to avoid unintentional writes to an attacker-controlled FIFO, where a program expected to create a regular file.

protected_regular:

This protection is similar to protected_fifos, but it avoids writes to an attacker-controlled regular file, where a program expected to create one.

When set to “0”, writing to regular files is unrestricted.

When set to “1” don’t allow O_CREAT open on regular files that we don’t own in world writable sticky directories, unless they are owned by the owner of the directory.

When set to “2” it also applies to group writable sticky directories.

即这个保护可以用以下命令关闭

sysctl fs.protected_regular=0

这个特性用于缓解以下漏洞

  • CVE-2000-1134
  • CVE-2007-3852
  • CVE-2008-0525
  • CVE-2009-0416
  • CVE-2011-4834
  • CVE-2015-1838
  • CVE-2015-7442
  • CVE-2016-7489

由于一些开发者没有注意到该特性,会导致一些空指针问题,例如如下代码
여기에 이미지 설명을 삽입하세요.

当一个用户运行此程序,会试图创建该文件,并将该文件的权限修改为 -rw-rw-rw- 。当另外一个用户运行此程序,按照正常逻辑,该文件已经存在,因此不需要创建,直接就会打开,但是其实是空指针。fclose 时报错。

0x50 索引节点

0x51 inode

索引节点的英文名 inode(index node),其实输入命令 ls -li 就可以看到文件的索引节点。

ls -lhi ~
total 617M
2360250 -rw-r--r--  1 lys lys    0 Jan  6 17:47 123
2360331 -rwxr-xr-x  1 lys lys  68M Apr 15  2021 code_1.55.2-1618307277_amd64.deb

Linux 文件系统类型有 ext2/3/4,每个存储设备或分区被格式化后,创建为一个新的文件系统,其实这个过程包含两部分:创建 inode,创建 block。inode 用于定位文件位置,block 用于存放实际的文件内容。inode 就是一块存储空间,不同操作系统默认大小不一样。

查看文件系统分区及类型

$ df -Th                                       
Filesystem       Type      Size  Used Avail Use% Mounted on
udev             devtmpfs  3.9G     0  3.9G   0% /dev
tmpfs            tmpfs     797M  996K  796M   1% /run
/dev/sda1        ext4       62G   56G  3.0G  95% /
tmpfs            tmpfs     3.9G     0  3.9G   0% /dev/shm
tmpfs            tmpfs     5.0M     0  5.0M   0% /run/lock
tmpfs            tmpfs     4.0M     0  4.0M   0% /sys/fs/cgroup
tmpfs            tmpfs     797M   56K  797M   1% /run/user/1000

查看指定文件 inode

$ stat 123       
  File: 123
  Size: 5               Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d      Inode: 2360250     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/     lys)   Gid: ( 1000/     lys)
Access: 2022-01-14 20:06:21.610734953 +0800
Modify: 2022-02-08 20:36:41.541211863 +0800
Change: 2022-02-08 20:36:41.541211863 +0800
 Birth: 2022-01-06 20:47:18.455172720 +0800

查看系统分区 inode 使用情况

$ df -i 
Filesystem        Inodes   IUsed   IFree IUse% Mounted on
udev             1010848     381 1010467    1% /dev
tmpfs            1019341     628 1018713    1% /run
/dev/sda1        4136960 1265184 2871776   31% /
tmpfs            1019341       1 1019340    1% /dev/shm
tmpfs            1019341       2 1019339    1% /run/lock
tmpfs               1024      17    1007    2% /sys/fs/cgroup
tmpfs             203868      65  203803    1% /run/user/1000

查看文件系统 inode 大小

sudo dumpe2fs /dev/sda1 | grep -i "inode size"
dumpe2fs 1.45.6 (20-Mar-2020)
Inode size:               256

查看文件系统 block 大小

$ sudo dumpe2fs /dev/sda1 | grep -i "block size"
dumpe2fs 1.45.6 (20-Mar-2020)
Block size:               4096

0x52 block

硬盘存储的最小单位是扇区(sector),每个扇区存储 512B。Linux 内核使用块(block)作为最小寻址单元,也就是说操作系统一次性会连续读取多个扇区,这些扇区组成了一个块。 block 的大小是 sector 的 2^n 次方倍(n 可以为 0),但是不大于 page size。常见的 block 大小为 512Bytes,1KB,4KB

查看每个分区 block 数量

$ df -l /dev/sda1   
Filesystem     1K-blocks     Used Available Use% Mounted on
/dev/sda1       64806500 58404920   3079828  95% /

查看指定分区的扇区、磁道、柱面、磁头等信息,磁盘的容量=磁头*磁道*扇区(512B)*柱面

$ sudo fdisk -l /dev/sda1                                                                     1 ⨯
Disk /dev/sda1: 63.04 GiB, 67693969408 bytes, 132214784 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

总结

Linux 系统是一种典型的多用户操作系统,不同用户处于不同地位,拥有不同权限。为保护系统安全,不同用户对同一文件的访问权限做了不同规定。我们在这里讨论了常见的文件属性,也讲述其中的一些特殊权限。并结合一些实际案例(拥有写权限却不能写入文件)介绍 Linux 内核新特性。这都是由实际项目中发现的安全问题引发的一些思考。

参考文献

추천

출처blog.csdn.net/song_lee/article/details/122827879