1
votes

I'm trying to filter certain packets with protocols using user input from a given pcap file and than move the packets to a new pcap file.

That the code I made so far:

# ===================================================
# Imports
# ===================================================


from scapy.all import *
from scapy.utils import PcapWriter
"""
your going to need to install the modules below
"""
from Tkinter import Tk
from tkFileDialog import askopenfilename

# ===================================================
# Constants
# ===================================================


#OS commands:
#~~~~~~~~~~~~~

if "linux2" in sys.platform:
    """
    linux based system clear command
    """
    CLEAR_COMMAND = "clear"
elif "win32" in sys.platform:
    """
    windows based system clear command
    """
    CLEAR_COMMAND = "cls"
elif "cygwin" in sys.platform:
    """
    crygwin based clear command
    """
    CLEAR_COMMAND = "printf \"\\033c\""
elif "darwin" in sys.platform:
    """
    mac OS X based clear command
    """
    CLEAR_COMMAND = "printf \'\\33c\\e[3J\'"

#Usage string:
#~~~~~~~~~~~~~~


FILE_STRING = "please choose a pcap file to use"
BROWSE_STRING = "press any key to browser files\n"
BAD_PATH_STRING = "bad file please try agien\n"
BAD_INPUT_STRING = "bad input please try agien\n"
PROTOCOL_STRING = "please enter the protocol you wish to filter\n"
NAME_STRING = "please enter the new pcap file name\n"



# ===================================================
# Code
# ===================================================


def filter_pcap():
    """
    filtering from the given pcap file a protocol the user chooce (from any layer in the OSI model)
    and than asks for a new pcap file name, than filters the given protocol to a new pcap file
    :param none
    :return nothing:
    """
    path = file_browse()
    i = 0
    filtertype = raw_input(PROTOCOL_STRING)
    name = raw_input(NAME_STRING)
    packs = rdpcap(path)
    for i in range(len(packs)):
        if filtertype in packs[i]:
           wrpcap(name +".pcap", packs[i])





def file_browse():


    """
    Purpose: It will allow the user to browse files on his computer
    than it will check if the path is ok and will return it

    :returns - the path to the chosen pcap file
    """
    path = "test"
    while ".pcap" not in path:
        print FILE_STRING
        raw_input(BROWSE_STRING)
        os.system(CLEAR_COMMAND)
        Tk().withdraw()
        path = askopenfilename()
        if ".pcap" not in path:
            print BAD_PATH_STRING
    return path

filter_pcap()

Now the problem is that I'm failing to filter the packets correctly.

The code need to filter protocols from any layer and any kind.

I have checked that thread: How can I filter a pcap file by specific protocol using python?

But as you can see it was not answered and the user added the problems I had in the edit, if any one could help me it would be great

Example for how it should work: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  1. lets say i use the file "sniff" as my first pcap file and it has 489 packets when 200 from those packets are http packets.

now there is that print:

please enter the protocol you wish to filter
'http'

and than there is the print:

please enter the new pcap file name
'new'

the user input was 'http' now the program will search for every packet that run on http protocol and will create a new pcap file called 'new.pcap'.

the file 'new.pcap' will contain 200 http packets.

now that thing should work with any protocol on the OSI model including protocols like IP, TCP, Ethernet and so on (all the protocols in the ascii model).

I have found out that wireshark command line has the option -R and tshark has .protocols, but it dont really work... Can any one check that?

edit: i found pyshark but i dont know how to write with it

1
isn't there any useful module i could use for that?asaf hirsh
Can you provide an example of input and what the program should output. I am having trouble understanding your requirements. If the user answers TCP, i would expect that all packets inside the original pcap that contain a TCP header to be outputted to the new pcap. Is that correct?Deney Fletcher
Yes that correct, i added some description to what it should do if it helpsasaf hirsh
I have added the editasaf hirsh

1 Answers

0
votes

I don't believe that scapy has any functions or methods to support application layer protocols in the way that you are after. However, using sport and dport as a filter will do the trick (provided you are going to see/are expecting default ports).

Try something like this:

def filter_pcap(filtertype = None):
    ..... snip .....
    # Static Dict of port to protocol values. Like so:
    protocols = {'http': 80, 'ssh': 22, 'telnet': 21} 

    # Check to see if it is in the list
    while filtertype not in protocols:
        filtertype = raw_input(PROTOCOL_STRING) 

    # Name for output file
    name = raw_input(NAME_STRING)

    # Read Input File
    packs = rdpcap(path)

    # Filters to only TCP packets
    for packet in packs[TCP]:

        # Filter only the proto (aka Port) that we want
        if protocols[filtertype] in packet.sport or protocols[filtertype] in packet.dport :

            # Write to file
            wrpcap(name +".pcap", packet)