Scapy

Most import commands to remember are:

Creating a packet

Packets are constucted as layers of protocols [like the OSI model, but exact]. They can be maniplulated independently or glued together. Example is the IP() object that represents an IPv4 header. Can use the show() method of an object to display all of its fields.

>>> IP().show()

Can modify all these fields. Either by passing them as arguments when the IP() object is created, or after saving it as a variable.

>>> ip.IP(src="192.168.0.1")
>>> ip.dst="192.168.0.2"
>>> ip
<IP src=192.168.0.1 dst=192.168.0.2 |>

Stringing the packetts together

"Of course, an IP packet by itself isn't very useful. We can add a layer four protocol like TCP or UDP by using the division operator to attach it to our IP packet."

>>> ip/TCP()
<IP  frag=0 proto=tcp src=192.168.0.1 dst=192.168.0.2 |<TCP  |>>

Can manipulate the TCP header fields just as like the IP header.

>>> tcp=TCP(sport=1025, dport=80)
>>> (tcp/ip).show()

NOTE: Remember to enclose combined headers in a pair of paranthese when using methods like show() on the entire packet.

Layer Two

Scapy supports Ethernet and IEEE 802.11 at layer two:

>>> Ether()/Dot1Q()/IP()
<Ether  type=0x8100 |<Dot1Q  type=0x800 |<IP  |>>>
>>> Dot11()/IP()
<Dot11  |<IP  |>>

Sending the packet

"Try combining different protocols to form a variety of packets. To send packets onto the wire, use the send() function if transmitting at layer three (i.e. without a layer two header) or the sendp() function if transmitting at layer two.

>>> send(ip/tcp)
.
Sent 1 packets.
>>> sendp(Ether()/ip/tcp)
.
Sent 1 packets.

Values for blank fields are populated automatically when possible.

send/receiving

The sr() function will transmit off a packet then record any response.

>>> sr(IP(dst="packetlife.net")/ICMP())
Begin emission:
Finished to send 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
(<Results: TCP:0 UDP:0 ICMP:1 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>)

If we want to send and listen for responses to multiple copies of the same packet, we can use the srloop() function and specify a count of packets to send.

>>> srloop(IP(dst="packetlife.net")/ICMP(), count=3)
RECV 1: IP / ICMP 174.143.213.184 > 192.168.1.140 echo-reply 0 / Padding
RECV 1: IP / ICMP 174.143.213.184 > 192.168.1.140 echo-reply 0 / Padding
RECV 1: IP / ICMP 174.143.213.184 > 192.168.1.140 echo-reply 0 / Padding

Sent 3 packets, received 3 packets. 100.0% hits.
(<Results: TCP:0 UDP:0 ICMP:3 Other:0>, <PacketList: TCP:0 UDP:0 ICMP:0 Other:0>)

How to setup a simple port scan

Say if you want to run a scan on IP:

>>> myip=IP(src="10.0.0.50",dst="10.10.22.1")
>>> mytcp=TCP(sport=9010,dport=22)
>>> p=myip/mytcp
>>> a,u=sr(p)           # <- this actually sends off a packet, and waits return

Note: Could have stored the results in a varible, results=sr(p) instead.

Or could split up Answered and Unanswered by a tulip, a,u=sr(p)
>>> a       # by itself will show results.
>>> a[0]    # will show the TCP settings
>>> a[1]    # would be UDP
>>> a[2]    # ICMP and so on.

To see what the options are: mytcp=TCP() mytcp.show() or: p=myip/mytcp p.show()

note: flags=S (for send) by default.

To change the current myip or mytcp use the .show() method, which lists the varibles you can change for instance mytcp.dport=81. IMPORTANT: after changing any varibles REMEMBER to reconstruct the packet. p=myip/mytcp

eof