How to count Duplicate IP in a Column in CSV by Python - python

I have program for extract PCAP ARP src_ip and Dest_IP and save in CSV file. i need code how to count Number of Times Src_IP is request to dest_ip (Example 192.168.0.1 src_IP try to connected 10 times with Dest_ip). so how to count duplicates IP in a Column. or how to count src to dest IP or any other idea for count duplicate IP in a Column pls.
below code I need to count number of times src to target
for ts, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf)
# If the packet is not arp
if eth.type != 2054:
continue
try:
arp = eth.arp
except Exception as e:
continue
packet_time = datetime.datetime.utcfromtimestamp(ts).strftime("%m/%d/%Y,%H:%M:%S")
src = dpkt.socket.inet_ntoa(arp.spa)
tgt = dpkt.socket.inet_ntoa(arp.tpa)

Use csv to load desired IPs into a list and then do something like:
from collections import Counter
Counter(ip_list)

Related

Parsing multiple DNS responses with Scapy

Trying to parse DNS responses with Scapy (see function below). My issue is all of the answers in the rdata[] field are not showing. When I do a packet capture with Wireshark, I see multiple answers in the rdata[] field, there are usually two or three answers in a single response packet for those unfamiliar with DNS.
I am only returned with one of the answers (the first). I have tried using sr() instead of sr1() and have also tried adding multi=True as a parameter when sending the packet but neither of these work.
Any ideas?
def send_query_recursion(resolver, target):
dns_req = IP(dst=f'{resolver}')/UDP(dport=53)/DNS(qr=0, rd=1, qd=DNSQR(qname=f'{target}'))
answer = sr1(dns_req, verbose=1)
for received in answer:
if received.haslayer(DNS):
for x in received:
print(str(x[DNS].id))
print("rrname: " + str(x[DNSRR].rrname))
print("Type: " + str(x[DNSRR].type))
if str(x[DNSRR].rclass) == "1":
print("Class: " + str(x[DNSRR].rclass) + " IN")
print("TTL: " + str(x[DNSRR].ttl))
print("Resource Data Length: " + str(x[DNSRR].rdlen))
print("Resource Data: " + str(x[DNSRR].rdata[:-1]))
I have the same issue as you do. I could not resolve it using scapy, so I have used dpkt package to parse the answer of the DNS responses as follow (python 3):
with open('your_pcap.pcap', 'rb') as f:
pcap = dpkt.pcap.Reader(f)
for timestamp, buf in pcap:
try:
eth = dpkt.ethernet.Ethernet(buf)
except:
continue
if eth.type != 2048:
continue
try:
ip = eth.data
except:
continue
if ip.p != 17:
continue
#filter on UDP assigned ports for DNS
try:
udp = ip.data
except:
continue
if udp.sport != 53 and udp.dport != 53:
continue
#make the dns object out of the udp data and
#check for it being a RR (answer) and for opcode QUERY
try:
dns = dpkt.dns.DNS(udp.data)
except:
continue
if dns.qr != dpkt.dns.DNS_R:
continue
if dns.opcode != dpkt.dns.DNS_QUERY:
continue
if dns.rcode != dpkt.dns.DNS_RCODE_NOERR:
continue
if len(dns.an) < 1:
continue
for qname in dns.qd:
print("The DNS response packet has ", len(dns.an), " answers")
print("The answers (in a list) are: ", dns.an)
You can find additional information on parsing DNS using dpkt on the following pages:
https://dpkt.readthedocs.io/en/latest/_modules/dpkt/dns.html
https://mmishou.wordpress.com/2010/04/13/passive-dns-mining-from-pcap-with-dpkt-python/

getting remote ip from local ip

given a local side IP address(ip): u'1.1.1.1/32' #unicode format
how to get the remote side ip? (which will be 1.1.1.2)
logic:
if local ip is even, remote ip will be local ip + 1
else, local ip - 1
i was trying something like this:
ip_temp = int(ip.replace('/32','').split('.')[-1])
if ip_temp % 2 == 0:
remote = ip + 1
else:
remote = ip - 1
remote_ip = <replace last octet with remote>
I looked into ipaddress module but couldnt find anything useful
Most Python socket utilities require that the Remote IP Be a tuple with a string and port number (integer). For example:
import socket
address = ('127.0.0.1', 10000)
sock.connect(address)
For your case, you have most of the logic required. However you need to determine what to do with the cases of X.X.X.0 and X.X.X.255.
The full code to do what you want is:
ip = '1.1.1.1/32'
# Note Drop the cidr notation as it is not necessary for addressing in python
ip_temp = ip.split('/')[0]
ip_temp = ip_temp.split('.')
# Note this does not handle the edge conditions and only modifies the last octet
if int(ip_temp[-1]) % 2 == 0:
remote = int(ip_temp[-1]) + 1
else:
remote = int(ip_temp[-1]) -1
remote_ip = ".".join(ip_temp[:3]) + "." + str(remote)

Strip TZSP Encapsulation - live traffic

