Archive for November, 2009

Weekend Challenge

November 27th, 2009

Here’s another challenge to test your bit wienie skills:

Write a tcpdump or Windump filter that will capture all traffic with a source IPv6 address of 2001:db8::10 through 2001:db8::20. Pretty easy, right? If you have not tried it, your going to find that tcpdump/Windump throws a few curves at you.

To check your work, here’s a capture file:

ipv6-icmp

The file contains a mix of source IPv6 addresses. Obviously your filter should only display the specified range of addresses.

The winner gets to inspire awe and admiration in lesser geeks.  ;)

I don’t know everything, and that’s OK

November 21st, 2009

Over the last few days I ran a challenge to see who could write a tcpdump/Windump filter to grab packets with the Window Scale option set. It was a bit of a brain twister. It was one of those problems that you start off thinking is easy, but then realize is very hard. You then start questioning if you are on the right track because it can’t possibly be as complex as it seems to be. I was specifically trying to push the envelope a bit on this one.

In the challenge I stated that folks should post their thoughts/answers in the comments section. Only one person was willing to do so, while everyone else contacted me via e-mail. At first I thought it was a privacy concern, but then I remembered that I let users pick any alias they want for a screen name. Folks had some really good ideas, but I think they were afraid to come across as too much of  a “newbie” in a public forum. I’ve seen the same thing in classroom settings where I will teach a topic, ask if there are questions, no one will raise their hand, but at the end of the day I have a line in front of my desk.

I hit a bit of a milestone this year in that I realized I’ve been in the industry for over 20 years. To give you an idea how long that is in Internet time, one of my first gigs was helping to convert a government contractor over from the “host file system” to this brand new technology called “Domain Name Services”. I remember when Gopher was the slickest kid on the block. Experienced first hand how AOL connecting to the Internet dramatically changed the landscape of computer security. I’ve worked with such greats as Robert Morris Sr. and Alan Paller. I’ve traded tip and tricks with thousands of the brightest minds via the SANS Institute. I’ve spent time consulting to The White House as well as a number of other government agencies.

And with all that said, I’m the first to admit that I by no means know everything. In fact, I fully recognize I still have far more to learn than I’ve already squirreled away in the little gray cells. Personally, I still run across stuff (like filtering for the WScale option) that I look at and say “How the heck have I missed that all these years?”.

One of the things the obsessive side of me loves about network security is that it is a bottomless pit. You can spend every waking moment reading blog/list posts, downloading tools, testing in the lab, and still not be able to wrap your brain around all of it. Network security is subtle and full of nuances. Everyone’s brain is wired differently, so some of these nuances are obvious, and others not so much. One of the cool things about sticking yourself out there is you get the benefit of other people’s brain chemistry. Clearly one of the biggest problems on the white hat side of the fence is that we do not exchange ideas/perspectives often enough. I think far too often ego holds us back.

Are there folks that think they know it all? Absolutely. Again, ego can be a tricky master. I’m reminded of those old t-shirts and posters that read: “Teenagers: Leave home while you still know everything!”. With network security, like most things in life, there is a barrier of enlightenment. On one side of the barrier, the pond seems small and you think you have a handle on it all. Once you break through however you recognize the vastness of the galaxy and just how far ahead that road still stretches.

So I’m proposing a 12 step geek program and I’ll be the first to climb on a soapbox and admit “I don’t know everything and I’m OK with that”. Part of the reason I gave Jeff second place is he came at the problem from a completely different approach and developed a solution I didn’t think of. In other words, by putting myself out there I received the benefit of his brain chemistry.

Like Jeff, everyone reading this draws on their own unique life experience and are fully capable of coming up with unique and innovative solutions as well. You’ll never know for sure however unless you check the ego gremlin and stick yourself out there.

</soapbox>

Chris

Oh where, oh where can WScale be?

November 20th, 2009

If this challenge seemed harder than it should be,you are on the right track. ;)

I ran across this problem when writing my Packet Decode tool. I have to say, it was a cool exercise for me, as I never really thought about creating tcpdump and Wireshark filters for every possible IP, TCP, UDP and ICMP field and/or value. By far the TCP options field is the most “broken” from a packet decode perspective than any other IP field.

First let’s talk about how the TCP options should have been implemented. If you look at the IPv4 options field, it begins with a “Type” identifier. If you are interested in a specific IP option, it is just a matter of checking this field for the right bit combination. Had the TCP options been implemented this way, this challenge would have been pretty straight forward.

