大家好,我是周杰伦。
提到网络攻击技术,你脑子里首先想到的是什么?
是DDoS
?
是 SQL 注入、XSS
?
还是栈溢出、RCE
(近程代码执行)?
这些最常见的网络攻击技术,基本上都是与网络、软件、代码、程序这些货色相干。
这也好了解,计算机网络安全,不跟这无关,还与什么有关系?
明天跟大家介绍一下,攻打技术,除了这些,还有一些脑洞大开的形式,它们可能跟 工夫、触动、频率、温度
等各种物理相干的元素相干,看完相对让你瞠目结舌!
这些不同于传统软件平安方向,而是从其余侧面进行的网络攻击,称作 侧信道攻打 ,也叫 边信道攻打。
内存冷冻
请大家思考一个问题:如果计算机忽然断电,内存里的数据是不是霎时就没了?
内存大家都晓得,计算机运行离不开这货色,程序指令和数据都存储在这里,但你晓得内存条存储数据的原理吗?
看到图中那一块块彩色的货色了吗?那就是内存条存储数据的中央:内存颗粒。
在内存颗粒外面,是超大规模集成电路,外面是稀稀拉拉的存储单元格,每一个单元格存储一个比特位:
这个单元格中的核心部件是一个电容,电容有电压,如果电压在肯定范畴内,这个单元格就是 1,否则就是 0。通过无数个这样的单元格,形成了 GB 级的存储空间。
但大家学过物理应该晓得,电容是一个不稳固的元件,随着工夫的流逝,电荷会透露,如果不加以控制,内存条中的电压最终就会变成 0,内存中的数据也就不精确了。
因而,内存在工作的时候,须要定时的进行数据刷新,对电容进行充电,个别最多 64ms 就得充一次电,能力保留数据的准确性。
好了,内存的背景常识交代结束,当初回到本节一开始提到的那个问题:计算机忽然断电了,内存中的数据霎时就没了吗?
内存中的数据是通过电容这种电子元件在承载,电容充放电都是须要工夫的,所以能够大胆猜想,即便断电了,内存中的数据全副隐没也是须要工夫的。
国外有人脑洞大开,做了一项试验,测试内存条断电后,外面的数据随着工夫的流逝,隐没的状况。
一般数据不不便察看,用图片最间接,试验中将一张蒙娜丽莎的图片载入内存中,而后断电,而后计算不同工夫后,这张图的变动状况:
能够看到,在断电后的 5s 内,图片数据肉眼上看不到变动,30s 后也影响不大,一分钟后也能依稀可见,5 分钟后才彻底看不到。
而更重要的是,如果温度升高时,电容中电荷脱漏的速度将更加迟缓。上面这个表格是测试内存条数据错误率在失常状况和冷冻状况下的比拟。
如上图所示,红色框是不冷冻状况,蓝色框是在零下 50 摄氏度状况,能够看到,在冷冻状况下,一分钟后,数据的错误率是 0,即使是在 300 秒(5 分钟)后,错误率也只有惊人的 0.0095%。
所以,一种新的攻击方式就进去了:应用内存冷冻的形式,能够从内存条中提取数据。
内存中有什么数据?很多程序的明码密钥可能都存在于内存之中,最典型的比方 Windows 的开机明码。
认为电脑关机了就平安了?可不是这么回事哦!
熔断与幽灵
熔断与幽灵破绽攻打大家应该不会生疏,在 2017 年刚刚暴发进去的时候,占据了有数媒体的头条,可见影响力之广。
在讲述这个破绽之前,先请大家看一个故事。
学过计算机组成原理的敌人可能都晓得,CPU 有两个重要的个性:分支预测和乱序执行。
在执行到判断分支的时候(比方 if 判断),CPU 会依据它本人的“教训”来判断,一会儿可能会走入哪一个分支,从而提前执行一些这个分支的指令,这叫分支预测。
另外,CPU 在执行一些指令的时候,可能并不是依照程序一条执行完再执行下一条,而是可能在会预执行一些 CPU 认为能够提前执行,对程序流程无关的指令,这个叫乱序执行。
但 CPU 认为能够提前执行,那就真的能够提前执行吗,执行了可能对程序自身流程没有影响,但会不会有什么副作用呢?
先留这个问题,一会儿再说,先来看另一个概念:缓存。
CPU 执行程序须要频繁与内存通信,读取数据或者写入数据。但内存的响应速度比 CPU 慢多了,于是 CPU 在其外部加了一块缓存,将最近要用的数据放到这里来,防止每一次都从内存拜访,进步工作效率。
因而,同样读取一个数据,从内存读和从缓存读,工夫上是有差别的。
熔断与幽灵正是利用这一点,来进行了零碎攻打。
如果你想读取操作系统内核的数据,但因为系统安全机制,应用程序是无奈间接拜访内核空间的,但这个破绽就能够帮你实现内核空间数据的读取。
上面这段程序,先执行几十次,每次传入的 x 都小于 16,每次都走入同一个分支,训练 CPU,让它取得一些“教训”,让它认为 < 16 是大概率要执行的分支,而后启用乱序执行,提前执行 x < 16 这个分支中的指令。
void bad_guy(int x) {if (x < 16) {temp &= array2[array1[x] * 512];
}
}
来看一下,在下面这个例子中,x < 16 这个分支中会通过 array1 这个数组拜访内存,假如 x 忽然来了一个很大的数,这样通过 array1[x]拜访的内存地址就溢出到了内核空间了。
乱序执行的结果,会提前计算 array1[x] * 512,并将其作为下标拜访 array2 数组的内容,而后会将这个内容从内存条加载到 CPU 缓存中。
忽然冷不丁的来一个大于 16 的参数,这下它提前执行的指令就徒劳了。
而随后,CPU 发现了这一次 x 是大于 16 的,不应该走到这个分支中来,下面形容的这一段活就白干了。
尽管是白干了,但它做了一件事:把 array2 数组对应下标的那一块数据从内存搬到缓存了。
这时再顺次拜访 array2 数组的每一个元素,就能晓得方才的下标,再进一步能够推断出那个内核空间的值。
而后一直变换 x 的输出,能够晓得任意内核地址空间的数据。
这就是熔断与幽灵破绽的核心思想:通过分支预测 + 乱序执行 + 缓存内存拜访工夫差别来推断内核数据。
计时攻打
熔断与幽灵,其实是利用了 CPU 拜访内存和拜访缓存的时间差来走漏信息,从而实现数据透露,也就是说,利用的外围是 工夫 这个物理量。
而利用工夫的另一个经典攻击方式就是计时攻打。
给大家举个例子,如果要应用 C 语言编写一个函数,用来判断输出的明码是否正确,有人可能会这样写:
bool check_passwd(char* input) {
bool result = false;
const char* passwd = "XiaoBaiGe2021";
if (input) {if (strlen(input) != strlen(passwd)) {return false;}
const char* p1 = input;
const char* p2 = passwd;
while (*p1 && *p2) {if (*p1 == *p2) {
p1++;
p2++;
} else {break;}
}
if (*p1 == '\0' && *p2 == '\0') {result = true;}
}
return result;
}
下面这个函数中,在正式的字符串比拟之前,先进行了长度的比拟,如果长度都不同,那就不必比拟了,节省时间。
但这个看上去很聪慧的做法,实际上可能会给攻击者提供了信息参考。
通过输出不同长度的字符串,发现程序验证所破费的工夫不同,攻击者可能猜测出真正明码的长度。
接下来的验证过程中,开始逐位比拟字符串的每一位,乍一看也没故障,但同样的问题,如果第一位就比拟谬误,程序很早就退出,而如果比拟的工夫绝对较长,则阐明明码的前几位可能是正确的。
通过这些信息,而后进行一直尝试,明码能够在短时间内破解进去,是不是感觉不堪设想?这是已经产生过的实在案例。
正则表达式
正则表达式在字符串校验、文本提取、格式化解析等畛域有十分宽泛的利用,基本上所有支流的编程语言都有对应的程序库。
但你晓得正则表达式的解析引擎是如何工作的吗,你晓得如果传入一些特定的字符串,可能让解析引擎陷入微小的计算陷阱吗?
正则表达式的解析引擎有一个重要的流派就是基于 NFA,这是一种状态机。随着解析引擎的逐字符解析,状态机可能会有不同的下一个状态。因为每一个状态都有许多个下一个状态,解析引擎可能会在这条链路上一直前行,直到找到一个匹配的。
比方在 《白帽子讲 Web 平安》 一书中所提到的例子:
点击下方支付《白帽子讲 Web 平安》 高清 PDF 版
【点我支付】
有一个这样的正则表达式:^(a+)+$
如果输出四个字符 ’aaaa’,解析引擎的执行过程是这样的:
它只有 16 条门路,很快就能走完。
但如果输出的字符 a 大量减少时,执行的门路将会暴增。
能够看到,随着后续字符串长度的减少,破费的工夫开始呈 2 倍增长趋势。如果输出 64 个字符 a,那将会是什么结果?
CPU 飞转,程序失去响应,服务回绝攻打 DOS!
没想到吧,你只是输出了一个正则表达式字符串,就能让服务器失去响应。
点击下方支付《白帽子讲 Web 平安》 高清 PDF 版
【点我支付】
总结
以上就是明天给大家介绍的一些侧信道攻打技术。