I'm creating a log server, that write incoming and outgoing connections (any type) to a TXT file . everything is working fine and here is my code :
from scapy.all import *
import datetime
from threading import Thread
from Queue import Queue, Empty
from scapy.layers.dns import DNS, DNSQR
firstime = 0
times = time.time()+86400
def print_summary(pkt):
global firstime
global times
if IP in pkt:
ip_src=pkt[IP].src
ip_dst=pkt[IP].dst
else:
ip_src="Null"
ip_dst="Null"
mac_src="Null"
mac_dst="Null"
if TCP in pkt:
tcp_sport=pkt[TCP].sport
tcp_dport=pkt[TCP].dport
else:
tcp_sport="Null"
tcp_dport="Null"
if DNSQR in pkt:
dns = pkt.qd.qname
else:
dns = "NULL"
if Ether in pkt:
mac_src = pkt[Ether].src
mac_dst = pkt[Ether].dst
else:
mac_src = "Null"
mac_dst = "Null"
Clog = " IP src: " + str(ip_src) +" ,MAC src: " + str(mac_src) + " , IP dst: " + str(ip_dst) +" ,MAC dst: "+str(mac_dst)+" ,TCP sport: " + str(tcp_sport) + ",TCP dport: " + str(tcp_dport) +", Time: " + str(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(pkt.time))) + " Dns: "+dns
if(times > pkt.time):
if(firstime == 0):
f = open("/root/Desktop/LOG-SERVER/"+time.strftime('%Y-%m-%d %H:%M:', time.localtime(time.time()))+".txt",'a')
f.write(Clog+"\n")
f.close()
else:
f.write(Clog+"\n")
f.close()
else:
f = open("/root/Desktop/LOG-SERVER/"+time.strftime('%Y-%m-%d %H:%M:', time.localtime(time.time()))+".txt",'a')
f.write(Clog+"\n")
f.close()
times=times+86400
def startsnif():
sniff(prn=print_summary, store=0)
# you can filter with something like that
#if ( ( pkt[IP].src == "192.168.0.1") or ( pkt[IP].dst == "192.168.0.1") ):
# print("!")
#def writing(log,indexp):
#if(indexp == 0):
#f = open("/root/Desktop/LOG-SERVER/"+time.strftime('%Y-%m-%d %H:%M:', time.localtime(time.time()))+".txt",'a')
#f.write(log+"\n")
#f.close()
#else:
#f.write(log+"\n")
#f.close()
thread.start_new_thread(startsnif,());
while 1:
pass
# or it possible to filter with filter parameter...!
#sniff(filter="ip and host 192.168.0.1",prn=print_summary)
output is:
IP Src: 192.168.10.1 MAC Src: 54:55:12:FC:2D:CA IP Dst:192.168.10.15 MAC Src: 54:55:12:FC:1F:3A TCP sport: 80 TCP dport: 51233 Time:2015-12-16 13:25:11 DNS:Null(IF available DNS Name)
the problem is that the company got mikrotics, mikrotics mirror traffic through a technique called TZSP Sniff which encapsulate the packet with the IP of the router and MAC of the router IP of the destination PC MAC of the destination pc, i was searching and i couldn't find any appropriate solution but i read that you need to strip first 5 bytes of a packet.
is there a way to strip the TZSP encapsulation live(without saving PCAP), could you please explain the process because I'm new to this stuff?
please if you have any question ask I'm not very good in explaining stuff.
Thank you!
After examining the binary of the TZSP packet header it appears that TZSP strip original mac address after adding it's own, so the project was closed thank you for the help.

Socket Programming; File corrupts when transferring over multiple devices

The problem I'm having is to get a file from the server to client across devices. Everything works fine on localhost.
Lets say I want to "get ./testing.pdf" which sends the pdf from the server to the client. It sends but it is always missing bytes. Is there any problems with how I am sending the data. If so how can I fix it? I left out the code for my other functionalities since they are not used for this function.
sending a txt file with "hello" in it works perfectly
server.py
import socket, os, subprocess # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
#host = ''
port = 5000 # Reserve a port for your service.
bufsize = 4096
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
while True:
userInput = c.recv(1024)
.... CODE ABOUT OTHER FUNCTIONALITY
elif userInput.split(" ")[0] == "get":
print "inputed get"
somefile = userInput.split(" ")[1]
size = os.stat(somefile).st_size
print size
c.send(str(size))
bytes = open(somefile).read()
c.send(bytes)
print c.recv(1024)
c.close()
client.py
import socket, os # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
#host = '192.168.0.18'
port = 5000 # Reserve a port for your service.
bufsize = 1
s.connect((host, port))
print s.recv(1024)
print "Welcome to the server :)"
while 1 < 2:
userInput = raw_input()
.... CODE ABOUT OTHER FUNCTIONALITY
elif userInput.split(" ")[0] == "get":
print "inputed get"
s.send(userInput)
fName = os.path.basename(userInput.split(" ")[1])
myfile = open(fName, 'w')
size = s.recv(1024)
size = int(size)
data = ""
while True:
data += s.recv(bufsize)
size -= bufsize
if size < 0: break
print 'writing file .... %d' % size
myfile = open('Testing.pdf', 'w')
myfile.write(data)
myfile.close()
s.send('success')
s.close
I can see two problems right away. I don't know if these are the problems you are having, but they are problems. Both of them relate to the fact that TCP is a byte stream, not a packet stream. That is, recv calls do not necessarily match one-for-one with the send calls.
size = s.recv(1024) It is possible that this recv could return only some of the size digits. It is also possible that this recv could return all of the size digits plus some of the data. I'll leave it for you to fix this case.
data += s.recv(bufsize) / size -= bufsize There is no guarantee that that the recv call returns bufsize bytes. It may return a buffer much smaller than bufsize. The fix for this case is simple: datum = s.recv(bufsize) / size -= len(datum) / data += datum.

