有没有办法将Scapy数据包中的字段链接到构建的str中的部分?

时间:2018-02-20 19:19:14

标签: python scapy coap

我使用Scapy来操纵CoAP数据包。现在我发现了一件我想要做的事情,我实际上无法弄清楚如何。

我有以下CoAP数据包:

>>> pkt
<CoAP  ver=1L type=CON tkl=8L code=PUT msg_id=<RandShort> token=<RandBin> options=[('If-Match', '\x04\xfc\xbbL'), ('Content-Format', ''), ('Uri-Path', '.well-known'), ('Uri-Path', 'core')] paymark='\xff' |<Raw  load='CC22 at 12:39:31.495' |>>
>>> str(pkt)
'H\x03\xf4\x08\xbdR_\x85\xa3\x04\xe9\xe9\x14\x04\xfc\xbbL\xab.well-known\x04core\x10\xffCC22 at 12:39:31.495'

我现在要做的是将表示索引1 ''处的选项的整个部分(不是选项值('Content-Format', ''))替换为null(\x00)字符。我知道此部分在str(pkt)[-22:-21]的末尾附近由str(pkt)表示,其值\x10代表内容格式选项,但没有实际值。

所以,我想知道:有没有办法从高级字段(\x10)获取str(pkt)[-22:-21](实际上,获取引用pkt.options[1]),所以我可以替换这部分字符串由另一个值组成?

提前致谢!

1 个答案:

答案 0 :(得分:1)

好的,问题几个小时后我想出了一个解决方案,如果我认为通过Scapy本身没有简单的方法可以做到这一点(可能是由于CoAP选项在CoAP中的实现方式)贡献层),似乎是一个公平的。

以下函数可用于“取消”整个CoAP选项字段:

def coap_option_to_null(pkt, opt_idx):
  ''' Changes the whole CoAP Option field at @opt_idx to null '''
  opt = pkt.options[opt_idx]
  l = pkt.options
  # Sort the list of options by option number
  l.sort( lambda x, y: cmp(coap_options[1][x[0]], coap_options[1][y[0]]) )
  # Replace options for the sorted one and grabs new opt_idx
  pkt.options = l
  opt_idx = pkt.options.index(opt)

  cur_delta = 0
  opt_total_len = []
  for opt in pkt.options:
    if (option_model[opt[0]][0] - cur_delta) < 13:
      delta_extended = 0
    elif (option_model[opt[0]][0] - cur_delta) < 269:
      delta_extended = 1
    else:
      delta_extended = 2
    cur_delta += (option_model[opt[0]][0] - cur_delta)

    if len(opt[1]) < 13:
      len_extended = 0
    elif len(opt[1]) < 269:
      len_extended = 1
    else:
      len_extended = 2

    opt_total_len.append(1+delta_extended+len_extended+len(opt[1]))

  opt_lidx = sum(opt_total_len[:opt_idx])
  opt_hidx = sum(opt_total_len[opt_idx+1:])
  new_pkt = str(pkt)[:4+pkt.tkl+opt_lidx] + '\x00'*opt_total_len[opt_idx] + str(pkt)[-(len(pkt.payload)+1+sum(opt_total_len[opt_idx+1:])):]
      return CoAP(new_pkt)

以下是演示:

>>> pkt
<CoAP  ver=1L type=CON tkl=8L code=PUT msg_id=<RandShort> token=<RandBin> options=[('If-Match', '\x04\xfc\xbbL'), ('Content-Format', ''), ('Uri-Path', 'separate')] paymark='\xff' |<Raw  load='CC22 at 12:39:31.495' |>>
>>> str(pkt)
'H\x03*\x88%T\xbe\xac\xd9\xee\xcd\xbd\x14\x04\xfc\xbbL\xa8separate\x10\xffCC22 at 12:39:31.495'
>>> npkt = coap_option_to_null(pkt, 1)
>>> npkt
<CoAP  ver=1L type=CON tkl=8L code=PUT msg_id=47784 token='\x90L\x0f\xd4u\xbe&\xd7' options=[('If-Match', '\x04\xfc\xbbL'), ('Uri-Path', 'separate'), ('Uri-Path', '')] paymark='\xff' |<Raw  load='CC22 at 12:39:31.495' |>>
>>> str(npkt)
'H\x03\xba\xa8\x90L\x0f\xd4u\xbe&\xd7\x14\x04\xfc\xbbL\xa8separate\x00\xffCC22 at 12:39:31.495'



>>> pkt
<CoAP  ver=1L type=CON tkl=8L code=PUT msg_id=<RandShort> token=<RandBin> options=[('If-Match', '\x04\xfc\xbbL'), ('Content-Format', ''), ('Uri-Path', 'separate')] paymark='\xff' |<Raw  load='CC22 at 12:39:31.495' |>>
>>> npkt = coap_option_to_null(pkt, 0)
>>> npkt
<CoAP  ver=1L type=CON tkl=8L code=PUT msg_id=14606 token='s\xad\xd0\xf5\x05\xac\x87C' options=[(0L, ''), (0L, ''), (0L, ''), (0L, ''), (0L, ''), (10L, 'separate'), ('Uri-Path', '')] paymark='\xff' |<Raw  load='CC22 at 12:39:31.495' |>>
>>> str(npkt)
'H\x039\x0es\xad\xd0\xf5\x05\xac\x87C\x00\x00\x00\x00\x00\xa8separate\x10\xffCC22 at 12:39:31.495'