Subsuming the Linux packet processing stack - python

We occasionally have to debug glitchy Cisco routers that don't handle the TCP Selective Acknowledgment (SACK) options correctly. This causes our TCP sessions to die when routed through an IPTABLES port redirection rule.
To help with the diagnosis, I've been constructing a python-based utility to construct a sequence of packets that can reproduce this error at will, the implementation uses raw sockets to perform this trick. I've got an ICMP ping working nicely but I've run into a snag on the UDP implementation, I can construct, send and receive the packet without problem, the issue that I'm seeing is that Linux doesn't like the UDP packets being sent back from the remote system and always sends an ICMP Destination unreachable packet, even though my python script is able to receive and process the packet without any apparent problems.
My question: Is it possible to subsume the Linux UDP stack to bypass these ICMP error messages when working with RAW sockets?.
Thanks

Are you receiving and processing the packet and only need to suppress the ICMP port-unreachable? If so, maybe just add an entry to the iptables OUTPUT chain to drop it?

Related

Scapy TCP Handshake - Windows

While trying to perform a tcp TWH in scapy I encountered a problem.
When my host receives the syn/ack, the kernel ip/tcp stack aborts the handshake by sending rst.
It happens because the first packet sent (the syn) is transparent to the os due to the raw socket that scapy is using.
In some other questions regarding the same issue the solution was to set up iptables to drop packets with the rst flag.
Does anyone have a solution for windows?
(I prefer not to use the FW unless there is no choice)
Thanks!
That's a common problem, and it is not specific to Windows (or Scapy, for that matters - you can face similar issues with Masscan, for example).
You have totally understood and describe it: the problem lies in the IP address being "shared" between Scapy and your host's IP stack.
You have two options:
Use a firewall to prevent your host from getting the SYN/ACK packet (Scapy will get it anyway) or to prevent your host from sending a RST packet.
Use a different IP address with Scapy. This is a bit more difficult because it requires some kind of ARP proxy (or a Scapy script) to answer ARP request for the IP address you will use with Scapy.
Hope this helps, happy hacking!

How to capture the packets that you send in Scapy?

I am sending packets using:
send(IP(dst="192.168.1.114")/fuzz(UDP()/NTP(version=4)), loop=1)
But I am not able to capture these packets in any other nearby machine (including the one with IP 192.168.1.114) which is on the same network. I am using wlan as my interface.
I also tried to sniff and then replay using scapy but I am still not able to capture those packets.
i would first try to capture the traffic on the sender machine with tcpdump while executing your program:
tcpdump -i any udp dst 192.168.1.114
if you can see the traffic leaving the source host it may be that it does not arrive on the target host. UDP packets are the first packets to be dropped by any network device and as it is the nature of UDP it wont get retransmitted. if you are sure the packet leaves the source verify if it arrives at the target:
tcpdump -i any upd dst 192.168.1.114
Another point to check is your firewall settings. It could be either on the source or target system that your firewall is blocking those requests.
I finally resolved this. Here is the checklist I made which might help others when dealing with replaying/fuzzing using scapy.
Check if all IP addresses you are dealing with are alive in the
network (use ping)
Understand the difference between send() (layer 3)and sendp() (layer 2)
If mutating existing packet make sure to
remove the checksum (using 'del') and recalculate the checksum
either using show2() or using str to convert packets to string
and then converting them back to packets
You should use Wireshark, or the sniff function in Scapy and make it pretty print the contents on the screen:
sniff(lambda x:x.show())

Unwanted RST TCP packet with Scapy

