Scapy, Socket and 3-way-handshake - python

I'm trying to do a pretty weird thing with Python/Scapy/Socket (Linux env). I'd like to manage the 3-way handshake and then go back to the usual "socket" management.
Here is what I did:
import socket
from scapy.all import *
pkt = IP(src='192.168.1.2',dst='192.168.1.1')/TCP(sport=12345,dport=44144,flags='S',seq=1000)
SYN = bytes(pkt)
outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
outs.connect(('192.168.1.1',44144))
outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
outs.sendto(SYN, ('192.168.1.1', 0))
raw_buffer = outs.recv(4096)
buffer = IP(raw_buffer)
my_ack = buffer.seq + 1
pkt=IP(src='192.168.1.2',dst='192.168.1.1')/TCP(sport=12345, dport=44144, flags='A', seq=1001, ack=my_ack)
ACK=bytes(pkt)
outs.sendto(ACK, ('192.168.1.1', 0))
So far so good, the connection is established. Then I try to use the socket and the created connection with the usual "send" method:
outs.send(bytes('AAA','utf8'))
At this point I get an error:
*** OSError: [Errno 22] Invalid argument
So, what I'm trying to do is to switch back from a RAW_SOCKET to a system handled one. Is that possible in some ways?
Thanks,

Related

python ssl socket OSerror An operation was attempted on something that is not a socket

So before anyone says its a duplicate, I have seen multiple questions with that error, but could not notice any of that being the same as my problem.
I am trying to make a small project including a socket over SSL, and when trying to catch if a user is trying to connect with a raw socket and not ssl wrapped socket (which is raising a ConnectionResetError) I get a different error.
My code:
import socket
from classes import ClientThread
import ssl
from time import sleep
server = 'localhost'
port = 12345
threads = []
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.load_cert_chain(certfile="cert.pem", keyfile="cert.pem")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((server, port))
print(f"[*] server started, listening on port {port}")
while True:
s.listen()
with context.wrap_socket(s, server_side=True) as ssock:
try:
conn, addr = ssock.accept()
client = ClientThread(conn=conn, ip=addr[0], port=addr[1])
client.start()
threads.append(client)
print(f'Threads running: {len(threads)}')
except ConnectionResetError:
print(f'Could not establish ssl handshake with a client.')
The error i get is:
Traceback (most recent call last):
File "C:/Users/x/x/server.py", line 17, in <module>
s.listen()
OSError: [WinError 10038] An operation was attempted on something that is not a socket
I tried setting some sleep time after the exception maybe it needed to reset the socket but didnt hlep, tried to play a bit with the placement of the While True, and while resetting the entire socket help, I dont want to reset all my clients thread just because of a client who didnt try to log in with a SSL socket.
I think it has something to do with the wrap_socket because it modified the socket instance passed to it , but couldnt find a way to unwrap.
Thank you in advance!
listen enables a socket to take incoming connection requests (also called a "passive socket") and establishes a backlog of how many of those requests can be pending in the network stack at any given time. accept accepts one of those connections. You call listen once and accept many times.
Pull the listen outside of the while so that is only called once to establish this as a listening socket.

Python - OSError in sendto(bytes, (ip,port))

I'm currently having a lot of trouble while writing a raw socket.
While my implementation is pretty big by now, i think solving the problem for the following code, would also solve it for my whole implementation:
from scapy.all import *
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
src_port = 12345 # any random port > 1024 i guess ...
dst_port = 80 # should be tcp, as http runs over it in the end
dst_addr = socket.gethostbyname("www.google.de")
# ensuring that kernel will not create its own ip header
sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, True)
# create a packet to send using scapy
packet = IP(dst = dst_addr)/TCP(dport = dst_port)
sock.sendto(bytes(packet), (dst_addr, 80))
I get the following error :
OS error: [Errno 22] Invalid argument
which is raised by:
sock.sendto(bytes(packet), (dst_addr, 80))
Does someone have a clue, why this is not working?
-- EDIT --
I'm working on MacOSX.
I already noticed this question: Raw sockets and sendto in python
However, I'm hoping that someone has an answer anyways, as the old question lacks a good answer and is also around 4 years old.

TCP connection state from RAW SOCKET packet sniffing

Here is my code:
ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, 3)
ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
ins.bind((interface_name, 3))
while True:
fmt = "B"*7+"I"*21
pkt, sa_ll = self.ins.recvfrom(65535)
x = struct.unpack(fmt, ins.getsockopt(socket.IPPROTO_TCP, socket.TCP_INFO, 92))
print "===>",x
print "HEX Packet",hexlify(pkt)
process_ipframe(sa_ll[2],hexlify(pkt))
Getting socket.error: [Errno 92] Protocol not available error. Or is there any better way to get the TCP(Need only ESTAB connctions) states for the connections.
Ok, my requirement is to get the established connections. But I was sniffing traffic on the interface for other purpose. So, I though I could get TCP states from raw sockets. But I found /proc/net/tcp: there is st field, from that I can get ESTABLISHED connections. So, I should read /proc/net/tcp continuously to get ESTAB for a specific time in different thread.
So, the answer is /proc/net/tcp. Check this question. or may I should use netfilter

Python sctp module - server side

