如何使用 scapy python 读取数据包 TLS 元数据

How to read a packet TLS meta-data with scapy python

如何使用 scapy 从数据包中读取 TLS 信息(记录长度、记录类型...)。我已经使用 load_layer('tls') 并且当数据包中有单个 TLS 记录时我能够读取一些信息但是当数据包中有多个 TLS 记录时我只能读取第一个 TLS 记录。 例如这个数据包包含 3 个 TLS 记录 and when I want to read the records length with scapy I only get the first record length

总 TLS 解码

如您所见,scapy 不会解码整个数据包。但这很好,因为我们可以手动解码 scapy 当前认为是 "Raw load" 字节的 TLS 部分。

>>> pkts = rdpcap("facebook.com.pcap")
>>> extra_tls_layers = TLS(pkts[5]["TLS"].load)
>>> # We can see that TLS is now decoded, with two new layers:
>>> extra_tls_layers.show()
###[ TLS ]###
  type= application_data
  version= TLS 1.2
  len= 1017    [deciphered_len= 1017]
  iv= b''
  \msg\
   |###[ TLS Application Data ]###
   |  data= '\x1f\x11\xc4\xab\x920l\xae]=\x10\xd4\x13\x81k\x14\x98e\x8b\xcd\xa0...
  mac= b''
  pad= b''
  padlen= None
