TCP Portals: The Handshake's a Lie! — Breakin...

来源:百度文库 编辑:神马文学网 时间:2024/05/01 09:16:47

Whenever I interview someone for an Application Engineer or Security Research position, my favorite introductory question is, "Can you describe for me the TCP three-way handshake?". It is a fine baseline question to understand a candidate's knowledge of modern networking. Answers range from "SYN, SYN/ACK, ACK,", to a full description of ARP, to initial sequence number generation. It's a good springboard question, because then you can start talking about spoofing addresses, port scanning, the significance of IPIDs, and more.

We are hiring a lot here at BreakingPoint, which means I'm asking this question a lot. After the fourth or fifth interview, I decided one morning to look over RFC 793 to make sure that I really did know everything there is to know about the handshake. That is when I found out that we've all been living a lie.

If you've spent any reasonable amount of time around network protocols, you're probably familiar with some version of this diagram:

Here, we see the client on the left starting up a conversation with the server on the right. All pretty normal and familar, right? Well, when I was reviewing the RFC again, I noticed something very, very, odd. Disturbing, even. Allow me to quote at some length:

  The synchronization requires each side to send its own initialsequence number and to receive a confirmation of it in acknowledgmentfrom the other side.  Each side must also receive the other side'sinitial sequence number and send a confirming acknowledgment.1) A --> B  SYN my sequence number is X2) A <-- B  ACK your sequence number is X3) A <-- B  SYN my sequence number is Y4) A --> B  ACK your sequence number is YBecause steps 2 and 3 can be combined in a single message this iscalled the three-way (or three message) handshake.

Do you see what I see? Because I'm thinking, "this is not a three-way handshake. This is a four-way handshake." The handshake is a lie, born of coalescing steps 2 and 3.

Now, surely, if I just decided to ACK a SYN, then send my own SYN, that couldn't possibly work, right? Enter PacketFu, my little Ruby library for crafting packets. Turns out, 28 years or so after this RFC was written, clients behave rather strangely when you decide to actually honor ol' RFC 793. After some experimentation, I have a pretty decent proof-of-concept stack that behaves like so:

This is the point where things get a little weird. What's happening here is:

    1) A --> B  SYN my sequence number is X2) That's nice. I'm not going to bother to ack that, because...3) A <-- B  SYN my sequence number is Y.4) A --> B  ACK your sequence number is Y, and my sequence number is X.5) A <-- B ACK your sequence number is X

Does this work? You betcha! Take a look at the packet captures, collected from Linux (stock Ubuntu), Apple (stock OSX), and Microsoft (stock Windows XP). These three desktop operating systems are all totally cool with this crazy backwards TCP portal.

But what does it mean? Is this simply a parlor trick, where you can reverse the roles of client and server? How does this affect stateful firewalls? How about inspection devices like IPSes, which often need to have an idea of who the "real" client and server are? How about NAT devices, where the idea of "relatedness" is absolutely tied up with where SYN packets come from.

Clearly, there is a ton of testing work to be done here. Lucky for me, I happen to work at a really advanced testing equipment manufacturer, so I've dropped this nugget in the next StrikePack. Now, strikes can employ the "SneakAckHandshake" TCP override option, and all servers simulated will behave in accordance with this crazy backwards handshake. We'll see how well network inspection gear detects clientside attacks when the client is tricked into behaving like a server.

At the very least, now I have better interview questions and I should at least be able to detect if the next candidate is reading this blog. :)

 

Posted by Tod Beardsley (2009/11/11)22 comments | Tags: ShareThis

Holy hell.

张贴人: Davenull 于 2009-11-11 04:04 Thats freaking odd man... I wouldnt think that that should work that way... Kinda makes for some interesting thoughts, I will keep looking for any updates you put here ;)

RFC 793 supports 3-way and 4-way handshake

张贴人: Robert 于 2009-11-11 05:16 Page 29 last paragraph of rfc 793 states

"The three-way handshake
reduces the possibility of false connections. It is the implementation of a trade-off between memory and messages to provide
information for this checking.

The simplest three-way handshake is shown in figure 7 below.

TCP A TCP B

1. CLOSED LISTEN

2. SYN-SENT --> --> SYN-RECEIVED

3. ESTABLISHED <-- <-- SYN-RECEIVED

4. ESTABLISHED --> --> ESTABLISHED

5. ESTABLISHED --> --> ESTABLISHED

Basic 3-Way Handshake for Connection Synchronization

