I have a problem with my script. For a test i want to print an src and dst ip address but the characters displayed are special and after many researches i still don't understand why ...
I'm sure this is a simply problem but i didnt get it ...
This is the output:
And this is my script:
import pcapy
import dpkt
from threading import Thread
import re
import binascii
liste=[]
listip=[]
piece_request_handshake = re.compile('13426974546f7272656e742070726f746f636f6c(?P<reserved>\w{8})(?P<info_hash>\w{20})(?P<peer_id>\w{20})')
piece_request_tcpclose = re.compile('(?P<start>\w{12})5011')
class PieceRequestSniffer(Thread):
def __init__(self, dev='eth0'):
Thread.__init__(self)
self.expr = 'udp or tcp'
self.maxlen = 65535 # max size of packet to capture
self.promiscuous = 1 # promiscuous mode?
self.read_timeout = 100 # in milliseconds
self.max_pkts = -1 # number of packets to capture; -1 => no limit
self.active = True
self.p = pcapy.open_live(dev, self.maxlen, self.promiscuous, self.read_timeout)
self.p.setfilter(self.expr)
#staticmethod
def cb(hdr, data):
eth = dpkt.ethernet.Ethernet(str(data))
ip = eth.data
#Select Ipv4 packets because of problem with the .p in Ipv6
if eth.type == dpkt.ethernet.ETH_TYPE_IP6:
return
else:
#Select only TCP protocols
if ip.p == dpkt.ip.IP_PROTO_TCP:
tcp = ip.data
try:
#Return hexadecimal representation
hex_data = binascii.hexlify(tcp.data)
except:
return
fin_flag = ( tcp.flags & dpkt.tcp.TH_FIN ) != 0
if fin_flag:
print " -------------------FIN filtered-------------------"
src_ip = ip.src
dst_ip = ip.dst
#listip.append(theip)
print "\n"
print "src_ip %s %s dst_ip %s" % (src_ip,"\n", dst_ip)
#for element in zip(str(listip),str(thedata)):
#print(element)
def stop(self):
#logging.info('Piece Request Sniffer stopped...')
self.active = False
def run(self):
while self.active:
self.p.dispatch(0, PieceRequestSniffer.cb)
sniffer = PieceRequestSniffer()
sniffer.start()
First, import socket, then use:
src_ip = socket.inet_ntoa(ip.src)
dst_ip = socket.inet_ntoa(ip.dst)
Related
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 wrote a python script using scapy to sniff TCP packets in my WIFI network and see if there was a connection between two destinations.
It works if i sniff the packets when i not in monitor mode, but when i sniff on monitor mode interface it's not working.
Any ideas how can make it work?
Snippet:
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
import time
class deferring_delete(object):
def __init__(self, d):
self._dict = d
def __enter__(self):
self._deletes = set()
return self
def __exit__(self, type, value, tb):
for key in self._deletes:
try:
del self._dict[key]
except KeyError:
pass
del self._deletes
def __delitem__(self, key):
if key not in self._dict:
raise KeyError(str(key))
self._deletes.add(key)
packet_count = 0
packets = {}
accepted = {}
YOUR_IP = '10.0.0.1'
FILTER = "tcp and host not {0}".format(YOUR_IP)
def handshake_status(packet):
global packets,accepted,packet_count
flag = packet[0][1].sprintf('%TCP.flags%')
src_ip = packet[0][1].src
dst_ip = packet[0][1].dst
if flag == 'S':
packets[packet_count] = {'src_ip': src_ip, 'dst_ip': dst_ip, 'time': time.ctime() , 'flag': flag}
print "%s ==> %s SYN_SENT" % (src_ip, dst_ip)
packet_count += 1
if flag == 'SA':
for key , packet in packets.iteritems():
if packet['src_ip'] == dst_ip:
accepted[key] = packet
if len(accepted) > 0:
with deferring_delete(packets) as p:
for key in accepted.keys():
print "%s ==> %s ESTABLISHED" % (packets[key]['src_ip'], packets[key]['dst_ip'])
del p[key]
with deferring_delete(accepted) as a:
for key in accepted.keys():
del a[key]
if __name__ == '__main__':
sniff(iface="mon0", filter=FILTER ,prn=handshake_status)
The problem lies with the following lines:
flag = packet[0][1].sprintf('%TCP.flags%')
src_ip = packet[0][1].src
dst_ip = packet[0][1].dst
Try rewriting them as follows:
flag = packet.getlayer(TCP).sprintf('%TCP.flags%')
src_ip = packet.getlayer(IP).src
dst_ip = packet.getlayer(IP).dst
I'm programming in python and i have a problem, indeed when i throw my script it end some seconds after when he detect an IP6 packet. Apparently i have to filter packets and take only IP4 packet to avoid this problem and i would like to know how can i use it with the library dpkt if possible as i started.
I tried something but i'm a beginner and it don't work as you can see in this line:
#Select Ipv4 packets because of problem with the .p in Ipv6
if ip.p == dpkt.ip6:
return`
The error encountered say: "AttributeError: 'IP6' object has no attribute 'p'". This is the traceback:
This is my code if you want to have a look :)
Thanks for your time :)
import pcapy
import dpkt
from threading import Thread
import re
import binascii
liste=[]
listip=[]
piece_request_handshake = re.compile('13426974546f7272656e742070726f746f636f6c(?P<reserved>\w{8})(?P<info_hash>\w{20})(?P<peer_id>\w{20})')
piece_request_tcpclose = re.compile('(?P<start>\w{12})5011')
class PieceRequestSniffer(Thread):
def __init__(self, dev='eth0'):
Thread.__init__(self)
self.expr = 'udp or tcp'
self.maxlen = 65535 # max size of packet to capture
self.promiscuous = 1 # promiscuous mode?
self.read_timeout = 100 # in milliseconds
self.max_pkts = -1 # number of packets to capture; -1 => no limit
self.active = True
self.p = pcapy.open_live(dev, self.maxlen, self.promiscuous, self.read_timeout)
self.p.setfilter(self.expr)
#staticmethod
def cb(hdr, data):
eth = dpkt.ethernet.Ethernet(str(data))
ip = eth.data
#Select only TCP protocols
if ip.p == dpkt.ip.IP_PROTO_TCP:
tcp = ip.data
#Select Ipv4 packets because of problem with the .p in Ipv6
if ip.p == dpkt.ip6:
return
else:
try:
#Return hexadecimal representation
hex_data = binascii.hexlify(tcp.data)
except:
return
handshake = piece_request_handshake.findall(hex_data)
if handshake:
print "-----------handsheck filtered-------------"
liste.append(handshake)
print "\n"
#for element in zip(liste,"123456789abcdefghijklmnopqrstuvwxyz"):
# print(element)
def stop(self):
self.active = False
def run(self):
while self.active:
self.p.dispatch(0, PieceRequestSniffer.cb)
sniffer = PieceRequestSniffer()
sniffer.start()
Finally i found the good way to do it, the line is not:
if ip.p == dpkt.ip6:
return
But:
if eth.type == dpkt.ethernet.ETH_TYPE_IP6:
return
I wanted to write simple udp port scanner on python and I faced some problems.
First of all am I understand right that there are 3 options:
send UDP - get nothing -> port is filtered|opened
send UDP - get icmp port unreachable -> port is closed
send UDP - get UDP - port is opened
I create raw socket, create ip header and udp header. In udp header write the dest port and add some data.
Then I send it to server and with select wait for a reply. But nothing neither on opened port nor on closed. Only timeout.
And is it possible to send just dummy data but not correct packet of the next level ?
[Update 1]
Added more data to send in udp packet. Now I get udp packet back from (194.226.244.126, 53) but my host send back icmp type 3 to 194.226.244.126 before I could read any recieved data. But still no response from 8.8.8.8
[Update 2]
Found that 8.8.8.8 reply only on correct dns packets. But still can't read udp packet with raw socket.
import socket
import time
import select
import sys
from packets_headers import iphdr, udphdr
from get_ip import Getip
timeout = 3
host = "8.8.8.8"
port = 53
my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW)
udp_header = udphdr(b"00000000000000000", port, 4242)
udp_packet = udp_header.assemble()
g = Getip()
ip_packet_header = iphdr(socket.IPPROTO_UDP, g.get_lan_ip(), host)
ip_packet_header.data = udp_packet
ip_packet = ip_packet_header.assemble()
my_socket.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
full_packet = ip_packet
while full_packet:
sent = my_socket.sendto(full_packet, (host, port))
full_packet = full_packet[sent:]
ready = select.select([my_socket], [], [], timeout)
if ready[0] == []: # Timeout
print("Timeout")
sys.exit()
rec_packet, addr = my_socket.recvfrom(1024)
print(rec_packet, addr)
Also packets_header.py
import socket
import struct
import random
class iphdr(object):
"""
This represents an IP packet header.
#assemble packages the packet
#disassemble disassembles the packet
"""
def __init__(self, proto=socket.IPPROTO_ICMP, src="0.0.0.0", dst=None):
self.version = 4
self.hlen = 5
self.tos = 0
self.length = 20
self.id = random.randint(2 ** 10, 2 ** 16)
self.frag = 0
self.ttl = 255
self.proto = proto
self.cksum = 0
self.src = src
self.saddr = socket.inet_aton(src)
self.dst = dst or "0.0.0.0"
self.daddr = socket.inet_aton(self.dst)
self.data = ""
def assemble(self):
header = struct.pack('BBHHHBB',
(self.version & 0x0f) << 4 | (self.hlen & 0x0f),
self.tos, self.length + len(self.data),
socket.htons(self.id), self.frag,
self.ttl, self.proto)
self._raw = header + b"\x00\x00" + self.saddr + self.daddr + self.data
return self._raw
#classmethod
def disassemble(self, data):
self._raw = data
ip = iphdr()
pkt = struct.unpack('!BBHHHBBH', data[:12])
ip.version = (pkt[0] >> 4 & 0x0f)
ip.hlen = (pkt[0] & 0x0f)
ip.tos, ip.length, ip.id, ip.frag, ip.ttl, ip.proto, ip.cksum = pkt[1:]
ip.saddr = data[12:16]
ip.daddr = data[16:20]
ip.src = socket.inet_ntoa(ip.saddr)
ip.dst = socket.inet_ntoa(ip.daddr)
return ip
def __repr__(self):
return "IP (tos %s, ttl %s, id %s, frag %s, proto %s, length %s) " \
"%s -> %s" % \
(self.tos, self.ttl, self.id, self.frag, self.proto,
self.length, self.src, self.dst)
class udphdr(object):
def __init__(self, data="", dport=4242, sport=4242):
self.dport = dport
self.sport = sport
self.cksum = 0
self.length = 0
self.data = data
def assemble(self):
self.length = len(self.data) + 8
part1 = struct.pack("!HHH", self.sport, self.dport, self.length)
cksum = self.checksum(self.data)
cksum = struct.pack("!H", cksum)
self._raw = part1 + cksum + self.data
return self._raw
#classmethod
def checksum(self, data):
# XXX implement proper checksum
cksum = 0
return cksum
def disassemble(self, data):
self._raw = data
udp = udphdr()
pkt = struct.unpack("!HHHH", data)
udp.src_port, udp.dst_port, udp.length, udp.cksum = pkt
return udp
I'd like to know how to write TCP tunnel/relay/bridge/proxy (you name it) using twisted.
I did some research in google, twisted doc/forum etc. etc but couldn't find anwser.
I already done it in pure python using socket, threading and select.
Here is code:
#!/usr/bin/env python
import socket
import sys
import select
import threading
import logging
import time
class Client(threading.Thread):
def __init__(self, client, address, id_number, dst_ip, dst_port):
self.log = logging.getLogger(__name__+'.client-%s' % id_number)
self.running = False
self.cl_soc = client
self.cl_adr = address
self.my_id = id_number
self.dst_ip = dst_ip
self.dst_port = dst_port
threading.Thread.__init__(self)
def stop(self):
self.running = 0
def run(self):
try:
self.dst_soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.dst_soc.connect((self.dst_ip,self.dst_port))
except:
self.log.error('Can\'t connect to %s:%s' % (self.dst_ip, self.dst_port))
else:
self.running = True
self.log.info('Bridge %s <-> %s created' % (
'%s:%s' % self.dst_soc.getpeername(), '%s:%s' % self.cl_adr))
try:
while self.running:
iRdy = select.select([self.cl_soc, self.dst_soc],[],[], 1)[0]
if self.cl_soc in iRdy:
buf = self.cl_soc.recv(4096)
if not buf:
info = 'Ended connection: client'
self.running = False
else:
self.dst_soc.send(buf)
if self.dst_soc in iRdy:
buf = self.dst_soc.recv(4096)
if not buf:
info = 'Ended connection: destination'
self.running = False
else:
self.cl_soc.send(buf)
except:
self.log.error('Sth bad happend', exc_info=True)
self.running = False
self.log.debug('Closing sockets')
try:
self.dst_soc.close()
except:
pass
try:
self.cl_soc.close()
except:
pass
class Server(threading.Thread):
def __init__(self, l_port=25565, d_ip='127.0.0.1', d_port=None):
self.log = logging.getLogger(__name__+'.server-%s:%s' % (d_ip,d_port))
threading.Thread.__init__(self)
self.d_ip = d_ip
if d_port == None:
self.d_port = l_port
else:
self.d_port = d_port
self.port = l_port
binding = 1
wait = 30
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
while binding:
try:
self.s.bind(('',self.port))
except:
self.log.warning('Cant bind. Will wait %s sec' % wait)
time.sleep(wait)
else:
binding = 0
self.log.info('Server ready for connections - port %s' % d_port)
def run(self):
self.s.listen(5)
input = [self.s, sys.stdin]
running = 1
self.cl_threads = []
id_nr = 0
while running:
iRdy = select.select(input, [], [],1)[0]
if self.s in iRdy:
c_soc, c_adr = self.s.accept()
c = Client(c_soc, c_adr, id_nr, self.d_ip, self.d_port)
c.start()
self.cl_threads.append(c)
id_nr += 1
if sys.stdin in iRdy:
junk = sys.stdin.readline()
print junk
running = 0
try:
self.s.close()
except:
pass
for c in self.cl_threads:
c.stop()
c.join(5)
del c
self.cl_threads = None
self.log.info('Closing server')
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG)
s = Server(1424, '192.168.1.6', 1424)
s.run()
this is actually, already built into twisted, from the command line you can type:
$ twistd --nodaemon portforward --port 1424 --host 192.168.1.6
to get the exact behavior you seem to be looking for.
If you'd like to roll your own, you can still use all of the bits, in twisted.protocols.portforward