文件属性结构如下所示,通过该图我们可以全局把握类 Unix 操作系统的文件属性组成结构,本篇博客不仅会介绍一些常用的属性,还会引申介绍一些容易被忽略的特殊权限。

0x10 文件类型

Linux 第一个字符代表的是文件类型

  • [ d ] -> directory,目录
  • [ - ] -> 普通文件
  • [ l ] -> link,链接文件
  • [ b ] -> block, 块设备,如硬盘和内存
  • [ c ] -> chapter,字符设备,如键盘和鼠标
  • [ s ] -> socket,套接字,即网络流

0x20 文件权限

紧接着为三个一组,每组都是 [rwx] 的组合,表示文件权限,即 read/write/execute,没有权限就是 [ - ]。文件类型和文件属性用 10 个字符来确定。

Linux/Unix 的文件调用权限分为三级 : 文件所有者(Owner)、用户组(Group)、其它用户(Other Users)。

只有文件所有者和超级用户可以修改文件或目录的权限。可以使用绝对模式(八进制数字模式),符号模式指定文件的权限。

0x21 命令行修改文件权限

1 八进制掩码

历史上,曾用 3 位二进制数表示权限 rwx,如下所示,刚好可以表示完所有的权限集合,|r|w|x|,哪一位置 1,表示拥有该权限

# 权限 rwx 二进制
7 读 + 写 + 执行 rwx 111
6 读 + 写 rw- 110
5 读 + 执行 r-x 101
4 只读 r– 100
3 写 + 执行 -wx 011
2 只写 -w- 010
1 只执行 –x 001
0 000

因此 chmod 就可以用简单的八进制掩码来修改文件权限,例如

chmod 777 test.txt       # -rwxrwxrwx,所有人可读可写可执行
chmod 666 test.txt      # -rw-rw-rw-

2 符号模式

符号模式对于初学者可能更加容易记忆,使用符号模式可以设置多个项目:who(用户类型),operator(操作符)和 permission(权限),每个项目的设置可以用逗号隔开。

who 的符号模式表所示:

who 用户类型 说明
u user 文件所有者
g group 文件所有者所在组
o others 所有其他用户
a all 所用用户, 相当于 ugo

operator 的符号模式表:

Operator 说明
+ 为指定的用户类型增加权限
- 去除指定用户类型的权限
= 设置指定用户权限的设置,即将用户类型的所有权限重新设置

permission 的符号模式表:

模式 名字 说明
r 设置为可读权限
w 设置为可写权限
x 执行权限 设置为可执行权限
X 特殊执行权限 只有当文件为目录文件,或者其他类型的用户有可执行权限时,才将文件权限设置可执行
s setuid/gid 当文件被执行时,根据who参数指定的用户类型设置文件的setuid或者setgid权限
t 粘贴位 设置粘贴位,只有超级用户可以设置该位,只有文件所有者u可以使用该位

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 位权限,表示在此目录下只有该文件的所有者或root 可以删除该文件。

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

参数 mode 有下列数种组合:

  • S_ISUID 04000 文件的 (set user-id on execution)位
  • S_ISGID 02000 文件的 (set group-id on execution)位
  • S_ISVTX 01000 文件的sticky 位
  • 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 特殊权限

众所周知,Linux的文件权限如: 777;666等,其实只要在相应的文件上加上UID的权限,就可以用到加权限人的身份去运行这个文件。所以我们只需要将bash复制出来到另一个地方,然后用root加上UID权限,只要用户运行此Shell就可以用用root的身份来执行任何文件了

这种方式可能被用于提权。

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 2月   8 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));}elsefclose(fp);return 0;
}

运行该程序

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

这个问题来源于在 Linux 4.19 内核引入的一个内核参数 this commit ,fs.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: 123Size: 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 +0800Birth: 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 内核新特性。这都是由实际项目中发现的安全问题引发的一些思考。

参考文献

  • Linux chmod命令
  • linux权限补充:rwt rwT rws rwS 特殊权限
  • User root can’t write to file in /tmp owned by someone else in 20.04, but can in 18.04
  • Group permissions for root not working in /tmp
  • https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1877151
  • https://www.techopedia.com/definition/22339/sticky-bit
  • https://en.wikipedia.org/wiki/Sticky_bit

