绕过 Firefox 的 WebUSB 支持:I-cant-believe-its-not-webusb
ArcaneNibble / **i-cant-believe-its-not-webusb ** Public
绕过 Firefox 中缺少 WebUSB 支持的技巧
License
0BSD license 90 stars 2 forks Branches Tags Activity
我们不需要该死的 WebUSB!
事实证明,有一种方法可以让网页访问 USB 设备,而无需 WebUSB 及其相关的政治争议! 不仅如此,设备还可以故意设计自身来绕过所有用户同意要求。
快速演示
将 u2f-hax.uf2 加载到 Raspberry Pi Pico (RP2040 版本) 上,然后从 localhost 或其他安全上下文中加载 index.html。
“On!” 和 “Off!” 按钮将切换 LED,并且引脚 GP22
的状态将定期在页面上更新(您可以方便地用一段电线或金属将其短接到相邻的 GND 焊盘)。
怎么做到的?!
Pico 被编程为模拟 U2F 加密狗(即物理双因素安全密钥)。 但是,它并没有执行任何安全功能,而是将任意数据走私到 U2F_AUTHENTICATE
消息的“密钥句柄”和签名中。 只要密钥句柄以 0xfeedface 开头,Pico 就会立即“确认”用户存在并返回数据。
为什么会这样?
按照设计,U2F 密钥句柄是一个不透明的数据块,在概念上“属于”安全加密狗。 它应该由加密狗作为注册结果返回,由依赖方按原样存储,然后在身份验证时按原样返回给安全加密狗。
此密钥句柄功能存在的一个原因是,使无限数量的网站能够与特定的低成本加密狗关联,而该加密狗的内存非常有限。 这种假设的加密狗在内部存储一个唯一的“主”加密密钥。 创建新注册时,它会创建一个新的公钥/私钥对,返回公钥,使用“主”密钥加密私钥,并_返回加密的私钥作为密钥句柄_。 无论创建多少个注册,加密狗都不必负责存储与它们关联的密钥。 当密钥句柄在身份验证期间传递回加密狗时,加密狗只需使用其主密钥解包私钥。
为了_允许_所有这些低成本设计,而不是_强制_任何特定的内部算法,密钥句柄被视为不透明的,因此我们可以滥用它来走私任意数据。
为了_返回_数据,我们需要以某种方式将其作为 ECDSA 签名走私。 ECDSA 签名是两个数字 $(r, s)$ 的元组,其中每个数字都以 $\mod n$ 计算,其中 $n$ 是椭圆曲线基点的_阶_。 这基本上意味着从 0 到 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 (secp256r1 基点的阶) 的任何值。 然后将这些数字打包到一些 ASN.1 中。
虽然_有时_可以判断 ECDSA 签名是“正确”计算出来的,还是我们刚刚编造的一些数字(参见 Issue #1),但除了依赖方之外,没有理由让任何人执行超出基本有效性检查的操作。 Chrome 似乎检查签名中的数字是否实际上在 0 到 $n$ 的范围内,但 Firefox 甚至不检查这一点。
因此,我们可以只生成一些虚拟 ASN.1,然后将我们实际想要发送的数据放入其中。 为了可靠地绕过 Chrome 的基本有效性检查,我们只需用值 0x7f 浪费每个数字的第一个字节。 这将导致数字始终为正数且小于 $n$。 整个软件堆栈直到浏览器 JavaScript 都会直接传递这些“足够有效”的数字。
最后,因为“访问 USB 设备”在政治上存在争议,但“使用户更安全”在整个浏览器行业中都获得了非常广泛的政治支持,所以这种功能得到了广泛支持,而无需额外的设置、配置或提示。
这是一个安全漏洞吗?
不。
这_不能_用于访问任意 USB 设备。 它只适用于_故意_违反规则的设备。 本质上,这是一个故意易受攻击的设备。
然而,众所周知,围绕 USB 设备的安全性模型通常......在大多数平台上都存在问题。 插入恶意 USB 设备允许它执行您自己可以使用键盘或鼠标等设备执行的任何操作。
不要将任意未知设备插入您的计算机(或您的手机等)。
关于
绕过 Firefox 中缺少 WebUSB 支持的技巧
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published