javascript 调用 程序-用几行JS读取笔记本上的所有数据?

2023-08-29 0 6,808 百度已收录

来源丨经授权转载自代码秘密花园(ID:code_mmhy)

作者丨ConardLi

大家好,我是ConardLi,之前为大家分析过很多浏览器策略:

很多朋友看完这些文章后都表示很困惑。 其实这个策略提到了一个漏洞:Spectre漏洞。 这个漏洞到底有何魔力,让浏览器频繁更新针对它的策略呢? ,今天我就给大家解释一下。

幽灵

如果一个漏洞构建起来比较困难,即使能够造成很大的危害,也可能不会引起浏览器如此大的关注。 那么我们的主角幽灵就很容易构造,而且造成的伤害也很大。 借助 Spectre,您可以:

只需几行 JavaScript,您就可以读取笔记本电脑/手机上的所有数据。 浏览器中的网页可以读取您的所有密码并知道其他程序在做什么。 这甚至不需要你写下的程序有漏洞就可以,因为这是计算机硬件层面的漏洞。

要理解Spectre,我们需要以下三个方面的知识:

其实都是一些特殊的计算机基础知识,你可能在中学就已经学过。 那么Spectre就巧妙地运用了前三个原则。 让我们一一看看。

你完全不用担心,我会用最简单的形式给你讲解,先把这类知识拆解,最后拼凑起来,看起来就很容易理解了。

记忆是如何运作的

首先我们的笔记本是由很多部分组成的:

当我们的计算机运行时javascript 调用 程序,程序从存储设备加载到CPU中,CPU负责处理大量的计算。 这些计算需要多次读取视频存储器中的数据。 然后将结果输出到我们的显示器等输出设备上,这大致就是计算机的简单工作原理。

接下来我们重点关注CPU和显存。 内存中存储着你正在运行的很多程序,包括系统、用户数据等,也存储着CPU运算的中间结果。

要存储如此多的信息,需要标准化的存储形式。 我们可以把显存想象成一堆排列好的小内存块,每个内存块存储一位信息。

另外,内存有很多层,CPU读取上面的数据非常慢,所以我们在CPU和内存中构建了几级缓存。 当我们取缓存的数据时,速度会更快。 那么当访问一个没有被缓存的数据时,该数据会在缓存内存中创建一个副本,下次访问的时候会非常快。

这就是显存的大致工作原理。 当然,这个过程就简化了很多。 我们只需要理解这里就可以了。

侧信道攻击

那么什么是侧信道呢?

我们可以简单地这样理解:如果你的程序的正常通信渠道之外还有另一个特征,这些特征反映了你不希望形成的信息,如果这个信息被别人收到了,你就会泄露它。 这种边缘特征形成的信息通道称为旁路。

例如,当你的显存在计算时,它会产生一个无线电波,它反映了显存中的内容。 有人用特定的方法收集这个无线电波,这就形成了旁路。 基于旁路的攻击称为旁路攻击。

常见的绕过包括:延迟、异常、能耗、电磁、噪声、可见光、错误信息、频率等。反正你的操作总是有边缘特征的,一不小心这个边缘特征就会泄露。 机会。

我们举一个根据信噪比旁路功率的例子:

假设我们希望笔记本验证密码,例如我们的密码是ConardLi。

我们从攻击者的角度来猜一下,密码是什么,我们从一个字母猜一下:

您注意到任何问题了吗? 我们的第一个字母是对的,但是计算机却告诉我们密码错误了0.1ms?

因为这次计算机发现第一个数字匹配后,需要验证第二个数字是否匹配,所以会花费更多的时间。 是不是很巧妙!

我们可以用同样的方式继续验证Ca,Cb,...Co,最终猜出我们的密码。

这时,我们的猜测时间与密码宽度呈线性关系,我们可以在O(n)的时间复杂度内猜出密码。 如果直接爆破的话,我们至少需要估算52的8次方!

这就是侧道攻击,这该死的魅力!

CPU 推测执行

上面我们提到,CPU在运行时,会频繁地从显存中读取信息。 但读取显存的速度非常慢,CPU为此花费了很长的时间空闲,只是等待显存的数据。 这似乎不是一个很好的解决方案。

那么,人们想,CPU能否推断出需要执行的命令呢?

假设我们有下面的代码来根据显存中的某个数据执行不同的语句:

if(Menory === 0){
  // 进行第一步计算
  // 进行第二步计算
  // 进行第三步计算
}

这里有两种可能,Menory为0或不为0。

