Python scapy: pcap file read, manipulate and write pcap - python

I want to read a pcap file using python scapy, manipulate the TCP payload (e.g. delete the current payload and replace it with 0s) and write the manipulated packets to a new pcap file.

Here's a solution using pypcap and dpkt. It assumes that IP is the L2 protocol.
import dpkt
from dpkt.ip import IP
from dpkt.tcp import TCP
for ts, raw_pkt in pcap.pcap(file_path):
ip = IP(raw_pkt[14:])
if(type(ip) != IP):
continue
tcp = ip.data
if(type(tcp) != TCP):
continue
do_something_with(tcp.data)

FTR, to answer the op question,
from scapy.all import *
with PcapWriter("output.pcap", sync=True) as outs:
with PcapReader("input.pcap") as ins:
for pkt in ins:
if TCP in pkt:
pkt[TCP].remove_payload()
outs.write(pkt)

Related

comparing port numbers of packets in python

from scapy.all import *
def print_summary(pkt):
for i in pkt:
sport=[pkt[TCP].sport]
if (sport[i]!=sport[i+1]):
packet=sport
print packet
sniff(offline="/root/ip2.pcap",prn = print_summary)
You could use rdpcap to read the .pcap file, create a list, and append the port number to the list after checking if it is already there or not.
from scapy.all import *
pcap = rdpcap('test_pcap.pcap')
ports = []
for pkt in pcap:
if pkt.haslayer(TCP):
if pkt.sport in ports:
pass
else:
ports.append(pkt.sport)
print(ports)

How to Create a port scanner TCP SYN using the method (TCP SYN )?

#####################################
# Portscan TCP #
# #
#####################################
# -*- coding: utf-8 -*-
#!/usr/bin/python3
import socket
ip = input("Digite o IP ou endereco: ")
ports = []
count = 0
while count < 10:
ports.append(int(input("Digite a porta: ")))
count += 1
for port in ports:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.settimeout(0.05)
code = client.connect_ex((ip, port)) #conecta e traz a msg de erro
#Like connect(address), but return an error indicator instead of raising an exception for errors
if code == 0: #0 = Success
print (str(port) + " -> Porta aberta")
else:
print (str(port) + " -> Porta fechada")
print ("Scan Finalizado")
The python script above is a TCP Scanning. How can I change it into a TCP SYN scanning ? How to Create a port scanner TCP SYN using the method (TCP SYN ) ?
As #Upsampled mentioned, you might use raw sockets (https://en.wikipedia.org/) as you only need a subset of TCP protocol (send SYN and recieve RST-ACK or SYN-ACK
).
As coding something like http://www.binarytides.com/raw-socket-programming-in-python-linux/
could be a good excersice, I would also suggest to consider https://github.com/secdev/scapy
Scapy is a powerful Python-based interactive packet manipulation
program and library.
Here's the code sample that already implements a simple port scanner
http://pastebin.com/YCR3vp9B and a detailed article on what it does:
http://null-byte.wonderhowto.com/how-to/build-stealth-port-scanner-with-scapy-and-python-0164779/
The code is a little bit ugly but it works — I've checked it from my local Ubuntu PC against my VPS.
Here's the most important code snippet (slightly adjusted to conform to PEP8):
# Generate Port Number
srcport = RandShort()
# Send SYNC and receive RST-ACK or SYN-ACK
SYNACKpkt = sr1(IP(dst=target) /
TCP(sport=srcport, dport=port, flags="S"))
# Extract flags of received packet
pktflags = SYNACKpkt.getlayer(TCP).flags
if pktflags == SYNACK:
# port is open
pass
else:
# port is not open
# ...
pass
First, you will have to generate your own SYN packets using RAW sockets. You can find an example here
Second, you will need to listen for SYN-ACKs from the scanned host in order to determine which ports actually try to start the TCP Handshake (SYN,SYN-ACK,ACK). You should be able to detect and parse the TCP header from the applications that respond. From that header you can determine the origin port and thus figure out a listening application was there.
Also if you implement this, you also basically made a SYN DDOS utility because you will be creating a ton of half-opened tcp connections.

What is the best way to fork scapy in order to duplicate packets

