-
Notifications
You must be signed in to change notification settings - Fork 651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix False SYNFLOOD alerts #8740
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -445,6 +445,13 @@ Flow::~Flow() { | |
constructor (viewed interfaces) */ | ||
delete srv_ip_addr; | ||
|
||
/* Clean up SYN Flood Counts if the we have an open conection and the flow is being purged*/ | ||
|
||
if( getCurrentConnectionState() == S0 ){ | ||
updateSynFloodAlerts(false); | ||
} | ||
|
||
|
||
/* | ||
Finish deleting other flow data structures | ||
*/ | ||
|
@@ -8733,6 +8740,27 @@ bool Flow::checkS1ConnState() { | |
!(isTCPFlagSet(src2dst_tcp_flags,TH_RST)) && !(isTCPFlagSet(dst2src_tcp_flags,TH_RST)) /* NO RST */ | ||
)); | ||
} | ||
/* **************************************************** */ | ||
|
||
void Flow::updateSynFloodAlerts(bool connection_opened){ | ||
if((current_c_state != S0 && !connection_opened) || | ||
(current_c_state !=MINOR_NO_STATE && connection_opened)) | ||
return; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If handled correctly in the calculateConnectionState() function, i don't think this check is needed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These checks are mainly for two cases:
This logic could be in the calculateConnectionState() function but I thought it would be cleaner here. |
||
|
||
|
||
NetworkStats *cli_network_stats = NULL, *srv_network_stats = NULL; | ||
if (srv_host) | ||
srv_network_stats = | ||
srv_host->getNetworkStats(srv_host->get_local_network_id()); | ||
|
||
if (cli_host) | ||
cli_host->updateSynFloodAlertsCounter(true,connection_opened); | ||
if (srv_host) | ||
srv_host->updateSynFloodAlertsCounter(false,connection_opened); | ||
|
||
if (srv_network_stats) | ||
srv_network_stats->updateSynFloodAlertsCounter(connection_opened); | ||
} | ||
|
||
/* **************************************************** */ | ||
|
||
|
@@ -8745,19 +8773,39 @@ MinorConnectionStates Flow::calculateConnectionState(bool is_cumulative) { | |
!(isTCPFlagSet(dst2src_tcp_flags,TH_SYN))) { | ||
if (!(isTCPFlagSet(dst2src_tcp_flags,TH_RST))) { | ||
if ((isTCPFlagSet(src2dst_tcp_flags,TH_RST))) { | ||
updateSynFloodAlerts(false); | ||
return(setCurrentConnectionState(RSTOS0)); | ||
} else { | ||
if ((isTCPFlagSet(src2dst_tcp_flags,TH_FIN))) { | ||
updateSynFloodAlerts(false); | ||
return(setCurrentConnectionState(SH)); | ||
} else { | ||
return(setCurrentConnectionState(S0)); | ||
/* We are assuming that the TCP connection is established on | ||
* server side when it sees the clients SYN | ||
* this helps us detect SYN flood victims even if all the SYN | ||
* packets are rejected or dropped*/ | ||
updateSynFloodAlerts(true); | ||
return(setCurrentConnectionState(S0)); | ||
} | ||
} | ||
} else { | ||
updateSynFloodAlerts(false); | ||
return(setCurrentConnectionState(REJ)); | ||
} | ||
} | ||
|
||
/* Account for connection being closed after SYNACK*/ | ||
if ((isTCPFlagSet(src2dst_tcp_flags,TH_SYN)) && | ||
(isTCPFlagSet(dst2src_tcp_flags,TH_SYN)) && | ||
(isTCPFlagSet(dst2src_tcp_flags,TH_ACK)) && | ||
!(isTCPFlagSet(src2dst_tcp_flags,TH_ACK))&& | ||
((isTCPFlagSet(dst2src_tcp_flags,TH_RST))|| | ||
(isTCPFlagSet(src2dst_tcp_flags,TH_RST)) || | ||
(isTCPFlagSet(src2dst_tcp_flags,TH_FIN)) || | ||
(isTCPFlagSet(dst2src_tcp_flags,TH_FIN)))) { | ||
updateSynFloodAlerts(false); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code wirtten in this way it's not very clean and hard to understand in the future when debugging. It would have been cleaner simply running a switch case at the end of the calculateConnectionState() function taking account for all the possible connection states and based on the value simply increase or decrease the counter. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense! However, I am a bit confused by the states we have defined as I feel they do not cover all possible connection states, such as when a connection is cancelled after a the server sends the SYNACK packet. Am I missing something or would it be ok to define another connection state? |
||
/* Check RSTRH */ | ||
if ((isTCPFlagSet(dst2src_tcp_flags,TH_SYN)) && | ||
(isTCPFlagSet(dst2src_tcp_flags,TH_ACK)) && | ||
|
@@ -8810,8 +8858,10 @@ MinorConnectionStates Flow::calculateConnectionState(bool is_cumulative) { | |
return(setCurrentConnectionState(RSTR)); | ||
|
||
/* Check S1 */ | ||
if (checkS1ConnState()) | ||
if (checkS1ConnState()){ | ||
updateSynFloodAlerts(false); | ||
return(setCurrentConnectionState(S1)); | ||
} | ||
|
||
if (getCurrentConnectionState() != MINOR_NO_STATE) | ||
return(getCurrentConnectionState()); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you have to check that current_hits is higher than 0.
It can happen in many ways that the first packet of a captured flow does not starts as a normal connection (for instance the packet is forged and starts with a SYN and FIN set or simply the flows in captured half-way during the real connection) and this might lead to a counter overflow issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check in the updateSynFLoodAlerts() function should ensure that we only
decrement the count if the connection has previously been opened. So half captured flows and spoofed packets shouldn't be able to trigger this and cause an overflow I think.