2024年3月11日发(作者:)

防火墙

计算机与网络

■周兵峰

■阚哲

控制流限制

正交防线是调节操作系统的控制流。通过确保攻击者无

法将控制权转移到他们选择的代码上,即使不删除内存错

误,也会使利用内存错误变得更加困难。最好的例子被称为

控制流完整性(

CFI

),现在许多编译器工具链(如

LLVM

和微

软的

VisualStudio

),于

2017

年以

ControlFlowGuard

的名义并

Windows

内核。

CFI

非常简单:从概念上讲,确保代码中的控制流始终遵

ID

设置为

root

用户的

ID

)。但是,如果对控制流的限制在

实践中如此成功,您可能想知道数据流是否也可以进行类似

的限制。事实上,它们确实如此,这被称为数据流完整性

DFI

)。在

DFI

中,静态地确定每个加载指令(即从内存中读

取的指令)存储指令可能合法地产生了数据,并且标记这些

指令并将这些标签保存在一组中。在运行时,对于内存中的

每个字节,记住该位置最后一个存储的标签。当遇到加载指

令时,会检查该地址的最后一个存储是否在合法存储集中,

如果不是,会发出警报。与

CFI

不同,

DFI

在实践中并未被广

泛采用,可能是因为其显著的性能开销。

信息隐藏

大多数当前操作系统的主要防线之一是隐藏攻击者可

能感兴趣的任何内容。具体来说,通过随机化所有相关内存

区域(在代码、堆、全局数据和堆栈中)的位置,攻击者将不知

道在哪里转移控制流,也无法发现哪个地址包含敏感数据

等。术语地址空间布局随机化(

ASLR

)是在

PaX

安全补丁发

布时创造的,该补丁在

2001

年为

Linux

内核实现了这种随机

化。很快,类似的努力出现在其他操作系统中,第一个默认启

ASLR

的主流操作系统是

2003

年的

OpenBSD

2005

Linux

。然而,这些

Windows

MacOS

2007

年紧随其后。

早期的实现只是随机化了用户程序中的地址空间,随机化直

到大约

10

年后才到达主要操作系统的内核。

如今,大多数实现都采用粗粒度随机化:它们随机化代

码、堆或堆栈的基本位置,但在这些区域中,每个元素都与基

本元素处于固定偏移量。这很简单,而且非常快,然而,一旦

攻击者设法通过信息泄漏获得哪怕一个代码指针,他们就会

知道每条指令的地址。对于堆、堆栈等,也是如此,因此,毫不

奇怪,这些信息泄漏是当今攻击者高度重视的目标。

更细粒度的随机化也是可能的。例如,可以在页面级别

或功能级别进行随机化。如果在内存区域中打乱函数的顺

序,即使知道内核代码的基础对于攻击者来说也是不够的。

事实上,我们可以更细粒度地洗牌基本块、指令(可能带有从

不执行或无效的垃圾指令)甚至寄存器分配。许多细粒度随

机化技术都是以空间和时间开销为代价的,例如,由于局部

性和碎片化减少。

除了代码之外,还可以对数据进行细粒度随机化。例如,

循静态控制流图。例如,一个函数的返回指令应该只允许返

回到它的调用站点,而使用

C

中的函数指针或

C++

中的虚

函数的间接调用应该只能够定位它应该能够调用的合法函

数的入口点。为了实现这种保护,可以标记间接控制转移指

令的所有合法目标(返回、间接调用和间接跳转),并将这

些标签添加到特定于此指令的集合。在运行时,检查指令即

CFI

会发出将进行的控制转移是否为集合中的目标。否则,

警报。

CFI

有多种与

ASLR

一样,“口味”,从粗粒度到细粒度,

从上下文敏感到上下文不敏感。就像在

ASLR

中一样,今天

的大多数实现只采用最简单、最粗粒度的保护。粗粒度

CFI

意味着为了性能而稍微放宽规则。例如,它不是将函数的返

回指令限制为可能调用此函数的仅目标合法调用站点,而是

可以针对任何调用站点。虽然不如细粒度

CFI

安全,但它仍

然极大地限制了攻击者的回旋余地,并且可以更快地在运行

时检查。

在现代机器上,某些形式的

CFI

甚至(或将要)得到硬件

的支持。例如,英特尔控制流强制技术(

CET

)支持影子堆栈

和间接分支跟踪,以帮助强制实施退货和前向控制传输的完

整性(以非常粗粒度的方式)。

ARM

也不甘示弱,它提供了指

针身份验证,以防止对指针值进行非法修改———主要是通过

使用指针的上位来存储指针身份验证代码(

PAC

),其功能类

似于加密指针值上的签名(除非获得正确的

PAC

,否则指针

无效)。

遗憾的是,函数指针和跳转

CFI

只能通过破坏返回地址、

目标等控制数据来帮助抵御改变控制流的攻击,但对非控制

数据攻击却无能为力。例如,它无法阻止覆盖当前进程的权

限级别并将其设置为“

root

