Ok, I realize this situation is somewhat unusual, but I need to establish a TCP connection (the 3-way handshake) using only raw sockets (in C, in linux) -- i.e. I need to construct the IP headers and TCP headers myself. I'm writing a server (so I have to first respond to the incoming SYN packet), and for whatever reason I can't seem to get it right. Yes, I realize that a SOCK_STREAM will handle this for me, but for reasons I don't want to go into that isn't an option.
The tutorials I've found online on using raw sockets all describe how to build a SYN flooder, but this is somewhat easier than actually establishing a TCP connection, since you don't have to construct a response based on the original packet. I've gotten the SYN flooder examples working, and I can read the incoming SYN packet just fine from the raw socket, but I'm still having trouble creating a valid SYN/ACK response to an incoming SYN from the client.
So, does anyone know a good tutorial on using raw sockets that goes beyond creating a SYN flooder, or does anyone have some code that could do this (using SOCK_RAW, and not SOCK_STREAM)? I would be very grateful.
MarkR is absolutely right -- the problem is that the kernel is sending reset packets in response to the initial packet because it thinks the port is closed. The kernel is beating me to the response and the connection dies. I was using tcpdump to monitor the connection already -- I should have been more observant and noticed that there were TWO replies one of which was a reset that was screwing things up, as well as the response my program created. D'OH!
The solution that seems to work best is to use an iptables rule, as suggested by MarkR, to block the outbound packets. However, there's an easier way to do it than using the mark option, as suggested. I just match whether the reset TCP flag is set. During the course of a normal connection this is unlikely to be needed, and it doesn't really matter to my application if I block all outbound reset packets from the port being used. This effectively blocks the kernel's unwanted response, but not my own packets. If the port my program is listening on is 9999 then the iptables rule looks like this:
iptables -t filter -I OUTPUT -p tcp --sport 9999 --tcp-flags RST RST -j DROP
You want to implement part of a TCP stack in userspace... this is ok, some other apps do this.
One problem you will come across is that the kernel will be sending out (generally negative, unhelpful) replies to incoming packets. This is going to screw up any communication you attempt to initiate.
One way to avoid this is to use an IP address and interface that the kernel does not have its own IP stack using- which is fine but you will need to deal with link-layer stuff (specifically, arp) yourself. That would require a socket lower than IPPROTO_IP, SOCK_RAW - you need a packet socket (I think).
It may also be possible to block the kernel's responses using an iptables rule- but I rather suspect that the rules will apply to your own packets as well somehow, unless you can manage to get them treated differently (perhaps applying a netfilter "mark" to your own packets?)
Read the man pages
socket(7)
ip(7)
packet(7)
Which explain about various options and ioctls which apply to types of sockets.
Of course you'll need a tool like Wireshark to inspect what's going on. You will need several machines to test this, I recommend using vmware (or similar) to reduce the amount of hardware required.
Sorry I can't recommend a specific tutorial.
Good luck.
I realise that this is an old thread, but here's a tutorial that goes beyond the normal SYN flooders: http://www.enderunix.org/docs/en/rawipspoof/
Hope it might be of help to someone.
I can't help you out on any tutorials.
But I can give you some advice on the tools that you could use to assist in debugging.
First off, as bmdhacks has suggested, get yourself a copy of wireshark (or tcpdump - but wireshark is easier to use). Capture a good handshake. Make sure that you save this.
Capture one of your handshakes that fails. Wireshark has quite good packet parsing and error checking, so if there's a straightforward error it will probably tell you.
Next, get yourself a copy of tcpreplay. This should also include a tool called "tcprewrite".
tcprewrite will allow you to split your previously saved capture files into two - one for each side of the handshake.
You can then use tcpreplay to play back one side of the handshake so you have a consistent set of packets to play with.
Then you use wireshark (again) to check your responses.
I don't have a tutorial, but I recently used Wireshark to good effect to debug some raw sockets programming I was doing. If you capture the packets you're sending, wireshark will do a good job of showing you if they're malformed or not. It's useful for comparing to a normal connection too.
There are structures for IP and TCP headers declared in netinet/ip.h & netinet/tcp.h respectively. You may want to look at the other headers in this directory for extra macros & stuff that may be of use.
You send a packet with the SYN flag set and a random sequence number (x). You should receive a SYN+ACK from the other side. This packet will have an acknowledgement number (y) that indicates the next sequence number the other side is expecting to receive as well as another sequence number (z). You send back an ACK packet that has sequence number x+1 and ack number z+1 to complete the connection.
You also need to make sure you calculate appropriate TCP/IP checksums & fill out the remainder of the header for the packets you send. Also, don't forget about things like host & network byte order.
TCP is defined in RFC 793, available here: http://www.faqs.org/rfcs/rfc793.html
Depending on what you're trying to do it may be easier to get existing software to handle the TCP handshaking for you.
One open source IP stack is lwIP (http://savannah.nongnu.org/projects/lwip/) which provides a full tcp/ip stack. It is very possible to get it running in user mode using either SOCK_RAW or pcap.
if you are using raw sockets, if you send using different source mac address to the actual one, linux will ignore the response packet and not send an rst.
I want to build a program in Python, using Scapy to count how many times SYN packet is received.
How do I find only the first SYN received in the 3-way handshake?
You can check the flag manually. Take a look at this link. The flag as 0x02 is what you want.
I want to send a packet with scapy to another interface.
I have the wlan2 interface and i want my packet (that i generate) to be send there.
I've tried using send with iface but it has no effect.
I also tried using srp and just sendp but i am getting this strange result:
answer = srp(pkt[Ether]/ip/new_pkt/html1, iface="wlan2")
pkt[Ether] is a valid pkt that comes from the wlan2 interface and i can sniff it.
i am trying to generate an http response packet using its Ethernet layer.
But my response is always going to another interface and i think this is the problem.
Wireshark Ethernet II
The packets are grey...
The question is how to fix this? how do i send a legit packet to the wlan2 interface.
I am currently working on a project where I need to send packets to a particular networking hardware, receive responses back, and generate packets based on the response in real time.
I came across Scapy, and to my understanding it is capable of doing the first two parts: sending and receiving. Is it possible through Python to retrieve the necessary fields in a response and respond back?
Thanks!
If I understand what you mean, you have (at least) two options with Scapy:
The clean one is to create an AnsweringMachine that matches your needs (you have several examples in Scapy's code).
The dirty (but maybe quicker if that's what you need) one is to give as prn parameter to sniff() a function that will receive the packet, craft an answer (or anything you like) and send() it on the network.
As an example, this code will send RST-ACK packets to any TCP packet seen with SYN flag on:
def rst(p):
ans = IP(src=p[IP].dst, dst=p[IP].src)/TCP(
flags='RA',
sport=p[TCP].dport,
dport=p[TCP].sport,
seq = 0,
ack = p[TCP].seq + 1,
)
send(ans, verbose=False)
return "%s\n => %s" % (p[IP].summary(), ans.summary())
sniff(iface="eth0", filter="tcp and tcp[tcpflags] & tcp-syn == tcp-syn",
prn=rst)
In order to perform a HTTP GET, I need to send a packet (the GET / HTTP/1.0\n\n) and wait for 3 packets:
The ACK of my GET
The GET answer: HTTP/1.0 200 OK
and the FIN ACK of the transmission
I found 2 ways:
=> use sr() with multi option
=> use sniff just after sending my GET request
For sr() function, the problem is to stop the sniffing, the only option is to set a timeout, but my script will test many different sites, so many different of time's answer, it could be hard to choose a static timeout value where I'm sure that no site exceed it anytime.
For sniff, there is no the same problem because I can set "count" argument to take only the 3 packets. But it's hard to make a filter good enough to be sure the 3 packets recorded are the 3 that I want (and no ARP, DNS or anything else).
But the main problem is sometimes the fist answer packet come before "sniff" is launched (between send(GET_PACKET) and answers=sniff(...)). In this case, I lost some information and all my post-treatment is corrupted.
The perfect way would be to use sr() function with "count=3" option to only get 3 packets, but that option doesn't exist with sr().
Anynone have an idea?
Thanks a lot
Sorry for my language, I'm French
Use Sniff and set the filter to TCP port 80
and for delay problem you can use a thread, first start your sniffer in thread then send the packets :
def sniffer():
packets=sniff(filter="tcp port 80" , count=5)
wrcap("test.cap" , packets) #save packets in .cap file
t = threading.Thread(target=sniffer)
t.start()
But you can use a better way that explained HERE. send your packets manually.
This is more of a hint than an answer, but the problem might be that you want to inspect transport layer packets for a application layer request. You could split up your HTTP GET down to transport layer by sending SYN, waiting for and answer and then send ACK, GET. Here is a link describing what you might want.