详细介绍:基于伪随机数的WPS PIN码逆向原理分析(精灵尘埃/仙尘攻击)

news/2025/9/23 17:16:11/文章来源:https://www.cnblogs.com/tlnshuju/p/19107549

详细介绍:基于伪随机数的WPS PIN码逆向原理分析(精灵尘埃/仙尘攻击)

2025-09-23 17:11  tlnshuju  阅读(0)  评论(0)    收藏  举报

文章目录

    • 1 WPS连接过程
      • 1.1 初始阶段
      • 1.2 注册阶段
    • 2 WPS攻击原理
      • 2.1 在线攻击
      • 2.2 离线攻击
        • 2.2.1 Ralink模式
        • 2.2.2 eCos模式
    • 3 参考资料

在2011年 Stefan Viehböck 演示过WPS的在线暴力攻击,由于PIN码猜测最多只需11000种组合,平均6小时就能攻破一台路由器。而在2014年 Dominique Bongard 又演示了一种离线暴力坡解的攻击,这种可怕的攻击可在不到一秒时间内破译WPA密钥,Bongard先生还在其幻灯片结尾发出警告:“立即禁用WPS!”

WPS(Wi-Fi Protected Setup)是一项旨在简化无线网络安全配置的标准,它通过PIN码(Personal Identification Number)或PBC(Push Button Configuration)等方式,使家庭用户能够轻松地将新设备安全地接入Wi-Fi网络。在PIN码模式下,WPS使用EAP-WSC(Extensible Authentication Protocol for Wi-Fi Simple Configuration)协议完成认证与密钥交换过程,该过程包含八个阶段(M1-M8)的消息交换。本文将深入探讨这八个阶段的详细流程,并重点分析其中涉及的关键参数(如E-Hash1、E-Hash2、PKE、PKR、AuthKey、E-Nonce等)的作用与相互计算关系。通过对这些参数和流程的理解,我们能够更深入地认识WPS的安全机制及其潜在脆弱性。

1 WPS连接过程

在WPS中有两个角色概念Enrollee和Registrar,Enrollee是入网设备(即手机物联网家居等各种终端),Registrar为认证服务器,一般也由AP(即路由器等设备)充当。

1.1 初始阶段

img

【发现过程】

  1. AP端的WSC开始工作后,它会广播带有WSC IE字段的beacon包,以声明AP支持WSC

  2. 如果Enrollee收到来自AP的端的beacon包,那么它会解析beacon包中的 WSC IE,并向AP发送单播Probe Request包;如果Enrollee没有收到带有WSC IE的beacon包,那么它就会去搜索周围支持WSC的AP,所以会向周围发送Probe Request广播包。

    如果Enrollee发现周围有两个或者两个以上的AP在跑WPS,则Enrollee会在发现阶段停止继续执行;同理,如果AP发现有两个或两个以上的Enrollee在尝试建立WPS连接,AP也会停止运行WPS。如果哪一天按下你router的WPS按钮,发现wps灯快闪了几下就不闪了,可能就是当时同时有两个Enrollee在尝试WPS连接。

  3. AP收到带有 WSC IE的Probe Request请求包以后,就会回复Probe Response包,这个包里面带有WSC IE,会告诉Enrollee一些信息,这些信息很多,Enrollee会根据这些信息来决定下一步的动作

【关联过程】

  1. 对于PIN WPS需要在这个步骤输入PIN,对于PUSH BUTTON则不需要输入,当然PIN有分AP PIN和client PIN,这个决定了需要在AP端还是在Enrollee端输入PIN, 这种输入都是in-band的方式,当然也可以使用out-band的方式输入信息,如NFC
  2. 当Enrollee获取到AP端的信息,并且通过判断符合接入条件的时候,Enrollee会尝试去和AP进行认证,向AP发送Auth包
  3. AP端回复Auth 成功包,认证成功
  4. 然后Enrollee发送Association Request 关联请求包,并附带WSC IE 信息,这个信息很重要,目的是告诉AP我这边使用的协议(如802.1x WPS 1.0 协议),我们接下来的M1-M8过程也将会遵守这个协议进行交互,如果不能接受这种协议的话,请及时告诉我。
  5. 这时,AP端表示这种协议是支持的,发送一个Association Response包给Enrollee,完成关联。

【准备过程】

  1. 发送EAPOL-Start
  2. 在STA和AP双方开展EAP-WSC流程前,AP需要确定STA的Identity以及使用的身份验证算法。该过程涉及三次EAP包交换。这三次包交换的内容,首先,AP发送EAP-Request/Identity以确定STA的ID
  3. 对于打算使用WSC认证方法的STA来说,它需要在回复的EAP-Response/Identity包中设置Identity为"WFA-SimpleConfig-Enrollee-1-0"。
  4. AP确定STA的Identity为"WFA-SimpleConfig-Enrollee-1-0"后,将发送EAP-Request/WSC_Start包以启动EAP-WSC认证流程。而后进入WPS认证与配置的M1~M8阶段。

