出于配置审核的原因,我希望能够在我的 ext3 文件系统中搜索具有不可变属性集(通过chattr +i
)的文件。我找不到任何find
可以执行此操作的选项或类似选项。在这一点上,恐怕我必须编写自己的脚本来解析lsattr
每个目录的输出。是否有提供更好方法的标准实用程序?
Ram*_*esh 10
它可以lsattr
通过grep
命令管道命令来部分完成。
lsattr -R | grep +i
Run Code Online (Sandbox Code Playgroud)
但是,我相信当您提到整个ext3
文件系统时,搜索可能涉及/proc
,/dev
以及其他一些可能报告一些您只想忽略的错误的目录。您可能可以将命令运行为,
lsattr -R 2>/dev/null | grep -- "-i-"
Run Code Online (Sandbox Code Playgroud)
您可能希望grep
通过使用grep
的 PCRE 工具来更严格地匹配“-i-”。
lsattr -R 2>/dev/null | grep -P "(?<=-)i(?=-)"
Run Code Online (Sandbox Code Playgroud)
这将适用于以下情况:
$ lsattr -R 2>/dev/null afile | grep -P "(?<=-)i(?=-)"
----i--------e-- afile
Run Code Online (Sandbox Code Playgroud)
但是是不完美的。如果在 immutable 标志周围启用了其他属性,那么我们将不会匹配它们,并且这将被名称恰好与上述模式匹配的文件所欺骗,例如:
$ lsattr -R 2>/dev/null afile* | grep -P "(?<=-)i(?=-)"
----i--------e-- afile
-------------e-- afile-i-am
Run Code Online (Sandbox Code Playgroud)
我们可以像这样收紧模式:
$ lsattr -a -R 2>/dev/null afile* | grep -P "(?<=-)i(?=-).* "
----i--------e-- afile
Run Code Online (Sandbox Code Playgroud)
但它仍然有点过于脆弱,需要根据文件系统中的文件进行额外的调整。更不用说@StephaneChazeles在评论中提到的,通过包含带有文件名的换行符来绕过上述模式,这可以很容易地进行游戏grep
。
https://groups.google.com/forum/#!topic/alt.os.linux/LkatROg2SlM
鉴于脚本的目的是审计,正确处理任意文件名尤其重要,例如包含换行符的名称。这使得无法lsattr
同时在多个文件上使用,因为lsattr
在这种情况下输出可能不明确。
您可以一次递归find
调用lsattr
一个文件。不过会很慢。
find / -xdev -exec sh -c '
for i do
attrs=$(lsattr -d "$i"); attrs=${attrs%% *}
case $attrs in
*i*) printf "%s\0" "$i";;
esac
done' sh {} +
Run Code Online (Sandbox Code Playgroud)
我建议使用不那么古怪的语言,例如 Perl、Python 或 Ruby,并自己完成工作lsattr
。lsattr
通过发出FS_IOC_GETFLAGS
ioctl 系统调用并检索文件的inode flags 进行操作。这是一个 Python 的概念验证。
#!/usr/bin/env python2
import array, fcntl, os, sys
S_IFMT = 0o170000
S_IFDIR = 0o040000
S_IFREG = 0o100000
FS_IOC_GETFLAGS = 0x80086601
EXT3_IMMUTABLE_FL = 0x00000010
count = 0
def check(filename):
mode = os.lstat(filename).st_mode
if mode & S_IFMT not in [S_IFREG, S_IFDIR]:
return
fd = os.open(filename, os.O_RDONLY)
a = array.array('L', [0])
fcntl.ioctl(fd, FS_IOC_GETFLAGS, a, True)
if a[0] & EXT3_IMMUTABLE_FL:
sys.stdout.write(filename + '\0')
global count
count += 1
os.close(fd)
for x in sys.argv[1:]:
for (dirpath, dirnames, filenames) in os.walk(x):
for name in dirnames + filenames:
check(os.path.join(dirpath, name))
if count != 0: exit(1)
Run Code Online (Sandbox Code Playgroud)
感谢 Ramesh、slm 和 St\xc3\xa9phane 为我指明了正确的方向(我错过-R
了lsattr
。不幸的是,到目前为止,没有一个答案对我来说正确。
我想出了以下几点:
\n\nlsattr -aR .//. | sed -rn '/i.+\\.\\/\\/\\./s/\\.\\/\\///p'\n
Run Code Online (Sandbox Code Playgroud)\n\n这可以防止使用换行符使文件看起来是不可变的,而实际上它并不是。它不能防止设置为不可变且文件名中包含换行符的文件。但由于这样的文件必须由 root 以这种方式创建,所以我可以确信在我的用例中我的文件系统上不存在这样的文件。(在 root 用户可能受到威胁的情况下,此方法不适合入侵检测,但也不适合使用lsattr
也属于同一 root 用户的同一系统实用程序。)
归档时间: |
|
查看次数: |
26189 次 |
最近记录: |