May 27th, 2004, 11:49 PM
TCP Flags: Their use and abuse.
Having read a recent post where a new network admin, recently graduated from college, stated something that I have known for a long time, (college degrees in Computer Science etc. rarely teach the students anything useful), was asking questions that led to a discussion of SYN, SYN/ACK and ACK I thought it would be useful to try to put the issue into "English" for others.
This is by no means a TCP/IP Primer or anything so complex, the subject is simply too broad. I intend to try to explain what the flags are for, how they are used and, with knowledge of how they are used some ways they can be abused. It isn't going to be exhaustive but it will, hopefully provide food for thought.
Note: While the title may contain the word "abuse" in some ways it isn't really abuse, it's more a knowledge of what the flag does, what the response is supposed to be and the subsequent use of that knowledge to use the protocol against itself or a given vendor's implementation of the protocol in their product.
The authority for this tutorial is RFC 793, Transmission Control Protocol, found here. I would suggest this is required reading. The RFC's are the "bible" if you will. If someone wants to write an operating system, (OS), or a service that interacts with a network over TCP/IP then they need to make sure that they comply with the RFC or it simply won't work with everything else. This RFC works hand in hand with the IP Protocol, RFC 791, found here, hence the common nomenclature TCP/IP. The IP Protocol does contain flags but they are not to be confused with those in the TCP protocol insofar as they only refer to the fragmentation state of the packets being sent/received.
The flags themselves indicate "connection status". Since TCP is a stateful and reliable protocol it is imperative that we know the purpose of each packet. This is what the flags are for, to designate what kind of packet, and therefore the connection state, we are looking at. The flags themselves are contained in a single byte in the packet with each bit having a specific meaning and task. They are as follows:-
1 . CWR: Congestion Window Reduced
2 . ECN: Echo
3 . URG: Urgent
4 . ACK: Acknowledge
5 . PSH: Push
6 . RST: Reset
7 . SYN: Synchronize
8 . FIN: Finish/End
For the purpose of this tutorial I will forget about flags 1-3. They are available but not commonly seen in "normal" transmissions and tend not to be commonly used in abuse situations. That leaves us with 4-8 that are commonly seen in transmissions and are regularly "abused".
The "normal" connection
A normal connection begins with the "three way handshake". It's a lot like a phone call... You dial the number, (the initial connection, (SYN)), the recipient picks up the phone, ("hello", (SYN/ACK)), and you respond "Hi there, this is Bill", (ACK). From there you two talk,, (lot's of ACK's). At the end of the conversation one of you says "well, I gotta go", (FIN), and the other person says, "ok, see you, bye, (FIN/ACK), you say "Bye", (ACK), and the conversation closes by you both putting the phone down. In between there are a bunch of ACK/PSH and ACK's as you two chat. Each part of the conversation is broken down into sentences if you will. As the two of you transfer "data" those sentences are passed back and forth with those ACK/PSH and ACK flags set... It's similar military radio procedure..... I say "X, over", you say "Y, over", I say "Z, over", etc. etc. till someone says "out". Conversation closed.
NOTE: The PSH packet is really saying that some fancy, and somewhat "pushy", higher application want's this data "right now".... Kinda like your boss that comes to you at 5:30 and tells you he needs the entire years firewall logs analyzed and reported for his secretary's IP address by 8:00am tomorrow....
Per the RFC there are certain things that must occur when packets with certain flags set are received. For example if a SYN flag is set in a received packet to a port that is hosting a service, (open) then a SYN/ACK must be returned and the sender of the SYN/ACK _expects_ an ACK in return to finalize the connection. To a closed port the response should be RST. But, for example, a firewall should not respond..... Well, there's a "hole".... I can tell when ports are firewalled if I don't get my expected RST because I don't receive it from a computer I know to be "up" because it has responded in any way to a request to a different port.
So, Can this be "abused"? Of course.....
Since certain things, by the RFC, require certain responses/actions we can "play" with them. The RFC requires that if you receive a SYN packet to an open port you must open a Transmission Control Block, (the thing that tracks the "conversation"). So if I send you a SYN, you have to open a TCB, if I send you 2 SYN's you have to open 2 TCB's.... 100 SYN's = 100 TCB's - If you don't do it then you limit your ability to receive/manage connections from the 'world".
So, Let me "mess with" the SYN packet.... Please....
I have a few choices.... I can:-
1. Keep sending you SYN packets to your open port(s), (SYN flag set), your OS has to set aside a TCB for each connection.... Well... If I send you enough of them with or without sending the required ACK your system will be "flooded" with connections that require memory to maintain the information.... Eventually, I will slow down or drop your system by filling the system with bogus SYN requests that require resources to maintain. It's called a SYN Flood and is a form of Denial of Service attack, (D0S). If I use a lot of machines to do this it's a form of Distributed Denial of Service attack , (DDoS).
2. Or I can send you a single SYN let you respond and send an RST. It's called a half open or stealth connection. I would use it to determine your OS. Different OS's implement the TCP protocol slightly differently. They may respond correctly but they may set other parameters in the packet in a certain way that differs from other OS's. If they do then the subsequent response may tell me about your OS yet show no completed connection... So your logs might not show a connection... they may show nothing.... But that would be a bad..... and most modern logging systems aside from the service logging itself will log SYN packets thus showing this scan.
3. I can "spoof" my IP address.... If I send you a SYN you will reply to the source address with a SYN/ACK on an open port. So I tell you Bill is trying to contact you, But I'm Joe.... You respond to Bill because that's who you think called you.... So you respond to Bill with a SYN/ACK... Ooops..... Poor Bill is getting these unrequested responses.... He must send a RST, (reset, because the connection wasn't for him in the first place)... Can we exploit that.... I think so... If we employ enough machines to keep sending him "odd" connections he has to respond... That's a Relfected Distributed Denial of Service attack, (RDDoS).
4. I can spoof my IP to a machine I control and send you a SYN. Again, you will respond with a SYN/ACK to the machine I control. I can sniff the packets coming inbound from your IP and determine what ports you have open and make an OS guess too. Some people refer to this as a blind scan. I can take it further and not even have control of the machine. If I _know_ the machine is idle then I can send a SYN with the IP spoofed to the idle machine. The target will send a SYN/ACK to the idle machine if the port is open or a RST if it is closed. If the port is firewalled nothing should be sent. I can then send a SYN to a port I know to be open on the idle machine. By looking at the sequence number in the TCP packet I can see if it incremented between my last attempt and this one. If it did then the target machine sent a SYN/ACK. How do I know? Because the RFC states that an unsolicited SYN/ACK should be responded to with an RST but an RST should not be replied to. So if the sequence number has incremented a SYN/ACK must have been sent. If the port is closed or firewalled then either an RST or nothing was sent thus the sequence number wouldn't need to be incremented.
Thats a few ways we can "abuse" the SYN flag... We can go to the other end of the conversation and cause some problems too.
The FIN Flag
Let's take a look at the FIN flag. This flag is the flag that tells the remote machine that the conversation is over, similar to the word "out" in a radio conversation, (note, in true radio conversations you can't say "over and out" like they do in the movies..... It's a contradiction. In TCP flag terms it's the equivalent of setting ACK, PSH and FIN in the same packet... You are saying "I have more important stuff for you, (ACK/PSH), but I'm closing the conversation, (FIN)". It just doesn't work.The proper response to a FIN flag during a conversation is a FIN/ACK, (you acknowledge that the conversation is closing) which is subsequently finalized with an ACK. The proper response to an unsolicited FIN packet is an RST to a closed port or no response to an open port. This is also a great example of how some vendors don't implement the RFC as written. Microsoft doesn't reply to unsolicited FIN packets on ports in any state, (open or closed). One would like to think it's because they had security in mind. I, for one, don't really think that is the case but the beneficial side of straying from the RFC in this case is that Microsoft products tend not to be vulnerable to FIN scanning because, since there is no response at all the attacker can't tell if the port is firewalled, open or closed.
The original purpose of the FIN scan was to evade firewalls. The early firewalls weren't stateful, (they didn't maintain a records of what conversations were actually taking place and what state they were in. Thus, if you sent a SYN to the firewalled machine that was on a port the firewall was told to block it would drop it, (send no response). But if you send a FIN, (or any other combination of flags), the firewall _had_ to let it pass because it was unaware of whether or not the packet was part of a valid conversation. Perfect, I can elicit a response from a machine firewalled by a non-stateful firewall regardless of the firewall. That's using the packet to abuse a firewall, but it's a valid use of the protocol against itself.
The ACK Flag
This Flag comes regularly in a normal conversation, (it the radio equivalent of "over"). It's use is to complete the "three way handshake", to imply that the conversation is continuing or that, after a FIN, FIN/ACK sequence that the conversation is now closed. Literally it means that I am using the acknowledgement number within the packet to indicate that the connection will remain ongoing. Like the FIN scan it is used primarily to determine whether there is a firewall and if it is stateful. The required response, per RFC's, to an unsolicited ACK packet on an open port is an RST. So, if the port is closed or there is a stateful firewall in place that simply drops the "out of state" packet. However, the RST will tell us that the port is not only open but that the firewall protecting the machine donesn't track the conversations, (isn't stateful).
The "Odd" combinations
Clearly there are some combinations of flags that are illogical.... FIN/PSH/URG = "I want to end the conversation, but there is a higher application that needs this data and there is urgent data in this packet". Well... What would you do with that? It's like me saying to you on the phone "I have to go now but what was it you were saying about the wife's mother 'cos she really wants to know". It's known as a Xmas scan. Open ports must drop the packet while closed ones have to send an RST. This functions well against stateless firewalls and, (I forget the reason....), it is very effective against Windows machines when fingerprinting the OS is the aim.
Another "odd" combination is no flags set at all..... Every packet, per the RFC has to have a flag of some kind... So what does it do when it doesn't find a flag at all? Well, an open port should be appropriately confused and not reply. A closed port is required to send a RST/ACK packet indicating that it is in response to a particular packet, (the ACK flag is set), but that it is resetting the connection, probably because it was invalid.
The possible permutations of "odd" flags is extensive. The RFC states what each _should_ be responded with but the different implementations of the TCP protocol by different vendors coupled with the other vagaries in the packet such as TTL, (Time To Live), etc. can allow a knowledgeable attacker to determine your OS/Firewall capabilities, (fingerprint), with the selected use of flags. In other circumstances he can deny you or someone else service.
All in all, the use of flags controls the conversation and gives appropriate information about the contents and future use each packet should be put to. However, as with any system that requires fixed, logical responses to given input the flag system can be 'subverted" to provide information that it really wasn't intended to. Remember, the TCP protocol was written to transmit data accurately and efficiently over a network. It was never intended to do it with security in mind, thus it has been "exploited".
If there are any questions you have they will almost certainly be answered by reading the appropriate parts of the RFC. However they can be a tad dry to read and require a reasonable understanding of packet structure etc. to understand so if you have questions that you can't find the answer to in the RFC then feel free to ask. I'll have a bash at answering them or, hopefully, someone who does understand will "pipe up" and help us both out.
Don\'t SYN us.... We\'ll SYN you.....
\"A nation that draws too broad a difference between its scholars and its warriors will have its thinking done by cowards, and its fighting done by fools.\" - Thucydides