Event for syn-ack packet

Hi,

I want to identify hosts within our monitored network that reply to certain external IP addresses. The reply could be as short as a syn-ack. The event connection_established is too late as it doesn’t matter whether the connection was established. All that matters is whether any of our hosts replied to the external IP even if that means a single syn-ack packet. Do we have an event that could be used to capture this information?

Regards,

Are you trying to reduce your latency in detecting something? I guess I don't understand why connection_established is too late.

  .Seth

I want to identify hosts within our monitored network that reply to certain external IP addresses. The reply could be as short as a syn-ack. The event connection_established is too late as it doesn't matter whether the connection was established. All that matters is whether any of our hosts replied to the external IP even if that means a single syn-ack packet. Do we have an event that could be used to capture this information?

I think the main ways to get that information would be to inspect a connection record's "resp$state" or "history" fields to determine if a reply was made, and I'd say within a handler for "connection_state_remove" is a good place to do that if timing isn't critical. A non-zero value of "resp$state" (not TCP_INACTIVE or not UDP_INACTIVE) or any lower-case letter in "history" would mean there was a reply.

Part of the default set of scripts that get loaded, base/protocols/conn/main.bro, already does some interpretation of endpoint states (at the time of handling "connection_state_remove") and puts that in the "Conn::Info::conn_sate" field. Along with that, it also picks up the connection records "history" field and will log both. There's more description of the meaning of those fields in that script's comments or online at: http://www.bro-ids.org/documentation/scripts/base/protocols/conn/main.html

So a simple example you can try (relying on that default "conn" scripts):

@load base/protocols/conn

global bad_stuff: set[addr] = { 1.2.3.4, 5.6.7.8 }

event Conn::log_conn(rec: Conn::Info)
    {
    if ( rec$id$orig_h in bad_stuff && /[a-z]/ in rec$history )
        {
        # do something like raise a notice that will generate email, etc.
        }
    }

I have a list of C&C servers and i want to detect which hosts in our network talk to them. The first case is simple, check all outbound connections in which the destination is C&C IP. In the second case when a C&C server takes the initiative and tries to connect to an internal host. In some cases, it may not proceed to establishing a full connection. Hear the syn-ack and leave it at that. Come back later or maybe that’s it’s idea of ‘i am at your service’ messages. I need this event for the second case as the connection may never be established at all, at least for the time for which i have pcap trace.

To clarify, a SYN-ACK in response to a SYN is enough for Bro to generate
connection_established. It doesn't actually look for a full 3-way handshake
(i.e., an ACK of the SYN-ACK). Does that help? Alternatively, if you have
traces you can share that demonstrate a failure to get the
connection_established event, then we can look into just what's going on.

    Vern

Thanks. I thought the event connection_established was generated after the initial 3-way handshake is completed as mentioned here:

http://bro-ids.org/documentation/scripts/base/event.bif.html#id-connection_established

Thanks. I thought the event connection_established was generated after the
initial 3-way handshake is completed as mentioned here:

Yeah, that's in fact a documentation glitch :-(. That describes what
probably *should* be done, but in fact the event is generated on seeing
the SYN-ACK (I just double-checked the code). I wrote it that way eons
ago when Bro often operated on TCP streams that had been filtered to
SYN/FIN/RST packets only, which meant it wouldn't see the pure ACK completing
the handshake.

    Vern

Ok, my confusion was that the comment for that event in event.bif was "The event is raised when the initial 3-way TCP handshake has successfully finished for a connection.", but actually testing it out it seems to be generated for just syn/syn-ack exchanges with nothing further. I'll update that comment unless there's some other subtlety about why it's worded that way.

One caveat could still be that connection_established is TCP-specific, the example I gave could be used for UDP "connections", too.

If someone tries to open up several half open connections to our host, how will we know if we don’t distinguish between SYN-ACK and ACK ? This implies that a connection for which an ACK was never heard would still be treated as an established connection.

Ok, my confusion was that the comment for that event in event.bif was "The event is raised when the initial 3-way TCP handshake has successfully finished for a connection."

Yeah, I think you can pin the blame on me for that comment.

I'll update that comment unless there's some other subtlety about why it's worded that way.

Updating it would be good.

One caveat could still be that connection_established is TCP-specific, the example I gave could be used for UDP "connections", too.

I don't believe we generate connection_established in a UDP context. There
it's instead udp_request and udp_reply. I'm not sure what example you're
referring to.

    Vern

If someone tries to open up several half open connections to our host, how
will we know if we don't distinguish between SYN-ACK and ACK ?

I'm not sure I understand your concern here. Connections are identified
by their five-tuple. If the five-tuple for an active connection is reused,
the two instances will be treated as a single connection; that would be
the case regardless of whether the connection has seen a 2-packet SYN
exchange or a full 3-way handshake.

In terms of TCP semantics, a connection that's only had a 2-packet SYN
exchange is still active, and shouldn't be reused. If the handshake
never completes, it will eventually be torn down with a RST - which will
also cause Bro to consider it no longer active.

    Vern

One caveat could still be that connection_established is TCP-specific, the example I gave could be used for UDP "connections", too.

I don't believe we generate connection_established in a UDP context. There
it's instead udp_request and udp_reply. I'm not sure what example you're
referring to.

Right, I meant the example of checking a connection's "history" field for any lower-case letters should indicate the responding side sent some type of packet during the connection lifetime and wouldn't need special handling for UDP separately from TCP.

And if it's important to distinguish half-open TCP connections from ones that complete a 3-way handshake, "history" looks like it could do that, too.

Right, I meant the example of checking a connection's "history" field
for any lower-case letters should indicate the responding side sent some
type of packet ...

Ah, right. Yes, that's indeed the right way to discern exactly what occurred.

    Vern