强制scapy在更改后重新剖析图层

时间:2015-06-30 08:29:49

标签: python security encryption zigbee

我正在使用名为scapyscapy-com(一个Python数据包操作工具)的分支。这实现了802.15.4和Zigbee解析/操作,以及其他协议。

在网络级安全标头中找到了Zigbee protcol的怪癖。最初,安全级别(定义消息完整性代码的加密和长度)已正确设置,但在发送之前设置为0(无加密)。来自规范:

  

安全控制字段的安全级别子字段应为   被3位全零字符串'000'覆盖。

规范可以是found here。相关部分是“4.3.1.1传出帧的安全处理”。

这意味着数据包捕获表明没有使用加密或消息完整性代码。安全级别必须在带外传达。

scapy-com没有解决这个问题。它天真地解析安全级别并将MIC的长度设置为0.执行此操作的代码是:

def util_mic_len(pkt):
    ''' Calculate the length of the attribute value field '''
    # NWK security level 0 seems to implicitly be same as 5
    if ( pkt.nwk_seclevel == 0 ): # no encryption, no mic
        return 0
    elif ( pkt.nwk_seclevel == 1 ): # MIC-32
        return 4
    elif ( pkt.nwk_seclevel == 2 ): # MIC-64
        return 8
    elif ( pkt.nwk_seclevel == 3 ): # MIC-128
        return 16
    elif ( pkt.nwk_seclevel == 4 ): # ENC
        return 0
    elif ( pkt.nwk_seclevel == 5 ): # ENC-MIC-32
        return 4
    elif ( pkt.nwk_seclevel == 6 ): # ENC-MIC-64
        return 8
    elif ( pkt.nwk_seclevel == 7 ): # ENC-MIC-128
        return 16
    else:
        return 0

使用scapy-com的项目尝试通过将安全级别设置为5来处理此问题:

#TODO: Investigate and issue a different fix:
# https://code.google.com/p/killerbee/issues/detail?id=30
# This function destroys the packet, therefore work on a copy - @cutaway
pkt = pkt.copy()   #this is hack to fix the below line
pkt.nwk_seclevel=5 #the issue appears to be when this is set

mic = pkt.mic

但是,这不起作用 - 已设置消息完整性代码。我通过简单地改变util_mic_len函数来正确地设置麦克风长度。

问题是,如何更改Zigbee解析器,以便在初始解剖后更改nwk_seclevel会导致更新麦克风长度?

我可以看到两种解决方案:

  1. 更改scapy-com代码,以便更改nwk_seclevel会自动更改麦克风长度。
  2. 在更改时,从scapy-com外部重新剖析数据包。
  3. 1的问题是我不知道该怎么做。

    2的问题是我有一些想法,但无法让它工作 - 我无法弄清楚如何在数据包加载后调用解剖。调用 pkt.dissect(pkt)似乎不起作用,看起来很奇怪。

    这里最好的或推荐的解决方案是什么?

2 个答案:

答案 0 :(得分:2)

Fixing scapy sounds right solution. scapy-com is quite old. Zigbee specific code in scapy-com is 1244 lines of code, which in large part are enumerations and field lists. So, it should not be too hard to migrate it to scapy-python3. If you would assist in migrating it to scapy-python3 http://github.com/phaethon/scapy , I could help with fixing the issue.

答案 1 :(得分:1)

您所指的项目是KillerBee,我解密时遇到了这个问题。我只是简单地“修复”了代码:

from struct import pack
f = pkt.getlayer(ZigbeeSecurityHeader).fields

pkt.nwk_seclevel = 5
nwk_mic = pkt.mic
nwk_encrypted = f['data'][:-6]

ext_source = f['ext_source']

nwk_sec_ctrl_byte = str(pkt.getlayer(ZigbeeSecurityHeader))[0]
nwk_nonce = struct.pack('Q',ext_source) + struct.pack('I',f['fc']) + nwk_sec_ctrl_byte

nwk_crop_size = 4 + 2 + len(pkt.getlayer(ZigbeeSecurityHeader).fields['data'])  # The length of the encrypted data, mic and FCS

# the Security Control Field flags have to be adjusted before this is calculated, so we store their original values so we can reset them later
zigbeeData = pkt.getlayer(ZigbeeNWK).do_build()
zigbeeData = zigbeeData[:-nwk_crop_size]

(nwk_payload, nwk_micCheck) = zigbee_crypt.decrypt_ccm(nkey, nwk_nonce, nwk_mic, nwk_encrypted, zigbeeData)