Just about all TCP options have a “Kind” and a “Length” field, both of which are 1 byte in size. The exceptions are “End of Option List” and “No-Operation” which only have a Kind field, and thus are one byte in size. Here’s a list of the common TCP options:

tcp-options

Page 15 of RFC 793 tells us “The TCP header (even one including options) is an integral number of 32 bits long.” In other words, the TCP header size in bytes must be evenly divisible by four (20 bytes, 24 bytes, etc.). If you look at the list of TCP options, only “maximum segment size” is divisible by four. So the use of any other options are going to require padding.

How the padding should be applied is a bit unclear. If we look at page 26 of RFC 1323 we find this:

APPENDIX A:  IMPLEMENTATION SUGGESTIONS

   The following layouts are recommended for sending options on non-SYN
   segments, to achieve maximum feasible alignment of 32-bit and 64-bit
   machines.

       +--------+--------+--------+--------+
       |   NOP  |  NOP   |  TSopt |   10   |
       +--------+--------+--------+--------+
       |          TSval   timestamp        |
       +--------+--------+--------+--------+
       |          TSecr   timestamp        |
       +--------+--------+--------+--------+

Note the NOP padding appears before the timestamp option, not at the end like you might expect. Also note the RFC specifically says this is for “non-SYN segments” and that it is “recommended”, not required. Seems however that most operating systems follow this recommendation and always place padding before the Kind and Length bytes. I’ve checked Windows, Linux, Mac, various hardware, etc. and they all put the padding at the beginning.

So we can count on this being the “standard”, right? Not quite.  Page 17 of RFC 793 describes NOP this way:

        This option code may be used between options, for example, to
        align the beginning of a subsequent option on a word boundary.
        There is no guarantee that senders will use this option, so
        receivers must be prepared to process options even if they do
        not begin on a word boundary.

In other words, its not just that NOP may or may not show up at the beginning, NOP might not be used at all! It is entirely legal to layout the TCP option field with no NOP padding and just use End of Option List as filler at the end to achieve the proper boundary.

So what do we end up with for a filter? If we count on NOP before the option we end up with a filter that looks like this:

tcp[13]&2=2 and tcp[12]&240>80 and ((tcp[20]=1 and tcp[21:2]=0×0303) or (tcp[24]=1 and tcp[25:2]=0×0303) or (tcp[28]=1 and tcp[29:2]=0×0303) or (tcp[32]=1 and tcp[33:2]=0×0303) or (tcp[36]=1 and tcp[37:2]=0×0303) or (tcp[40]=1 and tcp[41:2]=0×0303) or (tcp[44]=1 and tcp[45:2]=0×0303) or (tcp[48]=1 and tcp[49:2]=0×0303) or (tcp[52]=1 and tcp[53:2]=0×0303) or (tcp[56]=1 and tcp[57:2]=0×0303))