1.2 注册阶段

WPS使用EAP-WSC(EAP for Wi-Fi Simple Configuration)协议来完成配置过程,这部分是WPS的核心部分。该协议基于EAP(Extensible Authentication Protocol)框架,但专门用于WPS的设备注册流程。整个认证过程包含8个消息交换阶段(M1至M8),这些消息通过EAPoL-Data帧在Enrollee(设备)和Registrar(AP)之间传输,安全地交换配置信息(如 SSID、网络密钥等)。

消息方向说明主要作用与内容
M1设备 → AP发起注册Enrollee 发送能力信息和公钥PKE和随机数N1,启动注册流程。
M2AP → 设备派生密钥Registrar 发送能力信息和公钥PKR和随机数N1,并开始密钥派生。
M3设备 → AP生成证明Enrollee 发送设备PIN码的哈希证明E-Hash1E-Hash2
M4AP → 设备生成证明Registrar 回应设备PIN码的哈希证明R-Hash1R-Hash2,并提交第一个秘密随机数R-S1
M5设备 → AP验证证明Enrollee 提交第一个秘密随机数 E-S1
M6AP → 设备验证证明Registrar 提交第二个秘密随机数 R-S2
M7设备 → AP验证证明Enrollee 提交第二个秘密随机数 E-S2
M8AP → 设备配置网络Registrar 发送最终的加密配置信息(如 SSID、网络密钥等)。

deepseek_mermaid_20250908_59dba1

【建立加密】

  • 【M1】:初始化注册请求,提供Enrollee设备信息和安全能力。Enrollee选择随机数 A 为私钥,计算公钥 PKE = g^A mod p (使用指定的 1536-bit MODP 群)。

    发送UUID-E, MAC-E, PKE, N1(Enrollee随机数), Device Password ID, 能力属性等。

  • 【M2】:响应注册请求,提供Registrar信息并启动密钥交换。Registrar选择随机数 B 为私钥,计算公钥 PKR = g^B mod p

    发送UUID-R, PKR, N2(Registrar随机数), N1(回显), Auth_M2, 能力属性等。

根据交互的公钥与随机数,双方相互独立计算出共享密钥DHShared和密钥派生密钥KDK:
DHShared=PKEBmodp=PKRAmodp=g(A⋅B)modpDHKey=SHA-256(zeropad(DHShared,192))KDK=HMAC−SHA256(DHKey,N1∣∣MAC−E∣∣N2)DHShared = PKE^B \mod p = PKR^A \mod p = g^{(A \cdot B)} \mod p\\ DHKey = \text{SHA-256}(\text{zeropad}(DHShared, 192))\\ KDK = HMAC-SHA256(DHKey, N1 || MAC-E || N2) DHShared=PKEBmodp=PKRAmodp=g(AB)modpDHKey=SHA-256(zeropad(DHShared,192))KDK=HMACSHA256(DHKey,N1∣∣MACE∣∣N2)
最终派生出两个关键的会话密钥AuthKey和KeyWrapKey:
AuthKey∣∣KeyWrapKey∣∣EMSK=kdf(KDK,"Wi−FiEasyandSecureKeyDerivation",640)AuthKey || KeyWrapKey || EMSK = kdf(KDK, "Wi-Fi Easy and Secure Key Derivation", 640) AuthKey∣∣KeyWrapKey∣∣EMSK=kdf(KDK,"WiFiEasyandSecureKeyDerivation",640)

PS:kdf 是使用 HMAC-SHA256 的迭代函数,输出 640 位,分割为:

  • AuthKey (256 bits): 用于消息认证 (HMAC)。
  • KeyWrapKey (128 bits): 用于加密敏感数据 (AES)。
  • EMSK (256 bits): 扩展主会话密钥,可用于派生其他应用密钥。

M2中的Auth_M2 = HMAC-SHA256(AuthKey, M2_Data)M2_Data 是 M2 消息中在 Authenticator 属性之前的所有属性。后续M3-M8的Auth_MX计算同理。

至此,双方通过Diffie-Hellman密钥交换算法已共享 KDK, AuthKey, KeyWrapKey,为后续加密和认证打下基础。

