Skip to content

Go 主机安全面试:Linux 无文件执行与 memfd 检测

Linux 主机被入侵后,攻击者不一定把 payload 写成普通磁盘文件,也可能通过 memfd_create、管道、解释器内存加载或删除已执行文件来降低落地痕迹。面试官通常会追问:Go Agent 怎么发现无文件执行?哪些证据可信?如何避免把正常运行时、升级流程或临时文件误报成攻击?

岗位场景

text
进程执行事件
  -> 采集 exe、cmdline、fd、maps、文件 hash、父子进程和用户上下文
  -> 识别 memfd、deleted executable、匿名映射和解释器内存加载线索
  -> 关联网络外联、临时目录落地、提权命令和历史基线
  -> 输出可复盘的无文件执行告警

这类题考的是 Linux 进程取证、procfs、系统调用、攻击链关联、误报治理和 Go 侧低开销采集能力。

高频面试题

1. 什么是无文件执行,为什么 HIDS/EDR 要关注?

简洁答案:无文件执行是指 payload 不以稳定磁盘文件形式存在,或执行后立即删除文件,目的是绕过基于文件 hash、路径和落地扫描的检测。

关键知识点:

  • memfd_create 可以创建匿名内存文件,再通过 /proc/<pid>/fd/<n> 执行。
  • 执行中的文件被删除后,/proc/<pid>/exe 常能看到 (deleted) 线索。
  • 脚本解释器、动态链接器、bash -cpython -c 也可能承载无文件或弱落地行为。

Go 落地思路:

  • 不只依赖文件扫描,要把进程执行事件作为主线。
  • 事件字段至少包含 pidppiduidexecmdlinecwdfd_targetsmaps_summary
  • 告警要保留证据快照,因为进程退出后 /proc 证据会消失。

2. Linux 上哪些证据能提示 memfd 或 deleted executable?

