在仔细阅读D-Link的DIR-810l80211ac路由器的最新固件时,我在sbin/ncc中发现了一个有趣的代码位,这个二进制文件提供设备上许多其他进程使用的后端服务,包括HTTP和UPnP服务器:
从getWPSPinCode调用sub_4D56F8
我首先开始检查这段特定的代码,希望能够控制传递给u系统的格式字符串的一部分。但是,这个数据被证明不是用户可以控制的,因为放在格式字符串中的值是路由器的默认WPS pin。
默认WPS pin本身通过调用sub_4D56F8来检索。由于WPS pin通常在工厂编程为NVRAM,因此可以预期sub_4D56F8只是执行一些NVRAM查询,但事实并非如此:
子单元4D56F8的开始
这段代码根本不检索WPS pin,而是获取路由器的WAN MAC地址。然后,MAC地址被拆分为其OUI和NIC组件,随后会出现一组冗长的乘法、xor和移位(这里列出了完整的反汇编):
打开MAC,开始嚼NIC
虽然所执行的数学并不复杂,但由于编译器生成的程序集,确定原始程序员的意图并不一定简单。以以下指令序列为例:
li$v0,0x38E38E39multu$a3,$v0…mfhi$v0srl$v0,1个
li $v0, 0x38E38E39
multu $a3, $v0
...
mfhi $v0
srl $v0, 1
直接转换成C,内容如下:
这只是用9除以的一种奇特方法:
同样,大多数乘法和模运算也由各种移位、加法和减法序列执行。multu汇编指令仅用于上面的示例,其中需要产品的高32位,并且看不到divu。
但是,在将整个子4D56F8反汇编列表转换为更容易接受的格式之后,很明显,此代码使用了一个简单的算法来完全从设备的WAN MAC地址的NIC部分生成默认的WPS管脚:
由于BSSID只在广域网MAC中关闭一个,我们可以很容易地从被动数据包捕获中计算出任何DIR-810L的WPS pin:
但是DIR-810L并不是唯一使用这种算法的设备。事实上,它似乎已经使用了一段时间,可以追溯到2007年WPS首次引入时。以下是受影响和未受影响设备的不完整列表:
确认受影响:
- DIR-810L
- DIR-826L
- 目录-632
- DHP-1320号
- 目录-835
- DIR-615版本:B2、C1、E1、E3
- 目录-657
- 目录-827
- 目录-857
- 目录-451
- DIR-655转速:A3、A4、B1
- DIR-825转速:A1、B1
- 目录-651
- 目录-855
- DIR-628号
- DGL-4500型
- DIR-601转速:A1、B1
- DIR-836L
- DIR-808L型
- 目录-636L
- DAP-1350型
- DAP-1555型
确认未受影响:
- DIR-815号
- DIR-505L
- DIR-300型
- DIR-850L
- 目录-412
- DIR-600型
- DIR-685号
- DIR-817LW
- DIR-818LW
- 目录-803
- DIR-845L型
- DIR-816L
- 目录-860L
- 目录-645
- DIR-685号
- DAP-1522型
一些受影响的设备,如DIR-810L,从广域网MAC生成WPS pin;大多数是从BSSID生成的。在这里可以找到一个独立的工具来实现这个算法,它已经被应用到最新的Reaver Pro中。