【验证PIN码】

  • 【M3】:Enrollee其证明持有PIN码。Enrollee将PIN码分割为两部分(如8位PIN码12345670左右均分为1234和5670),再派生出PSK1PSK2
    PSK1=First−128−bits−of(HMAC−SHA256(AuthKey,First−Half−Password))PSK2=First−128−bits−of(HMAC−SHA256(AuthKey,Second−Half−Password))PSK1 = First-128-bits-of( HMAC-SHA256(AuthKey, First-Half-Password) )\\ PSK2 = First-128-bits-of( HMAC-SHA256(AuthKey, Second-Half-Password) ) PSK1=First128bitsof(HMACSHA256(AuthKey,FirstHalfPassword))PSK2=First128bitsof(HMACSHA256(AuthKey,SecondHalfPassword))
    然后生成秘密随机数E-S1, E-S2 (各 128 bits),计算证明哈希E-Hash1E-Hash2
    E−Hash1=HMAC−SHA256(AuthKey,E−S1∣∣PSK1∣∣PKE∣∣PKR)E−Hash2=HMAC−SHA256(AuthKey,E−S1∣∣PSK2∣∣PKE∣∣PKR)E-Hash1 = HMAC-SHA256(AuthKey, E-S1 || PSK1 || PKE || PKR)\\ E-Hash2 = HMAC-SHA256(AuthKey, E-S1 || PSK2 || PKE || PKR) EHash1=HMACSHA256(AuthKey,ES1∣∣PSK1∣∣PKE∣∣PKR)EHash2=HMACSHA256(AuthKey,ES1∣∣PSK2∣∣PKE∣∣PKR)
    发送 N2(回显), E-Hash1, E-Hash2, Auth_M3。

  • 【M4】:Registrar其证明持有PIN码,提供秘密随机数让Enrollee验证PIN码第一部分。Registrar按同样方法分割PIN码并派生PSK1和PSK2,再生成秘密随机数R-S1, R-S2 ,计算证明哈希R-Hash1R-Hash2
    R−Hash1=HMAC−SHA256(AuthKey,R−S1∣∣PSK1∣∣PKE∣∣PKR)R−Hash2=HMAC−SHA256(AuthKey,R−S1∣∣PSK2∣∣PKE∣∣PKR)R-Hash1 = HMAC-SHA256(AuthKey, R-S1 || PSK1 || PKE || PKR)\\ R-Hash2 = HMAC-SHA256(AuthKey, R-S1 || PSK2 || PKE || PKR) RHash1=HMACSHA256(AuthKey,RS1∣∣PSK1∣∣PKE∣∣PKR)RHash2=HMACSHA256(AuthKey,RS1∣∣PSK2∣∣PKE∣∣PKR)
    而后生成随机数IV(128bit),结合KeyWrapKey将第一个秘密随机数R-S1加密到EncryptedSettings,并使用AuthKey生成KWA以保护R-S1的完整性:
    KWA=First−64−bits−of(HMAC−SHA256(AuthKey,R−S1))DataToEncrypt=R−S1∣∣KWAEncryptedSettings=AES−Encrypt−CBC(KeyWrapKey,IV,DataToEncrypt)KWA = First-64-bits-of( HMAC-SHA256(AuthKey, R-S1) )\\ DataToEncrypt = R-S1 || KWA\\ EncryptedSettings = AES-Encrypt-CBC(KeyWrapKey, IV, DataToEncrypt) KWA=First64bitsof(HMACSHA256(AuthKey,RS1))DataToEncrypt=RS1∣∣KWAEncryptedSettings=AESEncryptCBC(KeyWrapKey,IV,DataToEncrypt)
    发送 N1(回显), R-Hash1, R-Hash2, EncryptedSettings (R-S1), IV, Auth_M4。

  • 【M5】:Enrollee提供秘密随机数让Registrar验证PIN码第一部分。Enrollee解密R-S1并验证其完整性:
    Data∣∣KWA′=AES−Decrypt−CBC(KeyWrapKey,IV,EncryptedSettings)KWA′==First−64−bits−of(HMAC−SHA256(AuthKey,R−S1))Data || KWA' = AES-Decrypt-CBC(KeyWrapKey, IV, EncryptedSettings)\\ KWA' == First-64-bits-of( HMAC-SHA256(AuthKey, R-S1) ) Data∣∣KWA=AESDecryptCBC(KeyWrapKey,IV,EncryptedSettings)KWA==First64bitsof(HMACSHA256(AuthKey,RS1))
    使用解密得到的 R-S1 和自己已知的 PSK1, PKE, PKR 重新计算 R-Hash1,与 M4 中的值比较。若计算不一致,触发WSC_NACK终止会话(后续同)。然后使用同样方法将自己的第一个秘密随机数E-S1加密到EncryptedSettings

    发送 N2(回显), EncryptedSettings (E-S1), IV, Auth_M5。

  • 【M6】:**Registrar提供秘密随机数让Enrollee验证PIN码第二部分。**Registrar解密E-S1并计算E-Hash1,将自己的第二个秘密随机数R-S2加密到EncryptedSettings

    发送 N1(回显), EncryptedSettings (R-S2), IV, Auth_M6。

  • 【M7】:**Enrollee提供秘密随机数让Registrar验证PIN码第二部分。**Enrollee解密R-S2并计算R-Hash2,将自己的第二个秘密随机数E-S2加密到EncryptedSettings

    发送 N2(回显), EncryptedSettings (E-S2 + Config-if-AP), IV, Auth_M7。

