570 likes | 612 Views
Scapy Packet Manuplation. CE 340/S. Kondakcı. What Scapy Does?. Creating a packet Send/Receiving packets Basic Scapy commands Capturing packets (and reading packet capture files into Scapy) Layering packets More Examples. The First Step. 1. Install Python 2.7+
E N D
Scapy Packet Manuplation CE 340/S. Kondakcı
What Scapy Does? • Creating a packet • Send/Receiving packets • Basic Scapy commands • Capturing packets (and reading packet capture files into Scapy) • Layering packets • More Examples
The First Step 1. Install Python 2.7+ 2. Download and install Scapy 3. (Optional): Install additional software for special features. 4. Run Scapy with root privileges.
Hello World send(IP(dst="127.0.0.1")/ICMP()/"HelloWorld") • send - this tells Scapy that you want to send a packet (just a single packet) • IP - the protocol of the packet you want to create • (dst=”127.0.0.1”) - the destination IP to send the packet to • /ICMP() - Create an ICMP packet with the default values provided by Scapy • /”HelloWorld” - the payload to include in the ICMP packet
Wireshark Capture Scapy command: send(IP(dst="127.0.0.1")/ICMP()/"HelloWorld") Wireshark capture: Internet Protocol Version 4, Src: 127.0.0.12 (127.0.0.12), Dst: 127.0.0.1 (127.0.0.1) Protocol: ICMP Data: 48656c6c6f576f726c64 or “HelloWorld”
Example: Fabricate an ICMP Packet send(IP(src="127.0.0.1", dst="127.0.0.1", ttl=128)/ICMP()/"HelloWorld") Wireshark: Internet Protocol Version 4, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1) Time to live: 128 What does this ICMP packet mean? Internet Protocol Version 4, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1) Internet Control Message Protocol Type: 0 (Echo (ping) reply)
Sending a ping packet ip=IP() # Creates an IP headerip.src=’192.168.1.25′ # Source address in the IP header with local IP ip.dst =’ 192.168.1.100′ # Destination address in the IP header.icmp=ICMP() # Creates an ICMP headericmp.type=8 # Type value inserted in ICMP header as 8 for ping icmp.code=0 # Code value inserted in ICMP header as 0 for pingsend(ip/icmp) # Sending ping packet.
Sending a ping packet with random source IP ip=IP() # Creates an IP headerip.src=RandIP() # The source address in the IP header with a random IP ip.dst =’ 192.168.1.100′ # Destination address in the IP header.icmp=ICMP() # Creates an ICMP headericmp.type=8 # Type value inserted in ICMP header as 8 for ping craftingicmp.code=0 # Code value inserted in ICMP header as 0 for ping crafting.send(ip/icmp) # Sending ping packet.
Sending & Receiving Layer 3 and 2 Packets • sr() – This function sends packets and receivesanswers. It returnsa couple of packet and answers, and the unanswered packets. • sr1() - This function is a variant that only returns one packet which answered the sentpacket sent. • Exp: Simple ICMP packet (layer 3) h=sr1(IP(dst=“127.0.0.1")/ICMP()/”Hello World”) • srp() - This function does the same for layer 2 packets (Ethernet, 802.3, etc).
Show the Packet Contents • h=sr1(IP(dst=“127.0.0.1")/ICMP()/”Hello World”) • h.show() ###[ IP ]### version= 4L ihl= 5L tos= 0x0 len= 38 id= 7395 flags= frag= 0L ttl= 64 proto= icmp chksum= 0x83d7 src= 127.0.0.1 dst= 127.0.0.1 \options\ ###[ ICMP ]### type= echo-reply code= 0 chksum= 0x0 id= 0x0 seq= 0x0 ###[ Raw ]### load= 'HelloWorld' ###[ Padding ]### load= '\x00\x00\x00\x00\xe7\x03N\x99' >>>
Show the TTL of the ICMP reply packet ip=IP() # Create an IP headerip.src=’192.168.1.25′ # Source address in the IP header is the loca IP ip.dst =’ 192.168.1.100′ # Destination address in the IP header. icmp=ICMP() # Create an ICMP headericmp.type=8 # Type value inserted in ICMP header as 8 for ping craftingicmp.code=0 # Code value inserted in ICMP header as 0 for ping crafting.p=sr1(ip/icmp) # Send and receive the packet in the variable pp.ttl # Displays the TTL value in the received IP header of the packet.
Create an ARP request ether=Ether() # Creates an ethernet headerether.src=’00:e0:1c:3c:22:b4′ # Source MAC address in the ethernet header ether.dst=’FF:FF:FF:FF:FF:FF’#Destination MAC address arp=ARP() # Create an ARP headerarp.op=1 # Set the ARP type as 1arp.hwsrc=’00:e0:1c:3c:22:b4′ # Set the sender MAC address for local IParp.psrc=’192.168.1.25′ # Set the sender IP address for that MAC addr.arp.pdst=’192.168.1.100′ # Set the target IP address arp.hwdst=’00:00:00:00:00:00′ # Set the target MAC address as NULLp=srp1(ether/arp) # Send the packet at layer 2 using the command srp1, appending the ether and arp headers.
Normal TCP Handshake Client SYN Server Client SYN/ACK Server Client ACK Server After this, you are ready to send data 18
SYN Port Scan Client SYN Server Client SYN/ACK Server Client RST Server The server is ready, but the client decided not to complete the handshake 19
UDP Scanning • No handshake, so less useful than TCP scans • Much more powerful in newer versions of Nmap • Sends valid UDP requests to well-known ports • Send a DNS query to port 53, etc. • Response indicates open UDP port
TCP Packets p=sr(IP(dst=“127.0.0.1")/TCP(dport=23)) Begin emission: .Finished to send 1 packets. * Received 2 packets, got 1 answers, remaining 0 packets >>> p (<Results: TCP:1 UDP:0 ICMP:0 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>) >>> If you try and use p.show() you now get an error message: >>> p.show() Traceback (most recent call last): File "<console>", line 1, in <module> AttributeError: 'tuple' object has no attribute 'show' >>> ans.summary() IP / TCP 127.0.0.1:ftp_data > 127.0.0.1:telnet S ==> IP / TCP 127.0.0.1:telnet > 127.0.0.1:ftp_data RA / Padding
TCP Packets a=sr(IP(dst=“127.0.0.1")/TCP(dport=[23,80,53])) Begin emission: .**Finished to send 3 packets. * Received 4 packets, got 3 answers, remaining 0 packets >>> a (<Results: TCP:3 UDP:0 ICMP:0 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>) >>>
TCP SYN to port 80 tcp=TCP() # Create a TCP headertcp.dport=80 # The destination port in the TCP header is 80.tcp.flags=’S’ # Set the flag in the TCP header with the SYN bit.ip=IP() # Create an IP headerip.src=’192.168.1.25′ # Source address in the IP header is local IP address ip.dst =’ 192.168.1.100′ # Destination address in the IP header. send(ip/tcp) # Send thecrafted tcp packet.
Details of the TCP packet >>> p (<Results: TCP:3 UDP:0 ICMP:0 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>) >>> >>> ans,unans=_ >>> ans.summary() IP / TCP 127.0.0.1:ftp_data > 127.0.0.1:telnet S ==> IP / TCP 127.0.0.1:telnet > 127.0.0.1:ftp_data RA / Padding IP / TCP 127.0.0.1:ftp_data > 127.0.0.1:http S ==> IP / TCP 127.0.0.1:http > 127.0.0.1:ftp_data SA / Padding IP / TCP 127.0.0.1:ftp_data > 127.0.0.1:domain S ==> IP / TCP 127.0.0.1:domain > 127.0.0.1:ftp_data SA / Padding >>>
The http (port 80) packet IP / TCP 127.0.0.15:ftp_data > 127.0.0.1:http S ==> IP / TCP 127.0.0.1:http > 127.0.0.15:ftp_data SA / Padding S = SYN from client (request from the client)) SA = SYN-ACK from the server (reply from the server)
The telnet (port 23) Packet IP / TCP 127.0.0.1:ftp_data > 127.0.0.1:telnet S ==> IP /TCP 127.0.0.1:telnet > 127.0.0.1:ftp_data RA / Padding SYN Sent from the source Destination responded with a RSTACK (RA) which is a RESet & ACKnowledge flag in the TCP packet telling the source to reset the connection
Port Scan (TCP-SYN Scan) a=sr(IP(dst="127.0.0.1")/TCP(sport=666,dport=[22,80,21,443], flags="S")) Source port=666 Destination ports: 22,80,21,and 443 flags="S"= SYN scan
Port Scan (TCP-SYN Scan) cont’d >>> p=sr(IP(dst="127.0.0.1")/TCP(sport=666,dport=[22,80,21,443], flags="S")) Begin emission: ***Finished to send 4 packets. * Received 4 packets, got 4 answers, remaining 0 packets >>> p (<Results: TCP:4 UDP:0 ICMP:0 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>) >>> ans,unans=_ >>> ans.summary() IP / TCP 127.0.0.15:666 > 127.0.0.1:ssh S ==> IP / TCP 127.0.0.1:ssh > 127.0.0.15:666 SA / Padding IP / TCP 127.0.0.15:666 > 127.0.0.1:http S ==> IP / TCP 127.0.0.1:http > 127.0.0.15:666 SA / Padding IP / TCP 127.0.0.15:666 > 127.0.0.1:ftp S ==> IP / TCP 127.0.0.1:ftp > 127.0.0.15:666 RA / Padding IP / TCP 127.0.0.15:666 > 127.0.0.1:https S ==> IP / TCP 127.0.0.1:https > 127.0.0.15:666 RA / Padding >>>
TCP ACK flag sent after SYN flag >>> p=sr(IP(dst="127.0.0.1")/TCP(sport=888,dport=[21,22,80,443], flags="A")) Begin emission: .***Finished to send 4 packets. * Received 5 packets, got 4 answers, remaining 0 packets >>> p (<Results: TCP:4 UDP:0 ICMP:0 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>) >>> ans,unans=_ >>> ans.summary() IP / TCP 127.0.0.15:888 > 127.0.0.1:ftp A ==> IP / TCP 127.0.0.1:ftp > 127.0.0.15:888 R / Padding IP / TCP 127.0.0.15:888 > 127.0.0.1:ssh A ==> IP / TCP 127.0.0.1:ssh > 127.0.0.15:888 R / Padding IP / TCP 127.0.0.15:888 > 127.0.0.1:http A ==> IP / TCP 127.0.0.1:http > 127.0.0.15:888 R / Padding IP / TCP 127.0.0.15:888 > 127.0.0.1:https A ==> IP / TCP 127.0.0.1:https > 127.0.0.15:888 R / Padding >>> Notice: • the A (ACK) flag onthe sent packet, with a R (RST) flag on the response, why? • Becausewe sent a packet that it's only supposed to receive after a SYN-ACK packet and so it's reset by the destination.
DNS Query sr1(IP(dst="127.0.0.1")/UDP()/DNS(rd=1,qd=DNSQR(qname="www.ieu.edu.tr"))) dst=27.0.0.1 = destionation IP (DNS server) /UDP() = DNS uses UDP protocol /DNS = This is a DNS packet rd=1 = Telling Scapy that recursion is desired qd=DNSQR(qname=”www.ieu.edu.tr") = Get the DNS info about www.ieu.edu.tr
Traceroute traceroute (["www.google.com"], maxttl=20) Begin emission: ..*Finished to send 20 packets. ***************** Received 20 packets, got 18 answers, remaining 2 packets 74.125.132.99:tcp80 1 172.1.16.2 11 3 80.3.129.161 11 4 212.43.163.221 11 5 62.252.192.157 11 6 62.253.187.178 11 17 74.125.132.99 SA 18 74.125.132.99 SA 19 74.125.132.99 SA 20 74.125.132.99 SA (<Traceroute: TCP:7 UDP:0 ICMP:11 Other:0>, <Unanswered: TCP:2 UDP:0 ICMP:0 Other:0>) >>>
ARP Scan on ANetwork >>> arping(“172.1.16.*") ***Finished to send 256 packets. * Received 4 packets, got 4 answers, remaining 252 packets 30:46:9a:83:ab:70 172.1.16.2 00:25:64:8b:ed:1a 172.1.16.18 00:26:55:00:fc:fe 172.1.16.12 d8:9e:3f:b1:29:9b 172.1.16.22 (<ARPing: TCP:0 UDP:0 ICMP:0 Other:4>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:252>)
The ICMP, TCP, and UDP Ping: ans,unans=sr(IP(dst=“172.1.1-254")/ICMP()) ans,unans=sr( IP(dst=”172.1.1.*”)/TCP(dport=80, flags=”S”) ) ans,unans=sr( IP(dst=“172.1.1.*"/UDP(dport=0) )
Packet Sniffing sniff() CTRL-C (to stop sniffing) get something like <Sniffed: TCP:43 UDP:24 ICMP:2 Other:0> a=_ a.nsummary() 0003 Ether / IP / UDP / DNS Qry "daisy.ubuntu.com." 0004 Ether / IP / UDP / DNS Qry "daisy.ubuntu.com." 0005 Ether / IP / UDP / DNS Qry "daisy.ubuntu.com." 0006 Ether / IP / UDP / DNS Qry "daisy.ubuntu.com." 0007 Ether / IP / UDP / DNS Qry "daisy.ubuntu.com." 0008 Ether / IP / UDP / DNS Ans "91.189.95.54" 0009 Ether / IP / UDP / DNS Ans "91.189.95.54" 0010 Ether / IP / UDP / DNS Ans "91.189.95.54" 0011 Ether / IP / UDP / DNS Ans "91.189.95.55
ICMP traffic through eth0 interface sniff(iface="eth0", filter="icmp", count=10) a=_ >>> a.nsummary() 0000 Ether / IP / ICMP / IPerror / UDPerror / DNS Ans "91.189.95.55" 0001 Ether / IP / ICMP / IPerror / UDPerror / DNS Ans "91.189.95.54" 0002 Ether / IP / ICMP 10.1.99.25 > 74.125.132.103 echo-request 0 / Raw 0003 Ether / IP / ICMP 74.125.132.103 > 10.1.99.25 echo-reply 0 / Raw 0004 Ether / IP / ICMP 10.1.99.25 > 74.125.132.103 echo-request 0 / Raw 0005 Ether / IP / ICMP 74.125.132.103 > 10.1.99.25 echo-reply 0 / Raw 0006 Ether / IP / ICMP 10.1.99.25 > 74.125.132.103 echo-request 0 / Raw 0007 Ether / IP / ICMP 74.125.132.103 > 10.1.99.25 echo-reply 0 / Raw 0008 Ether / IP / ICMP / IPerror / UDPerror / DNS Ans "wb-in-f103.1e100.net." 0009 Ether / IP / ICMP / IPerror / UDPerror / DNS Ans "wb-in-f103.1e100.net.“ a[2] <Ether dst=30:46:9a:83:ab:70 src=00:22:19:e7:90:ae type=0x800 |<IP version=4L ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0xfeaa src=10.1.99.25 dst=74.125.132.103
Nping • Nping is an open source tool for • network packet generation, • response analysis and response time measurement. • Nping can generate network packets for a wide range of protocols, allowing users full control over protocol headers. Syntax: nping [Probe mode] [Options] {target specification} Example: nping blabla.com Starting Nping 0.6.01 ( http://nmap.org/nping ) at 2012-06-20 20:27 CEST SENT (0.1879s) ICMP 192.168.60.129 > 199.83.132.66 Echo request (type=8/code=0) ttl=64 id=53514 iplen=28 SENT (1.1890s) ICMP 192.168.60.129 > 199.83.132.66 Echo request (type=8/code=0) ttl=64 id=53514 iplen=28 SENT (2.1901s) ICMP 192.168.60.129 > 199.83.132.66 Echo request (type=8/code=0) ttl=64 id=53514 iplen=28
Nping Using TCP Flags nping --tcp -p 80 --flags ack -c 3 aldeid.com
Nping Echo Client/Server nping --echo-server "pass123" -e eth0 -vvv nping --echo-client "pass123" 192.168.1.18 --tcp -p1-30 --flags ack
Nmap Single Target Scanning • ### Scan a single ip address ### • nmap 192.168.1.1 • ## Scan a host name ### • nmap www.google.com • ## Scan a host name with more info### • nmap –v myhost.ieu.edu.tr
Nmap Multiple Target Scanning • nmap 192.168.1.1192.168.1.2192.168.1.3 • nmap 192.168.1.1,2,3 • ## You can scan a range of IP address: • nmap 192.168.1.1-20 • ## IP addressrange using a wildcard: • nmap 192.168.1.* • ## Read list of hosts/networks from a file: • namp –iL ./hosts.txt
More Nmap Commands • ## Detect OS and OS version • nmap -A 192.168.1.254 • nmap -v -A 192.168.1.1 • nmap -A -iL /tmp/scanlist.txt • ## Is a host/network protected by a firewall • nmap -sA 192.168.1.254 • ## Scan it when protected by the firewall • nmap -PN 192.168.1.1
More Nmap Commands • ## host discovery or ping scan: • nmap -sP 192.168.1.0/24 • ## perform a fast scan • nmap -F 192.168.1.1 • ## Show only open ports • nmap --open 192.168.1.1 • ## Show all packets sent and received • nmap --packet-trace 192.168.1.1 • Show host interfaces and routes • nmap --iflist
More Nmap Commands • Show host interfaces and routes • nmap --iflist
Scan Specific ports • nmap -p [port] hostName • ## Scan port 80 • nmap -p 80 192.168.1.1 • ## Scan TCP port 80 • nmap -p T:80 192.168.1.1 • ## Scan UDP port 53 • nmap -p U:53 192.168.1.1 • ## Scan two ports ## • nmap -p 80,443 192.168.1.1 • ## Scan port ranges ## • nmap -p 80-200 192.168.1.1
Scan Specific ports • ## Combine all options ## • nmap -p U:53,111,137,T:21-25,80,139,8080 192.168.1.1 • nmap -v -sU -sT -p U:53,111,137,T:21-25,80,139,8080 192.168.1.254 • ## Scan all ports with * wildcard: • nmap -p "*" 192.168.1.1 • ## Scan top 10 most common ports ## • nmap --top-ports 10 192.168.1.1