当前位置:   article > 正文

python dpkt SSL 流tcp payload(从三次握手开始到application data)和证书提取

application data tcp

 

  1. # coding: utf-8
  2. #!/usr/bin/env python
  3. from __future__ import absolute_import
  4. from __future__ import print_function
  5. import traceback
  6. import argparse
  7. import ipaddress
  8. from binascii import hexlify
  9. import socket
  10. import struct
  11. import sys
  12. import dpkt
  13. import textwrap
  14. import os
  15. from asn1crypto import x509
  16. from dpkt import ssl, Packet
  17. import pickle
  18. from constants import PRETTY_NAMES
  19. from cert_filter import CertFilter
  20. global encrypted_streams
  21. encrypted_streams = [] # change_cipher
  22. global ssl_servers_certs
  23. ssl_servers_certs = {}
  24. global ssl_servers_with_client_hello
  25. ssl_servers_with_client_hello = set()
  26. global client_hello_set
  27. client_hello_set = set()
  28. global server_ip_set
  29. server_ip_set = set()
  30. global buffer
  31. buffer = {}
  32. need_more_parse = False
  33. def tls_multi_factory_new(buf):
  34. """
  35. Attempt to parse one or more TLSRecord's out of buf
  36. :param buf: string containing SSL/TLS messages. May have an incomplete record on the end
  37. :return: [TLSRecord] int, total bytes consumed, != len(buf) if an incomplete record was left at the end.
  38. Raises SSL3Exception.
  39. """
  40. i, n = 0, len(buf)
  41. msgs = []
  42. while i + 5 <= n:
  43. v = buf[i + 1:i + 3]
  44. if v in ssl.SSL3_VERSION_BYTES:
  45. try:
  46. msg = ssl.TLSRecord(buf[i:])
  47. msgs.append(msg)
  48. except dpkt.NeedData:
  49. break
  50. else:
  51. if i == 0: ############################################ added
  52. raise ssl.SSL3Exception('Bad TLS version in buf: %r' % buf[i:i + 5])
  53. else:
  54. break
  55. i += len(msg)
  56. return msgs, i
  57. class FlowDirection(object):
  58. OUT = 1
  59. IN = 2
  60. UNKNOWN = 3
  61. class Extension(object):
  62. """
  63. Encapsulates TLS extensions.
  64. """
  65. def __init__(self, payload):
  66. self._type_id, payload = unpacker('H', payload)
  67. self._type_name = pretty_name('extension_type', self._type_id)
  68. self._length, payload = unpacker('H', payload)
  69. # Data contains an array with the 'raw' contents
  70. self._data = None
  71. # pretty_data contains an array with the 'beautified' contents
  72. self._pretty_data = None
  73. if self._length > 0:
  74. self._data, self._pretty_data = parse_extension(payload[:self._length],
  75. self._type_name)
  76. def __str__(self):
  77. # Prints out data array in textual format
  78. return '{0}: {1}'.format(self._type_name, self._pretty_data)
  79. class OP:
  80. CHECK_TLS_PACKET = 1
  81. MERGE_TLS_PACKET = 2
  82. def analyze_packet(_timestamp, packet, nth, op):
  83. """
  84. Main analysis loop for pcap.
  85. """
  86. eth = dpkt.ethernet.Ethernet(packet)
  87. if isinstance(eth.data, dpkt.ip.IP):
  88. # print("timestamp:", _timestamp, "debug")
  89. parse_ip_packet(eth.data, nth, _timestamp, op)
  90. def parse_arguments():
  91. """
  92. Parses command line arguments.
  93. """
  94. global filename
  95. global verboseprint
  96. global output_file
  97. global is_white_sample
  98. parser = argparse.ArgumentParser(
  99. formatter_class=argparse.RawDescriptionHelpFormatter,
  100. description=textwrap.dedent('''\
  101. Captures, parses and shows TLS Handshake packets
  102. Copyright (C) 2015 Peter Mosmans [Go Forward]
  103. This program is free software: you can redistribute it and/or modify
  104. it under the terms of the GNU General Public License as published by
  105. the Free Software Foundation, either version 3 of the License, or
  106. (at your option) any later version.'''))
  107. parser.add_argument('-r', '--read', metavar='FILE', action='store',
  108. help='read from file (don\'t capture live packets)')
  109. parser.add_argument('-v', '--verbose', action='store_true',
  110. help='increase output verbosity')
  111. parser.add_argument('-t', '--is_white_sample', action='store_true',
  112. help='is white sample?')
  113. parser.add_argument('-o', '--output', action='store',
  114. help='output file')
  115. args = parser.parse_args()
  116. if args.verbose:
  117. def verboseprint(*args):
  118. print('# ', end="")
  119. for arg in args:
  120. print(arg, end="")
  121. print()
  122. else:
  123. verboseprint = lambda *a: None
  124. if args.is_white_sample:
  125. print("OK, process white sample data.")
  126. is_white_sample = True
  127. else:
  128. print("OK, process black sample data.")
  129. is_white_sample = False
  130. filename = None
  131. if args.read:
  132. filename = args.read
  133. output_file = "demo_output.pickle"
  134. if args.output:
  135. output_file = args.output
  136. def parse_ip_packet(ip, nth, timestamp, op):
  137. """
  138. Parses IP packet.
  139. """
  140. sys.stdout.flush()
  141. if isinstance(ip.data, dpkt.tcp.TCP):
  142. # print("****TCP packet found****", "tcp payload:", list(ip.data.data))
  143. """
  144. try:
  145. tls = dpkt.ssl.TLS(ip.data.data)
  146. if len(tls.records) < 1:
  147. return
  148. except Exception as e:
  149. print(e)
  150. return
  151. """
  152. parse_tcp_packet(ip, nth, timestamp, op)
  153. # TLS version
  154. def check_tls_version(data):
  155. version2 = False
  156. version3 = False
  157. if len(data) > 2:
  158. # ssl
  159. tmp = struct.unpack("bbb", data[0:3])
  160. else:
  161. return version2, version3
  162. # SSL v2. OR Message body too short.
  163. if (tmp[0] & 0x80 == 0x80) and (((tmp[0] & 0x7f) << 8 | tmp[1]) > 9):
  164. version2 = True
  165. elif (tmp[1] != 3) or (tmp[2] > 3): # 版本,SSL 3.0 or TLS 1.0, 1.1 and 1.2
  166. version3 = False
  167. elif (tmp[0] < 20) or (tmp[0] > 23): # 类型错误
  168. pass
  169. else:
  170. version3 = True
  171. return version2, version3
  172. def parse_tcp_packet(ip, nth, timestamp, op):
  173. """
  174. Parses TCP packet.
  175. """
  176. record_server_ip(ip)
  177. stream = ip.data.data
  178. if len(stream):
  179. record_data_flow(ip, stream, nth, timestamp)
  180. # def record_server_ip(ip):
  181. # """
  182. # >>> int(ipaddress.IPv4Address('192.168.0.1'))
  183. # 3232235521
  184. # >>> int(ipaddress.IPv4Address('0.0.0.1'))
  185. # 1
  186. # >>> int(ipaddress.IPv4Address('0.0.1.1'))
  187. # 257
  188. # """
  189. # src_ip = socket.inet_ntoa(ip.src)
  190. # dst_ip = socket.inet_ntoa(ip.dst)
  191. # # 这里使用一个确定规则(小ip作为源),把相同方向的数据汇聚到一起
  192. # if int(ipaddress.IPv4Address(src_ip)) < int(ipaddress.IPv4Address(dst_ip)):
  193. # connection_key = "{}-{}".format(dst_ip, src_ip)
  194. # global server_ip_set
  195. # if connection_key not in server_ip_set:
  196. # server_ip_set.add(connection_key)
  197. # buffer[connection_key] = [{"out":[], "in":[]}]
  198. def record_server_ip(ip):
  199. src_ip = '{0}:{1}'.format(socket.inet_ntoa(ip.src), ip.data.sport)
  200. dst_ip = '{0}:{1}'.format(socket.inet_ntoa(ip.dst), ip.data.dport)
  201. tcp = ip.data
  202. fin_flag = ( tcp.flags & dpkt.tcp.TH_FIN ) != 0
  203. syn_flag = ( tcp.flags & dpkt.tcp.TH_SYN ) != 0
  204. rst_flag = ( tcp.flags & dpkt.tcp.TH_RST ) != 0
  205. psh_flag = ( tcp.flags & dpkt.tcp.TH_PUSH) != 0
  206. ack_flag = ( tcp.flags & dpkt.tcp.TH_ACK ) != 0
  207. urg_flag = ( tcp.flags & dpkt.tcp.TH_URG ) != 0
  208. ece_flag = ( tcp.flags & dpkt.tcp.TH_ECE ) != 0
  209. cwr_flag = ( tcp.flags & dpkt.tcp.TH_CWR ) != 0
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号