【配置网络】

  • 【M8】:**完成验证并配置网络。**Registrar解密E-S2并计算E-Hash2,双向认证全部完成。组装ConfigData网络配置信息:
    ConfigData=Credential(SSID,NetworkKey,AuthType,EncType,...)ConfigData = Credential (SSID, Network Key, AuthType, EncType, ...) ConfigData=Credential(SSID,NetworkKey,AuthType,EncType,...)
    同样使用 KeyWrapKey 加密 ConfigData (过程同前,附加 KWA)。

    发送 N1(回显), EncryptedSettings (ConfigData), IV, Auth_M8。最终Enrollee 解密并应用 ConfigData,协议完成。

【通俗解释】

  1. Enrollee (手机):“你好路由器,我想加入网络,这是我的信息(M1)。”
  2. Registrar (路由器):“好的手机,请证明你知道PIN码。验证通过后,我就把Wi-Fi密码给你(M2)。“
  3. 双方都生成两个上锁的箱子(E-Hash1/E-Hash2, R-Hash1/R-Hash2),里面是能证明自己身份的秘密。箱子的钥匙(E-S1/E-S2, R-S1/R-S2)在自己手里。Enrollee 先把自己的两个锁上的箱子(M3)交给 Registrar,说:“给,这是我的证明。”
  4. Registrar 说:“好吧,但我看不到里面。为了表示诚意,这是我能打开你第一个箱子的钥匙(加密的R-S1),同时我也把我的两个锁上的箱子(R-Hash1/R-Hash2)给你。”(M4)
  5. Enrollee 用只有自己才有的密钥(KDK)解密拿到钥匙(R-S1), 打开Registrar的第一个箱子(验证R-Hash1)。一旦验证成功,Enrollee 就确信 Registrar 知道真正的 PIN。于是,Enrollee 放心地把打开自己第一个箱子所需的钥匙(E-S1)交给 Registrar(M5)。
  6. Registrar 用 E-S1 验证 Enrollee 的第一个箱子(E-Hash1),也确认了 Enrollee 的身份。后续的 M6、M7 重复这个过程,用第二对箱子和钥匙(E-Hash2/E-S2, R-Hash2/R-S2)进行二次确认。

2 WPS攻击原理

2.1 在线攻击

PIN码为8位纯数字,而第8位为前面1-7位的校验和,所以总共只有10的7次方种组合。而由于PIN码的验证过程是分段式的,即先验证前4位,再验证后4位,则攻击者只需先猜测前4位组合(104),再猜测后四位组合(103),即最多11000种组合即可猜出正确PIN码。而WPS协议最初默认没有对PIN的验证次数进行限制,这就使在线PIN坡解成为了可能。传统的在线攻击方案可以借助 reaver 或 bully 简便地实现,信号良好情况下大约 3s/pin(WPS1.0,无锁 PIN 现象),平均几小时即可攻破一台路由器。

image-20250910002321896

注意在WPS在线攻击中,攻击者电脑扮演的是Registrar,而受攻击路由器则充当Enrollee(与前面分析的逻辑相反)。攻击工具(如reaverbully)运行在攻击者的电脑上(Supplicant/Client)。它宣称自己是一个“外部注册器(External Registrar)”,使受攻击目标接受管理并传输网络配置信息。

image-20250910212210563

攻击者通过遍历所有PIN码组合,发送M4帧后根据是否收到AP回复的WSC_NACK来确定前半段PIN码是否正确,若不正确则递增下一个组合。直到猜中前半段PIN码,再发送M6帧并根据是否收到AP回复的WSC_NACK来确定后半段PIN码是否正确,最终完全确认整个PIN码。

image-20250910195829673

2.2 离线攻击