Linux 文件属性及特殊权限详解相关推荐

  1. Linux文件读写改权限详解

    Linux文件读写改权限详解 文件的rwx权限 [ r ] [ w ] [ x ] 该文件可读(read) 该文件可修改(write) 该文件可执行(execute) 注意:只有当该文件所在目录有写权 ...

  2. Linux的用户-组-权限详解

    在Linux中我们可以使用ll或者ls -l命令来显示一个文件的属性以及文件所属的用户和组. 一.用户 1.1.新增用户 useradd luckyboy 会创建同名的组和家目录 1.2.设置密码 p ...

  3. Linux系统中的权限详解

    我们linux服务器上有严格的权限等级,如果权限过高导致误操作会增加服务器的风险.所以对于了解linux系统中的各种权限及要给用户,服务等分配合理的权限十分重要. 一.文件基本权限 首先看下linux ...

  4. linux给目录赋访问权限_【Linux】Linux系统中的权限详解

    我们linux服务器上有严格的权限等级,如果权限过高导致误操作会增加服务器的风险.所以对于了解linux系统中的各种权限及要给用户,服务等分配合理的权限十分重要. 一.文件基本权限 首先看下linux ...

  5. Linux基础之文件权限详解

    Linux中对于权限的制定虽然没有Windows的那么精细,但是如果你了解并掌握Linux中文件的权限知识,也可以像Windows那样对权限做到精确配置. Linux中的文件权限是什么? 如何查看Li ...

  6. linux权限源码分析,Linux基础之文件权限详解

    Linux中对于权限的制定虽然没有Windows的那么精细,但是如果你了解并掌握Linux中文件的权限知识,也可以像Windows那样对权限做到精确配置. Linux中的文件权限是什么? 如何查看Li ...

  7. 【Linux系统】第10节 linux系统文件及目录权限详解

    目录 1 权限 1.1 权限的查看 1.2 权限解读 2 权限修改 2.1 修改文件/目录普通权限 2.1.1 方法1:指定权限修改 2.1.2 方法2:八进制赋权法 2.2 修改文件所属信息 2.3 ...

  8. 1.Linux常见指令及权限详解

    文章目录 前言 基础指令 ls 通配符 cd 绝对路径.相对路径 pwd touch mkdir rm tree --help man cp mv cat more/less echo 重定向 管道| ...

  9. Linux中samba的权限详解,活用三种权限 理解Samba的权限控制

    在企业内网开发环境方面,文件服务器是一个非常重要的环节.在这当中,Samba服务器由于其权限控制的高度灵活性,在这里抚琴煮酒会进行一些列详细的说明.之前我们已经介绍了Samba服务器一些入门和基本的更 ...

最新文章

  1. iOS开发UITableView随笔
  2. spring组键扫描
  3. vue与外部html通信,VUE页面实现加载外部HTML方法
  4. centos自带python2.6升级到python2.7。并解决yum pip easy_install pip等模块兼容性问题
  5. Bailian4128 单词序列【BFS】
  6. python多态_python 多继承及多态
  7. 全图各省市乡镇数据交流
  8. 为什么Eclipse Iceoryx使用Helix QAC
  9. 谷歌地图api根据经纬度查询地名php,在线查询经纬度 google map查询地名返回经纬度 geocode geocoder的完整实例 代码下载...
  10. [网络流24题] 洛谷P3356 火星探险问题 费用流
  11. Google Chrome企业咨询服务市场调研报告- 行业发展机遇、市场定位及主要驱动因素
  12. 基线、底线、顶线、中线
  13. 程序员转行可以做什么?
  14. 输入法中表情和小图标的应用
  15. 计算机启动时老是检测,笔记本电脑开机时总是自检怎么办 【详解】
  16. 手机中Ram和Rom详解
  17. python爬取实习僧招聘信息字体反爬
  18. 华为机试真题 Python 实现【不含 101 的数】【2022.11 Q4新题】
  19. 加入域时提示“不能访问网络位置” 域
  20. Romberg(龙贝格)积分法 | matlab

热门文章

  1. 《四个婚礼和一个葬礼》影评
  2. 【论文精读】TMI2022.FCP-Net
  3. 程序员必知的几种软件架构模式
  4. 使用第三方WheelView制作日期选择器
  5. phpStrom2019 Material Theme UI 主题的安装 超详细教程
  6. hexo的Matery主题优化(三)
  7. Controller层的处理
  8. 甄别集成灶品牌,对比集成灶排名,无边界青年这样构建无界厨房
  9. 一个java程序员的年终总结
  10. hdu 1717 小数化分数2(数学)