Skip to content

Commit

Permalink
stream: handle extra different SYN/ACK
Browse files Browse the repository at this point in the history
Until now, when processing the TCP 3 way handshake (3whs), retransmissions
of SYN/ACKs are silently accepted, unless they are different somehow. If
the SEQ or ACK values are different they are considered wrong and events
are set. The stream events rules will match on this.

In some cases, this is wrong. If the client missed the SYN/ACK, the server
may send a different one with a different SEQ. This commit deals with this.

As it is impossible to predict which one the client will accept, each is
added to a list. Then on receiving the final ACK from the 3whs, the list
is checked and the state is updated according to the queued SYN/ACK.
  • Loading branch information
victorjulien committed Apr 8, 2013
1 parent b807874 commit 61315e9
Show file tree
Hide file tree
Showing 7 changed files with 582 additions and 19 deletions.
4 changes: 3 additions & 1 deletion rules/stream-events.rules
Expand Up @@ -10,6 +10,8 @@ alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYNACK resend
alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYNACK resend with different seq"; stream-event:3whs_synack_resend_with_diff_seq; sid:2210005; rev:1;)
alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYNACK to server on SYN recv"; stream-event:3whs_synack_toserver_on_syn_recv; sid:2210006; rev:1;)
alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYNACK with wrong ack"; stream-event:3whs_synack_with_wrong_ack; sid:2210007; rev:1;)
# Excessive SYN/ACKs within a session. Limit is set in stream engine, "stream.max-synack-queued".
alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake excessive different SYN/ACKs"; stream-event:3whs_synack_flood; sid:2210055; rev:1;)
alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYN resend different seq on SYN recv"; stream-event:3whs_syn_resend_diff_seq_on_syn_recv; sid:2210008; rev:1;)
alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYN to client on SYN recv"; stream-event:3whs_syn_toclient_on_syn_recv; sid:2210009; rev:1;)
alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake wrong seq wrong ack"; stream-event:3whs_wrong_seq_wrong_ack; sid:2210010; rev:1;)
Expand Down Expand Up @@ -77,5 +79,5 @@ alert tcp any any -> any any (msg:"SURICATA STREAM Packet is retransmission"; st
# rule to alert if a stream has excessive retransmissions
alert tcp any any -> any any (msg:"SURICATA STREAM excessive retransmissions"; flowbits:isnotset,tcp.retransmission.alerted; flowint:tcp.retransmission.count,>=,10; flowbits:set,tcp.retransmission.alerted; classtype:protocol-command-decode; sid:2210054; rev:1;)

# next sid 2210055
# next sid 2210056

1 change: 1 addition & 0 deletions src/decode-events.h
Expand Up @@ -144,6 +144,7 @@ enum {
STREAM_3WHS_SYNACK_RESEND_WITH_DIFF_SEQ,
STREAM_3WHS_SYNACK_TOSERVER_ON_SYN_RECV,
STREAM_3WHS_SYNACK_WITH_WRONG_ACK,
STREAM_3WHS_SYNACK_FLOOD,
STREAM_3WHS_SYN_RESEND_DIFF_SEQ_ON_SYN_RECV,
STREAM_3WHS_SYN_TOCLIENT_ON_SYN_RECV,
STREAM_3WHS_WRONG_SEQ_WRONG_ACK,
Expand Down
1 change: 1 addition & 0 deletions src/detect-engine-event.h
Expand Up @@ -133,6 +133,7 @@ struct DetectEngineEvents_ {
{ "stream.3whs_synack_resend_with_diff_seq", STREAM_3WHS_SYNACK_RESEND_WITH_DIFF_SEQ, },
{ "stream.3whs_synack_toserver_on_syn_recv", STREAM_3WHS_SYNACK_TOSERVER_ON_SYN_RECV, },
{ "stream.3whs_synack_with_wrong_ack", STREAM_3WHS_SYNACK_WITH_WRONG_ACK, },
{ "stream.3whs_synack_flood", STREAM_3WHS_SYNACK_FLOOD, },
{ "stream.3whs_syn_resend_diff_seq_on_syn_recv", STREAM_3WHS_SYN_RESEND_DIFF_SEQ_ON_SYN_RECV, },
{ "stream.3whs_syn_toclient_on_syn_recv", STREAM_3WHS_SYN_TOCLIENT_ON_SYN_RECV, },
{ "stream.3whs_wrong_seq_wrong_ack", STREAM_3WHS_WRONG_SEQ_WRONG_ACK, },
Expand Down
21 changes: 20 additions & 1 deletion src/stream-tcp-private.h
Expand Up @@ -26,6 +26,22 @@

#include "decode.h"

#define STREAMTCP_QUEUE_FLAG_TS 0x01
#define STREAMTCP_QUEUE_FLAG_WS 0x02
#define STREAMTCP_QUEUE_FLAG_SACK 0x04

/** currently only SYN/ACK */
typedef struct TcpStateQueue_ {
uint8_t flags;
uint8_t wscale;
uint16_t win;
uint32_t seq;
uint32_t ack;
uint32_t ts;
uint32_t pkt_ts;
struct TcpStateQueue_ *next;
} TcpStateQueue;

typedef struct StreamTcpSackRecord_ {
uint32_t le; /**< left edge, host order */
uint32_t re; /**< right edge, host order */
Expand Down Expand Up @@ -100,7 +116,7 @@ enum
/** Server supports wscale (even though it can be 0) */
#define STREAMTCP_FLAG_SERVER_WSCALE 0x0010

/** vacancy at 0x0008 */
/** vacancy at 0x0020 */

/** Flag to indicate that the session is handling asynchronous stream.*/
#define STREAMTCP_FLAG_ASYNC 0x0040
Expand Down Expand Up @@ -186,13 +202,16 @@ enum

typedef struct TcpSession_ {
uint8_t state;
uint8_t queue_len; /**< length of queue list below */
uint16_t flags;
TcpStream server;
TcpStream client;
struct StreamMsg_ *toserver_smsg_head; /**< list of stream msgs (for detection inspection) */
struct StreamMsg_ *toserver_smsg_tail; /**< list of stream msgs (for detection inspection) */
struct StreamMsg_ *toclient_smsg_head; /**< list of stream msgs (for detection inspection) */
struct StreamMsg_ *toclient_smsg_tail; /**< list of stream msgs (for detection inspection) */

TcpStateQueue *queue; /**< list of SYN/ACK candidates */
} TcpSession;

#endif /* __STREAM_TCP_PRIVATE_H__ */
Expand Down

0 comments on commit 61315e9

Please sign in to comment.