最近再弄应急方面的内容,find 好久没用了,写篇文章备忘。
本篇文章参考:
find 基本用途 find 概述
在官方 Man 手册中,find 的作用是:在目录层次结构中搜索文件。
命令使用结构如下:
1 find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]
find 选项
由于 find 选项过于多了,这里只挑我经常用到或者看到的。
–help
find --help
是一个在类Unix操作系统中使用的命令,用于显示 find
命令的帮助手册或文档。
find --help
更多的是用法而不是说明,示例如下:
1 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 32 33 34 35 [root@localhost ~]# find --help Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression] default path is the current directory; default expression is -print expression may consist of: operators, options, tests, and actions: operators (decreasing precedence; -and is implicit where no others are given): ( EXPR ) ! EXPR -not EXPR EXPR1 -a EXPR2 EXPR1 -and EXPR2 EXPR1 -o EXPR2 EXPR1 -or EXPR2 EXPR1 , EXPR2 positional options (always true): -daystart -follow -regextype normal options (always true, specified before other expressions): -depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf --version -xautofs -xdev -ignore_readdir_race -noignore_readdir_race tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N -cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME -ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN -links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE -nouser -nogroup -path PATTERN -perm [-/]MODE -regex PATTERN -readable -writable -executable -wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N -used N -user NAME -xtype [bcdpfls] -context CONTEXT actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print -fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit -exec COMMAND ; -exec COMMAND {} + -ok COMMAND ; -execdir COMMAND ; -execdir COMMAND {} + -okdir COMMAND ; Report (and track progress on fixing) bugs via the findutils bug-reporting page at http://savannah.gnu.org/ or, if you have no web access, by sending email to <bug-findutils@gnu.org>.
注:如果要查看详细的说明文档,建议使用 man find。
-xtime
-atime
-atime 用于匹配文件的访问时间。
匹配访问时间精确为 n 天的文件:
1 find /path/to/directory -atime n
1 find /path/to/directory -atime +n
1 find /path/to/directory -atime -n
-ctime
-mtime
-newerxt -newermt
-newermt:用于查找在指定时间之后修改过的文件。
在根目录及其子目录中搜索类型为文件的文件,并且其修改时间在 2023 年 11 月 1 日 00:00:00 之后,并且在 2023 年 11 月 3 日 23:59:59 之前:
1 2 3 [root@localhost ~]# find / -type f -newermt "2023-11-01 00:00:00" -a ! -newermt "2023-11-03 23:59:59" find: ‘/proc/48553/task/48553/fdinfo/5’: No such file or directory find: ‘/proc/48553/fdinfo/6’: No such file or directory
-newerat
与 -newermt 同理,用于查找访问时间在指定时间之后的文件。
-newerct
与 -newermt 同理,用于查找状态改变时间在指定时间之后的文件。
-name
find 命令在没有指定其他选项和参数时,它会从当前目录开始搜索,并列出当前目录及其子目录中的所有文件和目录。
使用 -name 用于根据文件名来匹配搜索结果:
1 2 3 [root@localhost ~]# cd /etc ; find -name passwd ./pam.d/passwd ./passwd
1 2 3 4 5 6 7 8 9 [root@localhost etc]# cd /etc ; find -name 'passwd*' ./pam.d/passwd ./passwd ./passwd- [root@localhost etc]# cd /etc ; find -name '*.txt' ./pki/nssdb/pkcs11.txt ./brltty/brl-lb-all.txt ......
-path
-path 用于根据文件路径来匹配搜索结果。
-path 选项用于匹配文件路径而不是文件名,示例如下:
1 [root@localhost etc]# cd /etc ; find -path './rc*' -name 'network'
注:-path 选项是区分大小写的,如果想进行不区分大小写的文件路径匹配,可以使用 -ipath 选项。
-perm
-perm 用于根据文件权限来匹配搜索结果。
可以跟着一个用于匹配的权限模式,这个模式可以是一个八进制数字,也可以是一个符号表示的权限。
-perm mode
-perm mode 用于匹配具有指定权限模式的文件,也就是精确匹配:
1 2 [root@localhost tmp]# touch demo ; find -perm 644 ./demo
但在更多情况下,我们希望能够对权限进行模糊匹配。
比如:查找所属组具有写权限的目录,或者是查找其他用户具有写权限的文件等。
重点,要背:
数字 0 表示忽略相应位置的权限;
数字非 0 表示相应位置权限;
-perm -mode
-perm -mode:匹配具有至少包含指定权限模式的文件(和的关系)。
1 2 3 4 5 [root@localhost tmp]# touch demo ; find -perm -640 | grep demo ./demo [root@localhost tmp]# touch demo ; find -perm -620 | grep demo
-perm /mode
-perm /mode:匹配具有任意一个指定权限模式的文件(或的关系)。
1 2 3 4 5 [root@localhost tmp]# touch demo ; find -perm /644 | grep demo ./demo [root@localhost tmp]# touch demo ; find -perm /422 | grep demo ./demo
-perm +mode
不再支持此功能(自 2005 年起已弃用),请改用 -perm /mode。
-size
-size:用于根据文件大小来匹配搜索结果。
后面可以跟着一个用于匹配的大小值。这个大小值可以是以块(blocks)为单位的整数,也可以使用带有单位的字符串来表示。
可以使用以下后缀(常用):
C:bytes
K:KiB
M:MiB
G:GiB
-size n:匹配大小精确为n个块的文件:
1 find /path/to/directory -size 1024
1 find /path/to/directory -size +1024
1 find /path/to/directory -size -1024
-type
-type:用于在指定目录及其子目录中递归搜索文件和目录,Linux 文件类型如下:
文件类型
解释说明
-
普通文件是最常见的文件类型,存储了文本、二进制数据或程序代码等信息,大部分文件都属于这种类型。
d
目录是用于组织文件的特殊文件类型,它包含了其他文件和子目录。 在Linux中,一切皆文件,包括目录本身,类似于 Windows 的文件夹。
b
设备文件用于与系统中的设备进行通信。Linux 将设备文件分为块设备文件和字符设备文件两种类型,块设备文件用于访问像硬盘驱动器这样的块设备。
c
字符设备,用于访问像键盘、打印机等字符设备。
l
符号链接也称为软链接,它是一个指向另一个文件的特殊类型文件,类似于 Windows 中的快捷方式。
p
管道是一种用于进程间通信的文件类型,类似于套接字,但通常用于同一系统上的进程间通信。
s
套接字是一种用于进程间通信的特殊文件类型。它允许不同的进程通过网络或本地通信机制进行数据交换。
1 2 3 4 5 [root@localhost ~]# find /etc -type l /etc/mtab /etc/fonts/conf.d/62-google-crosextra-caladea-fontconfig.conf /etc/fonts/conf.d/61-urw-fallback-backwards.conf ......
-user
1 2 3 4 5 6 [root@localhost ~]# find /etc -user root /etc /etc/fstab /etc/crypttab /etc/mtab ......
-exec -exec command
-exec command:用于在找到的每个文件上 执行指定的命令。
完整的命令为:
{}:表示找到的文件的占位符,{} 将被实际找到的文件名替换,然后命令将在每个文件上执行;
; 表示命令的结束。
注:
请务必在 {} 和 ; 之间留出空格;
; 来表示分号字符本身,而不是作为命令的结束;
-exec 会对每个找到的文件执行指定的命令。
使用 ls -l 查看 /etc 目录下名称为 passwd 的文件:
1 2 3 [root@localhost ~]# find /etc -name 'passwd' -exec ls -l {} \; -rw-r--r--. 1 root root 188 Apr 1 2020 /etc/pam.d/passwd -rw-r--r--. 1 root root 2309 Nov 8 11:30 /etc/passwd
-execdir command
-execdir command:用于在找到的文件所在的目录中 执行指定的命令。
与 -exec 选项不同,-execdir 选项会将命令应用于每个找到的文件所在的目录,而不是文件本身。
使用 ls -l 查看 /etc 目录下名称为 passwd 的文件:
1 2 3 [root@localhost ~]# find /etc -name 'passwd' -execdir ls -ld {} \; -rw-r--r--. 1 root root 188 Apr 1 2020 ./passwd -rw-r--r--. 1 root root 2309 Nov 8 11:30 ./passwd
-prune
1 2 3 4 [root@localhost etc]# find /etc -type d -name "rc.d" -prune -o -type f -name "network" /etc/sysconfig/network /etc/rc.d /etc/vmware-tools/scripts/vmware/network
可以看到文件虽然被排除了,但是目录还是显示了出来,不利于后续执行命令,所以换一个命令 -not -path:
1 2 3 [root@localhost etc]# find /etc -not -path "*rc.d*" -name "network" /etc/sysconfig/network /etc/vmware-tools/scripts/vmware/network
find SUID
1 2 3 4 5 [root@localhost ~]# ll /usr/bin/find -rwsr-xr-x. 1 root root 199304 Oct 31 2018 /usr/bin/find [root@localhost ~]# chmod 4755 /usr/bin/find [root@localhost ~]# find /usr/bin -type f -perm /4000 2>/dev/null -exec ls -l {} \; | grep find -rwsr-xr-x. 1 root root 199304 Oct 31 2018 /usr/bin/find
切换到普通用户,使用 find
执行 whoami
命令:
1 2 3 4 5 [root@localhost ~]# su yongz [yongz@localhost root]$ id uid=1001(yongz) gid=1001(yongz) groups=1001(yongz) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 [yongz@localhost root]$ touch /tmp/1 ; find /tmp/1 -exec whoami \;; rm -rf /tmp/1 root
注:一定要加 -p,不然可能会提权失败。
1 2 3 [yongz@localhost root]$ touch /tmp/1 ; find /tmp/1 -exec /bin/bash -p \;; rm -rf /tmp/1 bash-4.2# id uid=1001(yongz) gid=1001(yongz) euid=0(root) groups=1001(yongz) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
注:
这里可以看到有出现了一个 euid(effective user ID),当用户执行一个可执行文件时,该执行文件的 euid 将被设置为文件所有者的 uid,这使得用户在执行该文件时可以暂时获得文件所有者的特权。
所以当一个可执行文件设置了 SUID 位,并且文件所有者是 root(uid 为 0),那么当普通用户执行该文件时,该进程的 euid 将设置为 0(root),以获得执行该文件所需的特权权限。
小问题:
为什么我要自己创建文件去查找,不创建用如下命令会发生什么?