TT Lab
开始
学习 学习路径 课程

cron 在凌晨三点执行了 curl

cron 在凌晨三点执行了 curl

在 TT Lab 中继续学习

本实验在 VM 中运行

一台 Ubuntu 24.04 VM 上,Falco 已经以 modern eBPF 驱动运行。系统调用插桩是内核功能,在实验 Pod 中根本无法实现。启动需要 2–3 分钟(因为要安装 Falco)。

目标

亲手编写能抓住标题中事件的规则。拆分列表和宏,把告警保存为 JSON 文件,真正种下一个计划任务,并在文件中确认规则抓到了它。然后再制造一个会命中同一规则的正常作业,只把它作为例外排除,再确认坏的仍然能被抓到。

为什么重要

基于日志的检测有结构性的局限。日志只会留下程序决定要留下的内容。系统调用则不同——无论是创建进程还是打开文件,都必须经过内核,而内核是骗不了的。

但是,如果把系统调用全看一遍,告警就会太多。所以运行时检测的实际工作不是“抓什么”,而是“可以排除什么”。只要一条规则把正常的备份作业也抓进来,几天之内就没人看告警了。这时如果把规则放宽,真正的事件也会一起漏掉。把例外收得窄、并写明理由,这个习惯决定了检测体系的寿命。

步骤

  1. 把 Falco 的版本、驱动和服务状态保存到 /root/falco/01-engine.txt。
  2. 在 /etc/falco/rules.d/labhub-cron.yaml 中用一个 list、一个 macro、一个 rule 编写规则。输出中必须包含 %user.name 和 %proc.cmdline。
  3. 在 /etc/falco/config.d/labhub-output.yaml 中开启 JSON 输出和文件输出(/var/log/falco/events.json),并重启服务。
  4. 创建 /etc/cron.d/telemetry,让它每分钟向外发出请求。
  5. 等待 1 分钟以上,把捕获到的一行告警保存到 /root/falco/05-alert.json。
  6. 创建 /etc/cron.d/backup-sync,再放一个会命中同一规则的正常作业,只把它通过规则的 exceptions 排除,然后重启服务。
  7. 清空 events.json,等计划任务运行一次,在 /root/falco/07-verify.txt 中确认正常作业没有被抓到、坏的被抓到了。
  8. 把规则的依据写到 /root/falco/08-report.md,分为 ## 무엇을 잡는가、## 왜 예외를 두었나、## auditd 와 무엇이 다른가、## 다음에 넓힐 곳(韩文,依次意为“抓什么”“为什么设置例外”“与 auditd 有什么不同”“下一步要扩大的地方”)四节。

参考

什么在用什么驱动运行

把 falco --version 的版本号、它以哪个驱动(单元名称)运行、以及服务状态保存到 /root/falco/01-engine.txt。

systemctl show -p Id --value falco 会给出实际的单元名称。falco 是该单元的别名。不知道驱动,就无法找出“为什么抓不到”。

编写一条规则

在 /etc/falco/rules.d/labhub-cron.yaml 中编写一个 list、一个 macro、一个 rule。要抓住计划任务下运行外部请求工具的行为,output 中必须包含 %user.name 和 %proc.cmdline,priority 为 WARNING 以上。

list 和 macro 只能引用定义在自己前面的内容,所以按列表 → 宏 → 规则的顺序书写。cron 会启动 shell,所以要看的不是父进程而是祖先。写完后,连同默认规则文件一起用 --validate 确认。

把告警留在文件里

在 /etc/falco/config.d/labhub-output.yaml 中开启 json_output: true 和文件输出(/var/log/falco/events.json),并重启服务。不要整个修改 falco.yaml。

config.d 下的文件会叠加到默认配置上。重启后查看 journal,会逐行打印出读取了哪些配置文件——这就是“真的生效了”的证据。

种下事件

创建 /etc/cron.d/telemetry,让它每分钟用 curl 向外发出请求。它是 /etc/cron.d 格式,所以在调度时间之后有一栏是执行命令的用户。

每分钟是 * * * * *。请求不需要真的成功——进程被执行了这件事会被系统调用捕获。

在文件中看是否抓到

等计划任务运行一次后,从 /var/log/falco/events.json 中挑出自己规则的一行告警,保存到 /root/falco/05-alert.json。

用 jq -c 'select(.rule == "<규칙 이름>")' /var/log/falco/events.json | tail -1 就会得到一行(占位符为规则名称)。文件里也混有 Falco 内部告警,所以要按规则名称过滤。

窄窄地排除一个正常作业

创建 /etc/cron.d/backup-sync,再放一个会命中同一规则的正常作业,只把它通过规则的 exceptions 排除,然后重启服务。不要在 condition 末尾加 and not …。

exceptions 用 name、fields、comps、values 书写。在 fields 中写要看的事件字段,在 comps 中写比较方式,在 values 中写值的集合,引擎就会把它以 and not (…) 的形式接到条件后面。值收得太宽,会在第 7 步被抓到。

两个都再运行一遍

清空 /var/log/falco/events.json,等计划任务运行一次(最多 1 分钟),确认 telemetry 被抓到而 backup-sync 没有被抓到,并用两行以上写到 /root/falco/07-verify.txt。

服务重新读取规则,例外才会生效(上一步已经重启过了)。旧告警还在会干扰判断,所以请清空文件,只看新收到的。如果例外太宽,该抓的也会变得安静。

留下规则的依据

在 /root/falco/08-report.md 中写四节:## 무엇을 잡는가、## 왜 예외를 두었나、## auditd 와 무엇이 다른가、## 다음에 넓힐 곳(韩文,依次意为“抓什么”“为什么设置例外”“与 auditd 有什么不同”“下一步要扩大的地方”)。正文中必须出现 exceptions、priority、events.json 三个词。

下一个人看到这条规则时,最想先删掉的就是例外。如果没有写明为什么设置它,就真的会被删掉。也请整理一下它与前一个模块中的内核审计有哪些重叠、哪些不同。