Reconstruct HTTP Webpage from libpcap python script

I am trying to reconstruct a webpage from a libpcap file from a python script. I have all the packets so the goal I guess is to have a libpcap file as input and you find all the necessary packets and somehow have a webpage file as output with all pictures and data from that page. Can anyone get me started off in the right direction. I think I will need dkpt and/or scaPY.
Update 1: Code is below! Here is the code I have come up so far with in Python. It is suppose to grab the first set of packets from a single HTTP session beginning with a packet with the SYN and ACK flags set to 1 and ends with a packet that has the FIN flag set to 1.
Assuming there is only one website visited during the packet capture does this code append all the necessary packets needed to reconstruct the visited webpage?
Assuming I have all the necessary packets how do I reconstruct the webpage?
import scaPy
pktList = list() #create a list to store the packets we want to keep
pcap = rdpcap('myCapture.pcap') #returns a packet list with every packet in the pcap
count = 0 #will store the index of the syn-ack packet in pcap
for pkt in pcap: #loops through packet list named pcap one packet at a time
count = count + 1 #increments by 1
if pkt[TCP].flags == 0x12 and pkt[TCP].sport == 80: #if it is a SYN-ACK packet session has been initiated as http
break #breaks out of the for loop
currentPkt = count #loop from here
while pcap[currentPkt].flags&0x01 != 0x01: #while the FIN bit is set to 0 keep loops stop when it is a 1
if pcap[currentPkt].sport == 80 and pcap[currentPkt].dport == pcap[count].dport and pcap[currentPkt].src == pcap[count].src and pcap[currentPkt].dst == pcap[count].dst:
#if the src, dst ports and IP's are the same as the SYN-ACK packet then the http packets belong to this session and we want to keep them
pktList.append(pcap[currentPkt])
#once the loop exits we have hit the packet with the FIN flag set and now we need to reconstruct the packets from this list.
currentPkt = currentPkt + 1
Perhaps something like tcpick -r your.pcap -wRS does the job for you.
http://tcpick.sourceforge.net/?t=1&p=OPTIONS
This python script will extract all unencrypted HTTP webpages that are in a PCAP File and output them as HTML Files. It uses scaPY to work with the individual packets (another good python module is dpkt).
from scapy.all import *
from operator import *
import sys
def sorting(pcap):
newerList = list()
#remove everything not HTTP (anything not TCP or anything TCP and not HTTP (port 80)
#count = 0 #dont need this it was for testing
for x in pcap:
if x.haslayer(TCP) and x.sport == 80 and bin(x[TCP].flags)!="0b10100":
newerList.append(x);
newerList = sorted(newerList, key=itemgetter("IP.src","TCP.dport"))
wrpcap("sorted.pcap", newerList)
return newerList
def extract(pcap,num, count):
listCounter = count
counter = 0
#print listCounter
#Exit if we have reached the end of the the list of packets
if count >= len(pcap):
sys.exit()
#Create a new file and find the packet with the payload containing the beginning HTML code and write it to file
while listCounter != len(pcap):
thisFile = "file" + str(num) + ".html"
file = open(thisFile,"a")
s = str(pcap[listCounter][TCP].payload)
#print "S is: ", s
x,y,z = s.partition("<")
s = x + y + z #before was y+z
if s.find("<html") != -1:
file.write(s)
listCounter = listCounter + 1
break
listCounter = listCounter + 1
#Continue to loop through packets and write their contents until we find the close HTML tag and
#include that packet as well
counter = listCounter
while counter != len(pcap):
s = str(pcap[counter][TCP].payload)
if s.find("</html>") != -1:
file.write(s)
file.close
break
else:
file.write(s)
counter = counter + 1
#Recursively call the function incrementing the file name by 1
#and giving it the last spot in the PCAP we were in so we continue
#at the next PCAP
extract(pcap, num+1, counter)
if __name__ == "__main__":
#Read in file from user
f = raw_input("Please enter the name of your pcap file in this directory. Example: myFile.pcap")
pcapFile = rdpcap(f)
print "Filtering Pcap File of non HTTP Packets and then sorting packets"
#Sort and Filter the PCAP
pcapFile = sorting(pcapFile)
print "Sorting Complete"
print "Extracting Data"
#Extract the Data
extract(pcapFile,1,0)
Print "Extracting Complete"

Categories

Resources