当前位置: 首页 > 科技观察

为了防止fork暴力攻击,Linux加入了Brute安全模块

时间:2023-03-13 05:11:38 科技观察

Linux中很多严重的漏洞,尤其是提权漏洞,都是利用暴力的fork()系统调用导致内核崩溃,从而突破内存限制得手,如StackClash漏洞、“Heartbleed”漏洞,以及新曝光的sudoCVE-2021-3156等。为了一劳永逸地解决此类漏洞,Linux安全模块(LSM)新增了一个“Brute”模块来检测和防止此类攻击。Brute补丁集版本6最近发布,预计很快就会发布到主线分支。“Brute”补丁集于去年9月由JohnWood作为RFC发布。它最初被命名为“fbfam”(forkbruteforceattackmitigation,forkbruteforceattackmitigation),后来经过社区讨论改名,变成了LSM。这类问题的解决方案实际上已经存在了很长时间。grsecurity内核补丁已经有了GRKERNSEC_BRUTE功能,可以减少暴力攻击fork()的使用,并防止setuid/setgid二进制攻击。Weinberger在2014年发布的补丁中使用了类似的技术来延迟fork(),因为fork()崩溃问题(这可能意味着它是攻击的一部分)。但这些尝试并没有进一步推动他们。在Brute补丁的文档中,Wood描述了BruteLSM所针对的行为类型。基本思想是有几种类型的攻击可以使用多个fork()来接收所需的内存布局。每个派生的子进程都可以通过多种方式进行探测,如果这些探测失败并且子进程崩溃,它可以简单地重新派生另一个子进程来重试。由于使用它创建的子进程与其父进程共享相同的内存布局,成功探测可用于突破Linux虚拟内存地址空间随机化布局(ASLR),可用于探测堆栈Stack_canaries或其他敏感信息。Brute采用与grsecurity或Weinberger补丁不同的方法,因为它不会在检测到问题时简单地延迟后续的fork()调用。相反,Brute会杀死与攻击相关的所有进程。此外,Brute检测更多类型的fork()使用攻击(包括检测父进程而不是子进程的攻击。它还关注跨特权边界的进程崩溃以避免误报。Brute通过计算崩溃率来做到这一点。Brute收集有关在一组已经分叉的进程中发生的“失败”次数的信息,但在这些进程中没有使用execve()执行任何新操作。所有这些进程之间共享一个brute_stats结构。执行一个新程序会导致用于跟踪新(潜在)fork()层次结构中故障的新结构。进程启动与进程的子进程或其任何共享内存布局崩溃(即没有execve())之间的时间间隔,或连续崩溃,最终用于确定是否发生攻击的时间。为了防止多次调用,插件使用EMA(指数移动平均)计数,一旦发生五次崩溃红色,计算周期(EMA)。EMA用于确定是否正在发生“快速暴力”攻击。如果崩溃之间的时间间隔的EMA低于30秒的阈值,则触发缓解攻击。对于“慢速暴力”变体,将层次结构中的绝对崩溃数与200阈值进行比较。使用ask_fatal_signal()LSM挂钩,作为集合中的第一个补丁添加。每当内核向进程传递致命信号时调用此方法。Brute还使用现有的task_alloc()挂钩检测forks()调用,使用bprm_committing_creds()挂钩检测execve()调用,使用task_free()挂钩清理一切。安全边界检查是通过跟踪对各种用户和组的更改来实现的执行新程序时出现的ID...Linux功能补丁中没有提到,但是功能更改也会表明权限边界已被破坏;也许稍后会添加。除了ID更改之外,还宝可以使用检测网络的socket_sock_rcv_skb()LSM挂钩。通过执行Setuid/setgid程序或通过网络接收数据,将崩溃检查限制在那些跨越特权边界的进程中,从而减少误报的数量。