I have a pretty simple script which supposed to duplicate packets using scapy:
from scapy.all import *
import pprint
ips = [
"192.168.0.1",
"192.168.0.2",
"192.168.0.3",
"192.168.0.4",
"192.168.0.5",
"192.168.0.6",
"192.168.0.7"
]
def dup_pkt(pkt):
pprint.pprint(pkt)
if pkt[IP].dst == "10.0.0.1":
for ip in ips:
pkt2 = copy.deepcopy(pkt)
pkt2[IP].dst = ip
print "Packet1:",pkt[IP].dst,"Packet2:",pkt2[IP].dst
send(pkt2)
pkts = sniff(prn=dup_pkt, filter="port 53", store=0, count=2)
Instead of the for loop, I wish to send it to the multiple destination all at once. I thought about forking processes which each one will send the packets but it still leaves me with the for loop.
Also - send() is very slow, but sendp() does not fit as I have different destinations.
I've read this one: how to send one udp packet multiple time in scapy ? but there is no answer there.
How can I send multiple packets at once?
Thanks
The send() function can receive a list of packets to send:
def dup_pkt(pkt):
pprint.pprint(pkt)
if pkt[IP].dst == '10.0.0.1':
pkts = []
for ip in ips:
pkt2 = pkt.copy() # use the copy method rather than copy.deepcopy
pkt2[IP].dst = ip
pkts.append(pkt2)
print "Packet1: ", pkt[IP].dst, " Packet2: ", pkt2[IP].dst
send(pkts) # send all packets at once

receiving packets from a socket in scapy

I am trying to code a basic packet sniffer by listening to a socket in python and found that we could use the socket library in python and do the following,
s = socket.socket( socket.AF_PACKET , socket.SOCK_RAW , socket.ntohs(0x0005))
Wanted to know whether if we would do the same in scapy?
From the Scapy Documentnat:
from scapy.all import sniff
data = sniff(filter="icmp and host 127.0.0.1", count=2)
print data.summary()

Python - Pcapy to Scapy on SPAN port, odd behaviour

I built a network sniffer in Scapy but it can't handle the rate of packets I am sniffing (it adds 15-20 minutes of latency which is just unacceptable). I have used Pcapy before in the past at this speed with success, but this time to save me having to re-write all my parsing code that uses Scapy, I want to convert a packet received by Pcapy into a Scapy IP object. The problem is when I try to do this, the IP's and protocol numbers I get are scrambled/unusable, like Scapy is reading the wrong section of the packet.
Some example code below:
#!/usr/bin/python
from pcapy import findalldevs, open_live
from impacket import ImpactDecoder, ImpactPacket
from scapy.all import *
def sniff():
interface = "eth3"
print "Listening on: %s" % interface
# Open a live capture
reader = open_live(interface, 65535, 1, 100)
# Set a filter to be notified only for TCP packets
reader.setfilter('ip proto \\tcp')
# Run the packet capture loop
reader.loop(0, callback)
def callback(hdr, data):
pkt = IP(data)
if IP in pkt:
print pkt[IP].dst
# Parse the Ethernet packet
#decoder = ImpactDecoder.EthDecoder()
#ether = decoder.decode(data)
# Parse the IP packet inside the Ethernet packet
#iphdr = ether.child()
# Parse the TCP packet inside the IP packet
#tcphdr = iphdr.child()
# Only process SYN packets
#if tcphdr.get_SYN() and not tcphdr.get_ACK():
# # Get the source and destination IP addresses
# src_ip = iphdr.get_ip_src()
# dst_ip = iphdr.get_ip_dst()
# # Print the results
# print "Connection attempt %s -> %s" % (src_ip, dst_ip)
def main():
sniff()
if __name__ == "__main__":
main()
And an example of the output:
30.184.113.84
0.120.231.205
30.184.113.91
5.64.113.97
0.120.231.206
21.248.113.98
0.120.231.207
0.120.231.208
0.120.231.209
0.120.231.210
0.120.231.211
0.48.243.73
As you can see these IP's dont make sense, where do you think I am going wrong. Eth3 is connected to a NetGear mirror port.
Thanks for your time.
Never mind, just me being an idiot, I blame bank-holiday Mondays. I was trying to detect the packet from the wrong layer. Convert raw to Ether and Scapy does the rest of the work for me.
def callback(hdr, data):
pkt = Ether(data)
if IP in pkt:
print pkt[IP].dst
else:
print list(pkt)
Cheers

Categories

Resources