In order to understand how TCP works, I tried to forge my own TCP SYN/SYN-ACK/ACK (based on the tutorial: http://www.thice.nl/creating-ack-get-packets-with-scapy/ ).
The problem is that whenever my computer recieve the SYN-ACK from the server, it generates a RST packet that stops the connection process.
I tried on a OS X Lion and on a Ubuntu 10.10 Maverick Meerkat, both reset the connection. I found this: http://lkml.indiana.edu/hypermail/linux/net/0404.2/0021.html, I don't know if it is the reason.
Does anyone could tell me what could be the reason? And how to avoid this problem?
Thank you.
The article you cited makes this pretty clear...
Since you are not completing the full TCP handshake your operating system might try to take control and can start sending RST (reset) packets, to avoid this we can use iptables:
iptables -A OUTPUT -p tcp --tcp-flags RST RST -s 192.168.1.20 -j DROP
Essentially, the problem is that scapy runs in user space, and the linux kernel will receive the SYN-ACK first. The kernel will send a RST because it won't have a socket open on the port number in question, before you have a chance to do anything with scapy.
The solution (as the blog mentions) is to firewall your kernel from sending a RST packet.
I don't have a non-iptables answer, but one can fix the reset issue. Instead of trying to filter the outgoing reset in the filter table, filter all of the incoming packets from the target in the raw table instead. This prevents the return packets from the target from even being processed by the kernel, though scapy still sees them. I used the following syntax:
iptables -t raw -A PREROUTING -p tcp --dport <source port I use for scapy traffic> -j DROP
This solution does force me to use the same source port for my traffic; feel free to use your own iptables-fu to identify your target's return packets.
The blog article cited in other answers is not entirely correct. It's not only that you aren't completing the three way handshake, it's that the kernel's IP stack has no idea that there's a connection happening. When it receives the SYN-ACK, it sends a RST-ACK because it's unexpected. Receiving first or last really doesn't enter into it. The stack receiving the SYN-ACK is the issue.
Using IPTables to drop outbound RST packets is a common and valid approach, but sometimes you need to send a RST from Scapy. A more involved but very workable approach is to go lower, generating and responding to ARP with a MAC that is different from the host's. This allows you to have the ability to send and receive anything without any interference from the host.
Clearly this is more effort. Personally, I only take this approach (as opposed to the RST dropping approach) when I actually need to send a RST myself.
I found a solution without IPTables in https://widu.tumblr.com/post/43624355124/suppressing-tcp-rst-on-raw-sockets .
To bypass this problem, simply create a standard TCP socket as a server socket and bind to the requested port. Don’t do accept().
Just socket(), bind() on the port and listen(). This relaxes the kernel and let you do the 3-way handshake.

Problem with asyn icmp ping

I'm writing service in python that async ping domains. So it must be able to ping many ip's at the same time. I wrote it on epoll ioloop, but have problem with packets loss.
When there are many simultaneous ICMP requests much part of replies on them didn't reach my servise. What may cause this situation and how i can make my service ping many hosts at the same time without packet loss?
Thanks)
A problem you might be having is due to the fact that ICMP is layer 3 of the OSI model and does not use a port for communication. In short, ICMP isn't really designed for this. The desired behavior is still possible but perhaps the IP Stack you are using is getting in the way and if this is on a Windows system then 100% sure this is your problem. I would fire up Wireshark to make sure you are actually getting incoming packets, if this is the case then I would use libpcap to track in ICMP replies. If the problem is with sending then you'll have to use raw sockets and build your own ICMP packets.

How do I send an ARP packet through python on windows without needing winpcap?

Is there any way to send ARP packet on Windows without the use of another library such as winpcap?
I have heard that Windows XP SP2 blocks raw ethernet sockets, but I have also heard that raw sockets are only blocked for administrators. Any clarification here?
There is no way to do that in the general case without the use of an external library.
If there are no requirements on what the packet should contain (i.e., if any ARP packet will do) then you can obviously send an ARP request if you're on an Ethernet network simply by trying to send something to any IP on your own subnet (ensuring beforehand that the destination IP is not in the ARP cache by running an external arp -d tar.get.ip.address command), but this will probably not be what you want.
For more information about raw socket support see the TCP/IP Raw Sockets Docs page, specifically the Limitations on Raw Sockets section.
You could use the OpenVPN tap to send arbitrary packets as if you where using raw sockets.

Categories