现在多数路由器都是 WPS2.0(WSC),会出现锁 PIN 现象,一定程度提高了安全性。可就算是几次 PIN 尝试的机会,也留给了攻击者可乘之机。2014年Dominique Bongard演示了一种离线WPS的方法,对某些存在安全漏洞的路由器可在不到一秒内破译。该攻击利用了某些路由厂商芯片只能生成低熵的伪随机数,进而坡解加密过程。攻击称为“pixie-dust attack”,翻译为“小精灵尘埃攻击”或“仙尘”攻击(外国人起名灵感感觉大都跟游戏影视作品有关)。

image-20250909172542790

入网设备和AP之间没有传输PIN码,是通过计算PIN码的Hash值来验证的。如果PIN码验证失败,流程会止于M4阶段。根据之前在线PIN坡解过程分析,攻击者可以获取到PIN码最终计算产物E-Hash1和E-Hash2(AP发送的M3帧),以及中间计算值AuthKey、PKE、PKE,而初始参数PIN码与两个中间计算使用的随机数E-S1和E-S2是不知道的。但是如果攻击者能猜测到AP生成的随机数E-S1和E-S2,就可以通过代入所有PIN码组合去猜测验证,最终获取到PIN码。

其实这里笔者有点疑惑,为什么攻击者不按常规流程充当Enrollee角色,去获取AP发送的M4帧,这样还可以多获取到一个随机数信息。可能是因为代码是基于reaver改编的分支,而reaver就是使用Registrar角色去进行攻击吧。

那么怎么能猜到AP生成的随机数呢?Dominique Bongard发现某些路由器的芯片生成的是不安全的伪随机数(Pseudo-Random Number Generator,PRNG),导致其可以通过上一个随机数进行逆向预测。例如,Broadcom基本上使用C中的Rand()函数,在Ralink中随机数始终不会生成(因此为0),而RTL819x生成的随机数存在复用(N1、E-S1、E-S2均相同)。

易受攻击的路由器收录:https://docs.google.com/spreadsheets/d/1tSlbqVQ59kGn8hgmwcPTHUECQ3o9YhXR91A_p7Nnj5Y/edit#gid=2048815923

在攻击过程中,M1阶段受攻击路由器会生成随机数N1(E-Nonce),到M3阶段又会生成的随机数E-S1和E-S2,这两个随机数是紧接着N1生成的。而N1可以直接捕获到,如果路由器生成的是伪随机数,就可以进行逆向分析。下面分析pixiewps源码中的两种逆推伪随机数的模式:Ralink模式(直接计算)和eCos模式(暴力枚举)。

2.2.1 Ralink模式
//Ranlink随机数生成
static unsigned char ralink_randbyte(struct ralink_randstate *state)
{
unsigned char r = 0;
for (int i = 0; i <
8; i++) {
unsigned char result;
if (state->sreg &
0x00000001) {
// 检查LSB
state->sreg = ((state->sreg ^ 0x80000057) >>
1) | 0x80000000;
result = 1;
}
else {
state->sreg = state->sreg >>
1;
// 简单右移
result = 0;
}
r = (r <<
1) | result;
// MSB优先累积
}
return r;
}

伪随机数生成流程:

  1. 选定一个初始的数S0,在LFSR中通常称为状态(可以理解为种子,如:1010…1011 ,共32位),先取最低位(Least Significant Bit,LBS)作为输出随机数的第一位(最左边的一位)。
  2. 如果最低位为1则S0与多项式(0x80000057)进行异或操作,如果最低位为0则不变,得到S0‘。
  3. 对S0‘右移一位,如果进行了异或操作则高位补1,如果没有操作则高位补0,得到S1。
  4. 接着重复这个过程,再次对S1取值、操作、右移,一步步得到随机数的第二、三、…、八位,循环做8次就可以得到1字节(8bit)的随机数。而N1为16字节,则需做8x16次运算。
static void ralink_randstate_restore(struct ralink_randstate *state, uint8_t r)
{
for (int i = 0; i <
8; i++) {
const unsigned char result = r &
1;
// 取LSB(从后向前处理)
r = r >>
1;
if (result) {
// 如果输出位是1
state->sreg = (((state->sreg) <<
1) ^ 0x80000057) | 0x00000001;
}
else {
// 如果输出位是0
state->sreg = state->sreg <<
1;
// 简单左移
}
}
}

通过随机数逆向种子:

