Scapy, RST packets and iptables - python

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?

Related

How to capture martian packets without letting the linux kernel to drop them and then catching them using raw sockets

I'm trying to setup a network to simulate an Edge computing scenario with LTE. But the question here is more pertaining to IP tables and raw sockets on the server.
I have the following setup:
PC-A is the Tower, PC-C is the LTE Core, PC-B is acting as intermediary and routing data using proxy ARPs
Cell phone wants to connect to a TCP server on PC-B(IP: 172.17.1.3)
Cell phone(IP:192.172.0.2) sends packets to PC-A(IP: 172.17.1.1)
The data from PC-A(172.17.1.1) generally has to reach LTE-EPC on 172.17.1.4 which is connected via PC-B(172.17.1.2 - 172.17.1.3 with proxy ARPs). And the data comes in the form of UDP packets to PC-B(IP: 172.17.1.2)
I use NAT table and python script with raw sockets to send all of these UDP packets to a local port, do some filtering, decapsulate the GTP headers and send the TCP/IP packet to the TCP server on PC-B interface(172.17.1.3). I use the below iptables settings to do this
iptables -t nat -A PREROUTING -p udp -d 172.17.1.4 --dport 2152 -j DNAT --to-destination 172.17.1.2:7000
Until here everything works, the extracted TCP/IP packet also reaches the TCP server on 172.17.1.3. The server responds to these packets. For example, for the SYN packet from the cell phone, the server now sends out SYN, ACK. However, the server responds to the original source address 192.172.0.2.
I want to catch these response TCP/IP packets from the TCP server 172.17.1.3 to 192.172.0.2 and do some GTP encapsulation before sending them back to PC-A.
Can anyone tell me how I can use the iptables to tell the kernel to stop dropping these martian packets with destination address 192.172.0.2, but instead forward to a local ip and port, so I can read the same.
I can see the SYN, ACK responses from the server on wireshark. But I assume that these are dropped as I already tried to route it to local ip:port using a similar iptables rule from above.
Any help is much appreciated, Thank you.
It sounds like a tun/tap interface could be useful here. Here's the official Linux kernel documentation.
Both these interface types allow a program to create a virtual network interface. This is designed for tunnels and VPNs and it seems like that is exactly what you are creating.
According to the linked documentation, you may create an interface by opening /dev/net/tun (O_RDWR) and issuing this ioctl to initialize it:
struct ifreq req;
memset(&req, 0, sizeof(req));
req.ifr_flags = IFF_TUN; // or IFF_TAP
strncpy(req.ifr_name, "tunnel%d", IFNAMSIZ); // optional; leave it blank to get a default name; you don't have to have a %d
ioctl(fd, TUNSETIFF, &req); // error check omitted for demonstration
// req.ifr_name now contains the name that was actually selected
After the ioctl you have a virtual network interface in your system. You can configure IP addresses, routes, whatever.
Any time the kernel sends a packet out through your interface it will go into a queue and you'll be able to read it. Any time you write to the interface the kernel will process it as if it's a real packet that just arrived.
You will need to configure networking like it's a real interface. Set up a static route so that 192.172.0.0/16 (or whatever your subnet is) is reached through the tunnel interface. I'm not sure if Linux will let you do this without giving it an address; you might have to give it a dummy address like 192.172.255.254. Or a completely unrelated address like 1.2.3.4 and then let Linux think there's another router in front of your cellphone subnet. Or maybe it will just work without an address - not sure.
The difference between "tun" and "tap" is whether Ethernet processing happens or not (IP tunnel vs Ethernet tap). I expect tun is right for your application. If you choose tap then Linux will also use ARP and so on, and the interface will certainly need an address.
You might find it convenient to use the tunnel interface in both directions, or just one. IP packets aren't required to take the same route in both directions. This is the "correct" way to implement a tunnel, so you might find that a lot of mysterious bugs go away by using it.

Netcat only receiving first UDP packet from Scapy and 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)))

Python raw socket doesn't see outgoing data

I use the following code to create a raw socket : http://pastebin.com/pmg9iKgG
As you can see, i want :
all TCP received packet send from port 5555 of a server to my PC,
all TCP send packets from my PC to port 5555 of a server.
The problem is : i'm only able to see incoming packets, not outgoing packets. This is quite annoying for a sniffer...
Could you help me with this?
I'm using Anaconda as python distro (3.6, x64), on windows 10. wireless (intel) or ethernet (through USB adapter cause slim laptop).
I've search the internet and i haven't seen any problem like that. Moreover, MSDN says that it should work in both way (outgoing and incoming) : https://msdn.microsoft.com/en-us/library/windows/desktop/ms740548%28v=vs.85%29.aspx
One common use of raw sockets are troubleshooting applications that need to examine IP packets and headers in detail. For example, a raw socket can be used with the SIO_RCVALL IOCTL to enable a socket to receive all IPv4 or IPv6 packets passing through a network interface. For more information, see the SIO_RCVALL reference.
I would appreciate any help with this )))
Just on thing :
i bypass this line of code :
host = socket.gethostbyname(socket.gethostname())
by :
host = "192.168.0.29"
cause it's not the right value (but that's not the problem, moreover the methode socket.getfqdn() does the job, but i didn't updated my script)
EDIT : it was the windows FW that caused this strange behaviour, by deactivating some filter, i was able to see all incoming and outgoing packets.

udp socket stops receiving data

I am learning network programing in python and I'm trying to write a Toy vpn forked from android sdk https://github.com/android/platform_development/tree/master/samples/ToyVpn.
My Toy vpn is https://github.com/325862401/ToyVPN.
It's only for Linux.
My home network is behind NAT.
I can use this vpn to surf the internet after connect to remote sever.
But about half an hour or some time later the client udp socket stops receiving any data but the server can receive and send normally.
At this point I must terminate my client and run ToyVpnClient again.
It works normal for some time until it stop receiving again.
Please help me check the client logs.
>2013-08-24 11:42:38 INFO receive data from the tunnel timeout`
you can see that when problem happens, the socket always sends, not receive.
> means send, < means receive
I want to know why the udp socket stops receiving data.
Is there any debug method to find the cause?
For now I've just used logging to debug my program.
Since you're trying your client on the Internet, there is the whole universe of possible causes represented by all the Internet newtwork.
There's not a simple way of debugging here. Possible causes could be of course a software error but also some intermediate network configurations between you and the remote server.
You should capture the udp traffic using the good wireshark or the commandline tcpdump between you and the server and check if you're stopping sending packets or if the server is stopping receiving them.
If you send packets but your server doesn't receive them ( tcpdump on the server ) then there is something on the network which decides to filter your packets. And if it's not on the server (firewall rules to rate limit packets for example or something like that) then there's nothing you can do to that without modifying the logic of your program. Like changing UDP port every X seconds or using a persistent tcp connection.
A udp socket is not stable and may become null once a scanning or other event occupy your network interface for a while (especially true on Android). Using tcp avoids this problem. If you wants to maintain a stable udp, keep monitoring the status of your udp socket; if it becomes null or any unusual things happens, delete this socket and create a new one. Put this reactivating staff in a loop so that your udp socket is always alive.

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