Saturday, April 25, 2015

To Frag or Not To Frag, That's Hardly A Question

In the beginning, for there certainly was once a beginning, the gods created the Arpanet and saw that it was good. Skip ahead several years and they further begat TCP, then IP, then UDP and so on and so forth. Considering that they always had in mind the notion that data would be sent in small packages of a size that could be easily determined, they decided to call these packets. Because, sure, why not? However, not everything was called a packet. It all depended on where the chunking up took place as to what you called the end results. In the case of chunking at the Internet Protocol (IP) layer, the result was indeed called a packet. IP then needed to be able to handle this idea of packets and be able to put them back together again. This meant knowing the size and where they needed to be placed, much like putting a puzzle back together. If you try to simply jam all the little dangly bits into holes on other pieces, you ran the risk of having gaps in the resulting puzzle where the dangly bits didn’t cleanly go into holes. Not to mention, the resulting image probably just won’t look right.

Let’s say, for example, that you have this chunk of data that’s 100 bytes, as you can see in the figure below. Maybe it gets broken up into chunks of 20, 30 and 50 bytes each. For ease of reference, let’s call each A, B and C. If what you are sending starts with abcdefghijklmnopqrstuvwxyz, which is 26 bytes. Only 20 of them would fit into the first chunk of data, or packet. If I were to send that to my friend Allan, but if I were to send them in separate packets (maybe think of them as envelopes), he would need to know which to open first and how to arrange them. Because of that, it’s helpful to have some sort of identifier associated with them. This puts us back to A, B and C.

If I were to receive C first, followed by A then B, I would know, because I know my alphabet, that A comes first, then B, then C. One of the problems with fragmentation is that I can’t tell what’s really going on by looking at a single fragment. Maybe I catch the one that says uvwxyz. I don’t know what that means. I suppose it could be the tail end of the alphabet, but that’s just guessing. What really comes before or after? It’s this uncertainty that opens the door to some bad behaviors. The utility fragroute, written by Dug Song, allows us to establish some rules that can actually cause fragmentation of messages. In the IP world, we have an expression for the names A, B and C that we used above. There is a field in the IP header called the IP identification field that associates a lot of related messages together. From there, we have a second field called an offset that tells the receiving end where that particular part of the message slots in. You can see a sample IP header below showing the IP identification field (IPID) and the Fragment offset field. The receiving end needs both of these in order to pull the entire puzzle together with all the pieces in the right order.


Let’s say, though, that you were sitting in the middle looking at all of the puzzles that were going through and you needed to determine whether they were bad puzzles or not. Maybe, in the case of me mailing letters to my friend Allan, I have put a single sheet of paper into an envelope and sent them to him. Maybe out of order, maybe one a day at a time. The complete thing is the Anarchist’s Cookbook with bomb making recipes and so forth in it. Once he has it, he can do bad things. You might want to stop him, and if you knew Allan, that might be a really wise idea. You’d have to know that what he is getting is really bad. You’d need the entire collection of papers, potentially, before you could make a determination. If we are talking about a network device, though, you need all of the fragments before you can determine whether to send it on. If fragments come in out of order or delayed, that means the receiving application is going to be delayed and that’s often unacceptable. So, maybe if it’s fragmented, you just send the fragments along because you don’t have enough information to make a decision from each individual fragment. Rather than holding up the train, which may cause users to be upset, you just push everything through.

We can take advantage of this with fragroute. Using fragroute, we can grab messages from applications and fragment and otherwise mangle them before they get sent on their merry way. Let’s try this as a ruleset.

delay random 10

dup random 20

ip_frag 48

ip_ttl 3

print

You may be able to figure most of this out on your own but let’s step through just to be sure. The first line says to delay random messages by 10 milliseconds. The next line says to duplicate random messages with a 20 percent chance to perform the duplication. The next line is the one that we’ve been talking about. Fragment each message at 48 bytes. Finally, set the IP time to live field to be 3 and then print out what has happened.

Below is one of the frames (another way of talking about messages that have been broken up but this is each chunk of data that is seen on the wire) that results from running fragroute. You can see that the total length of the frame is 68 bytes. Out of that 68 bytes, 20 of them are just the IP header. The other 48 bytes are the actual data. Based on looking at the fragment offset, it looks as though each fragment was 48 bytes, just as we had set in the fragroute rules. The offset is a multiple of 48, indicating that this is the third fragment (0-47, 48-95).


You may notice that there is no indication here what the data indicates. Normally, you would have some indication of what protocol was being used. The problem is that we don’t have the TCP header in this fragment. You can see from the IP header that the next layer protocol is TCP but we don’t know what the protocol above that is. If you look at the very bottom of the Wireshark window above, you can see the actual data. This suggests a user agent from an HTTP request. But without the actual TCP header, we can’t determine for sure that it’s an HTTP request. Other requests can use a user agent and there is really nothing else to suggest that this is HTTP. We certainly don’t have a port number, because of the lack of TCP header.

You can see from this why fragmented packets is such a problem. We can pull it all together, of course. You can see the message in Wireshark that the entire message is reassembled in frame 3765. I can also follow the conversation by looking at frame 3765 and I find the following.


This is clearly an HTTP request. The section highlighted in red is the request that we were looking at a fragment from. The section highlighted in blue is the response. This doesn’t look at all like anything worth getting worried about. It’s just a standard HTTP request and response. But just from the fragment we saw, it was hard to say. In this case, the entire conversation was fractions of a second. We could easily have delayed the frames by quite a bit, which would have required a lot of hold up. This is why fragmentation attacks can be challenging when it comes to detection and certainly when it comes to prevention.