由随机数的最后一位,可以知道上一次的操作数Sn的最后一位(如果随机数最后一位是0,则Sn’的最后一位为0;如果随机数最后一位是1,则Sn’的最后一位为1)。同理,由随机数倒数第二位,可以知道上上次的操作数Sn-1的最后一位,以此类推。由于知道每次操作数的最后一位,从最后一次操作数Sn开始进行补值、操作、左移(逆运算)。

  1. 如假如随机数最后一位为1,则设最后一次操作数Sn为0000…0001(最后一位为0则设0000…0000,最后一位前面的值随便设,因为后续会不断左移去掉)。
  2. 然后观察随机数倒数第二位,倒数第二位为1,则说明Sn-1’到Sn做了异或操作,那么需要再与多项式(0x80000057)做一次异或操作使其变为Sn-1’;如果随机数倒数第二位为0,则无需操作Sn即Sn-1’。
  3. 将Sn-1‘左移,然后末尾补随机数的倒数第二位,变为Sn-1。
  4. 重复这个过程,直至将最开始Sn的最后一位左移到第一位。一共32位,所以做31次即可逆向出某个时刻的操作数(种子)。
static unsigned char ralink_randbyte_backwards(struct ralink_randstate *state)
{
unsigned char r = 0;
for (int i = 0; i <
8; i++) {
unsigned char result;
if (state->sreg &
0x80000000) {
// 检查MSB
state->sreg = ((state->sreg <<
1) ^ 0x80000057) | 0x00000001;
result = 1;
}
else {
state->sreg = state->sreg <<
1;
// 简单左移
result = 0;
}
r |= result << i;
// LSB优先累积
}
return r;
}

通过种子逆向生成随机数:

前面是通过种子往后生成随机数,这个代码是通过种子往前生成随机数,过程类似。

  1. 选定一个初始的数Sn,先取最高位(Most Significant Bit,MSB)作为输出随机数的最后一位(最右边的一位,这里是第八位)。
  2. 如果最高位为1则S0与多项式(0x80000057)进行异或操作,如果最高位为0则不变,得到Sn‘。
  3. 对Sn‘右移一位,如果进行了异或操作则低位补1,如果没有操作则低位补0,得到Sn-1。
  4. 接着重复这个过程,再次对Sn-1取值、操作、左移,一步步得到随机数的第七、六、…、一位,循环做8次就可以得到1字节(8bit)的随机数。

deepseek_mermaid_20250913_c68ff0

LFSR算法生成的随机数是完全可逆的,在源码中是先通过随机数N1(E-Nonce)反推种子,然后回退 16 字节得到 E‑S2,再接着回退 16 字节得到 E‑S1。这里笔者是挺疑惑的,按照WSC规范,生成顺序应该是N1 -> E-S1 -> E-S2。不清楚代码为什么不是从N1继续正向生成随机数E-S1和E-S2,而是逆向生成E-S2和E-S1,也许这个随机数的生成逻辑就是逆向生成吧。

2.2.2 eCos模式
  • eCos simple 模式基于线性同余生成器(LCG,Linear Congruential Generator)算法生成伪随机数,源自 C 语言标准库的rand()函数,生成代码如下。
static uint32_t ecos_rand_simple(uint32_t *seed)
{
uint32_t s = *seed;
uint32_t uret;
// 第一步:线性同余生成
s = (s * 1103515245) + 12345;
// 生成s1
uret = s &
0xffe00000;
// 取高11位 (bits 31-21)
// 第二步:继续生成 
s = (s * 1103515245) + 12345;
// 生成s2
uret += (s &
0xfffc0000) >>
11;
// 取高14位右移11位 (bits 31-18 → bits 20-7)
// 第三步:再次生成
s = (s * 1103515245) + 12345;
// 生成s3
uret += (s &
0xfe000000) >>
(11 + 14);
// 取高7位右移25位 (bits 31-25 → bits 6-0)
*seed = s;
return uret;
// 返回32位值,但实际只使用低8位
}
//使用时只取低8位
output_byte = ecos_rand_simple(&seed) &
0xFF;

伪随机数生成流程:

  1. 选定一个初始的数S0(32位)作为种子。对这个数乘以一个乘数(1103515245),再进行增量(12345),得到S1,取高11位作为随机数的高11位。
  2. 对S1再乘以乘数并进行增量,得到S2,取高14位作为随机数中间14位。
  3. 对S2再乘以乘数并进行增量,得到S3,取高7位作为随机数低7位。总共得到11+14+7=32位随机数,但使用时只取低8位。

整体操作为对操作数做3次LCG固定计算s = (s * a + c) % m,每次取部分高位拼接成随机数。末尾取模在代码中没有显式编写,实际上因为使用了无符号整数(232),计算后溢出的高位会被丢弃,相当于取2^32的模。

