github.com/Coalfire-Research/Slackor@v0.0.0-20191010164036-aa32a7f9250b/impacket/examples/split.py (about)

     1  #!/usr/bin/env python
     2  # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
     3  #
     4  # This software is provided under under a slightly modified version
     5  # of the Apache Software License. See the accompanying LICENSE file
     6  # for more information.
     7  #
     8  # Pcap dump splitter.
     9  #
    10  # This tools splits pcap capture files into smaller ones, one for each
    11  # different TCP/IP connection found in the original.
    12  #
    13  # Authors:
    14  #  Alejandro D. Weil <aweil@coresecurity.com>
    15  #  Javier Kohen <jkohen@coresecurity.com>
    16  #
    17  # Reference for:
    18  #  pcapy: open_offline, pcapdumper.
    19  #  ImpactDecoder.
    20  from __future__ import division
    21  from __future__ import print_function
    22  import sys
    23  import pcapy
    24  from pcapy import open_offline
    25  
    26  from impacket.ImpactDecoder import EthDecoder, LinuxSLLDecoder
    27  
    28  
    29  class Connection:
    30      """This class can be used as a key in a dictionary to select a connection
    31      given a pair of peers. Two connections are considered the same if both
    32      peers are equal, despite the order in which they were passed to the
    33      class constructor.
    34      """
    35  
    36      def __init__(self, p1, p2):
    37          """This constructor takes two tuples, one for each peer. The first
    38          element in each tuple is the IP address as a string, and the
    39          second is the port as an integer.
    40          """
    41  
    42          self.p1 = p1
    43          self.p2 = p2
    44  
    45      def getFilename(self):
    46          """Utility function that returns a filename composed by the IP
    47          addresses and ports of both peers.
    48          """
    49          return '%s.%d-%s.%d.pcap'%(self.p1[0],self.p1[1],self.p2[0],self.p2[1])
    50  
    51      def __cmp__(self, other):
    52          if ((self.p1 == other.p1 and self.p2 == other.p2)
    53              or (self.p1 == other.p2 and self.p2 == other.p1)):
    54              return 0
    55          else:
    56              return -1
    57  
    58      def __hash__(self):
    59          return (hash(self.p1[0]) ^ hash(self.p1[1])
    60                  ^ hash(self.p2[0]) ^ hash(self.p2[1]))
    61  
    62  
    63  class Decoder:
    64      def __init__(self, pcapObj):
    65          # Query the type of the link and instantiate a decoder accordingly.
    66          datalink = pcapObj.datalink()
    67          if pcapy.DLT_EN10MB == datalink:
    68              self.decoder = EthDecoder()
    69          elif pcapy.DLT_LINUX_SLL == datalink:
    70              self.decoder = LinuxSLLDecoder()
    71          else:
    72              raise Exception("Datalink type not supported: " % datalink)
    73  
    74          self.pcap = pcapObj
    75          self.connections = {}
    76  
    77      def start(self):
    78          # Sniff ad infinitum.
    79          # PacketHandler shall be invoked by pcap for every packet.
    80          self.pcap.loop(0, self.packetHandler)
    81  
    82      def packetHandler(self, hdr, data):
    83          """Handles an incoming pcap packet. This method only knows how
    84          to recognize TCP/IP connections.
    85          Be sure that only TCP packets are passed onto this handler (or
    86          fix the code to ignore the others).
    87  
    88          Setting r"ip proto \tcp" as part of the pcap filter expression
    89          suffices, and there shouldn't be any problem combining that with
    90          other expressions.
    91          """
    92  
    93          # Use the ImpactDecoder to turn the rawpacket into a hierarchy
    94          # of ImpactPacket instances.
    95          p = self.decoder.decode(data)
    96          ip = p.child()
    97          tcp = ip.child()
    98  
    99          # Build a distinctive key for this pair of peers.
   100          src = (ip.get_ip_src(), tcp.get_th_sport() )
   101          dst = (ip.get_ip_dst(), tcp.get_th_dport() )
   102          con = Connection(src,dst)
   103  
   104          # If there isn't an entry associated yetwith this connection,
   105          # open a new pcapdumper and create an association.
   106          if ('%s%s' % (con.p1, con.p2)) not in self.connections:
   107              fn = con.getFilename()
   108              print("Found a new connection, storing into:", fn)
   109              try:
   110                  dumper = self.pcap.dump_open(fn)
   111              except pcapy.PcapError:
   112                  print("Can't write packet to:", fn)
   113                  return
   114              self.connections['%s%s' % (con.p1, con.p2)] = dumper
   115  
   116          # Write the packet to the corresponding file.
   117          self.connections['%s%s' % (con.p1, con.p2)].dump(hdr, data)
   118  
   119  
   120  
   121  def main(filename):
   122      # Open file
   123      p = open_offline(filename)
   124  
   125      # At the moment the callback only accepts TCP/IP packets.
   126      p.setfilter(r'ip proto \tcp')
   127  
   128      print("Reading from %s: linktype=%d" % (filename, p.datalink()))
   129  
   130      # Start decoding process.
   131      Decoder(p).start()
   132  
   133  
   134  # Process command-line arguments.
   135  if __name__ == '__main__':
   136      if len(sys.argv) <= 1:
   137          print("Usage: %s <filename>" % sys.argv[0])
   138          sys.exit(1)
   139  
   140      main(sys.argv[1])