Netcat only receiving first UDP packet from Scapy and Python - python

I'm currently making a DNS tunnel in python using Scapy. I can send packets just fine (according to Wireshark). The problem is, when listening on Netcat on what I'm transmitting the dns packets to, I only receive the first packet.
I've heard that when binding, a UDP "connection" (for lack of better words) locks on a port, and drops all other packets from any other source port. However, I defined a source port, so I'm not sure what is going on.
def sendDns(incomingBytes):
print('sending packet data :\n' + incomingBytes.decode('utf-8'))
incomingBytes = base64.encodebytes(incomingBytes)
send(IP(dst=dnsServer)/UDP(dport=53, sport=12345)/DNS(qd=DNSQR(qname=incomingBytes)))

Related

python UDP socket - recvfrom works, but getpeername() gives "Transport endpoint is not connected" error?

I have a udp server in python that i'm testing out by sending packets with netcat -u server_ip server_port
on the udp server, I can receive the packets with
data,addrport = socket.recvfrom(some_number) — I can read the data received and see the other socket's address port with addrport.
But if I try to use socket.getpeername() on the same variable instead it gives the OSError: [Errno 107] Transport endpoint is not connected error.
What causes this? I'm confused as my netcat terminal doesn't close after sending, which I assume means its already connected to my UDP socket.
I can receive the packets with data,addrport = socket.recvfrom(some_number)
recvfrom means that you are working with an unconnected UDP socket, i.e. the case where a single socket could receive packets from various sources and also send data to various sources using sendto. getpeername instead expects a connected socket, i.e. one which will only receive data from a single source (using recv not recvfrom) and only send to a single source (using send not sendto). This is the case with TCP established sockets (the ones returned by accept) but also with UDP socket which are explicitly connected by calling connect.

Does a Python 3 TCP Socket have to be connected in order to send data? Or not like UDP?

I want to make a TCP Socket that doesn't connect to the host but instead sends data without connecting... Is that possible with the Python 3 Socket module?
TCP sockets always need to be connected before sending data. Establishing the connection involves an actual packet exchange with the peer, i.e. the TCP 3-way handshake. This is also means that the connect can fail if the target cannot be reached. This is not specific to Python but specific to how TCP sockets work.
With UDP a socket can be connected but does not need to be. Connecting a UDP socket essentially just sets the target on the local socket but does not involve any actual data transfer. This also means that the connect will usually not fail even but a later data transfer might not be able to reach the target.

Python : Receive UDP packets from port

I have a client which is creating packets and sending packets to a destination in a network which has been created using mininet. Now I am writing a python program at the destination to count the number of packets which has arrived. Now I know for sure that the packets are arriving at the destination (used tcpdump to verify it)
How do I go about it?
I thought of using this -
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
print s.recvfrom(5001)
But this seems to be slow. Is there any other alternative?
You want socket.IPPROTO_UDP for UDP packets, but otherwise, that's basically what you must do. No matter what other things you try, it's going to have to do those things.
Oh, and you'll want to do a socket.bind(('',PORT)) to bind it to the port you want it to listen on.

Scapy, RST packets and iptables

I wrote a script that basically does the following: Opens a socket, connects and then an object that parses this socket so I can play around with scapy. It turns out that the packets are arriving to my destination but the responses from the destination host back to me are lost "somewhere" "somehow". I can see from the dump of the destination host that it clearly replies with some RST packets back, however from my "attacking" host I cant see these RST packets. Is this related to my TCP/IP stack and the generation of these RST packets locally or what? Do I have to set up an iptables rule for solving this problem?
I have the following snippet from my script
for i in range (0,int(args.packets)):
time.sleep(5)
ans,unans=sr(IP(dst=args.dst)/TCP(dport=int(args.port))/fuzz(Raw()), timeout=0.5, inter=0, iface=args.interface)
unans.nsummary()
ans.nsummary()
Another issue is that supposedly this is using the fuzz() method from scapy and it fuzzes the actual payload of the packet (not the IP / TCP header ). However when I am listening with netcat for example nothing is getting printed and I can also see from the dump that the packets are getting interpreted to either FTP-DATA or something other...
Any help?

Python Raw Socket cannot recieve ICMP messages; show up in Wireshark

I am trying to implement a python traceroute that sends UDP messages and receives the ICMP responses via raw sockets. I've run into an issue where the ICMP packets seem to avoid capture at all cost. The ICMP responses show up in wireshark as exactly what I'd expect, but the socket never receives any data to read. Another complication is that I am running the code on VirtualBox running Ubuntu, as the sendto() would not get the packets on the wire in Windows 7. (I'm running wireshark in windows to capture the packets). The strange thing is that wireshark will capture the ICMP messages when I run the python script from the virtual machine. However, when I try to run the script on windows, the ICMP messages don't show up in wireshark. (The UDP packets have magically started working on windows)
I've played around with all sorts of different versions of setting up the socket from online examples, and played around with using bind() and not using it, but no configuration seems to produce a socket that reads. It will just time out waiting to read the ICMP message.
It should also be noted that if I try to read my udp sending socket, it successfully reads the udp packets. As soon as I set IPPROTO_ICMP the read times out.
receive_response method:
def receive_response(rec_socket, packetid, tsend, timeout):
remain = timeout
print packetid
while remain > 0:
ready = select.select([rec_socket], [], [], remain)
if ready[0] == []:
return
print 'got something'
setting up the socket:
rec_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, ICMP_CODE)
rec_socket.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
rec_socket.bind(("",0)) #played with using this statement and skipping it
call to receive is simply:
reached = receive_response(rec_socket, packetid, time.time(), timeout)
It looks like the problem is VirtualBox will default to using NAT to connect to the network. This means that the virtual machine won't receive the ICMP messages by virtue of them being ICMP messages. It seems like the solution to this is to configure VirtualBox networking to use "Bridged networking" mode. Unfortunately I cannot confirm this as I can't set up the virtual machine on my university's network within bridged mode. As for the reason they didn't work in windows, it must be related to windows' lack of support for raw sockets.

Categories

Resources