ssn->flags &=~ STREAMTCP_FLAG_4WHS;
}
+/** \internal
+ * \brief detect timestamp anomalies when processing responses to the
+ * SYN packet.
+ * \retval true packet is ok
+ * \retval false packet is bad
+ */
+static inline bool StateSynSentValidateTimestamp(TcpSession *ssn, Packet *p)
+{
+ /* we only care about evil server here, so skip TS packets */
+ if (PKT_IS_TOSERVER(p) || !(TCP_HAS_TS(p))) {
+ return true;
+ }
+
+ TcpStream *receiver_stream = &ssn->client;
+ uint32_t ts_echo = TCP_GET_TSECR(p);
+ if ((receiver_stream->flags & STREAMTCP_STREAM_FLAG_TIMESTAMP) != 0) {
+ if (receiver_stream->last_ts != 0 && ts_echo != 0 &&
+ ts_echo != receiver_stream->last_ts)
+ {
+ SCLogDebug("ssn %p: BAD TSECR echo %u recv %u", ssn,
+ ts_echo, receiver_stream->last_ts);
+ return false;
+ }
+ } else {
+ if (receiver_stream->last_ts == 0 && ts_echo != 0) {
+ SCLogDebug("ssn %p: BAD TSECR echo %u recv %u", ssn,
+ ts_echo, receiver_stream->last_ts);
+ return false;
+ }
+ }
+ return true;
+}
+
/**
* \brief Function to handle the TCP_SYN_SENT state. The function handles
* SYN, SYN/ACK, RST packets and correspondingly changes the connection
SCLogDebug("ssn %p: pkt received: %s", ssn, PKT_IS_TOCLIENT(p) ?
"toclient":"toserver");
+ /* check for bad responses */
+ if (StateSynSentValidateTimestamp(ssn, p) == false)
+ return -1;
+
/* RST */
if (p->tcph->th_flags & TH_RST) {
if (!StreamTcpValidateRst(ssn, p))