”的内存损坏(例如通过将有效用

Copyright©博看网. All Rights Reserved.

44

计算机与网络

防火墙

器、中断、来自另一个的消息工艺等,如果用户进程为信号注

册了一个处理程序,操作系统将停止进程的当前执行,将其

所有处理器状态存储在进程堆栈上,形成所谓的信号,并在

信号处理程序上继续执行。当信号处理程序返回时,进程执

sigreturn

系统调用,使操作系统接管,还原堆栈上的处理

器状态并继续执行进程。

安全域(如操作系统内核和用户空间进程)之间的边界

是检查系统调用本身及其安全性参数的好地方。例如,在基

于功能的操作系统中,内核将验证功能,而在

MINIX3

等操

作系统中,只允许特定进程进行特定调用,因此任何尝试拨

打不在预先批准列表中的呼叫将被标记为违规。同样,基于

Windows

UNIX

的操作系统必须检查许多系统调用的参

研究表明,堆栈上的堆分配、全局变量甚至变量都可以分散

在内存中。当然,这样做会产生性能和内存方面的成本。

考虑到

KASLR

,尤其是粗粒度的

KASLR

,作为抵御内

存错误攻击的第一道防线,这不会离目标太远。不幸的是,它

也是一个非常薄弱的防御,许多出版物表明,通过从内存、侧

KASLR

可以相当容易地信道等泄漏数据和(或)代码指针,

被破解。

保护环

Multics

引入的最具革命性的想法之一是保护环的概

念———一种特权的分层,其中内环(环

0

)是最有特权的,并

且外环的特权最低。因此,不受信任的用户进程在外环中执

行,而直接与硬件交互的受信任和特权内核在环

0

中执行,

其他环可用于或多或少特权的系统进程。

保护环通常采用硬件支持,这是当今大多数通用处理器

提供的功能,尽管保护环的数量可能有所不同。例如,霍尼韦

6180

支持多达

8

个环,英特尔的

x86

支持

4

个,

ARMv7

3

个(加上

TrustZone

的额外

1

个)和

PowerPC

2

个。但

是,故事变得有点混乱,因为一些现代处理器也引入了更多

不同的处理器模式;大多数常规操作系统只使用

2

个环:一

个用于操作系统,一个用于用户进程。

每当权限较低的代码需要更多权限的函数时,它就会

“调用”下环以请求将此函数作为服务执行。因此,只有受信

任的特权代码才能执行最敏感的指令或操作最敏感的数据。

除非具有较少权限的进程诱骗更多特权的代码执行它不应

该做的事情(作为困惑的副手),否则环会提供强大的保护。

Multics的最初想法是,环之间的转换将通过实施严格控制和

数。例如,考虑常见的读写系统调用,通过这些调用,用户请

求将数据从文件或套接字读取到缓冲区中,或者从缓冲区分

别到文件或套接字中。在执行此操作之前,操作系统应检查

要写入或读取的内存是否实际归进程所有。

执行系统调用后,操作系统将控制权返回给进程,操作

系统还必须注意不要返回危及系统安全性的结果。例如,如

果一个进程使用

mmap

系统调用请求操作系统将更多内存

映射到其地址空间,则操作系统应确保它返回的内存页不再

包含来自另一个进程的敏感数据(如首先将每个字节初始化

为零)。

零初始化问题可能非常微妙,如编译器经常在数据结构

中引入填充字节以对齐。由于这些填充字节在编程语言级别

根本不可见,因此编译器可能认为没有理由将它们初始化为

零。但是,当操作系统返回此类数据结构以响应系统调用并

且单元化填充包含来自内核或其他进程的敏感数据时,就会

发生安全违规。

即使是

UNIX

系统中的信令子系统也是一个有趣的安

全案例。回想一下,

sigreturn

采用堆栈上的任何处理器状态并

恢复该状态。假设攻击者能够破坏进程的堆栈并在堆栈上存

储虚假信号帧,如果攻击者能够触发

sigreturn

,或可以设置整

个处理器状态(包括所有寄存器值),这样在熟练的攻击者手

中就提供了

一个强大的

基元,被称

sigreturn

导向编程

SROP

)。

如前所

述,为此,添

调解的特殊呼叫门进行。例如,外环中的代码不能调用内环

中的任何指令,而只能调用第一个调用的预定义入口点经过

审查,看它及其参数是否违反任何安全策略。

虽然像

x86

这样的处理器仍然支持呼叫门,但很少有操

作系统使用它们,因为它们相对较慢。相反,用户进程通过执

行操作系统处理的软件中断(陷阱),或更常见的是通过特殊

的高效操作过渡到操作系统内核(系统调用)。系统调用指令

(如

SYSCALL

SYSENTER

SVC

SCALL

等,具体取决于体

系结构)。许多操作系统将系统调用的参数放在一组预定义

的寄存器中。与调用门一样,陷阱和系统调用指令也确保在

操作系统中的预定义地址继续执行,代码在其中检查参数,

然后调用相应的系统调用函数。

除了用户进程调用操作系统外,大多数操作系统还允许

内核调用用户进程。例如,基于

UNIX

的系统支持操作系统

用来通知用户程序“有趣的事情”的信号:错误、过期的计时

Copyright©博看网. All Rights Reserved.

