使用audit分析文件权限被篡改

背景

使用的unas系统,用户home目录权限老是被篡改导致ssh登录不上。开启ssh密钥登录后sshd会依次检查${HOME}/.ssh目录权限是否正常。 unas每次启动后home目录权限变为777,非常危险

过程

安装audit

apt install auditd

如果要追踪systems服务启动前的audit,最好在boot kernel参数加上audit=1,但我这儿估计问题发生在应该没那么早,就先不加了

首先查看文件监控

auditctl -w $HOME/a.txt -p a
chmod 600 a.txt

能正常看到审计日志 为了避免日志堆积污染,每次测试完成后都会清理日志:

echo -n '' > /var/log/audit/audit.log

再试一下监控系统调用chmod

auditctl -a always,exit -S chmod

不能正常看到日志,而且报warning

WARNING - 32/64 bit syscall mismatch, you should specify an arch

加上-F参数规避报警, 以及限制一下path

auditctl -a always,exit -F arch=b64 -S fchmodat -F path=$HOME/a.txt

手动调用测试,然而还是没有日志 最后看-w上面的监控才看到问题所在 type=SYSCALL msg=audit(): arch=c000003e syscall=268 success=yes 搜索了一下268系统调用,发现是fchmodat.

chmod命令使用的不是chmod系统调用,而是它的变体fchmodat

把所有变体都加入监控试试:

auditctl -a always,exit  -S fchmodat -S chmod -S fchmod -F path=$HOME

审核日志就正常了 这儿使用的的-F path参数和-F dir参数是有差别的, dir参数会递归包含子文件. 而 auditctl -w的则是自动会使用dir

将它写入audit文件持久化:

cat <<EOF >> /etc/audit/rules.d/audit.rules
-a always,exit  -S fchmodat -S chmod -S fchmod -F path=$HOME
EOF

重启

ausearch -f $HOME

能看到

type=PROCTITLE msg=audit(...): proctitle=63686D6F640030373737002F6D...
type=PATH msg=audit(...): item=0 name="<home>" inode=...
type=CWD msg=audit(1721973898.519:4883): cwd="/"
type=SYSCALL msg=audit(...): arch=c000003e syscall=268 success=yes exit=0 ... items=1 ppid=6692 pid=6694 ... tty=(none) ses=4294967295 comm="chmod" exe="/usr/bin/chmod" subj=unconfined key="call_chmod"

这儿将proctitle 按hex解码后看:

echo 63686D6F640030373737002F6D... |sed 's/00/09/g' | xxd -r -p
---
chmod	0777	/m...

'\0' 转义为'\t' 方便阅读。

改进了一下新的脚本,交互式解码 #hex #decode:

cat |gsed 's/00/09/g;s/$/0A/1' -u |  xxd -r -p

这儿用的是gsed方便macOS上使用,行末自动加0A, 方便xxd生成回车换行, 加上-u选项免buffer立即输出。

初步完成,但?

能看到chmod 0777 /m...命令被执行导致权限变更。可是,是谁执行的这个命令呢? 能否显示这个命令的父进程? 虽然上文能看到ppid=6692, 可是该进程早已经退出。 audit也不支持记录调用时的进程树,仿佛又进入了死胡同

追踪调用链

好在,我们可以记录execve系统调用来追踪所有的进程关系:

auditctl -a always,exit  -S fchmodat -S chmod -S fchmod -F path=... -k chmod_home
auditctl -a always,exit -S execve -S execveat -k exec_cmd

这儿加上-k参数方便后续搜索关键字 将之持久化,重启

ausearch -k chmod_home

根据输出的ppid, 依次调用

ausearch -p <pid>

proctitle 放到上面的hex脚本解码后就能得出一条调用连。

注:后面发现audit里面type=EXECVE的日志直接就可阅读参数

- init(systemd)
- "/bin/sh" "/etc/rc.local" "start"
- "bash" "/unas/sbin/init.d/unas_startup.sh"
- "php" "/unas/sbin/init.d/unas_startup.php"
- "sh" "-c" "chmod 0777 .../homes/*"
- "chmod" "0777" ...

修复措施

  • /unas/sbin/init.d/unas_startup.php这儿并不是纯文本,我也不打算修改它
  • 就在/etc/rc.local 后加一行把权限改回来就行了
chmod 750 ...