uint32_t known = wps->e_nonce[0] <<
25;
/* 将熵从32位减少到25位 */
uint32_t seed, counter = 0;
while (counter <
0x02000000) {
// 2^25 = 33,554,432次尝试
int i;
seed = known | counter;
// 构建候选种子
// 验证后续15个字节
for (i = 1; i < WPS_NONCE_LEN; i++) {
if (wps->e_nonce[i] != (uint8_t)(ecos_rand_simple(&seed) &
0xff))
break;
}
// 如果所有字节都匹配
if (i == WPS_NONCE_LEN) {
// 找到正确种子,继续生成E-S1和E-S2
wps->s1_seed = seed;
for (i = 0; i < WPS_SECRET_NONCE_LEN; i++)
wps->e_s1[i] = (uint8_t)(ecos_rand_simple(&seed) &
0xff);
wps->s2_seed = seed;
for (i = 0; i < WPS_SECRET_NONCE_LEN; i++)
wps->e_s2[i] = (uint8_t)(ecos_rand_simple(&seed) &
0xff);
break;
}
counter++;
}

通过随机数逆向种子:

首先一字节的随机数(8位)的后7位就是取自最后一次操作数的S3的前7位,那么对于S3还有剩下的25位未知。而LCG算法与前面LFSR算法不同,生成随机数会溢出部分数据导致计算不可逆。但伪随机数的特点就是计算过程是固定的,通过分析连续生成的随机数,知道结果就可以直接套初始值去猜测,最终逆推出种子。

deepseek_mermaid_20250913_d391ea

对于WPS中生成的N1(E-Nonce)总共16字节,我们取第1个字节,其前7位做种子的前7位,对于未知的后25位进行枚举猜测,同样使用LCG算法去计算后面生成的随机数,与N1的后15字节结果进行比对。如果计算结果比对实际随机数完全一致,那就说明猜测成功。这种方式即暴力坡解,最多猜测2^25次(33,554,432),计算机可在几秒内完成。

猜出种子后,再往后计算就可以得到E-S1和E-S2。

笔者实验:https://blog.csdn.net/2301_81348092/article/details/151667512

3 参考资料

https://ifconfig.dk/pixiedust/

https://github.com/2EXP/2exp.github.io/issues/3

https://mlg556.github.io/posts/bruteforce-wps-with-reaver-and-pixiewps/bruteforce-wps-with-reaver-and-pixiewps.html

https://blog.csdn.net/moonlinux20704/article/details/109102318

http://archive.hack.lu/2014/Hacklu2014_offline_bruteforce_attack_on_wps.pdf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/913284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

52805 JLINK 端口保护机制硬件保护具体流程分析;

硬件保护(Hardware AP-Protect) 通过写特定值(如 Enabled/0x00)到 UICR.APPROTECT 并复位生效。 一旦启用,只有通过 CTRL-AP 执行 ERASEALL(全片擦除,包括 Flash、UICR、RAM)才能解除保护。 这种保护是持久的,…

构建你的 MCP 能力层:.NET 9 + SK 的系统方案

构建你的 MCP 能力层:.NET 9 + SK 的系统方案环境准备与基线项目(.NET 9 + SK + MCP) 目标:搭建最小可运行的 .NET 控制台,引用 SK 与 MCP,完成一次 MCP Ping 健康检查(Stdio 与 SSE/HTTP 各跑通一次),并为后…

网页设计需要什么seo织梦网站建设步骤

在此整理并记录自己的思考过程&#xff0c;其中不乏有一些尚未成熟或者尚未实现的idea&#xff0c;也有一些idea实现之后没有效果或者正在实现&#xff0c;当然也有部分idea已写成论文正在投稿&#xff0c;都是自己的一些碎碎念念的思考&#xff0c;欢迎交流。 研一上学期 9.…

百度联系电话巩义关键词优化推广

视频扩散模型因其能够生成连贯且高保真的视频而日益受到关注。然而&#xff0c;迭代去噪过程使得这类模型计算密集且耗时&#xff0c;限制了其应用范围。香港中文大学 MMLab、Avolution AI、上海人工智能实验室和商汤科技公司的研究团队提出了AnimateLCM&#xff0c;这是一种允…

网站推广业务展会布置

一、位图 1.1 概念 所谓位图&#xff0c;就是用每一位来存放某种状态&#xff0c;适用于海量数据&#xff0c;数据无重复的场景。通常是用来判断某个数据存不存在的。 数据是否在给定的整形数据中&#xff0c;结果是在或者不在&#xff0c;刚好是两种状态&#xff0c;那么可以…

wix做网站的建议做一个公司网站需要多少钱

1.下载eclipseCDT组合包。 2.电脑上安装GCC&#xff0c; G 3.在eclipse上创建一个C project 4. Eclipse CDT功能很强大&#xff0c;安装完虽然可以编译运行c程序&#xff0c;但有个问题&#xff0c;就是找不到c标准库的头文件&#xff0c;无法打开诸如之类的文件&#xff0c;编…

