Go 主机安全面试:Linux 勒索加密与批量文件改写检测
Linux 服务器上的勒索攻击不一定像办公终端那样弹窗,它更常表现为短时间内大量业务文件被打开、改写、重命名、删除原文件,并伴随可疑扩展名、勒索说明文件和异常 CPU/IO 峰值。面试官通常会追问:Go Agent 怎么在不拖垮机器的前提下发现批量加密?如何区分正常备份、日志轮转、压缩归档和攻击?检测结果怎样帮助客户快速止损?
岗位场景
Linux 主机
-> 采集文件写入、rename、unlink、进程执行、资源指标和目录基线
-> 标准化进程、用户、路径、文件类型、改写速率、扩展名变化和熵变化
-> 识别短时间大规模改写、可疑扩展名、勒索说明文件和业务目录异常破坏
-> 关联 Web RCE、SSH 登录、提权、落地样本和后续清理痕迹
-> 输出可解释的勒索加密行为告警,并支持阻断或限速策略这类题考的是 Linux 文件系统事件、行为检测、误报治理、资源控制、攻击链还原和 Go Agent 的实时聚合能力。
高频面试题
1. 勒索加密检测为什么不能只靠文件名或 hash?
简洁答案:勒索样本可以变种、改名、加壳,hash 很容易失效;主机侧更稳定的证据是“同一进程在短时间内批量读取、改写、重命名大量文件”的行为模式。
关键知识点:
- 勒索行为通常有批量遍历目录、读取原文件、写入加密内容、rename 扩展名、删除原文件等步骤。
- 文件名黑名单只能覆盖已知家族,发现不了新样本或客户现场定制脚本。
- 单个文件改写很常见,真正异常的是速度、范围、文件类型和进程上下文组合。
- 服务端 Linux 场景要重点关注业务目录、共享目录、数据库备份目录和挂载盘。
Go 落地思路:
- 采集层输出结构化文件事件,不把判断写死在采集模块里。
- 检测层按
host + pid + user + time_window聚合改写数量、目录分布和扩展名变化。 - 对命中行为输出
reason_codes,例如mass_file_rewrite、suspicious_extension_rename、ransom_note_created。
type FileMutationEvent struct {
HostID string
PID int
UID int
Op string
Path string
Ext string
Size int64
}2. Linux 上哪些文件事件最适合识别批量加密?
简洁答案:重点看 open/write/rename/unlink/chmod 这类文件改写链路,再结合进程执行和资源指标。单看 inotify 的路径变化不够,最好能补上执行者和父进程。
关键知识点:
| 事件 | 检测价值 | 常见风险 |
|---|---|---|
openat / read | 发现批量读取原文件 | 单独看噪声大 |
write / truncate | 发现内容被改写 | 日志写入也会大量出现 |
rename | 发现追加异常扩展名 | logrotate、部署发布会误报 |
unlink | 发现删除原文件或备份 | 清理任务和临时文件也常见 |
chmod / chown | 发现权限破坏或阻断恢复 | 运维脚本可能合法修改 |
Go 落地思路:
- 小范围目录可以用 inotify/fanotify 触发,关键证据可由 audit/eBPF 补充。
- 对高频文件事件做本地窗口聚合,避免每个
write都上报服务端。 - 记录事件来源能力,例如
file_watch、auditd、ebpf,便于解释证据强度。
3. 怎么判断“批量改写”真的可疑?
简洁答案:看单位时间、文件类型多样性、目录影响面、扩展名变化、内容特征和进程身份。比如一个陌生进程 30 秒内改写 500 个业务文档,比单个日志文件持续写入更可疑。
关键知识点:
- 勒索会跨目录、跨文件类型批量处理,常覆盖
.doc、.pdf、.sql、.jpg、配置和备份文件。 - 正常日志通常集中在少数路径,扩展名稳定,写入进程也稳定。
- 正常备份或压缩会产生大文件,但通常不会覆盖原业务文件并追加陌生扩展名。
- 攻击进程可能来自
/tmp、/dev/shm、Web 目录、用户下载目录或无签名落地文件。
Go 落地思路:
- 为每个进程维护滑动窗口计数:文件数、目录数、扩展名数、rename 比例、unlink 比例。
- 阈值不要全局写死,可按主机角色和目录重要性调整。
- 告警时给出样本路径和聚合统计,不上传海量文件名。
type MutationWindow struct {
PID int
FileCount int
DirCount int
RenameCount int
UnlinkCount int
ExtDiversity int
}4. 文件熵变化在勒索检测里有什么用?
简洁答案:加密后的内容通常更接近随机数据,熵会上升;但熵只能作为辅助信号,不能单独作为勒索结论,因为压缩包、图片、数据库文件本身也可能高熵。
关键知识点:
- 熵可以帮助区分“普通文本改写”和“疑似加密后内容”。
- 已压缩文件、媒体文件、归档文件、数据库页本来就可能高熵。
- 全量读取大文件计算熵成本高,Agent 只能做采样或延迟分析。
- 熵变化要结合写入进程、文件类型、rename 和批量速度一起看。
Go 落地思路:
- 对小文件或文件头尾做采样估算,不对所有大文件全量扫描。
- 本地只保存摘要统计:采样大小、估算熵、文件类型、是否高风险目录。
- 将熵作为评分因子,而不是一票否决条件。
func byteEntropy(sample []byte) float64 {
if len(sample) == 0 {
return 0
}
var counts [256]int
for _, b := range sample {
counts[b]++
}
var entropy float64
for _, c := range counts {
if c == 0 {
continue
}
p := float64(c) / float64(len(sample))
entropy -= p * math.Log2(p)
}
return entropy
}5. 如何区分勒索攻击和正常备份、压缩、部署发布?
简洁答案:正常任务通常有固定进程、固定路径、固定时间窗口和可解释产物;勒索更像陌生进程快速遍历多个业务目录,覆盖原文件、追加异常扩展名、生成勒索说明,并可能先删除快照或备份。
关键知识点:
| 场景 | 正常特征 | 风险信号 |
|---|---|---|
| 备份 | 读多写少,目标目录固定 | 删除备份、覆盖源文件 |
| 压缩 | 生成归档文件,源文件保留 | 边压缩边删除大量源文件 |
| 部署 | 发布目录集中,有 CI/CD 进程 | Web 进程或临时目录进程改业务数据 |
| logrotate | 日志目录固定,rename 形态稳定 | 跨业务目录批量追加陌生扩展名 |
Go 落地思路:
- 建立可信任务基线:进程路径、父进程、执行用户、目录范围和时间窗口。
- 对压制事件保留审计样本,客户反馈后能 replay 规则。
- 规则输出“为什么没有压制”的原因,便于现场排障。
6. Go Agent 怎么在高 IO 场景下控制资源?
简洁答案:不要逐事件做重计算和全量上报。采集层要限速、采样、聚合和降级;检测层关注窗口特征,必要时只上报代表性证据。
关键知识点:
- 勒索攻击会制造文件事件风暴,Agent 不能因为检测攻击反而拖垮业务。
- 哈希、签名、熵计算、路径归一化都可能成为 CPU 或 IO 热点。
- 事件队列满时要优先保留高价值事件,记录丢弃指标。
- 对网络盘、容器挂载和大型备份目录要有更谨慎的策略。
Go 落地思路:
- 使用有界 channel 和 worker pool,避免无限堆积。
- 对同一
pid + dir + op做本地合并,再周期性 flush。 - 暴露健康指标:队列长度、丢弃数、聚合窗口数量、扫描耗时和 CPU 占用。
select {
case events <- ev:
metrics.Accepted.Add(1)
default:
metrics.Dropped.Add(1)
}7. 勒索攻击链路还原需要关联哪些上下文?
简洁答案:至少关联入口进程、样本落地、批量文件改写、备份破坏、勒索说明和外联。只有文件事件会让告警像“文件系统噪声”,关联后才能解释攻击过程。
关键知识点:
- 常见入口可能是 Web RCE、SSH 弱口令、计划任务、恶意脚本或供应链组件。
- 勒索前常见动作包括下载样本、提权、枚举目录、关闭安全服务、删除备份。
- 勒索过程中会出现 CPU/IO 异常、短时间大量文件事件和勒索说明文件。
- 勒索后可能出现日志清理、横向移动或 C2 外联。
Go 落地思路:
- 用短窗口关联
process_exec -> file_mutation_burst -> ransom_note -> backup_delete。 - 对跨进程行为保留
parent_pid、session_id、container_id、login_user。 - 告警详情展示时间线,而不是只展示最高分规则。
nginx -> sh -> /tmp/.cache/update
-> 遍历 /data/www 和 /backup
-> 3 分钟内 rename 1200 个文件为 *.locked
-> 创建 README_RECOVER.txt
-> 删除 /backup/snapshot8. 如果客户要求自动阻断,应该怎么设计边界?
简洁答案:阻断要谨慎,最好分级:先告警和限速,再对高置信进程做 kill、隔离或暂停文件写入。误杀业务进程的代价可能比漏报一次低危行为更高。
关键知识点:
- 自动 kill 可能中断数据库、备份、部署任务或批处理作业。
- 高置信条件应包括陌生进程、业务目录批量破坏、异常扩展名、勒索说明和备份删除。
- 阻断动作必须可审计、可配置、可灰度,并能按客户策略关闭。
- 对容器和宿主机进程要区分命名空间,避免误伤其他租户或宿主关键进程。
Go 落地思路:
- 采集告警和响应动作解耦,响应模块只消费高置信处置事件。
- 支持 dry-run 模式,先记录“本应阻断”的证据,再让客户决定是否开启。
- 响应结果要回传:动作、目标 pid、权限错误、是否成功和失败原因。
学习要点
- Linux 文件事件:
openat、write、rename、unlink、truncate、chmod。 - 行为检测:滑动窗口、聚合统计、路径基线、扩展名变化和熵辅助判断。
- 降噪方法:区分备份、压缩、logrotate、部署发布和真实破坏行为。
- Go 工程实现:有界队列、worker pool、采样计算、指标暴露和事件 replay。
- 攻击链还原:入口进程、样本落地、批量改写、备份破坏和勒索说明文件。
小练习
- 写一个滑动窗口聚合器,统计同一 PID 在 60 秒内修改了多少个不同目录和文件扩展名。
- 设计一个最小规则:
未知进程 + 业务目录 + 大量 rename + 可疑扩展名才升级为高危告警。 - 取一批文本文件和压缩文件,比较采样熵差异,说明为什么熵不能单独作为判断依据。
复盘题
- 为什么勒索检测更适合做行为规则,而不是只做样本 hash 黑名单?
- 如果客户的备份程序被误报,你会优先看哪五个字段来降噪?
- 当 Agent 文件事件队列开始丢弃时,你会如何保证告警仍然有解释力?