###[ TLS ]###
     type= application_data
     version= TLS 1.2
     len= 1517    [deciphered_len= 240]
     iv= b''
     \msg\
      |###[ TLS Application Data ]###
      |  data= '\xac\x0b\xda\xba\xe8z\x99\xad\x0b_\x82\x96c\xb3\xff\x9f\xcc...

     mac= b''
     pad= b''
     padlen= None```

要访问每个层的值(新解码的层从 0、2 开始),请使用 deciphered_len 属性。

>>> pkts[5][TLS][0].deciphered_len
122
>>> pkts[5][TLS][5].deciphered_len
1
>>> extra_tls_layers[0].deciphered_len
1017
>>> extra_tls_layers[2].deciphered_len
240

验证完整性

这里整个TLS段的长度是1400,我们用len(pkts[5][TLS])得到的。请注意,TLS 记录头是 5 个字节(内容类型 = 1 个字节,版本 = 2 个字节,长度 = 2 个字节)。

所以预算为 1400 字节,让我们检查一下记录长度:

  • 记录 1: 5 + 122 => 127
  • 记录 2: 5 + 1 => 6
  • 记录 3: 5 + 1017 => 1022
  • 记录 4: 5 + 240 => 245

检查 4 个 TLS 记录是否相加,

TLS 部分为 127 + 6 + 1022 + 245 = 1400。

原始数据包#6

对于未来的读者,如果 pcap 不可用,并且您在 scapy 解释器中,这是数据包 6 的相关数据包字节:

>>> pkt = b'\x00\r:\x8a\x18P\x124Vx\x9a\xbc\x08\x00E\x00\x05\xa0E\xfc@\x00R\x06)E\x9d\xf0\x08#\n\x00\x04\x04\x01\xbb\xca`0l;1\xfa\x93\n\xc2P\x10\x00r<\xd3\x00\x00\x16\x03\x03\x00z\x02\x00\x00v\x03\x03\x94\x01\xb5\xcc1b\x86Jh\x85\xf0vG\xb7#\xe7\xd2\n\x1d\xd0\'\x01\x8d\xb6\xab\xa9\x8af\x92=h= \x98\x0fJKbJ\xff(sw\xcbdW\xae\x16\x17\xec\xec\xb7\xba\x139\x92/9\xed\xc2\xeb\xa3\x07\x88\xaa\x13\x01\x00\x00.\x00+\x00\x02\x03\x04\x003\x00$\x00\x1d\x00 \xed\xfd\x0f*\x87\x9a;Q\xbb\x88\n\xad*\x9d,C\x96\xdd\x14\xab\xd8\xd8}\xf9(\x8f\xcb\xb3\x10+\xa63\x14\x03\x03\x00\x01\x01\x17\x03\x03\x03\xf9\x1f\x11\xc4\xab\x920l\xae]=\x10\xd4\x13\x81k\x14\x98e\x8b\xcd\xa0\x9f\xca\xfd\xcf\xd5\xc2\xa3\xc9S\xd0\x86G\xf3\xdc\x08\x8a,\x15\xbe+\x84\xfd\x87\x8bk\x956zO\xb3;\x875\xf4\xbd\x01\xe7`\x0f=\x08\xc5\xd8\xe6\x9e\xa4\xd9\xa3\x89C^\x07y"\x85\xb9|\xfc:{\x19\x99r\x9av\x15{\xf6\xf4\x91\x97\xfd\xe6\x7f\xbf\x1c\x81\xb9\x81\xc7W\xbao\x98X>n\'\x91\x11X\x9660\x92\ub\xb896\xce\r\x84\xe0\x82:r{\xff\xbet\xea*\x03\x97Iw\xc8\x8b\x1d\xe3m\xe2%\x054\xc7\x0e\x9e\xe2LQ")a\x11M\x92eY=\xcc\x89\x9cj\xae\xa73\xf0\x90\xf9.&\xf5\x14\xbc\\x8f\xa5\xfc\x0e"bD\xce\x92\xb0\x9d\xc3\xddm\xc2\x94\x90\x93T\no\xc7\x10k\x1a\xdfP\xecF\xa9\xeb\xe3=\xe4\xe5\xf5\x8b\x1a]l\x82\xdb\x93\x0c\xb7Q\x15bS\x97\xd6xu\xec\x0fd5$\xb03A\xa8\x14 \x00\xd7h\x82\xb0\xb7\xb3QY\x82%s\xf8H\x1a\xf3\xa1\xac\xcd\x07\xb0=\xdcdv\x16y\x91D\xb1\xbfzq\x92\xcf\x07\xef\x84\x8c\'\xefD\x05\xcb\xe1\xd1\x01\'\xcf\xbedG\rg\x94\x073\x9c\xe7e-\xd3\xd2|\x0e\xa2\xeb$\xc2\xe3\xa4&`\x9c\xd6\xe9\xf3\xd4fP\xf5\xdb\x10\x85\xbf\xc8\xa1\x86d;\x9e\xe3\xa2\xce\xe2Tx\xba~g\t\x8e\xbd5\xce8T\x00\xa4*\xc7\x15\xf1\xa3\xae\x90\xearT\x03\xcaK\xb9\xf8\x04-\xd7\xeb\xfb\xc1<}\x95\x85\xd97\'\xfbIH\xcf\x07\x85G\xd7\xe6~\xaeb\x14*\xcf\xe2@\xbc\xa5\xc79+\x1e\xff\x90 Df[\xc3\xb9;\x9c\x8a\x0b\x02\xb4*\xb7s/\x9c\xaa{\xb7\xbd4\xfb\x00\xa7\xa6u\xdf0\x84\x060\xbf#\x17\xba\x0e\xbe\x86\x83\xc8h\xba!\x86j\x04\x98\x0c/\xfa\xe2wp\x16:z\x04\xc5\xc0yo\x06\xfd\xcd\x9fCxJ\xb0fS\x989\x1c\xe5\xfe\x18Kl\x8b\'\xcday%\xe5\xa7\xa6T_`\x07{\xdc\xe7OI\x80\x03\xc9\x92(\x9f\xa5\xee\x0e\xac\xc4\x01`g*|\x88\x13\x8d\xe3I\x8dZ;\xfdcV\xc0\xdb,*@\xd4Y\xd7\x9b\xe0\xd0J6u\xedn\xe3VR\xab\xb5x(\xe7\x9cF\xfd\xc0\xea\xf2\xb5\xc2\xce\r\xd1\xec\xb6 {\xce;<\x8f\n\x80\xa0\xf7W\xf0R"\x80N\xdc\x82\x92\x19wa\xb3/\xab\xf6\xec\x99\xfa\xca\xeb\x08\xaf\x97\xc8\x89g\xdd\xf3\xf2\xb1|Yo\xca\x0b\xd3_\n/\x8e!\xf7\x11b&\xae\xed\xa3\xcc\\xeb\xbf\x19\xd6\xacE\x02\n[\xa4i(\xaa\x0cQ\xcf\xf0\xf6"`\x04M\xe9%\x8e\xfdRo\xae]eA6}l\x1e\xe2\x04[\xf0\x93\xa2)\x02\xf1\xd0&\x00_J\xd3y\x99\x90(\x85VrN\t\xf3z\xfel\xd7.\x80\x07\x8e\x1f=\x9c\xebrK\x06 6-O\xb1\x8f\xfa\xc6"f\x02\t%\xf8q\xb5\x14\xcbp*\xb4!({r\x00S\xf1\x19\t\xb2\xafs`\xd1\x0b\xc8\x14V]{B\x15\xc4\xc3\x06\x08\n\xa02&\xe1`b\xf0\xd8PZL\xb5\x8b\x93\xb8<a[\xcc\x07\xadtr\xa3hbNv\xa9t)\xb4hB\xe5\xf5\xe1\xbb\xde\x03\xe3\x14\xac\xe2\xb6i\xfe\x9a/"\x95\x9332 \xabu\xbb\x1a\xf2x\x85C\xad;\x8d\x87\x95;\x14O%\xa9f\xe1\x10x\xce">-\xb3.\xc9w\xf0fB\xfe;\xdd\xea\xf5\x85\xa2\'\x8b\x08\xe8\x1c\xb8\xeb\x7fb\xd4\xf0\xba\x7f\xfd\x9a{\x92]\x0bp5\x91.Q\'\x03Q\xf9#\xbc{\x93\xa9\xc9\x96W&\xb8\x15\x8d\xa9_k\xd2\x8bz\x90\xde\xc0\xa1`\xe4r8\xd2W\xfb\x1f\xd2]S?\xe4\x0cK^\xde\xfds\xd3\xf0\xc6\xb9\x04\x05\xd1\xf6\xb3\xd8\x0fz6\xdf\x86\xa8Z\x1cj\xadO\xa0\x89;\x94%\xa4K"`\x8b:\xdc\xb6\xa0=g\xc7\x04k/f\x04\xf5E\x00\xdd\r\xbd]\xe8\x869+\xd7\x85\xb3{yG\x1bH\x8fn\xad\xd5\xd7\xea\xf6u\x13\x85\xcd\xa3$\xbaF~\x1e\xc1M#>\n!\x97\xcd\x1aF\x86\x84\xb2\x9b\xf9u}\x96\xc68\x89\x97\x17\x03\x03\x05\xed\xac\x0b\xda\xba\xe8z\x99\xad\x0b_\x82\x96c\xb3\xff\x9f\xcc\t\xbd \x9cM\x0bP\xe2\xb0\xa5@\xfb)\xda:K\x9b-\xb0\x0b\xb36p\xe2<oOj\x96\x10\xe2jEq o\xc8\x99\xf2\x0es\x9fj\xc5\x0c\xc5\xc0\x83\x92>\x9d\x05\x17\xed\x85\xc8,Q\xf1W\xa9\xac\x9ez\x19\x14\x90i\x1ef\xe8E\xd6\xf1\x9f\xe0\xc1@\xed\'\x88\xb13\xf5;pg\x18\xc19,\xe2u\xefTJ\xd2\x08\xb5\x8e\xf2\xcf\xd2\xce\xf0L\xfa]\x95\x05wk\x8f\x85\xa2\x8aQ\x00\x12\r\x0f\xa6\xa9\x88:4\xb3\xa3z\xa8\xf6\xeaV\x1c\x86w\xce\xe7\x97\xf4\xc3\x19.\n\xe7>\xb2\x8dj\xcf\\xaf5{$\xa0L\x1e\x15\xb6\xd4\xc7\xdb\xbc\x99l"D\x890K\xa8\x03\x0fz\xfd\x88\xabH\xcb\xbe\xbc0\xa3\xbetp\x90\xd3_BGe\x93[\x98\x9c\xf86\xc8\xdd\xb3]\x1c\xf0\x83\xbf\xbfs\xccj\xbd\x8fR\x8d\x9e\t\xe8\xce\xd33R/'
>>> # To reconstitute, create an Ethernet packet
>>> new_pkt = Ether(pkt)