Showing posts with label scapy. Show all posts
Showing posts with label scapy. Show all posts

Friday, January 14, 2011

Python + divert sockets + scapy

I have prepared a small class for playing with divert sockets and python. This example shows how to register a packet handler for packets fetched from the divert, then it loads a Scapy packet from the IP layer, displaying the contents, and at last it forward the packet to be delivered. It's just a Proof of Concept, that doesn't block packets, but if you implement your logic at the packet handler, setting the veredict to false it should block it.

And you might think now, why not just use a crafted RST packet from scapy? And I would answer, because it is more reliable, and because you might prefer not to send anything to the source IP that you want to block. An rst packet is enough to know that something (some app) is alive at the other side. On the other hand, a combination of both would be the best fit here, because that will avoid long timeouts while waitting for an answer, and duplicated requests (some browsers make a lot of retries).


To test it (on MacOSX), you need to have scapy installed. Then create a divert socket with a rule similar to this (be careful, this will enqueue all the packets at ipfw and it might break your connections if you don't attach a program to veredict them on time):

one@macuto2$ sudo ipfw add divert 3282 tcp from any to any
Password:
00100 divert 3282 ip from any to any proto tcp

Now run the attached script as follows:
sudo python2.6 DivertSocket.py 3282
And it should start fetching packets reaching the function of the packet handler, where you should place your logic. You might want to try to block petitions by for example ip addresses (just for testing), or content payload, but remember that this doesn't reassemble tcp streams, there would be much more to do for content inspection. Anyway I hope someone will have some fun testing it.


DivertSocket.py
-- cut here --
import socket
import sys
import re

from scapy.all import *

if not socket.__dict__.has_key("IPPROTO_DIVERT"):
# Define if
socket.IPPROTO_DIVERT = 254

class DivertSocket:
def __init__(self, port, delegateFunc=None):

self.sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_DIVERT)
# Here the addr can be any. The important one is the port
self.sock.bind(("0.0.0.0", port))
# By default the max
self.bufsize = 65535
# Set blocking
self.sock.setblocking(True)
# Register callback
self.delegateFunc = delegateFunc
self.__loop = 1

def start(self, default=0):
self.fetchPackets(default)

def fetchPackets(self, default=0):
while self.__loop:
buf, addr = self.sock.recvfrom(self.bufsize)
# If we registered a delegate funcion, call it
if self.delegateFunc != None:
self.delegateFunc(buf, addr)
# Else send it if the default behavior matches
else:
print "Warning, no functions registered for inspection!"
if default:
self.sendPacket(buf, addr)
else:
print "You need to implement a callback function for inspection"
sys.exit(-1)

def setVeredict(self, buf, addr, veredict=False):
if veredict:
if self.__sendPacket(buf, addr) == False:
print "Pkt not sent. Weird.. Need to see which packet causes this error"

def __sendPacket(self, buf, addr = None):
try:
if addr:
return self.sock.sendto(buf, addr)
#else try send it raw anyway..
return self.sock.send(buf)
except KeyboardInterrupt, e:
print "Stopping Engine..."
sys.exit(0)
except:
print "Could not send packet..."
return False

def stop(self):
self.__loop = 0
self.sock.close()


def pktHandler(buf, addr):
p = IP(buf)
print p.display()
ds.setVeredict(buf,addr, True)

ds = DivertSocket(int(sys.argv[1]), pktHandler)

ds.start()
-- stop here --

BTW, I would be very pleased if someone can test it under linux using iptables. Sooner or later I'll try it anyway.

Happy hacking!
;-)

Friday, December 25, 2009

Improved version of pcap2rawc

This version split each packet into layers, and each layer is pointed from an array of name like rawpktLayer_name[]


-- pcap2RawCLayers.py --
#!/usr/bin/python
try:
from scapy.all import *
except:
print "old way..."
from scapy import *

import sys
from binascii import *

if len(sys.argv) ==2:
print "Parsing "+str(sys.argv[1])
else:
print "Usage: python "+sys.argv[0]+" file.pcap"
exit(10)

pcap=rdpcap(sys.argv[1])
out=file(sys.argv[1]+".rawc","w")

out.write("// Generated from pcap2RawCLayers.py\n")

i=0
buff=""
arrays=[]

for p in pcap:
print "// packet "+str(i)+": ***"

while p.payload and len(p.payload) > 0:
q=p.copy()
q.payload = ''
bytes=len(q)
strbyte=""

for j in range(0,bytes):
if j %8 ==0:
strbyte = strbyte +"\n "
strbyte = strbyte + "0x" + str(hexlify(str(q)[j]))
if j < bytes-1:
if j+1 %8:
strbyte= strbyte + ","
else:
strbyte= strbyte + ", "