dw做网站怎么加视频网站怎么做百度推广

1.Amazon Certified Cloud Practitioner 转码小白超友好的一门入门级证书&#xff0c;对于之前没有IT或者project经验的同学也可以轻轻松松顺利拿下&#xff0c;含金量很高可以直接标到linkedln的个人介绍里面。 (1)将如何帮助职业生涯 获得此认证可验证对 AWS Cloud、服务和…

会议专属网站平台建设报价单电子政务门户网站建设

1、常用位操作符 1.1、位与& (1)注意&#xff1a;位与符号是一个&&#xff0c;两个&&是逻辑与。 (2)真值表&#xff1a;1&00 1&11 0&00 0&10 (3)从真值表可以看出&#xff1a;位与操作的特点是&#xff0c;只有1和1位于结果为1&…

做策划有帮助的网站二级网站建设规范

简单排序&#xff1a;插入排序、选择排序、 冒泡排序 分治排序&#xff1a;快速排序、归并排序 分配排序&#xff1a;桶排序、基数排序 树状排序&#xff1a;堆排序 其他&#xff1a;计数排序、希尔排序 稳定排序&#xff1a;如果 a 原本在 b 的前面&#xff0c;且 a b&#x…

pl/sql使用

1.下载地址 https://www.allroundautomations.com/try-it-free/ 2.下载instantclient(连接oracle必须) https://www.oracle.com/database/technologies/instant-client/downloads.html 下载完成后,进入plsql=>conf…

PLC中的运动控制 - (二)基本控制指令MC_Power,MC_Stop,MC_Halt

本章介绍PLC中的基本控制指令,包括最基本的启停指令MC_Power和MC_Stop,MC_Halt,并详解MC_Stop何MC_Halt的区别启动指令 MC_Power MC_Power 功能块是运动控制中用于管理轴使能状态的核心指令,其本质是控制PLC与驱动…

WPF Prism PrismApplication OnInitialized()

Install-Package Prism.Wpf; Install-Package Prism.DryIOC; //app.xaml <prism:PrismApplication x:Class="WpfApp38.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"…

公司微网站建设汽车网站建设

深度学习在图像识别中的革命性应用标志着计算机视觉领域的重大进步。以下是深度学习在图像识别方面的一些革命性应用&#xff1a; 1. **卷积神经网络&#xff08;CNN&#xff09;的崭新时代**&#xff1a; - CNN是深度学习在图像识别中的核心技术&#xff0c;通过卷积层、池化…

FOC之电机模型

概述FOC全称磁场定向控制,从该名称可推导出适用电机的几个特点:磁场是主动方 无机械换向 转子是永磁体符合以上特点的有直流无刷电机(BLDC)和永磁同步电机(PMSM)。实际上,这两种电机的总体结构是一样的,区别在于电…

使用shell脚本一键部署docker及docker-compose环境

准备安装包: 安装包邮箱留言获取 ahui6-docker-compose-binary-install.tar.gz 脚步内容: #!/bin/bash #auther: ahui6 #博客地址: https://www.cnblogs.com/ahui6#加载操作系统的变量,主要是ID变量。 . /etc/os-re…

网站seo文章只有网站才需要域名吗

准备在工作之余看看Python的东西 收录一些资料 Python初学者&#xff08;零基础学习Python、Python入门&#xff09;常见问题&#xff1a;书籍推荐、资料、社区 http://blog.csdn.net/xiaowanggedege/article/details/8566606 小甲鱼零基础入门学习Python(全87集) http://pan.b…

怎么修改网站关键词精准引流怎么推广

需求背景 做一个OCR识别的功能,需要导出原图和识别出来的结果的图纸,将数据导出. 解决方案 EasyPOI中可以用字节类型,导出图片,可以将图片存放的url 转成字节,然后导出.但是整个导出过程耗时较久。 具体代码 /*** 草图OCR识别记录-导出.** @param response: Http…

怎么打开google网站互联网营销推广服务商

博主介绍&#xff1a;✌程序员徐师兄、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

pexels素材网站个人信用信息服务平台

CCS6软件安装 第一步&#xff1a;点击右键->以管理员身份安装&#xff08;安装路径不能有中文&#xff09; 第二步&#xff1a;安装驱动

购物网站开发技术湘icp备 网站建设 农业 湖南

本文主要包括以下内容 阈值分割技术基于区域的图像分割技术本章的典型案例 基于LoG和Canny算子的精确边缘检测基于Hough变换的直线检测图像的四叉树分解 阈值分割 我们曾在3.5节学习过灰度阈值变换的相关知识&#xff0c; 利用灰度阈值变换分割图像就称为阈值分割&#xf…