HackBlue

Tools · Wireshark · 11 / 30

The TCP handshake

Three frames open a connection: SYN, SYN-ACK, ACK. Relative sequence numbers make the first data byte look like 1.

13 min read · practice only with authorization

What each frame is for

A TCP connection in the lab file opens with three frames. The client sends SYN. The server sends SYN-ACK. The client sends ACK. After that, data may flow. A row that says SYN in the Info column is the start of an attempt, and an attempt is not yet a connection. The connection is the three-frame exchange, or a SYN that died.

Filter the client’s attempts with tcp.flags.syn == 1 && tcp.flags.ack == 0. Add the server’s replies with tcp.flags.syn == 1 && tcp.flags.ack == 1. The third frame is the ACK with the acknowledgment number advanced and the SYN bit clear. If you only have the first frame, you have a client that tried, and this capture point did not observe the rest.

Snippet
tcp.flags.syn == 1 && tcp.flags.ack == 0 && ip.addr == 10.8.0.20

Relative numbers and the options

Wireshark shows relative sequence numbers by default. The SYN displays as sequence 0, and the first data byte displays as 1. The raw initial sequence number is still in the frame, under tcp.seq_raw. Quote the relative number in a note only if you say it is relative. A second tool with relative numbers off will not print 0.

The SYN carries the options the stack is offering: MSS, window scale, and often SACK permitted. The scale factor is negotiated here. Wireshark applies it to the calculated window, tcp.window_size, for the rest of the connection. If the SYN is missing because the capture started late, that calculated window can be wrong. Say so before you compare window sizes.

Worked case: the lab client reached the web server

In the lab file, 10.8.0.40 sends a SYN to 10.8.0.20 port 443, frame 100. Frame 101 is the SYN-ACK. Frame 102 is the ACK. tcp.stream on those rows is 7. The Info column on frame 100 also shows the window and the MSS. You click the window scale option and read a shift of 7, which means later windows are multiplied by 128. You write “stream 7, handshake frames 100–102, scale 7.”

A second SYN to port 4443, frame 140, has no SYN-ACK before the client retransmits the SYN and then stops. That is a failed attempt observed at this capture point. You record the destination port and the number of SYNs. You do not record that the service is down. The capture-point lesson still applies: this interface did not observe a reply.

RST and FIN are different endings

tcp.flags.reset == 1 is an abort. A RST answering a SYN means something at that address refused the port, or a middlebox answered for it. A RST in the middle of a healthy stream is a different story and needs the frames around it. tcp.flags.fin == 1 is an orderly close, usually one side and then the other.

Statistics, then Flow Graph, drawn for TCP, is the picture of this exchange when the list is hard to read. Limit it to the display filter for the stream so the graph is the connection you mean. The graph is a view of the same frames.

Diagram

From a SYN to a stream you can name

  1. SYN

    The client’s first frame has SYN set and ACK clear.

    Attempts toward the server
    tcp.flags.syn == 1 && tcp.flags.ack == 0 && ip.dst == 10.8.0.20
  2. SYN-ACK

    The server answers with both SYN and ACK set, and its own initial sequence.

  3. ACK

    The client acknowledges. Data can follow. Note tcp.stream.

  4. Options

    Read the scale and MSS on the SYN. A missing SYN makes later windows uncertain.

Check yourself

1. Which filter shows TCP connection attempts, and not the SYN-ACK replies?

2. The first frame of a connection shows sequence number 0. What are you looking at?

3. A SYN appears three times and no SYN-ACK is in the file. What is the careful claim?