I have been trying to test SCTP for a network deployment.
I do not have an SCTP server or client and was hoping to be able use pysctp.
I am fairly certain that I have the client side code working.
def sctp_client ():
print("SCTP client")
sock = sctp.sctpsocket_tcp(socket.AF_INET)
#sock.connect(('10.10.10.70',int(20003)))
sock.connect(('10.10.10.41',int(21000)))
print("Sending message")
sock.sctp_send(msg='allowed')
sock.shutdown(0)
sock.close()
Has anybody had luck with using the python sctp module for the server side?
Thank you in Advance!
I know that this topic's a bit dated, but I figured I would respond to it anyway to help out the community.
In a nutshell:
you are using pysctp with the sockets package to create either a client or a server;
you can therefore create your server connection as you normally would with a regular TCP connection.
Here's some code to get you started, it's a bit verbose, but it illustrates a full connection, sending, receiving, and closing the connection.
You can run it on your dev computer and then use a tool like ncat (nmap's implementation of netcat) to connect, i.e.: ncat --sctp localhost 80.
Without further ado, here's the code... HTH:
# Here are the packages that we need for our SCTP server
import socket
import sctp
from sctp import *
import threading
# Let's create a socket:
my_tcp_socket = sctpsocket_tcp(socket.AF_INET)
my_tcp_port = 80
# Here are a couple of parameters for the server
server_ip = "0.0.0.0"
backlog_conns = 3
# Let's set up a connection:
my_tcp_socket.events.clear()
my_tcp_socket.bind((server_ip, my_tcp_port))
my_tcp_socket.listen(backlog_conns)
# Here's a method for handling a connection:
def handle_client(client_socket):
client_socket.send("Howdy! What's your name?\n")
name = client_socket.recv(1024) # This might be a problem for someone with a reaaallly long name.
name = name.strip()
print "His name was Robert Paulson. Er, scratch that. It was {0}.".format(name)
client_socket.send("Thanks for calling, {0}. Bye, now.".format(name))
client_socket.close()
# Now, let's handle an actual connection:
while True:
client, addr = my_tcp_socket.accept()
print "Call from {0}:{1}".format(addr[0], addr[1])
client_handler = threading.Thread(target = handle_client,
args = (client,))
client_handler.start()
Unless you need the special sctp_ functions you don't need an sctp module at all.
Just use protocol 132 as IPPROTO_SCTP (is defined on my python3 socket module but not on my python2 socket module) and you can use the socket,bind,listen,connect,send,recv,sendto,recvfrom,close from the standard socket module.
I'm doing some SCTP C development and I used python to better understand SCTP behavior without the SCTP module.

An existing connection was forcibly closed by the remote host (simple UDP client-server)

Absolute newbie here, and I can't quite seem to find the answer to my question. Running python 2.7.
My code for the server is as follows:
#UDPPingerClient.py
from socket import *
#Create a UDP socket
clientSocket = socket(AF_INET, SOCK_DGRAM)
#Assign IP address and port number to socket
clientSocket.bind(("127.0.0.1",9501))
#Set a timeout value of 1 second
clientSocket.settimeout(1)
msg = "test"
#the server info
sIP = "127.0.0.1"
sPort = 12007
addr = (sIP,sPort)
a = 10
# the server will automatically drop some messages
# so we send 10 to make sure it gets there and then
# listen for a response from the server
while a > 0:
clientSocket.sendto(msg,addr)
try:
received, server = clientSocket.recvfrom(1024)
print received
except timeout:
print ('an error occured')
a = a - 1
The server code:
# UDPPingerServer.py
# We will need the following module to generate randomized lost packets
import random
from socket import *
# Create a UDP socket
# Notice the use of SOCK_DGRAM for UDP packets
serverSocket = socket(AF_INET, SOCK_DGRAM)
# Assign IP address and port number to socket
serverSocket.bind(("127.0.0.1", 12007))
while True:
# Generate random number in the range of 0 to 10
rand = random.randint(0, 10)
# Receive the client packet along with the address it is coming from
message, address = serverSocket.recvfrom(1024)
# Capitalize the message from the client
message = message.upper()
12 # If rand is less is than 4, we consider the packet lost and do not respond
if rand < 4:
continue
# Otherwise, the server responds
serverSocket.sendto(message, address)
Thus far I haven't been able to get a reply from the server. The most I've been able to accomplish is sending once and timing out before getting this error:
an error occured <-- output from exception
Traceback (most recent call last):
File "C:/Python27/UDPPingerClient.py", line 23, in <module>
received, server = clientSocket.recvfrom(1024)
error: [Errno 10054] An existing connection was forcibly closed by the remote host
The reproducibility on this one is 100%, this is the outcome every time I run the server file and then the client file. Same thing with the firewall on or off. I have a feeling this has to do with the exception but I can't quite wrap my head around why.
this is the output i got:
foggy#dew ~ $ python UDPPingerClient.py
TEST
TEST
an error occured
TEST
TEST
TEST
an error occured
TEST
an error occured
TEST
exactly ten messages, some have timeouted others were passed back.
besides that extra 12 above rand line in Server (and that doesn't bother the interpreter) i don't see anything wrong with the code.

Categories