rawpkt=" rawpkt" + str(q.name) + "["+str(i)+"] = {" + strbyte + " }; /* end rawpkt" + str(p.name) +"["+ str(i) +"] */\n"
p=p.payload
arrays.append("rawpkt" + str(q.name))
buff = buff + rawpkt

if not p.payload and p.load:
q=p.copy()
bytes=len(q.load)
strbyte=""

for j in range(0,bytes):
if j %8 ==0:
strbyte = strbyte +"\n "
strbyte = strbyte + "0x" + str(hexlify(str(q.load)[j]))
if j < bytes-1:
if j+1 %8:
strbyte= strbyte + ","
else:
strbyte= strbyte + ", "

rawpkt=" rawpktPayload["+str(i)+"] = {" + strbyte + " }; /* end rawpktPayload["+ str(i) +"] */\n"
p=p.payload
arrays.append("rawpktPayload")

i=i+1
buff = buff + rawpkt

declares=""
for l in arrays:
declares = declares + " uint8_t *"+ l +"["+str(i)+"];\n"

filebuff = declares+ "\n"+ buff + "\n"
out.write(filebuff)
out.close()

print filebuff
print "//"+ str(i) +" packets written in "+sys.argv[1]+".rawc"

Tuesday, December 22, 2009

Rule2Alert

Hi, some updates.
I have started a new project with Josh Smith and Will Metcalf. Talking about scapy Josh told me if I would like to get involved in the project, and we created a google project called "rule2alert".


It's written in python and use scapy. The purpose of this project is to read snort compatible rules and write a pcap with packets that should match the rules. This can be used later to test NIDS like suricata and snort and detect problems on the detection plugins. Of course this needs a lot of development, for each rule keyword, so we don't think we will generate payloads for all the rules, but also for the majority of them. At the moment we deal with content and content modifiers, and also content hexa data specification, and flow options, performing TCP 3 way handshakes. The next steps will be focussed on http protocol options, like uricontent.

We hope it will be a good QA tool. If you would like to get involved, feel free to get in touch.

Tuesday, October 27, 2009

pcap2rawc.py

This is another script that maybe help someone coding things with raw c Packets. It take a pcap file and create a file with all that packets declared as c arrays.



#!/usr/bin/python
# File: pcap2rawc.py
# Pablo Rincon Crespo [pablo.rincon.crespo at gmail]
#
try:
from scapy.all import *
except:
print "old way..."
from scapy import *

import sys
from binascii import *

if len(sys.argv) ==2:
print "//Parsing "+str(sys.argv[1])
else:
print "Usage: python "+sys.argv[0]+" file.pcap"
exit(10)

pcap=rdpcap(sys.argv[1])
out=file(sys.argv[1]+".rawc","w")

out.write("// Generated from pcap2rawc.py\n")

i=0
for p in pcap:
i=i+1
print "//processing packet "+str(i)+": ***"
print p.command()
bytes=len(p)
strbyte=""
for j in range(0,bytes):
if j %8 ==0:
strbyte = strbyte +"\n "
strbyte = strbyte + "0x" + str(hexlify(str(p)[j]))
if j < bytes-1:
if j+1 %8:
strbyte= strbyte + ","
else:
strbyte= strbyte + ", "
rawpkt=" uint8_t rawpkt" + str(i) + "[] = {" +strbyte + " }; /* end rawpkt" + str(i) +" */\n"
print rawpkt

out.write(rawpkt + "\n")

out.close()
print "//"+ str(i) +" packets written in "+sys.argv[1]+".rawc"

Monday, August 10, 2009

NetMirror

I have created a small project hosted in code.google.com. The project hosting in Google has a lot of great features. If you are interested in network traffic mirroring, soft taps, traffic redistribution, have a look at NetMirror

Friday, June 19, 2009

pcap to scapy

Script that generate a python file with the packet generation code that Scapy need to replicate the traffic of a pcap file. I hope it would be useful for someone when testing NIDS features :)


## pcap2scapy.py ##
###################
# Author: Pablo Rincon Crespo
# mail: pablo@ossim.net
# Comments: This script read a pcap and write a .py with the scapy commands needed to replicate the traffic.

from scapy import *
import sys


if len(sys.argv) ==2:
print "Parsing "+str(sys.argv[1])
else:
print "Usage: python "+sys.argv[0]+" file.pcap"
exit(10)

pcap=rdpcap(sys.argv[1])
out=file(sys.argv[1]+".py","w")

out.write("from scapy import *\n\nl=[]\n")
i=0
for p in pcap:
i=i+1
# p.display()
print "*** Scapy packet "+str(i)+": ***"
print p.command()
out.write("p="+p.command()+"\nl.append(p)\n\n")

out.write("\n\n#sendp(l,iface='eth0')\n#wrpcap('/tmp/tmp.pcap',l)")

out.close()
print str(i) +" packets written in "+sys.argv[1]+".py"