Date post: | 10-Jul-2015 |
Category: |
Technology |
Upload: | adam-maxwell |
View: | 851 times |
Download: | 2 times |
packets, pcap’s & python
BSides London 2014 Scapy Workshop
By Adam Maxwell / @catalyst256
Pre-requites for workshop
1. Have a laptop.
2. Have Scapy installed (VM is fine).• Kali or BackTrack
• Linux
• Mac OSX
• Windows (you’re on your own)
3. If possible clone this GitHub repo:• https://github.com/catalyst256/ScapyWrkShop
4. A BSides London Scapy Cheat Card
What are we going to learn today
• Who am I
• Scapy - brief intro
• Write some packets
• Read some packets
• Some cool Scapy features
• Using Scapy with Python
Who am I – The bad stuff
• I don’t work in InfoSec.
• I’m not a network engineer.
• I am VMware Certified (that impressed you right??).
• I work for an insurance company (someone has to).
• This is my first EVER workshop (sorry).
Who am I – The slightly better stuff
• I’m the author of “The Very Unofficial Dummies Guide to Scapy”.
• I hold an OSCP & OSWP and I’ve sat the SANS SEC503 course.
• Spend far too much time with the 3 P’s:• Packets
• pcaps
• Python
• I wrote a Maltego Transform set for analyzing pcap files called sniffMyPackets.
Scapy - A Brief Intro
• Written by Philippe Biondi.
• Based on Python
• Some of the cool stuff it can do:• Forge packets
• Decode packets
• Send & Receive packets
• ARP Poisoning
• Sniff packets
• Current version: 2.2.0-dev
• Check out: http://bb.secdev.org/scapy/overview
Packets – Vanilla Packet
• Lets create the 3 layers for a TCP packet.
• Now lets view it.
>>> a = Ether()>>> b = IP()>>> c = TCP()
>>> a.show()>>> b.show()>>> c.show()
Packets – Tweak it a bit
• Lets change the IP destination port
• Lets change the TCP destination port
>>> b.dst = ’1.1.1.1'
>>> c.dport = 80
Packets – The Humble ICMP
• One liner ICMP Packet (Request)
• But wait we didn’t set a ICMP Type.
• The Scapy default for an ICMP packet is type 8 (or echo-request).
>>> i = IP(dst='127.0.0.1')/ICMP()/"HelloWorld"
>>> i<IP frag=0 proto=icmp dst=127.0.0.1 |<ICMP |<Raw load='HelloWorld' |>>>
>>> ls(ICMP)type : ByteEnumField = (8)…
Packets – The Humble ICMP
• Time to release your packet..
• Oh did you want to see the response??
• Change your src IP & dst IP to something “valid” eg.
>>> sendp(i).Sent 1 packets.>>>
>>> i[IP].src = '10.1.99.28'>>> i[IP].dst = '10.1.99.1'
Packets – The Humble ICMP
• Now lets send it and collect the response.
>>> x = sr1(i)Begin emission:..Finished to send 1 packets..*Received 4 packets, got 1 answers, remaining 0 packets>>> x<IP version=4L ihl=5L tos=0x0 len=38 id=22514 flags= frag=0L ttl=64 proto=icmp chksum=0x48c6 src=10.1.99.1 dst=10.1.99.28 options=[] |<ICMP type=echo-reply code=0 chksum=0x0 id=0x0 seq=0x0 |<Raw load='HelloWorld' |>>>
Packets – Something a little different?
• DNS?
• Port Scanner?
• Traceroute?
• This is actually a ICMP & TCP traceroute, default destination port is 80 (which you can change of course).
>>> p = sr1(IP(dst="8.8.8.8")/UDP()/DNS(rd=1,qd=DNSQR(qname="www.citrix.com")))
>>> p=sr(IP(dst="10.1.99.1")/TCP(dport=[23,80,53,443]))>>> p=sr(IP(dst="10.1.99.1")/TCP(dport=80))
>>> traceroute (["www.google.com"], maxttl=20)
>>> traceroute(["www.google.com"], dport=443, maxttl=20)
Packets – HTTP GET Request
• HTTP packets require the TCP 3 way handshake to be completed first.
• Using Python + Scapy it is easier to create the necessary packets.
• Scapy uses Raw packets which might get dropped by your Kernel/OS. You may need to run this command (on Linux).
iptables -A OUTPUT -p tcp --tcp-flags RST RST -s [source IP] -j DROP
Packets – HTTP GET Request
• Using Python the GET Request looks like this:#!/usr/bin/env pythonfrom scapy.all import *
# Set the GET requestget='GET / HTTP/1.0\n\n'# Set your targetip=IP(dst="www.google.com")
# Create a random source port (not needed but nice to have)port=RandNum(1024,65535)
# Create the SYN packetSYN=ip/TCP(sport=port, dport=80, flags="S", seq=666)# Send SYN and receive SYN,ACKSYNACK=sr1(SYN)
# Create ACK with GET requestACK=ip/TCP(sport=SYNACK.dport, dport=80, flags="A", seq=SYNACK.ack, ack=SYNACK.seq + 1) / get# SEND our ACK-GET requestreply,error=sr(ACK)
# Print the replyprint reply.show()
PCAPS – The 3 R’s
• Reading>>> pkts = rdpcap('pcap/evidence02.pcap')
>>> pkts<evidence02.pcap: TCP:490 UDP:52 ICMP:0 Other:30>
>>> pkts.summary()>>> pkts.nsummary()
>>> pkts[48]
Pull out DNS packets
>>> x = []>>> for p in pkts:>>> if p.haslayer(UDP) and p.haslayer(DNS):>>> x.append(p)>>>
>>> x.nsummary()
PCAPS – The 3 R’s
• wRiting
>>> wrpcap('pcap/test.pcap', x)>>> wireshark(x)
>>> wrpcap('pcap/replay1.pcap',x[0])>>> wireshark(x[0])
PCAPS – The 3 R’s
• Replaying>>> pkts = rdpcap('pcap/replay1.pcap')
>>> del pkts[0][Ether].dst>>> del pkts[0][Ether].src>>> pkts[0][IP].src = '10.1.99.28'>>> pkts[0][IP].dst = '8.8.8.8'>>> del pkts[0][IP].chksum>>> del pkts[0][UDP].chksum
>>> x = srp1(pkts[0])>>> x.summary()'Ether / IP / UDP / DNS Ans "smtp.cs.com." '
>>> srploop(pkts[0])
>>> wrpcap(‘pcap/replay2.pcap’, pkts[0])
Python – Importing Scapy
• The quick way
• Turn off “warning messages”
• Turn off verbose in Scapy interactive
from scapy.all import *
import logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)
>>> conf.verb = 0
(default is 2)
Python – Simple Packet Sniffer
• Sniff all the packets#!/usr/bin/env python
import sysfrom scapy.all import *
iface = sys.argv[1]
pkts = sniff(iface=iface, prn=lambda x: x.summary())
Python – Simple Packet Sniffer
• Sniff some of the packets
• Scapy uses Berkeley Packet Filter for filtering packets when sniffing (same as TCPDUMP).
#!/usr/bin/env python
import sysfrom scapy.all import *
iface = sys.argv[1]pkts = sniff(iface=iface, filter=sys.argv[2], prn=lambda x: x.summary())
sudo ./simplesniffer.py en1 'tcp port 80'
Python – Parse a pcap file
• Looking for HTTP traffic??def find_http_requests(pkts):
get_requests = []http_get = 'GET /'
for p in pkts:if p.haslayer(TCP) and p.haslayer(Raw):
raw = p.getlayer(Raw).loadif http_get in raw:
dstip = p.getlayer(IP).dstdport = p.getlayer(TCP).dportsrcip = p.getlayer(IP).srcnew_raw = p.getlayer(Raw).loadrequest = ''host = '' for t in re.finditer('(GET) (\S*)', new_raw):
request = t.group(2)for s in re.finditer('(Host:) (\S*)', new_raw):
host = s.group(2)talker = request, srcip, dstip, dport, hostif talker not in get_requests:
get_requests.append(talker)
for url, src, dst, port, host in get_requests:print GREEN + '[+] Web traffic from: ' + str(src) + ' to ' + str(dst) + ' on port ’/
+ str(port) + ' to ' + host + ' for ' + url + END
Python – WiFi Fun??
• Create your own De Auth packets??
• Sniff some beacons??
packet = RadioTap()/Dot11(type=0,subtype=12,addr1=client,addr2=bssid,addr3=bssid)/Dot11Deauth(reason=7)
def sniffBeacons(p):if p.haslayer(Dot11Beacon):
enc = ''ssid = p[Dot11Elt].infobssid = p[Dot11].addr3channel = int(ord(p[Dot11Elt:3].info))capability = p.sprintf("{Dot11Beacon:%Dot11Beacon.cap%}{Dot11ProbeResp:%Dot11ProbeResp.cap%}")rssi = (ord(p.notdecoded[-4:-3])-256)if re.search("privacy", capability):
enc = 'Y'else:
enc = 'N'entity = ssid, bssid, channel, enc, rssi, interface
sniff(iface=interface, prn=sniffBeacons)
The End !!
• Questions??