这时CPU只会预测什么时候等待显存数据。 假设读显存返回0,CPU可以直接跑掉,无需等待显存返回:跳过if判断,直接执行上面的估计命令。

那么如果显存真的返回0,则CPU已经成功超前运行,CPU可以继续执行之前的命令。 但如果显存不返回0,CPU就会回滚之前执行的结果。

因此CPU执行时需要特别小心,不能直接覆盖寄存器的值,从而真正改变程序的状态,一旦发现预测失败立即回滚改变。

攻击原理

前面我们已经掌握了该漏洞利用的所有诱因,我们来看看它具体是做什么的。

假设底部是我们的缓存,读取它很慢。 系统内核将其阻塞并分配给不同的程序,如果考虑到云计算,则可能会分配给不同的虚拟机。

不同程序可能分配的内存块是相邻的,我们继续使用上一篇文章中的例子:

红色内存块存储受害者的数据,例如受害者的密码:

操作系统试图确保一个程序很难访问属于其他程序的内存块,并且不同程序的内存块是隔离的。

所以其他程序很难直接读取“受害者”(红色区域)的数据:

如果我们尝试直接访问黑色区域,肯定读不到,但缓存中可能已经有一些数据了。 接下来我们可以尝试利用缓存来做一些事情。

我们在蓝色内存块中放入一个链表A。 这段显存是属于我们程序的,可以合法访问javascript 调用 程序,但是它很小,只有两位。

但我们不满足于读取链表A中的两个元素,我们尝试超出A的范围(下标越界),访问A数组的第X位。 但X很可能超过A阵列的厚度。

通常情况下,CPU会停止这个操作,抛出一个错误:“非法操作”,然后操作就会被强制结束,但是我们可以尝试再次观察这个过程,看看它是怎么做的。

我们在允许访问的显存范围内创建一个新区域,可以称为工具箱。

我们非常要求CPU不要把这些数据复制到缓存中,而只保留在显存中,显存是一块连续的显存区域。

假设我们执行的命令是这样的,首先有一个if判断语句:

if(name === 'code秘密花园'){
  // ...
}

一般来说,CPU执行会先忽略这个判断,因为它需要等待显存返回name的值是否等于代码的秘密花园,因为有预测执行之类的技术,里面的东西if 语句会提前执行。

if(name === 'code秘密花园'){
  access Tools[A[x]]
}

我们尝试读取 Tools 的第 (A) 个元素。 假设我们读取的受害者内存包含3:

这是我们不应该阅读的内容,但我们可以通过推测执行执行以下操作:

当CPU执行完不应该执行的命令后,CPU认为需要检查A[X]的值。 验证下标是否越界,如果越界,程序将被强制终止。

因此,预测执行直接查询A[X]的值,然后发现A[X] = 3,即:

Tools[A[x]] = Tools[3]

也就是我们实际显存中Tools中存储的第四个元素a。 这是关键点:

CPU访问a后,将a(即Tools[3])放入缓存!

最后一步是遍历 Tool 中的每个元素。 我们发现访问前几个元素有点慢,直到访问第三个元素突然变得非常快! 因为第三个元素a在缓存中存储了一份副本!

当推测执行检测到错误时,它还会回滚寄存器更改,但不会回滚缓存!

由于访问第三个元素比其他元素花费的时间更少,因此信息被泄露! 这也称为基于时间的旁路。

所以,我们知道“受害者”在显存的这个位置有一个3。

稍后我们可以把工具区域做得更大,你就可以猜测更多其他数据了! 当然,这是实际攻击时需要考虑的损失~

对网络的影响

上述原理我们已经分析清楚了。 事实上,使用JavaScript来实现这个功能是非常容易的。 在JavaScript中,几乎可以绕过所有边界检测,从而实现任意显存边界读取。 我们可以看下面的代码:

if(index < array.length){
  index = array[index | 0];
  index = (((index * TABLE_STRIDE) | 0) & (TABLE_BYTES - 1)) | 0;
  localJunk ^= probeTable[index | 0] | 0;
}

来自不同站点的多个页面最终可能会在浏览器中共享单个进程。 当使用 window.open 或 iframe 打开另一页面时,可能会出现问题,并且如果一个网站包含特定用户的敏感数据,则另一个网站可以利用此类漏洞读取该用户的数据。

上面只是一个简单的例子。 事实上,实际的攻击范围比这要广得多。 为此,浏览器制定了很多安全策略来解决这个问题。 下面我们就来看看:

浏览器策略缓存推荐设置

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 javascript javascript 调用 程序-用几行JS读取笔记本上的所有数据? https://www.wkzy.net/game/180567.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务