<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Scapy in 15 minutes (or longer)
Guillaume Valadon & Pierre Lalet
Scapy is a powerful Python-based interactive packet manipulation program and library. It can be used to forge or decode packets for a wide number of protocols, send them on the wire, capture them, match requests and replies, and much more.
This iPython notebook provides a short tour of the main Scapy features. It assumes that you are familiar with networking terminology. All examples were built using the development version from https
Step1:  2_ Advanced firewalking using IP options is sometimes useful to perform network enumeration. Here is a more complicated one-liner
Step2:  Now that we've got your attention, let's start the tutorial !
Quick setup
The easiest way to try Scapy is to clone the github repository, then launch the run_scapy script as root. The following examples can be pasted at the Scapy prompt. There is no need to install any external Python modules.
```shell
git clone https
Step3:  First steps
With Scapy, each network layer is a Python class.
The '/' operator is used to bind layers together. Let's put a TCP segment on top of IP and assign it to the packet variable, then stack it on top of Ethernet.
Step4:  This last output displays the packet summary. Here, Scapy automatically filled the Ethernet type as well as the IP protocol field.
Protocol fields can be listed using the ls() function
Step5:  Let's create a new packet to a specific IP destination. With Scapy, each protocol field can be specified. As shown in the ls() output, the interesting field is dst.
Scapy packets are objects with some useful methods, such as summary().
Step6:  There are not many differences with the previous example. However, Scapy used the specific destination to perform some magic tricks !
Using internal mechanisms (such as DNS resolution, routing table and ARP resolution), Scapy has automatically set fields necessary to send the packet. These fields can of course be accessed and displayed.
Step7:  Scapy uses default values that work most of the time. For example, TCP() is a SYN segment to port 80.
Step8:  Moreover, Scapy has implicit packets. For example, they are useful to make the TTL field value vary from 1 to 5 to mimic traceroute.
Step9:  Sending and receiving
Currently, you know how to build packets with Scapy. The next step is to send them over the network !
The sr1() function sends a packet and returns the corresponding answer. srp1() does the same for layer two packets, i.e. Ethernet. If you are only interested in sending packets send() is your friend.
As an example, we can use the DNS protocol to get www.example.com IPv4 address.
Step10:  Another alternative is the sr() function. Like srp1(), the sr1() function can be used for layer 2 packets.
Step11:  sr() sent a list of packets, and returns two variables, here r and u, where
Step12:  With Scapy, list of packets, such as r or u, can be easily written to, or read from PCAP files.
Step13:  Sniffing the network is as straightforward as sending and receiving packets. The sniff() function returns a list of Scapy packets, that can be manipulated as previously described.
Step14:  sniff() has many arguments. The prn one accepts a function name that will be called on received packets. Using the lambda keyword, Scapy could be used to mimic the tshark command behavior.
Step15:  Alternatively, Scapy can use OS sockets to send and receive packets. The following example assigns an UDP socket to a Scapy StreamSocket, which is then used to query www.example.com IPv4 address.
Unlike other Scapy sockets, StreamSockets do not require root privileges.
Step16:  Visualization
Parts of the following examples require the matplotlib module.
With srloop(), we can send 100 ICMP packets to 8.8.8.8 and 8.8.4.4.
Step17:  Then we can use the results to plot the IP id values.
Step18:  The raw() constructor can be used to "build" the packet's bytes as they would be sent on the wire.
Step19:  Since some people cannot read this representation, Scapy can
Step20:  "hexdump" the packet's bytes
Step21:  dump the packet, layer by layer, with the values for each field
Step22:  render a pretty and handy dissection of the packet
Step23:  Scapy has a traceroute() function, which basically runs a sr(IP(ttl=(1..30)) and creates a TracerouteResult object, which is a specific subclass of SndRcvList().
Step24:  The result can be plotted with .world_trace() (this requires GeoIP module and data, from MaxMind)
Step25:  The PacketList.make_table() function can be very helpful. Here is a simple "port scanner"
Step26:  Implementing a new protocol
Scapy can be easily extended to support new protocols.
The following example defines DNS over TCP. The DNSTCP class inherits from Packet and defines two field
Step27:  This new packet definition can be direcly used to build a DNS message over TCP.
Step28:  Modifying the previous StreamSocket example to use TCP allows to use the new DNSCTP layer easily.
Step29:  Scapy as a module
So far, Scapy was only used from the command line. It is also a Python module than can be used to build specific network tools, such as ping6.py
Step30:  Answering machines
A lot of attack scenarios look the same
Step31:  Cheap Man-in-the-middle with NFQUEUE
NFQUEUE is an iptables target than can be used to transfer packets to userland process. As a nfqueue module is available in Python, you can take advantage of this Linux feature to perform Scapy based MiTM.
This example intercepts ICMP Echo request messages sent to 8.8.8.8, sent with the ping command, and modify their sequence numbers. In order to pass packets to Scapy, the following iptable command put packets into the NFQUEUE #2807
Step32:  Automaton
When more logic is needed, Scapy provides a clever way abstraction to define an automaton. In a nutshell, you need to define an object that inherits from Automaton, and implement specific methods
Step33:  Pipes
Pipes are an advanced Scapy feature that aims sniffing, modifying and printing packets. The API provides several buildings blocks. All of them, have high entries and exits (>>) as well as low (>) ones.
For example, the CliFeeder is used to send message from the Python command line to a low exit. It can be combined to the InjectSink that reads message on its low entry and inject them to the specified network interface. These blocks can be combined as follows
Step34:  Packet can be sent using the following command on the prompt
<ASSISTANT_TASK:>
Python Code:
send(IP(dst="1.2.3.4")/TCP(dport=502, options=[("MSS", 0)]))
Explanation: Scapy in 15 minutes (or longer)
Guillaume Valadon & Pierre Lalet
Scapy is a powerful Python-based interactive packet manipulation program and library. It can be used to forge or decode packets for a wide number of protocols, send them on the wire, capture them, match requests and replies, and much more.
This iPython notebook provides a short tour of the main Scapy features. It assumes that you are familiar with networking terminology. All examples were built using the development version from https://github.com/secdev/scapy, and tested on Linux. They should work as well on OS X, and other BSD.
The current documentation is available on http://scapy.readthedocs.io/ !
Scapy eases network packets manipulation, and allows you to forge complicated packets to perform advanced tests. As a teaser, let's have a look a two examples that are difficult to express without Scapy:
1_ Sending a TCP segment with maximum segment size set to 0 to a specific port is an interesting test to perform against embedded TCP stacks. It can be achieved with the following one-liner:
End of explanation
ans = sr([IP(dst="8.8.8.8", ttl=(1, 8), options=IPOption_RR())/ICMP(seq=RandShort()), IP(dst="8.8.8.8", ttl=(1, 8), options=IPOption_Traceroute())/ICMP(seq=RandShort()), IP(dst="8.8.8.8", ttl=(1, 8))/ICMP(seq=RandShort())], verbose=False, timeout=3)[0]
ans.make_table(lambda x, y: (", ".join(z.summary() for z in x[IP].options) or '-', x[IP].ttl, y.sprintf("%IP.src% %ICMP.type%")))
Explanation: 2_ Advanced firewalking using IP options is sometimes useful to perform network enumeration. Here is a more complicated one-liner:
End of explanation
from scapy.all import *
Explanation: Now that we've got your attention, let's start the tutorial !
Quick setup
The easiest way to try Scapy is to clone the github repository, then launch the run_scapy script as root. The following examples can be pasted at the Scapy prompt. There is no need to install any external Python modules.
```shell
git clone https://github.com/secdev/scapy --depth=1
sudo ./run_scapy
Welcome to Scapy (2.4.0)
```
Note: iPython users must import scapy as follows
End of explanation
packet = IP()/TCP()
Ether()/packet
Explanation: First steps
With Scapy, each network layer is a Python class.
The '/' operator is used to bind layers together. Let's put a TCP segment on top of IP and assign it to the packet variable, then stack it on top of Ethernet.
End of explanation
    >>> ls(IP, verbose=True)
    version    : BitField (4 bits)                   = (4)
    ihl        : BitField (4 bits)                   = (None)
    tos        : XByteField                          = (0)
    len        : ShortField                          = (None)
    id         : ShortField                          = (1)
    flags      : FlagsField (3 bits)                 = (0)
                   MF, DF, evil
    frag       : BitField (13 bits)                  = (0)
    ttl        : ByteField                           = (64)
    proto      : ByteEnumField                       = (0)
    chksum     : XShortField                         = (None)
    src        : SourceIPField (Emph)                = (None)
    dst        : DestIPField (Emph)                  = (None)
    options    : PacketListField                     = ([])
Explanation: This last output displays the packet summary. Here, Scapy automatically filled the Ethernet type as well as the IP protocol field.
Protocol fields can be listed using the ls() function:
End of explanation
p = Ether()/IP(dst="www.secdev.org")/TCP()
p.summary()
Explanation: Let's create a new packet to a specific IP destination. With Scapy, each protocol field can be specified. As shown in the ls() output, the interesting field is dst.
Scapy packets are objects with some useful methods, such as summary().
End of explanation
print(p.dst)  # first layer that has an src field, here Ether
print(p[IP].src)  # explicitly access the src field of the IP layer
# sprintf() is a useful method to display fields
print(p.sprintf("%Ether.src% > %Ether.dst%\n%IP.src% > %IP.dst%"))
Explanation: There are not many differences with the previous example. However, Scapy used the specific destination to perform some magic tricks !
Using internal mechanisms (such as DNS resolution, routing table and ARP resolution), Scapy has automatically set fields necessary to send the packet. These fields can of course be accessed and displayed.
End of explanation
print(p.sprintf("%TCP.flags% %TCP.dport%"))
Explanation: Scapy uses default values that work most of the time. For example, TCP() is a SYN segment to port 80.
End of explanation
[p for p in IP(ttl=(1,5))/ICMP()]
Explanation: Moreover, Scapy has implicit packets. For example, they are useful to make the TTL field value vary from 1 to 5 to mimic traceroute.
End of explanation
p = sr1(IP(dst="8.8.8.8")/UDP()/DNS(qd=DNSQR()))
p[DNS].an
Explanation: Sending and receiving
Currently, you know how to build packets with Scapy. The next step is to send them over the network !
The sr1() function sends a packet and returns the corresponding answer. srp1() does the same for layer two packets, i.e. Ethernet. If you are only interested in sending packets send() is your friend.
As an example, we can use the DNS protocol to get www.example.com IPv4 address.
End of explanation
r, u = srp(Ether()/IP(dst="8.8.8.8", ttl=(5,10))/UDP()/DNS(rd=1, qd=DNSQR(qname="www.example.com")))
r, u
Explanation: Another alternative is the sr() function. Like srp1(), the sr1() function can be used for layer 2 packets.
End of explanation
# Access the first tuple
print(r[0][0].summary())  # the packet sent
print(r[0][1].summary())  # the answer received
# Access the ICMP layer. Scapy received a time-exceeded error message
r[0][1][ICMP]
Explanation: sr() sent a list of packets, and returns two variables, here r and u, where:
1. r is a list of results (i.e tuples of the packet sent and its answer)
2. u is a list of unanswered packets
End of explanation
wrpcap("scapy.pcap", r)
pcap_p = rdpcap("scapy.pcap")
pcap_p[0]
Explanation: With Scapy, list of packets, such as r or u, can be easily written to, or read from PCAP files.
End of explanation
s = sniff(count=2)
s
Explanation: Sniffing the network is as straightforward as sending and receiving packets. The sniff() function returns a list of Scapy packets, that can be manipulated as previously described.
End of explanation
sniff(count=2, prn=lambda p: p.summary())
Explanation: sniff() has many arguments. The prn one accepts a function name that will be called on received packets. Using the lambda keyword, Scapy could be used to mimic the tshark command behavior.
End of explanation
import socket
sck = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # create an UDP socket
sck.connect(("8.8.8.8", 53))  # connect to 8.8.8.8 on 53/UDP
# Create the StreamSocket and gives the class used to decode the answer
ssck = StreamSocket(sck)
ssck.basecls = DNS
# Send the DNS query
ssck.sr1(DNS(rd=1, qd=DNSQR(qname="www.example.com")))
Explanation: Alternatively, Scapy can use OS sockets to send and receive packets. The following example assigns an UDP socket to a Scapy StreamSocket, which is then used to query www.example.com IPv4 address.
Unlike other Scapy sockets, StreamSockets do not require root privileges.
End of explanation
ans, unans = srloop(IP(dst=["8.8.8.8", "8.8.4.4"])/ICMP(), inter=.1, timeout=.1, count=100, verbose=False)
Explanation: Visualization
Parts of the following examples require the matplotlib module.
With srloop(), we can send 100 ICMP packets to 8.8.8.8 and 8.8.4.4.
End of explanation
%matplotlib inline
ans.multiplot(lambda x, y: (y[IP].src, (y.time, y[IP].id)), plot_xy=True)
Explanation: Then we can use the results to plot the IP id values.
End of explanation
pkt = IP() / UDP() / DNS(qd=DNSQR())
print(repr(raw(pkt)))
Explanation: The raw() constructor can be used to "build" the packet's bytes as they would be sent on the wire.
End of explanation
print(pkt.summary())
Explanation: Since some people cannot read this representation, Scapy can:
  - give a summary for a packet
End of explanation
hexdump(pkt)
Explanation: "hexdump" the packet's bytes
End of explanation
pkt.show()
Explanation: dump the packet, layer by layer, with the values for each field
End of explanation
pkt.canvas_dump()
Explanation: render a pretty and handy dissection of the packet
End of explanation
ans, unans = traceroute('www.secdev.org', maxttl=15)
Explanation: Scapy has a traceroute() function, which basically runs a sr(IP(ttl=(1..30)) and creates a TracerouteResult object, which is a specific subclass of SndRcvList().
End of explanation
ans.world_trace()
Explanation: The result can be plotted with .world_trace() (this requires GeoIP module and data, from MaxMind)
End of explanation
ans = sr(IP(dst=["scanme.nmap.org", "nmap.org"])/TCP(dport=[22, 80, 443, 31337]), timeout=3, verbose=False)[0]
ans.extend(sr(IP(dst=["scanme.nmap.org", "nmap.org"])/UDP(dport=53)/DNS(qd=DNSQR()), timeout=3, verbose=False)[0])
ans.make_table(lambda x, y: (x[IP].dst, x.sprintf('%IP.proto%/{TCP:%r,TCP.dport%}{UDP:%r,UDP.dport%}'), y.sprintf('{TCP:%TCP.flags%}{ICMP:%ICMP.type%}')))
Explanation: The PacketList.make_table() function can be very helpful. Here is a simple "port scanner":
End of explanation
class DNSTCP(Packet):
    name = "DNS over TCP"
    
    fields_desc = [ FieldLenField("len", None, fmt="!H", length_of="dns"),
                    PacketLenField("dns", 0, DNS, length_from=lambda p: p.len)]
    
    # This method tells Scapy that the next packet must be decoded with DNSTCP
    def guess_payload_class(self, payload):
        return DNSTCP
Explanation: Implementing a new protocol
Scapy can be easily extended to support new protocols.
The following example defines DNS over TCP. The DNSTCP class inherits from Packet and defines two field: the length, and the real DNS message. The length_of and length_from arguments link the len and dns fields together. Scapy will be able to automatically compute the len value.
End of explanation
# Build then decode a DNS message over TCP
DNSTCP(raw(DNSTCP(dns=DNS())))
Explanation: This new packet definition can be direcly used to build a DNS message over TCP.
End of explanation
import socket
sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # create an TCP socket
sck.connect(("8.8.8.8", 53))  # connect to 8.8.8.8 on 53/TCP
# Create the StreamSocket and gives the class used to decode the answer
ssck = StreamSocket(sck)
ssck.basecls = DNSTCP
# Send the DNS query
ssck.sr1(DNSTCP(dns=DNS(rd=1, qd=DNSQR(qname="www.example.com"))))
Explanation: Modifying the previous StreamSocket example to use TCP allows to use the new DNSCTP layer easily.
End of explanation
    from scapy.all import *
    import argparse
    parser = argparse.ArgumentParser(description="A simple ping6")
    parser.add_argument("ipv6_address", help="An IPv6 address")
    args = parser.parse_args()
    print(sr1(IPv6(dst=args.ipv6_address)/ICMPv6EchoRequest(), verbose=0).summary())
Explanation: Scapy as a module
So far, Scapy was only used from the command line. It is also a Python module than can be used to build specific network tools, such as ping6.py:
End of explanation
# Specify the Wi-Fi monitor interface
#conf.iface = "mon0"  # uncomment to test
# Create an answering machine
class ProbeRequest_am(AnsweringMachine):
  function_name = "pram"
  # The fake mac of the fake access point
  mac = "00:11:22:33:44:55"
  def is_request(self, pkt):
    return Dot11ProbeReq in pkt
  def make_reply(self, req):
    rep = RadioTap()
    # Note: depending on your Wi-Fi card, you might need a different header than RadioTap()
    rep /= Dot11(addr1=req.addr2, addr2=self.mac, addr3=self.mac, ID=RandShort(), SC=RandShort())
    rep /= Dot11ProbeResp(cap="ESS", timestamp=time.time())
    rep /= Dot11Elt(ID="SSID",info="Scapy !")
    rep /= Dot11Elt(ID="Rates",info=b'\x82\x84\x0b\x16\x96')
    rep /= Dot11Elt(ID="DSset",info=chr(10))
    OK,return rep
# Start the answering machine
#ProbeRequest_am()()  # uncomment to test
Explanation: Answering machines
A lot of attack scenarios look the same: you want to wait for a specific packet, then send an answer to trigger the attack.
To this extent, Scapy provides the AnsweringMachine object. Two methods are especially useful:
1. is_request(): return True if the pkt is the expected request
2. make_reply(): return the packet that must be sent
The following example uses Scapy Wi-Fi capabilities to pretend that a "Scapy !" access point exists.
Note: your Wi-Fi interface must be set to monitor mode !
End of explanation
    from scapy.all import *
    import nfqueue, socket
    def scapy_cb(i, payload):
      s = payload.get_data()  # get and parse the packet
      p = IP(s)
      # Check if the packet is an ICMP Echo Request to 8.8.8.8
      if p.dst == "8.8.8.8" and ICMP in p:
        # Delete checksums to force Scapy to compute them
        del(p[IP].chksum, p[ICMP].chksum)
        
        # Set the ICMP sequence number to 0
        p[ICMP].seq = 0
        
        # Let the modified packet go through
        ret = payload.set_verdict_modified(nfqueue.NF_ACCEPT, raw(p), len(p))
        
      else:
        # Accept all packets
        payload.set_verdict(nfqueue.NF_ACCEPT)
    # Get an NFQUEUE handler
    q = nfqueue.queue()
    # Set the function that will be call on each received packet
    q.set_callback(scapy_cb)
    # Open the queue & start parsing packes
    q.fast_open(2807, socket.AF_INET)
    q.try_run()
Explanation: Cheap Man-in-the-middle with NFQUEUE
NFQUEUE is an iptables target than can be used to transfer packets to userland process. As a nfqueue module is available in Python, you can take advantage of this Linux feature to perform Scapy based MiTM.
This example intercepts ICMP Echo request messages sent to 8.8.8.8, sent with the ping command, and modify their sequence numbers. In order to pass packets to Scapy, the following iptable command put packets into the NFQUEUE #2807:
$ sudo iptables -I OUTPUT --destination 8.8.8.8 -p icmp -o eth0 -j NFQUEUE --queue-num 2807
End of explanation
class TCPScanner(Automaton):
    @ATMT.state(initial=1)
    def BEGIN(self):
        pass
    @ATMT.state()
    def SYN(self):
        print("-> SYN")
    @ATMT.state()
    def SYN_ACK(self):
        print("<- SYN/ACK")
        raise self.END()
    @ATMT.state()
    def RST(self):
        print("<- RST")
        raise self.END()
    @ATMT.state()
    def ERROR(self):
        print("!! ERROR")
        raise self.END()
    @ATMT.state(final=1)
    def END(self):
        pass
    
    @ATMT.condition(BEGIN)
    def condition_BEGIN(self):
        raise self.SYN()
    @ATMT.condition(SYN)
    def condition_SYN(self):
        if random.randint(0, 1):
            raise self.SYN_ACK()
        else:
            raise self.RST()
    @ATMT.timeout(SYN, 1)
    def timeout_SYN(self):
        raise self.ERROR()
TCPScanner().run()
TCPScanner().run()
Explanation: Automaton
When more logic is needed, Scapy provides a clever way abstraction to define an automaton. In a nutshell, you need to define an object that inherits from Automaton, and implement specific methods:
- states: using the @ATMT.state decorator. They usually do nothing
- conditions: using the @ATMT.condition and @ATMT.receive_condition decorators. They describe how to go from one state to another
- actions: using the ATMT.action decorator. They describe what to do, like sending a back, when changing state
The following example does nothing more than trying to mimic a TCP scanner:
End of explanation
# Instantiate the blocks
clf = CLIFeeder()
ijs = InjectSink("enx3495db043a28")
# Plug blocks together
clf > ijs
# Create and start the engine
pe = PipeEngine(clf)
pe.start()
Explanation: Pipes
Pipes are an advanced Scapy feature that aims sniffing, modifying and printing packets. The API provides several buildings blocks. All of them, have high entries and exits (>>) as well as low (>) ones.
For example, the CliFeeder is used to send message from the Python command line to a low exit. It can be combined to the InjectSink that reads message on its low entry and inject them to the specified network interface. These blocks can be combined as follows:
End of explanation
clf.send("Hello Scapy !")
Explanation: Packet can be sent using the following command on the prompt:
End of explanation
<END_TASK>