Scapy:插入新层和记录问题 [英] Scapy: Inserting a new layer and logging issues

查看:75
本文介绍了Scapy:插入新层和记录问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  1. 我正在尝试使用 Scapy 在 GRE 和 IP 之间插入 GRErouting 层.我正在阅读的 pcap 包含一个按如下方式堆叠的数据包:Ethernet/IPv4/GRE/IPv4/ICMP.我看到的是 getLayer 返回当前层 + 它的有效载荷,其中可能包括其他层,这对我不利.我只想获取当前图层.当我为每一层执行 getLayer,然后写入整个数组时,我得到一个奇怪的 pcap,因为每一层都有额外的负载.
  2. 我也无法使用简单的打印"将任何数据输出到控制台.我知道这是因为 Scapy 添加了日志记录模块,并禁止了系统日志记录,但我想知道如何撤消该操作并能够使用打印"语句.

  1. I am attempting to insert GRErouting layer in between GRE and IP using Scapy. The pcap I am reading contains a single packet stacked as follows: Ethernet/IPv4/GRE/IPv4/ICMP. What I see is that getLayer returns the current layer + its payload, which may include other layers, and that's not good for me. I would like to only get the current layer. When I do getLayer for each layer, and then write the entire array I get a strange pcap because of the additional payload that each layer has over it.
  2. I am also not able to use a simple 'print' to output any data to console. I understand this is because Scapy adds the logging module, and suppresses system logging, but I'd like to know how to undo that and be able to use the 'print' statement.

import os
import sys
import logging
logging.basicConfig()
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import PcapReader, PcapWriter, fuzz, Packet
from scapy.layers.l2 import GRE, GRErouting
from scapy.layers.inet import IP
logging.getLogger("scapy.runtime").setLevel(logging.DEBUG)
logging.getLogger().setLevel(logging.DEBUG)


def foo(in_filename, out_filename):
    f = PcapReader(in_filename)
    o = PcapWriter(out_filename)

    p = f.read_packet()

    while p:
        layers = []
        counter = 0
        while True:
            layer = p.getlayer(counter)
            if (layer != None):
                layers.append(layer)

                if (type(layer) is IP):
                    del layer.chksum
                if (type(layer) is GRE):
                    logging.getLogger().debug("there is a GRE layer") 
                    layer.routing_present = 1
                    gr = GRErouting()
                    fuzz(gr)
                    layers.append(gr)
                    del layer.chksum
            else:
                break
            counter += 1
        logging.getLogger().debug("Layers are: %s\t\t",layers)
        for l in layers:
            logging.getLogger().debug("%s", l)
        o.write(layers)
        p = f.read_packet()


    f.close()
    o.close()

if __name__ == "__main__":
    logging.getLogger().debug('Executing main')
    if (len(sys.argv) == 3):
        in_filename = str(sys.argv[1])
        out_filename = str(sys.argv[2])
        if os.path.exists(in_filename) == False:
            sys.stderr.write("Either {0} does not exist, or you do not have proper permissions\n".format(in_filename))
        else:
            foo(in_filename, out_filename)
    else:
        sys.stderr.write("USAGE: {0} <path to input file> <path to output file>\n".format(str(sys.argv[0])))            

推荐答案

我终于能够回答我自己的两个问题了.请参阅下面的修改代码:

I was finally able to answer my own two questions. See modified code below:

    # importing the os package (see api at http://docs.python.org/2.6/library/io.html)
    import os
    # import function 'basename' from module os.path
    from os.path import basename
    # importing the sys package (see api at http://docs.python.org/2.6/library/sys.html)
    import sys
    # importing the logging package (see api at http://docs.python.org/2.6/library/logging.html)
    import logging
    # by default Scapy attempts to find ipv6 routing information, 
    # and if it does not find any it prints out a warning when running the module.
    # the following statement changes log level to ERROR so that this warning will not 
    # occur 
    effective_level = logging.getLogger("scapy.runtime").getEffectiveLevel()
    logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
    # importing Scapy
    from scapy.all import PcapReader, PcapWriter
    from scapy.layers.l2 import GRE, GRErouting, NoPayload
    # return the log level o be what it was
    logging.getLogger("scapy.runtime").setLevel(effective_level)
    # unfortunately, somewhere in Scapy sys.stdout is being reset.
    # thus, using the 'print' command will not produce output to the console.
    # the following two lines place stdout back into sys.
    if sys.stdout != sys.__stdout__:
        sys.stdout = sys.__stdout__

    # this is a function declaration. there is no need for explicit types.
    # python can infer an object type from its usage
    def foo(in_filename, out_filename):
        # open the input file for reading
        f = PcapReader(in_filename)
        # open the output file for writing
        o = PcapWriter(out_filename)

        # read the first packet from the input file
        p = f.read_packet()

        # while we haven't processed the last packet
        while p:
            # gets the first layer of the current packet
            layer = p.firstlayer()
            # loop over the layers
            while not isinstance(layer, NoPayload):

                if layer.default_fields.has_key('chksum'):
                    del layer.chksum
                if layer.default_fields.has_key('len'):
                    del layer.len

                if (type(layer) is GRE):
                    layer.routing_present = 1
                    layer.chksum_present = 1
                    # make sure to delete the checksum field. hopefully scapy will calculate it correctly one day
                    del layer.chksum

                    gr = GRErouting()
                    gr.address_family = 0x0800
                    gr.SRE_len = 4
                    gr.SRE_offset = 0
                    gr.routing_info = "1111"
                    # the NULL routing field
                    empty_gr = GRErouting()
                    empty_gr.address_family = 0x0000
                    empty_gr.SRE_len = 0

                    gr.add_payload(empty_gr)
                    gr.add_payload(layer.payload)
                    layer.remove_payload()
                    layer.add_payload(gr)
                    layer = empty_gr

                # advance to the next layer
                layer = layer.payload


            # write the packet we just dissected into the output file    
            o.write(p)
            # read the next packet
            p = f.read_packet()

        # close the input file
        f.close()
        # close the output file
        o.close()

    # i believe this is needed only if we are running the this module
    # as the main module. i don't know if this will get executed if this module
    # is imported into some other main module
    if __name__ == "__main__":
        # letting the user know we are starting. 
        # sys.argv[0] includes the path to the module, including the module name.
        # convert sys.argv[0] into string, and extract the module name only
        # (using basename)
        print '===> Running', basename(str(sys.argv[0]))
        # making sure that two parameters were entered on the command line
        if (len(sys.argv) == 3):
            # get the path to the input file
            in_filename = str(sys.argv[1])
            # get the path to the output file
            out_filename = str(sys.argv[2])
            # make sure the input file actually exists.
            # if it doesn't, we print out an error and exit
            if os.path.exists(in_filename) == False:
                # note the method for entering conversion specifiers ({<ordinal>})
                sys.stderr.write("Either {0} does not exist, or you do not have proper permissions\n".format(in_filename))
            else:
                # if the input file does exist, execute 'foo'
                foo(in_filename, out_filename)
                # print an end script notification
                print basename(str(sys.argv[0])), '===> completed successfully'
        else:
            # write a USAGE message to the standard output stream
            sys.stderr.write("USAGE: {0} <path to input file> <path to output file>\n".format(basename(str(sys.argv[0]))))

这篇关于Scapy:插入新层和记录问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