简洁答案:重点看 /proc/<pid>/exe/proc/<pid>/fd/*/proc/<pid>/maps 和执行事件里的路径形态。

常见线索:

text
/proc/<pid>/exe -> /memfd:<name> (deleted)
/proc/<pid>/exe -> /tmp/.x (deleted)
/proc/<pid>/fd/5 -> /memfd:<name> (deleted)
/proc/<pid>/maps contains /memfd:<name>
cmdline contains /proc/self/fd/<n>

关键知识点:

  • (deleted) 不等于一定恶意,升级、临时文件和容器运行时也可能出现。
  • memfd 名称可伪装,不能只依赖 name。
  • maps 可以补充可执行映射,但采集成本比读 exe 更高。

Go 落地思路:

  • 先读 /proc/<pid>/exe 和少量 fd 链接,命中风险线索后再采集 maps
  • 对短生命周期进程,优先在 exec 事件到达时立即快照。
  • 解析失败要保留错误类型,例如权限不足、进程已退出、路径不存在。

3. 为什么只看 (deleted) 容易误报?

简洁答案:很多正常软件升级、包管理替换、临时执行和容器镜像层切换都会产生 deleted executable,必须结合上下文评分。

关键知识点:

  • 系统升级时旧二进制仍在运行,路径会显示 (deleted)
  • 临时目录执行可能是正常安装脚本,也可能是恶意 payload。
  • 容器内路径和宿主机路径需要区分,否则会把容器行为误判成宿主机入侵。

Go 落地思路:

  • 评分维度包括路径、签名或 hash、父进程、用户、命令参数、网络外联和历史基线。
  • 对包管理器、已知升级进程、可信发布路径设置低风险标签,不直接静默放行。
  • 告警等级用分层结果,例如 suspicioushighcritical,方便运营降噪。

4. Go Agent 如何低开销采集这些进程证据?

简洁答案:用事件驱动优先,定时巡检兜底;先采集低成本字段,命中可疑条件后再补充高成本证据。

关键知识点:

  • eBPF、auditd 或 netlink 可以提供进程执行触发点。
  • procfs 适合补充快照,但全量高频扫描会带来 CPU 和 IO 压力。
  • fd 和 maps 数量可能很大,需要限制采集范围。

Go 落地思路:

go
func suspiciousExePath(path string) bool {
	return strings.Contains(path, "/memfd:") || strings.Contains(path, " (deleted)")
}
  • exec 事件进来后先读取 execmdlinecwd、少量 fd。
  • 只有 execmdline 或父进程命中规则时,再采集 maps 摘要。
  • 对每个进程设置采集预算,例如 fd 最多读取前 64 个,maps 只提取可执行匿名映射。

5. 如何把无文件执行放进攻击链还原?

简洁答案:不要把 memfd 当成孤立告警,要关联前置入口、payload 加载、权限变化、网络连接和后续持久化动作。

关键知识点:

  • 常见链路可能是 Web RCE -> 下载或内存加载 -> memfd 执行 -> 反弹 shell。
  • 父子进程能解释来源,例如 nginx -> sh -> memfdsystemd -> trusted daemon 更可疑。
  • 网络连接和 DNS 查询能补齐外联证据。

Go 落地思路:

  • agent_id + boot_id + pid + start_time 做进程实体键,避免 pid 复用。
  • 事件标准化后按时间窗口聚合,保留父子关系和关键证据。
  • 输出告警时给出最短可读链路,而不是堆所有原始事件。

6. 面对客户说“这是误报”,你怎么排查?

简洁答案:先确认进程来源和证据完整性,再用基线、包管理记录、父子进程、网络行为和文件摘要判断是否正常。

关键知识点:

  • 先确认采集时间、主机、pid start time,避免查错进程。
  • 看父进程是否来自包管理、部署系统、容器运行时或可信安全软件。
  • 看 deleted 文件原路径是否属于正常升级路径,是否伴随异常外联。

Go 落地思路:

  • 为每条告警保存 raw_evidence,包含 exe readlink、cmdline、fd 摘要和 maps 摘要。
  • 支持离线 replay,把同一批事件重新跑规则,验证是否规则阈值过低。
  • allowlist 应限定条件,例如 hash + signer + parent + path,避免只按进程名放行。

7. 如何设计面向无文件执行的检测规则?

简洁答案:用多条件组合规则,基础线索负责召回,行为上下文负责提准。

规则示例:

text
if exe contains "/memfd:" and parent in [nginx, apache2, php-fpm, java]
and outbound_connection within 60s
then high severity

关键知识点:

  • 单一条件适合打标签,不适合直接高危告警。
  • 规则应区分 Linux 发行版、容器、业务部署方式和安全软件行为。
  • 阈值要能通过历史样本回放验证。

Go 落地思路:

  • 把检测拆成 tag、score、decision 三层,便于解释和调参。
  • 规则命中结果保留每个加分项,方便面试时说明可解释性。
  • 性能上优先用字符串前缀、包含判断和预编译正则,避免热路径复杂解析。

通俗答案

无文件执行不是“完全没有文件”,而是攻击者尽量不留下稳定、可扫描、可复查的磁盘 payload。HIDS/EDR 的 Go Agent 要做的是在进程还活着时抓住短暂证据:exe 指向哪里、fd 里有没有 memfd、maps 是否有匿名可执行映射、父进程是谁、后面有没有外联。检测时不能看一个关键词就报警,要把路径、用户、父子进程、网络和历史基线合起来判断。

Go 落地思路

text
采集层:exec 事件 + procfs 快照 + 网络事件
标准化层:统一 pid、start_time、exe、cmdline、fd、maps、container_id
检测层:memfd/deleted 标签 + 行为评分 + 误报压制
证据层:保存 readlink、参数、映射摘要和关联链路
验证层:样本回放 + 客户现场证据复盘

实现时保持简单:先把 execmdline、父子进程和网络关联做好,再按命中条件补充 fd/maps。不要一上来全量扫描所有进程的所有 fd 和 maps。

学习要点

  • 理解 memfd_create/proc/<pid>/exe/proc/<pid>/fd/proc/<pid>/maps 的取证价值。
  • 明白 (deleted) 是风险线索,不是恶意结论。
  • 掌握 pid 复用、短生命周期进程、权限不足和容器路径带来的工程问题。
  • 能用 Go 写低开销采集逻辑,并为规则命中保留可解释证据。
  • 能从 Web RCE、反弹 shell、提权和持久化角度还原攻击链。

小练习

  1. 设计一个 ProcessEvidence 结构体,覆盖 memfd 检测所需的最小字段。
  2. 给出 3 条可能误报的 deleted executable 场景,并说明如何降噪。
  3. 写一个函数判断 exe path 是否包含 memfd 或 deleted 线索,再补充一条父进程评分规则。
  4. 解释为什么 pid + start_time 比单独使用 pid 更适合做进程关联。
  5. 如果客户只提供一条 memfd 告警,你会要求补哪些证据来判断是否真实攻击?
最近更新