Three shalt be the number thou shalt count, and the number of the counting shalt be three.

张贴人: Tod Beardsley 于 2009-11-11 07:33 Thanks for the quotation, Robert.

The surprising thing, at least to me, is that I presumed that the "three-way" in "three-way handshake" requires exactly three packets. This is clearly not the case.

The fact that TCP B can optionally choose to ACK TCP A's SYN introduces some ambiguity that third-parties might trip up on when they're watching for TCP session establishment.

There's already an ambiguity as far as firewalls are concerned; Microsoft Windows XP's stock firewall is fine with this setup, but Ubuntu's stock iptables is very much not cool with this (incoming non-synacks are dropped). So, which one is behaving correctly?

If three shall be we should update rfc 793

张贴人: Robert 于 2009-11-11 08:21 I too have wondered that. There definitely is a need for some clarifications.

Clarifications.

张贴人: Robert 于 2009-11-16 01:29 Of course we all know TCP is suppose to be a 3-way handshake.

I am not sure why the end of page 26 was included in the original rfc.

Quote:
" The synchronization requires each side to send it's own initial
sequence number and to receive a confirmation of it in acknowledgment
from the other side. Each side must also receive the other side's
initial sequence number and send a confirming acknowledgment.

1) A --> B SYN my sequence number is X
2) A <-- B ACK your sequence number is X
3) A <-- B SYN my sequence number is Y
4) A --> B ACK your sequence number is Y

[Page 27]

September 1981
Transmission Control Protocol
Functional Specification

Because steps 2 and 3 can be combined in a single message this is
called the three way (or three message) handshake."

The only thing I can assume is that some vendors have adopted this even though it clearly states in the philosophical and technical areas of rfc 793 that lines that steps 2 and 3 can be combined. Which as you say would makes it look like a 4-way handshake.

This would lead me to think either; 1)Vendors did not fully or still do not read the rfc hence some of these things were/are included.
2)The rfc should not have included that example.
3)maybe tcp also supported a 4-way handshake. Who know I did not have discussions with DOD and researchers when the original rfc was created.

The most logical answer 28 years deserves a rewrite.

Some very cool work

张贴人: Chris Brenton 于 2009-11-11 11:10 Actually, this makes sense if you follow the RFC. Its not that you can't use more than three packets, its just that three is the minimum required.

For example once you reach established state we ACK and send data in the same packet. Nothing in the spec says you can't use two packets instead, its just not as efficient.

Re on firewalls:
Depends on the product. Some monitor flag state and some do not. Based on my testing Cisco would block this but CP and Netscreen would let it though.

As for which is correct, XP or Netfilter, the RFC does not say you "must" use four packets, so the XP operation is probably more correct. Its for the wrong reason however because the XP firewall is not watching flag state. You could just as easily generate a state entry with an ACK.

RE on IDS/IPS:
I have two different vendor products here in the lab and results are not good.

Another interesting point is that Wireshark tags Packet #4 as a dup ACK even though it is not.

Great work!
Chris

hmm

张贴人: Michael B 于 2009-11-16 01:29 "There's already an ambiguity as far as firewalls are concerned; Microsoft Windows XP's stock firewall is fine with this setup, but Ubuntu's stock iptables is very much not cool with this (incoming non-synacks are dropped). So, which one is behaving correctly?"

is this a problem? isn't resend/'un-ack-ed things don't exist' way of things going to fix it? establishing the connection might take considerably longer then normal.

I suppose I'll say this since noone else has.

张贴人: Cody Tubbs (loophole) 于 2009-11-11 07:33 In your method you can actually and totally ignore your step 1. If you follow the rest of your steps, you are following a "standard" 3-way handshake. The only difference is that YOU are attempting to initiate the connection via your first SYN packet that contains your seq #. If side B does stateful packet inspection (meaning it knows and tracks when a full handshake has occured), you will get blocked being that you are sending a wild SYN that was not expected (it just so happens that in your case it's immediately after host A tried initiating a connection with you)... what are the odds? :)

SYN_SENT and LISTENING states

张贴人: Tod Beardsley 于 2009-11-11 07:43 Right.

But the punchline is, client OS'es are fine with responding to "wild" syns on their ephemeral ports, provided they're in the SYN_SENT state. In other words, you can set up a session with a port that technically was never in LISTENING.

ephemeral port<->ephemeral port establishment.

