Pycon Sec

2,005 views
1,938 views

Published on

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,005
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
52
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Pycon Sec

  1. 1. PyCon India 2009 Presentation Python tools for Network Security Anand B Pillai (abpillai@gmail.com)
  2. 2. Agenda <ul><li>Brief overview
  3. 3. Python tools </li><ul><li>Pypcap, Dpkt, Scapy
  4. 4. Quick introduction to pypcap, dpkt
  5. 5. Using Scapy to write your own tools
  6. 6. Examples </li></ul><li>Links
  7. 7. Questions </li></ul>
  8. 8. Requirements <ul><li>Basic knowledge of Python and using the interpreter
  9. 9. Basic knowledge of network protocols – TCP/UDP/ICMP etc
  10. 10. Background in Network security is useful </li></ul>
  11. 11. Network Security <ul><li>Involves writing software to anticipate, prevent and stop attacks using the network
  12. 12. Network security practitioner requires a toolset which allows him to, </li><ul><li>Capture Packets from the wire
  13. 13. Inspect Packets obtained
  14. 14. Craft Packets for testing </li></ul><li>In short, the network security toolset should allow the developer to capture, inspect and create/craft network packets </li></ul>
  15. 15. Packet Capture <ul><li>Favorite tool of every network security hacker – Wireshark (previously Ethereal)
  16. 16. Uses the libpcap library behind the scenes to capture packets off the network
  17. 17. 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 </li></ul>
  18. 18. Python + libpcap <ul><li>In the Python world, there are a few extensions to libpcap namely -> pypcap, pcapy and python-libcap. </li><ul><li>Pcapy – By Darknet.org, works best with their Impacket, InlineEgg tools, latest stable rel 0.10.5
  19. 19. 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
  20. 20. Pypcap - Simplified object-oriented Python extension module for libpcap, by dugsong, hosted on Google code, latest stable rel 1.1 </li></ul><li>I will be focusing on Pypcap for this session </li></ul>
  21. 21. Pypcap <ul><li>Grab from http://code.google.com/p/pypcap/
  22. 22. Installs using distutils as any other Python library
  23. 23. Requires libpcap library and header files
  24. 24. Ubuntu package available
  25. 25. Once installed, accessed using import of ”pcap” module
  26. 26. >>> import pcap
  27. 27. >>> </li></ul>
  28. 28. Pypcap in action <ul>>>> 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> <li>Traceback (most recent call last):
  29. 29. File &quot;<stdin>&quot;, line 1, in <module>
  30. 30. File &quot;pcap.pyx&quot;, line 425, in pcap.pcap.__next__
  31. 31. TypeError: raise: exception class must be a subclass of BaseException
  32. 32. >>> pc.stats()
  33. 33. (135L, 12L, 0L) </li></ul>
  34. 34. Pypcap <ul><li>Create an object of type ”pcap”. If no arguments are passed listens on the first available up interface.
  35. 35. >>> import pcap
  36. 36. >>> pc = pcap.pcap()
  37. 37. To listen to a specific interface pass it explicitly
  38. 38. >>> pc = pcap.pcap('wlan0')
  39. 39. By default listens promiscously. To listen non-promiscously,
  40. 40. >>> pc = pcap.pcap(promisc=False)
  41. 41. To use a dumpfile,
  42. 42. >>> pc = pcap.pcap(dumpfile='pkts.pcap') </li></ul>
  43. 43. Pypcap - Usage <ul><li>Pcap objects are their own iterators, returning the packet timestamp and the packet as a 2-tuple
  44. 44. Code is written as follows, iterating on the pcap object
  45. 45. >>> pc = pcap.pcap()
  46. 46. >>> for ts, pkt in pc:
  47. 47. .. # Process pkt
  48. 48. 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.
  49. 49. The loop method works similarly, but in an infinite loop. </li></ul>
  50. 50. 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()
  51. 51. Dpkt – Packet creation/parsing <ul><li>Dpkt is a library which provides packet creation/parsing capabilities with an object oriented interface
  52. 52. Project hosted at http://code.google.com/p/dpkt/
  53. 53. Stable version is 1.6
  54. 54. Pure Python library, installtion using distutils
  55. 55. No external depedency
  56. 56. Supports a number of protocols with an API that allows easy creation of custom protocol classes.
  57. 57. Has a Pcap writer class which allows to save pycap packets to pcap files. These files are compatible with tcpdump/wireshark.
  58. 58. Pcap is useful with dpkt than simply by itself </li></ul>
  59. 59. 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
  60. 60. 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()
  61. 61. 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
  62. 62. Http Protocol Sniffer <ul><li>An HTTP protocol sniffer tool which saves http packets to a pcap file. </li></ul>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
  63. 63. 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()
  64. 64. Scapy <ul><li>A powerful interactive, general purpose, packet manipulation program written purely in Python, available as a single file.
  65. 65. Craft packets of a variety of protocols, send them on the wire, recieve replies, match requests and replies...
  66. 66. Handles most basic tasks like scanning, traceroute, ping, probe etc.
  67. 67. Scapy can be used to write new tools without the need of any special libraries
  68. 68. Instead of writing 100 lines of code in C for a special tool, write 2 lines in Scapy! </li></ul>
  69. 69. 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 |>>
  70. 70. A host scanner <ul><li>Enumerate hosts on a network that have port number 80 listening </li></ul>>>> 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>)
  71. 71. 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
  72. 72. 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')
  73. 73. A slow port-scanner (contd). Sample Run <ul><li>anand@anand-laptop:~/programs/python$ sudo python portscan.py </li></ul>Port 80 is open Port 113 is open Port 443 is open [80, 113, 443] <ul><li>Scapy has a powerful tool named ”report_ports” which automates the entire process and outputs a Latex table containing the list of open ports. </li></ul>>>> report_ports('random.org',range(80,1024)) Begin emission: .*************** <Prints a latex table containing open ports>
  74. 74. 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' |>> |>>>
  75. 75. 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
  76. 76. Packet Sniffing <ul><li>Scapy can replace wireshark or tcpdump! </li></ul>>>> 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;
  77. 77. 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)'])
  78. 78. Further <ul><li>Capabilities of Scapy are endless, limited only by your imagination and Python skills...!
  79. 79. For exploring further, try these links, </li><ul><li>http://www.secdev.org/projects/scapy/build_your_own_tools.html
  80. 80. http://www.secdev.org/projects/scapy/demo.html
  81. 81. http://hackaholic.org/papers/blackmagic.txt </li></ul></ul>
  82. 82. Real life Examples <ul><li>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/ </li><ul><li>Good example of using pypcap and dpkt together to write a network security tool </li></ul><li>Packet monitoring with dpkt and pypcap - http://code.activestate.com/recipes/576678/ </li></ul>
  83. 83. Links <ul><li>Pypcap - http://code.google.com/p/pypcap/
  84. 84. Dpkt - http://code.google.com/p/dpkt/
  85. 85. Scapy - http://www.secdev.org/projects/scapy/
  86. 86. Python-libcap - http://sourceforge.net/projects/pylibpcap/
  87. 87. Pcapy - http://oss.coresecurity.com/projects/pcapy.htm </li></ul>

×