Pycon Sec
Upcoming SlideShare
Loading in...5
×
 

Pycon Sec

on

  • 2,361 views

 

Statistics

Views

Total Views
2,361
Views on SlideShare
2,351
Embed Views
10

Actions

Likes
3
Downloads
38
Comments
0

1 Embed 10

http://www.slideshare.net 10

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Pycon Sec Pycon Sec Presentation Transcript

  • PyCon India 2009 Presentation Python tools for Network Security Anand B Pillai (abpillai@gmail.com)
  • Agenda
    • Brief overview
    • Python tools
      • Pypcap, Dpkt, Scapy
      • Quick introduction to pypcap, dpkt
      • Using Scapy to write your own tools
      • Examples
    • Links
    • Questions
  • Requirements
    • Basic knowledge of Python and using the interpreter
    • Basic knowledge of network protocols – TCP/UDP/ICMP etc
    • Background in Network security is useful
  • Network Security
    • Involves writing software to anticipate, prevent and stop attacks using the network
    • Network security practitioner requires a toolset which allows him to,
      • Capture Packets from the wire
      • Inspect Packets obtained
      • Craft Packets for testing
    • In short, the network security toolset should allow the developer to capture, inspect and create/craft network packets
  • Packet Capture
    • Favorite tool of every network security hacker – Wireshark (previously Ethereal)
    • Uses the libpcap library behind the scenes to capture packets off the network
    • Libpcap -> Is the most basic library and most widely used for packet capturing. Almost every network security tool which requires packet capturing is based on libpcap
  • Python + libpcap
    • In the Python world, there are a few extensions to libpcap namely -> pypcap, pcapy and python-libcap.
      • Pcapy – By Darknet.org, works best with their Impacket, InlineEgg tools, latest stable rel 0.10.5
      • Pylibcap - Python module for the libpcap packet capture library, based on the original python libpcap module by Aaron Rhodes, hosted on SF, latest stable rel 0.6.2
      • Pypcap - Simplified object-oriented Python extension module for libpcap, by dugsong, hosted on Google code, latest stable rel 1.1
    • I will be focusing on Pypcap for this session
  • Pypcap
    • Grab from http://code.google.com/p/pypcap/
    • Installs using distutils as any other Python library
    • Requires libpcap library and header files
    • Ubuntu package available
    • Once installed, accessed using import of ”pcap” module
    • >>> import pcap
    • >>>
  • Pypcap in action
      >>> import pcap >>> pc = pcap.pcap('wlan0') >>> for ts, pkt in pc: ... print ts, repr(pkt) 1253881836.82 <read-only buffer ptr 0xb78e7046, size 42 at 0xb7cdac40> 1253881836.82 <read-only buffer ptr 0xb7907046, size 42 at 0xb7cdac00> ^C1253881850.28 <read-only buffer ptr 0xb7c87046, size 1474 at 0xb7cdac00>
    • Traceback (most recent call last):
    • File &quot;<stdin>&quot;, line 1, in <module>
    • File &quot;pcap.pyx&quot;, line 425, in pcap.pcap.__next__
    • TypeError: raise: exception class must be a subclass of BaseException
    • >>> pc.stats()
    • (135L, 12L, 0L)
  • Pypcap
    • Create an object of type ”pcap”. If no arguments are passed listens on the first available up interface.
    • >>> import pcap
    • >>> pc = pcap.pcap()
    • To listen to a specific interface pass it explicitly
    • >>> pc = pcap.pcap('wlan0')
    • By default listens promiscously. To listen non-promiscously,
    • >>> pc = pcap.pcap(promisc=False)
    • To use a dumpfile,
    • >>> pc = pcap.pcap(dumpfile='pkts.pcap')
  • Pypcap - Usage
    • Pcap objects are their own iterators, returning the packet timestamp and the packet as a 2-tuple
    • Code is written as follows, iterating on the pcap object
    • >>> pc = pcap.pcap()
    • >>> for ts, pkt in pc:
    • .. # Process pkt
    • Optionally the dispatch method can be used to pass the packet to a call-back function. The callback function accepts the time-stamp, pkt and any other arguments.
    • The loop method works similarly, but in an infinite loop.
  • Examples Import pcap pc = pcap.pcap('wlan0') pc.setfilter('icmp') def process(ts, pkt, *args): &quot;&quot;&quot; Process packets &quot;&quot;&quot; print ts, pkt if __name__ == &quot;__main__&quot;: try: pc.loop(process) except Exception: pc.stats()
  • Dpkt – Packet creation/parsing
    • Dpkt is a library which provides packet creation/parsing capabilities with an object oriented interface
    • Project hosted at http://code.google.com/p/dpkt/
    • Stable version is 1.6
    • Pure Python library, installtion using distutils
    • No external depedency
    • Supports a number of protocols with an API that allows easy creation of custom protocol classes.
    • Has a Pcap writer class which allows to save pycap packets to pcap files. These files are compatible with tcpdump/wireshark.
    • Pcap is useful with dpkt than simply by itself
  • Using dpkt with pypcap A simple example which prints details of IP traffic in the network. import pcap, dpkt, socket pc = pcap.pcap('wlan0') count =0 def process(ts, pkt, *args): eth = dpkt.ethernet.Ethernet(pkt) ip = eth.data if ip.__class__==dpkt.ip.IP: global count count += 1
  • Using dpkt with pypcap ... src_ip = socket.inet_ntoa(ip.src) dst_ip = socket.inet_ntoa(ip.dst) print 'Packet #%d, %s=>%s, length %d, proto: %d' % (count, src_ip, dst_ip, ip.len, ip.p) if __name__ == &quot;__main__&quot;: try: pc.loop(process) except KeyboardInterrupt: print pc.stats()
  • Sample Output anand@anand-laptop:~/programs/python$ sudo python2.5 pcap2.py Packet #1, 192.168.1.2=>66.102.7.99, length 84, proto: 1 Packet #2, 66.102.7.99=>192.168.1.2, length 84, proto: 1 Packet #3, 192.168.1.2=>192.168.1.1, length 70, proto: 17 Packet #4, 192.168.1.1=>192.168.1.2, length 246, proto: 17 Packet #5, 192.168.1.2=>66.102.7.99, length 84, proto: 1 Packet #6, 74.125.67.17=>192.168.1.2, length 80, proto: 6 Packet #7, 192.168.1.2=>74.125.67.17, length 52, proto: 6 Packet #8, 66.102.7.99=>192.168.1.2, length 84, proto: 1 Packet #9, 192.168.1.2=>192.168.1.1, length 70, proto: 17 Packet #10, 192.168.1.1=>192.168.1.2, length 246, proto: 17 ^Packet #11, 192.168.1.2=>66.102.7.99, length 84, proto: 1
  • Http Protocol Sniffer
    • An HTTP protocol sniffer tool which saves http packets to a pcap file.
    import pcap, dpkt, socket pc = pcap.pcap('wlan0') count =0 ports = (80,8080,888) # Pcap writer pcw = dpkt.pcap.Writer(open('pkts.pcap','wb')) # Snooping on HTTP traffic def process(ts, pkt, *args): eth = dpkt.ethernet.Ethernet(pkt) ip = eth.data
  • HTTP Protocol Sniffer (Contd.) if ip.__class__==dpkt.ip.IP: ip1, ip2 = map(socket.inet_ntoa,[ip.src, ip.dst]) if ip.p != 6: return l7 = ip.data sport, dport = [l7.sport, l7.dport] if sport in ports or dport in ports: print 'From %s to %s, length: %d' % (ip1, ip2, len(l7.data)) # Save packet to file... pcw.writepkt(pkt) if __name__ == &quot;__main__&quot;: try: pc.loop(process) except KeyboardInterrupt: print pc.stats() pcw.close()
  • Scapy
    • A powerful interactive, general purpose, packet manipulation program written purely in Python, available as a single file.
    • Craft packets of a variety of protocols, send them on the wire, recieve replies, match requests and replies...
    • Handles most basic tasks like scanning, traceroute, ping, probe etc.
    • Scapy can be used to write new tools without the need of any special libraries
    • Instead of writing 100 lines of code in C for a special tool, write 2 lines in Scapy!
  • An interactive session with Scapy Send an echo request and dissect the first return packet. >>> from scapy import * >>> ip=IP(dst='www.google.com') >>> icmp=ICMP() >>> sr1(ip/icmp) Begin emission: .Finished to send 1 packets. * Received 2 packets, got 1 answers, remaining 0 packets <IP version=4L ihl=5L tos=0x60 len=28 id=1 flags= frag=0L ttl=239 proto=ICMP chksum=0xc007 src=66.102.7.104 dst=192.168.1.2 options='' |<ICMP type=echo-reply code=0 chksum=0x0 id=0x0 seq=0x0 |>>
  • A host scanner
    • Enumerate hosts on a network that have port number 80 listening
    >>> p=IP(dst='210.212.26.27'/24)/TCP(dport=80, flags='S') >>> sr(p) Begin emission: ..*....Finished to send 256 packets. ******.*.***..**********.*************.**..*********.........**...*********.***.********.***.****.*******..**.... (This goes on for a while) Received 4963 packets, got 83 answers, remaining 173 packets (<Results: UDP:0 TCP:77 ICMP:6 Other:0>, <Unanswered: UDP:0 TCP:173 ICMP:0 Other:0>)
  • Host scanner (contd.) >>> results = _[0] >>> for pout, pin in results: ... if pin.flags == 2: print pout.dst ... 210.212.26.5 210.212.26.15 210.212.26.19 210.212.26.20 210.212.26.22 210.212.26.23 210.212.26.24 210.212.26.25 210.212.26.26 210.212.26.27
  • A slow port-scanner from scapy import * def scan(ip,start=80,end=443): open_ports = [] ip=IP(dst=ip)/TCP(dport=range(start,end+1), flags='S') results=sr(ip,verbose=0,timeout=30) for res in results[0]: if res[1]==None: continue if res[1].payload.flags==18: print 'Port %d is open' % res[0].dport open_ports.append(res[0].dport) return open_ports if __name__ == &quot;__main__&quot;: print scan('random.org')
  • A slow port-scanner (contd). Sample Run
    • anand@anand-laptop:~/programs/python$ sudo python portscan.py
    Port 80 is open Port 113 is open Port 443 is open [80, 113, 443]
    • Scapy has a powerful tool named ”report_ports” which automates the entire process and outputs a Latex table containing the list of open ports.
    >>> report_ports('random.org',range(80,1024)) Begin emission: .*************** <Prints a latex table containing open ports>
  • DNS Query >>> sr1(IP(dst=&quot;192.168.1.1&quot;)/UDP()/DNS(rd=1,qd=DNSQR(qname=&quot;www.python.org&quot;))) Begin emission: .Finished to send 1 packets. * Received 2 packets, got 1 answers, remaining 0 packets <IP version=4L ihl=5L tos=0x0 len=152 id=17093 flags=DF frag=0L ttl=250 proto=UDP chksum=0xba3b src=192.168.1.1 dst=192.168.1.2 options='' |<UDP sport=domain dport=domain len=132 chksum=0xee58 |<DNS id=0 qr=1L opcode=QUERY aa=0L tc=0L rd=1L ra=1L z=0L rcode=ok qdcount=1 ancount=1 nscount=2 arcount=2 qd=<DNSQR qname='www.python.org.' qtype=A qclass=IN |> an=<DNSRR rrname='www.python.org.' type=A rclass=IN ttl=30106 rdata=' 82.94.164.162 ' |> ns=<DNSRR rrname='python.org.' type=NS rclass=IN ttl=27914 rdata='ns.xs4all.nl.' |<DNSRR rrname='python.org.' type=NS rclass=IN ttl=27914 rdata='ns2.xs4all.nl.' |>> ar=<DNSRR rrname='ns.xs4all.nl.' type=A rclass=IN ttl=117171 rdata='194.109.6.67' |<DNSRR rrname='ns2.xs4all.nl.' type=A rclass=IN ttl=117171 rdata='194.109.9.100' |>> |>>>
  • Traceroute >>>ans,unans=sr(IP(dst=' www.google.com ',ttl=(4,25),id=123)/TCP(flags=0x2) Finished to send 22 packets. ********************.. >>> for snd,rcv in ans: ... print snd.ttl, rcv.src, isinstance(rcv.payload, TCP) 8 218.248.255.66 False 9 218.248.250.82 False 10 195.2.7.37 False 11 198.32.146.46 False 12 216.239.43.12 False 13 72.14.238.130 False 14 209.85.243.122 False 15 209.85.251.94 False 16 74.125.19.105 True
  • Packet Sniffing
    • Scapy can replace wireshark or tcpdump!
    >>> sniff(iface=&quot;wlan0&quot;,prn=lambda x:x.summary()) Ether / IP / TCP 217.25.178.5:www > 192.168.1.2:57655 A / Raw Ether / IP / TCP 192.168.1.2:57655 > 217.25.178.5:www A Ether / IP / TCP 217.25.178.5:www > 192.168.1.2:57655 A / Raw Ether / IP / TCP 217.25.178.5:www > 192.168.1.2:57655 A / Raw Ether / IP / TCP 192.168.1.2:57655 > 217.25.178.5:www A Ether / IP / TCP 217.25.178.5:www > 192.168.1.2:57655 A / Raw Ether / IP / TCP 217.25.178.5:www > 192.168.1.2:57655 A / Raw Ether / IP / TCP 192.168.1.2:57655 > 217.25.178.5:www A Ether / IP / TCP 217.25.178.5:www > 192.168.1.2:57655 A / Raw Ether / IP / TCP 217.25.178.5:www > 192.168.1.2:57655 A / Raw Ether / IP / TCP 192.168.1.2:57655 > 217.25.178.5:www A Ether / IP / UDP / DNS Qry &quot;www.google.com.&quot; Ether / IP / UDP / DNS Ans &quot;www.l.google.com.&quot;
  • Passive OS fingerprinting >>> p <Ether dst=00:10:4b:b3:7d:4e src=00:40:33:96:7b:60 type=0x800 |<IP version=4L ihl=5L tos=0x0 len=60 id=61681 flags=DF frag=0L ttl=64 proto=TCP chksum=0xb85e src=192.168.8.10 dst=192.168.8.1 options='' |<TCP sport=46511 dport=80 seq=2023566040L ack=0L dataofs=10L reserved=0L flags=SEC window=5840 chksum=0x570c urgptr=0 options=[('Timestamp', (342940201L, 0L)), ('MSS', 1460), ('NOP', ()), ('SAckOK', ''), ('WScale', 0)] |>>> >>> p0f(p) (1.0, ['Linux 2.4.2 - 2.4.14 (1)'])
  • Further
    • Capabilities of Scapy are endless, limited only by your imagination and Python skills...!
    • For exploring further, try these links,
      • http://www.secdev.org/projects/scapy/build_your_own_tools.html
      • http://www.secdev.org/projects/scapy/demo.html
      • http://hackaholic.org/papers/blackmagic.txt
  • Real life Examples
    • Python port scan detection tool using pypcap and dpkt written by the author – available as an ASPN Python Cookbok recipe at http://code.activestate.com/recipes/576690/
      • Good example of using pypcap and dpkt together to write a network security tool
    • Packet monitoring with dpkt and pypcap - http://code.activestate.com/recipes/576678/
  • Links
    • Pypcap - http://code.google.com/p/pypcap/
    • Dpkt - http://code.google.com/p/dpkt/
    • Scapy - http://www.secdev.org/projects/scapy/
    • Python-libcap - http://sourceforge.net/projects/pylibpcap/
    • Pcapy - http://oss.coresecurity.com/projects/pcapy.htm