{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Scapy" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "##### Suraj Deshmukh (surajssd009005@gmail.com)\n", "##### http://deshmukhsuraj.wordpress.com/\n", "#### @surajssd009005" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## What is Scapy?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- An interactive tool; that lets you send, sniff, craft and manipulate packets\n", "- Craft and decode packets of wide number of protocols\n", "- You can do network scans, traceroutes, arpspoofs, so almost all tasks of nmap and tcpdump\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Why use Scapy(and not other tools)?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- Scapy is a very flexible tool to use(you'll know when you do hands-on).\n", "- Uses Python as a tool usage language, hence easier to use.\n", "- Break open tool designer's perspective." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Tool designer's perspective" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- Computers are good at decoding but not so good at interpreting.\n", "- So a programmer while designing tool makes his tool mimic interpretation.\n", "- e.g. When a packet is sent on a TCP port with SYN flag and response comes back as SYN-ACK then port is open\n", "- They show the result in a way what original author thought was appropriate, though it is helpful for beginners.\n", "- So much information is lost in the process." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "- But computer networks has so many protocols, so permutation of doing things increase\n", "- So somebody would like to play in some unique way with protocols what nobody has ever thought about\n", "- But playing with networks is not as easy job\n", "- Need to write 100's of lines of C code" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### enter Scapy..." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- just a single line to send packet of your choice" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## In a Nutshell" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Lets start some packets rolling..." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING: No route found for IPv6 destination :: (no default route?)\n", "WARNING:scapy.runtime:No route found for IPv6 destination :: (no default route?)\n" ] } ], "source": [ "from scapy.all import *" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Basics" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "###[ IP ]###\n", " version = 4\n", " ihl = None\n", " tos = 0x0\n", " len = None\n", " id = 1\n", " flags = \n", " frag = 0\n", " ttl = 64\n", " proto = hopopt\n", " chksum = None\n", " src = 127.0.0.1\n", " dst = 127.0.0.1\n", " \\options \\\n" ] } ], "source": [ "ip = IP()\n", "ip.show()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "###[ IP ]###\n", " version = 4\n", " ihl = None\n", " tos = 0x0\n", " len = None\n", " id = 1\n", " flags = \n", " frag = 0\n", " ttl = 100\n", " proto = hopopt\n", " chksum = None\n", " src = 127.0.0.1\n", " dst = 127.0.0.1\n", " \\options \\\n" ] } ], "source": [ "ip.ttl = 100\n", "ip.show()" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "###[ IP ]###\n", " version = 4\n", " ihl = None\n", " tos = 0x0\n", " len = None\n", " id = 1\n", " flags = \n", " frag = 0\n", " ttl = 100\n", " proto = hopopt\n", " chksum = None\n", " src = 192.168.0.60\n", " dst = 192.168.0.1\n", " \\options \\\n" ] } ], "source": [ "ip.dst = '192.168.0.1'\n", "ip.show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Encapsulating Layers" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ ">" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ip = IP(dst='192.168.0.1')\n", "icmp = ICMP()\n", "pkt = ip/icmp\n", "pkt" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ ">" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pkt = IP(dst='www.google.com')/TCP(dport=80)\n", "pkt" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ ">>" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pkt = Ether()/IP()/TCP()\n", "pkt" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Send and Receive Packets" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Sent 1 packets.\n" ] } ], "source": [ "send(IP()/ICMP())" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Received 21 packets, got 1 answers, remaining 0 packets\n", "Begin emission:\n", "Finished to send 1 packets.\n" ] }, { "data": { "text/plain": [ ">" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p = sr1(IP(dst='192.168.0.1')/ICMP())\n", "p" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Received 29 packets, got 2 answers, remaining 0 packets\n", "0000 IP / TCP 192.168.0.60:ftp_data > 192.168.0.1:domain S ==> IP / TCP 192.168.0.1:domain > 192.168.0.60:ftp_data RA\n", "0001 IP / TCP 192.168.0.60:ftp_data > 192.168.0.1:http S ==> IP / TCP 192.168.0.1:http > 192.168.0.60:ftp_data SA\n", "Begin emission:\n", "Finished to send 2 packets.\n" ] } ], "source": [ "ans, unans = sr(IP(dst='192.168.0.1')/TCP(dport=[53, 80]))\n", "ans.show() " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Ping" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "###[ IP ]###\n", " version = 4\n", " ihl = None\n", " tos = 0x0\n", " len = None\n", " id = 1\n", " flags = \n", " frag = 0\n", " ttl = 64\n", " proto = hopopt\n", " chksum = None\n", " src = 127.0.0.1\n", " dst = 127.0.0.1\n", " \\options \\\n" ] } ], "source": [ "ip = IP()\n", "ip.show()" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "###[ IP ]###\n", " version = 4\n", " ihl = None\n", " tos = 0x0\n", " len = None\n", " id = 1\n", " flags = \n", " frag = 0\n", " ttl = 64\n", " proto = hopopt\n", " chksum = None\n", " src = 192.168.0.60\n", " dst = 192.168.0.1\n", " \\options \\\n" ] } ], "source": [ "# default gateway\n", "ip.dst = '192.168.0.1'\n", "ip.show()" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "###[ ICMP ]###\n", " type = echo-request\n", " code = 0\n", " chksum = None\n", " id = 0x0\n", " seq = 0x0\n" ] } ], "source": [ "icmp = ICMP()\n", "icmp.show()" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Received 62 packets, got 1 answers, remaining 0 packets\n", "Begin emission:\n", "Finished to send 1 packets.\n" ] }, { "data": { "text/plain": [ ">" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# send and receive, stops after receiving a single reply\n", "# store the reply in variable named 'gateway'\n", "gateway = sr1(ip/icmp)\n", "gateway" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "###[ IP ]###\n", " version = 4L\n", " ihl = 5L\n", " tos = 0x0\n", " len = 28\n", " id = 1\n", " flags = \n", " frag = 0L\n", " ttl = 30\n", " proto = icmp\n", " chksum = 0x1b53\n", " src = 192.168.0.1\n", " dst = 192.168.0.60\n", " \\options \\\n", "###[ ICMP ]###\n", " type = echo-reply\n", " code = 0\n", " chksum = 0xffff\n", " id = 0x0\n", " seq = 0x0\n" ] } ], "source": [ "gateway.show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Traceroute" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Received 41 packets, got 1 answers, remaining 0 packets\n", "###[ IP ]###\n", " version = 4L\n", " ihl = 5L\n", " tos = 0x0\n", " len = 56\n", " id = 0\n", " flags = \n", " frag = 0L\n", " ttl = 30\n", " proto = icmp\n", " chksum = 0x1b38\n", " src = 192.168.0.1\n", " dst = 192.168.0.60\n", " \\options \\\n", "###[ ICMP ]###\n", " type = time-exceeded\n", " code = ttl-zero-during-transit\n", " chksum = 0x9111\n", " unused = 8634536\n", "###[ IP in ICMP ]###\n", " version = 4L\n", " ihl = 5L\n", " tos = 0x0\n", " len = 28\n", " id = 1\n", " flags = \n", " frag = 0L\n", " ttl = 0\n", " proto = udp\n", " chksum = 0x5dad\n", " src = 192.168.0.60\n", " dst = 216.58.196.4\n", " \\options \\\n", "###[ UDP in ICMP ]###\n", " sport = domain\n", " dport = domain\n", " len = 8\n", " chksum = 0xa250\n", "Begin emission:\n", "Finished to send 1 packets.\n" ] } ], "source": [ "# Traceroute works by sending packets each time with decreasing 'ttl' value\n", "reply = sr1(IP(dst='www.google.com', ttl=1)/UDP())\n", "reply.show()" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ "'192.168.0.1'" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "reply.src" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Received 33 packets, got 22 answers, remaining 38 packets\n", " 106.10.139.246:tcp80 204.79.197.200:tcp80 216.58.220.4:tcp80 \n", "1 192.168.0.1 11 192.168.0.1 11 192.168.0.1 11 \n", "2 172.31.28.250 11 - 172.31.28.250 11 \n", "12 - 204.79.197.200 SA - \n", "13 - 204.79.197.200 SA - \n", "14 - 204.79.197.200 SA - \n", "15 - 204.79.197.200 SA - \n", "16 106.10.139.246 SA 204.79.197.200 SA - \n", "17 106.10.139.246 SA 204.79.197.200 SA - \n", "18 106.10.139.246 SA 204.79.197.200 SA 216.58.220.4 SA \n", "19 106.10.139.246 SA 204.79.197.200 SA 216.58.220.4 SA \n", "20 106.10.139.246 SA 204.79.197.200 SA 216.58.220.4 SA \n", "Begin emission:\n", "Finished to send 60 packets.\n" ] } ], "source": [ "ans, unans = traceroute([\"www.google.com\",\"www.yahoo.com\",\"www.bing.com\"],maxttl=20)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 106.10.139.246:tcp80 204.79.197.200:tcp80 216.58.220.4:tcp80 \n", "1 192.168.0.1 11 192.168.0.1 11 192.168.0.1 11 \n", "2 172.31.28.250 11 - 172.31.28.250 11 \n", "12 - 204.79.197.200 SA - \n", "13 - 204.79.197.200 SA - \n", "14 - 204.79.197.200 SA - \n", "15 - 204.79.197.200 SA - \n", "16 106.10.139.246 SA 204.79.197.200 SA - \n", "17 106.10.139.246 SA 204.79.197.200 SA - \n", "18 106.10.139.246 SA 204.79.197.200 SA 216.58.220.4 SA \n", "19 106.10.139.246 SA 204.79.197.200 SA 216.58.220.4 SA \n", "20 106.10.139.246 SA 204.79.197.200 SA 216.58.220.4 SA \n" ] } ], "source": [ "ans.show()" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "ans.graph()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Sniff" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ether / IP / UDP / DNS Qry \"fonts.googleapis.com.\" \n", "Ether / IP / UDP / DNS Qry \"fonts.googleapis.com.\" \n", "Ether / IP / UDP / DNS Qry \"fonts.googleapis.com.\" \n", "Ether / IP / UDP / DNS Qry \"fonts.googleapis.com.\" \n", "Ether / IP / UDP / DNS Qry \"fonts.googleapis.com.\" \n", "Ether / IP / UDP / DNS Qry \"tiles.services.mozilla.com.\" \n", "Ether / IP / UDP / DNS Qry \"tiles.services.mozilla.com.\" \n", "Ether / IP / UDP / DNS Qry \"tiles.services.mozilla.com.\" \n", "Ether / IP / UDP / DNS Ans \"tiles.r53-2.services.mozilla.com.\" \n", "Ether / IP / TCP 192.168.0.60:37661 > 52.25.165.135:https S\n" ] } ], "source": [ "a = sniff(iface='wlan0', count=10, filter='ip')\n", "a.summary()" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "802.3 c4:12:f5:04:1b:82 > 1c:65:9d:94:e7:c8 / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 1c:65:9d:94:e7:c8 / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 1c:65:9d:94:e7:c8 / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:5b:b6:95 / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 1c:65:9d:94:e7:c8 / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 1c:65:9d:94:e7:c8 / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 1c:65:9d:94:e7:c8 / LLC / Raw\n", "Ether / IP / UDP / DNS Ans \"216.58.196.3\" \n", "Ether / IP / TCP 192.168.0.60:46113 > 216.58.196.3:http S\n", "Ether / IP / UDP / DNS Ans \"216.58.196.3\" \n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sniff(iface=\"wlan0\", prn=lambda x: x.summary(), count=10)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Capture and Store Packets" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 14:dd:a9:b0:f9:75 / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 1c:65:9d:94:e7:c8 / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 1c:65:9d:94:e7:c8 / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n", "802.3 c4:12:f5:04:1b:82 > 90:21:81:67:f5:fb / LLC / Raw\n" ] } ], "source": [ "pkts = sniff(iface=\"wlan0\", prn=lambda x: x.summary(), count=20)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "wrpcap('temp.pcap', pkts)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "pkts = rdpcap(\"temp.pcap\")" ] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 0 }