张贴人: Cody Tubbs (loophole) 于 2009-11-11 08:21 With that said, the only odd thing I see occuring by doing this is the connection is established between BOTH ephemeral ports. Side A would have established the connection
on its ephemeral port by nature.

DoS

张贴人: Ricky Lawshae 于 2009-11-11 05:32 So, if I made a client that reacted the same way your server does to a SYN (ignore and SYN), then tried to connect to your server, would we just keep SYN'ing each other back and forth indefinitely?

Infinite SYN Loops

张贴人: Tod Beardsley 于 2009-11-11 07:33 If your client cared naught for state, probably.

The way to make it work is to ensure that your listening side moves along the state path like:

LISTEN -> SYN_RECV -> SYN_SENT -> SYN_RECV -> ESTABLISHED

..while the sending side follows the path of:

CLOSED -> SYN_SENT -> SYN_RECV -> SYN_SENT -> ESTABLISHED

It would all be predicated on where you start the state process.

cool

张贴人: Egeste 于 2009-11-11 05:32 Cool work

Just simultaneous open

张贴人: mhp 于 2009-11-11 07:42 This is simply the result of allowing simultaneous open to work (see fig 8 of RFC793). Personally, I am not convinced that allowing simultaneous open was a good decision, given the scope for confusion.

For bonus points you can work out why simultaneous open doesn't work for TLS connections, despite being ok for the underlying TCP stream.

TCP Simultaneous Open

张贴人: james woodyatt 于 2009-11-11 10:52 TCP Simultaneous Open gets a lot of treatment in RFC 5382 because there are a lot of stupid middleboxes implemented by people who didn't read RFC 793 very carefully. It remains to be seen whether anyone will read RFC 5382.

A few issues at work

张贴人: Chris Adams 于 2009-11-11 10:20 It seems like there are a few things going on here. First, a flawed simultaneous open implementation whereby the client goes to SYN_RCVD instead of sending RST. Second, client TCP stacks aren't properly implementing non-piggybacked SYN/ACKs. Third, stateful firewalls don't recognize non-piggybacked SYN/ACKs are related.

http://www.brainonfire.net/

张贴人: Tim McCormack 于 2009-11-11 11:07 In your second TCP exchange, the 5th line has A and B reversed, which tripped me up when I was trying to read it.

Flipped and reversed

张贴人: Tod Beardsley 于 2009-11-11 11:33 Thanks Tim -- Fixed (5) so it reads more sensibly.

Interview Questions ...

张贴人: nick.zoic.org 于 2009-11-12 01:34 Very amusing. I got this one "wrong" on a El Goog phone screen :-).

-----N

duh!

张贴人: danstermeister 于 2009-11-12 01:34 I thought everyone knew that!

Just kidding, that's definitely an eye-opener. And the impact on security device identification of client and server definitely seems like a valid concern. But are those roles decided by the last step in the handshake process, or by the first?

This opens up a world of possibilities...

张贴人: Clint 于 2009-11-12 05:17 It's somewhat surprising that equipment will work with this, but I guess it's understandable since the stack is meant to be robust.

But this is very disturbing. Even if high-end traffic monitoring hardware and software is updated to maintain the correct view of who initiated a connection, there will ALWAYS be cheap, poorly implemented technology out there in use, and unless this issue becomes more well known I think it'll be taken advantage of.

An excellent find.

ipfw

张贴人: per 于 2009-11-16 01:29 Using ipfw (stock Mac OS X) we could drop established connections that don't have a dynamic rule:

ipfw -q add check-state

ipfw -q add deny log tcp from any to any established

See: http://codesnippets.joyent.com/posts/show/1267

BreakingPoint testing tools accelerate the development of next-generation content-aware network devices by focusing on application, performance and security testing.

legal | privacy | sitemap

Testing Tools
BreakingPoint Elite
Application Library
Custom Application Toolkit
Custom Strike Toolkit
Service and Support Testing Resources
Testing Methodologies
How-to Guides
White Papers
Data Sheets
Screencasts Testing Community
BreakingPoint Labs Blog
The Test Insider Newsletter
Follow Us on Twitter
BreakingPoint RSS Feed Testing Solutions
DPI Testing
Firewall Testing
IPS Testing
Security Equipment Testing
Server Load Testing

? 2005-2009 BreakingPoint Systems, Inc. All rights reserved. The BreakingPoint logo is a trademark of BreakingPoint Systems, Inc.
All other trademarks are the property of their respective owners.