45

防火墙

计算机与网络

2022

■家修

近日,北京网际思安科技有限公司麦赛邮件安全实验室

MailSecLab

)研究发布了《

2022

年全球邮件威胁报告》(以下

简称“报告”),报告数据显示:在

2022

年,全球每

1000

个邮

箱,平均每月遭受的邮件攻击数量为

299.27

次(不含垃圾邮

件),同比增加

12.36%

根据报告研究人员的统计与分析,

2022

年全球邮件安全

威胁概况如下:

钓鱼邮件占邮件攻击的绝大部分,高达

68.47%

,紧随其

后的是病毒攻击和商业电子邮件(

BEC

)攻击;

来自我国域名

.cn

所关联的钓鱼网站数量正在快速上

升,目前已位居全球第

2

位,占比为

15.24%

全球遭受钓鱼邮件攻击数量最多的行业是批发与零售

业,相比

2021

年攻击数量激增

359%

Office

文件类型的病毒附件同比大幅下降,占病毒邮件

一年中每

1000

个邮箱,平均每月遭受的

BEC

邮件攻击数量

3.32

次。

钓鱼邮件威胁

根据麦赛邮件安全实验室的监测数据,美国已多年位

2022

年遭受了钓鱼邮件攻击数量的

41%

,相比居榜首,

遭受的钓鱼

2021

年占比增长了

5%

。俄罗斯相比

2021

年,

邮件攻击数量激增

427%

,且增长主要集中在俄乌地区冲

突爆发之后。与此同时,随着新加坡经济持续繁荣发展,该

2022

年比国遭受的钓鱼邮件攻击数量也保持持续增长,

2021

年增加了

245%

我国在

2022

年遭受的钓鱼邮件攻击数量仍居世界第

相比

2021

年的增长达到了

78%

2022

年,国内重大钓

2

位,

鱼邮件事件包括:

西北工业大学邮件系统遭受境外网络攻击

6

22

日西北工业大学发布声明称,近期学校电子邮件

总数的

19%

Windows

可执行文件类型仍然是最常见的病

毒附件类型,占比近

50%

BEC

攻击持续高速增长,同比增长近

60%

。在过去的

系统遭受网络攻击,有来自境外的黑客组织和不法分子向学

校师生发送包含木马程序的钓鱼邮件,企图窃取相关师生邮

独立的固件,并且始终处于活动状态:在启动过程中,当机器

运行时,当它处于睡眠状态时,即断电。只要计算机连接到电

源,就可以通过网络与

ME

通信,如安装更新。虽然非常强

大,但它的功能在很大程度上是未知的,除了运行自己的小

型操作系统,研究人员发现其中包含漏洞。主

CPU

附带的附

加处理器(无论是

ME

还是

Apple

T2

Google

Titan

片等相关处理器)都提出了一个有趣的点———在主

CPU

运行的操作系统是否能够满足当今的安全要求?至少,这种

趋势似乎通过专用系统(硬件和软件)来增强它的安全性。

低端设备和物联网

上述许多功能都可以在大多数通用处理器体系结构中

找到。然而,在物联网或一般的嵌入式系统中不一定如此,并

且通常使用定制的操作系统。简单的微控制器通常没有

有时甚至没有

MPU

、保护环或在常见操作系统中依赖

MMU

的任何高级功能。系统通常很小(减少攻击面),应用程序受

信任(并可能经过验证)。然而,设备的嵌入式性质使其很难

检查甚至测试其安全性,并且无论它们在安全敏感活动中发

挥作用的何处,安全性隔离

/

遏制和调解的手段应由环境在

外部强制执行。更广泛的物联网问题在网络物理系统安全

CyBOK

知识领域得到解决。

加了看起来像底部额外戒指的东西。由于在

x86

处理器上,

术语

ring0

已成为“操作系统内核”的同义词(以及“环”与“用

户进程”的同义词),因此这种新的虚拟机管理程序环通常

称为

ring

-

1

。它还指示其各自虚拟机中的操作系统可以继续

在本地执行环

0

指令。严格来说,它的目的与原始戒指大不

相同,虽然环-

1

这个名字已经卡住了,但它可能有点像用词

不当。

为了完整起见,应该提到的事情可能会变得更加复杂,

因为一些现代处理器仍然具有其他模式。例如,

x86

提供所谓

的系统管理模式(

SMM

)。当系统启动时,固件控制硬件,并

为操作系统接管系统做好准备。但是,启用

SMM

后,固件会

在向

CPU

发送特定中断时重新获得控制权。例如,固件可以

指示每当按下电源按钮时它都希望接收中断,在这种情况

下,常规执行将停止,固件将接管。例如,可以保存处理器状

态,执行任何需要执行的操作,然后恢复操作系统以进行有

序关闭。在某种程度上,(环-

2

SMM

有时被视为比其他环

低的水平。

英特尔甚至以英特尔管理引擎(

ME

)的形式增加了环

-

3

ME

是一个完全自主的系统,现在几乎存在于英特尔的

所有芯片组中。它在单独的微处理器上运行一个秘密且完全

Copyright©博看网. All Rights Reserved.

46