To break down what this filter is doing:

  • Only check SYN & SYN/ACK packets:  tcp[13]&2=2
  • TCP header is greater than 20 bytes (options are set): tcp[12]&240>80
  • Check the first byte of each four byte boundary for NOP: tcp[20]=1, tcp[24=1, ...
  • Check the next two bytes to see if Kind=3 and Length=3: tcp[21:2]=0×0303, tcp[25:2]=0×0303, …

If however we want to ensure that we catch all possibilities in case a system does not implement NOP we end up with:

tcp[13]&2=2 and tcp[12]&240>80 and (tcp[20:2]=0×0303 or tcp[21:2]=0×0303 or tcp[22:2]=0×0303 or tcp[23:2]=0×0303 or tcp[24:2]=0×0303 or tcp[25:2]=0×0303 or tcp[26:2]=0×0303 or tcp[27:2]=0×0303 or tcp[28:2]=0×0303 or tcp[29:2]=0×0303 or tcp[30:2]=0×0303 or tcp[31:2]=0×0303 or tcp[32:2]=0×0303 or tcp[33:2]=0×0303 or tcp[34:2]=0×0303 or tcp[35:2]=0×0303 or tcp[36:2]=0×0303 or tcp[37:2]=0×0303 or tcp[38:2]=0×0303 or tcp[39:2]=0×0303 or tcp[40:2]=0×0303 or tcp[41:2]=0×0303 or tcp[42:2]=0×0303 or tcp[43:2]=0×0303 or tcp[44:2]=0×0303 or tcp[45:2]=0×0303 or tcp[46:2]=0×0303 or tcp[47:2]=0×0303 or tcp[48:2]=0×0303 or tcp[49:2]=0×0303 or tcp[50:2]=0×0303 or tcp[51:2]=0×0303 or tcp[52:2]=0×0303 or tcp[53:2]=0×0303 or tcp[54:2]=0×0303 or tcp[55:2]=0×0303 or tcp[56:2]=0×0303 or tcp[57:2]=0×0303 or tcp[58:2]=0×0303)

The difference with this filter is that we are checking Kind=3 and Length=3 all the way through the options field (as Elizabeth suggested).

Can either of these filters generate false positives? Absolutely! Two possibilities:

  1. The value of Timestamp may match the pattern we are looking for.
  2. The filter assumes a 40 byte option field. It could be less with these values in the payload.

So which filter should you use? The first will generate fewer false positives but miss systems that are RFC compliant but different from the norm. The second will always catch Window Scale if it has been set, but the chance of a false positive is higher.

I’m going to designate Elizabeth as the winner of the challenge. A few others were just as close but she was the only one with the guts to post her train of thought in the comments. I’m going to award a second prize to Jeff who came up with this solution partially kidding around:

tcpdump -nn | grep ‘wscale ‘ > wscale-matches.txt

This will not generate an actual packet capture, but you could do a:

tcpdump -nn -X -s 0 | grep ‘wscale ‘ > wscale-matches.txt

And then run the output through txt2cap to get it back into pcap format. He didn’t follow the challenge specifically, but you’ve gotta give kudos for thinking outside the box as this fixes all false positive issues. ;)

Elizabeth and Jeff, I’ll be contacting you both via e-mail. Congrats!

TCP Options – Final clue

November 19th, 2009

I’ve had one thread post and four e-mails that are soooooo close to the right answer. Here’s one last clue to hopefully get folks over the final hurdle.

I mentioned the helpful tshark command. Here’s the output:

C:\testing>tshark -n -r linux-syn.cap -T fields -e tcp.options
02:04:05:b4:04:02:08:0a:02:47:4a:a8:00:00:00:00:01:03:03:05

So what you have above is the TCP options section (byte 20 and higher) of the test packet. The Window Scale option is the last option in the list.

I know writing this filter is not easy. In fact that’s why I turned it into a challenge. It is possible however. ;)

TCP Options Challenge – clues

November 18th, 2009

Earlier I posted a challenge to write a tcpdump/Windump filter that would capture packets that have the TCP option “Window Scale” set. Some folks are close, but I wanted to post a few hints. Also, I have no problem with you e-mailing me directly, but to win the challenge you have to post the answer to the comments section. That way there is no question as to who found the answer first.

All TCP options are specified by a “Registry Kind” value (similar to the ICMP “Type” field). In the case of Window Scale, that value is 3. Also, all TCP options except for NOP contain a secondary field called “Length”. This defines how many bytes the options is using, including the “Registry Kind” byte. In the case of Window Scale the length value is always 3. So we have:

  • 1 byte for Registry Kind
  • 1 byte for Length
  • 1 byte for the actual WScale value

Hint 2: If you have never drilled into the TCP Options field, tshark has a cool option:

tshark -n -r capture-file.cap -T fields -e tcp.options

This will output the entire TCP options field in Hex so you can at least see what it looks like.

Final clue, I’ve posted a Linux SYN packet which sets WScale to 5 for you to use to check your filter.

linux-syn

Good luck!

Chris

TCP Options Challenge

November 18th, 2009

I’ve had a bit going on including the release of a new reference tool for the Apple iPhone and iPod. The tool is call Packet Decode and I’ve setup an alternate site to help maintain it.

I feel bad at neglecting this site over the last few weeks, so I’ve decided to throw out another challenge. The winner will receive a free copy of the above mentioned Packet Decode tool. OK, so you will not be able to retire on the proceeds, but hopefully the tool will make your life a bit easier. ;)

So here’s the challenge:

Write a tcpdump or Windump filter that will only capture packets that have the TCP “Window Scale” option set. All other TCP option settings can be ignored.

Pretty simple, eh? First person to post the answer in the comments section gets the prize.