1515from slips_files .common .flow_classifier import FlowClassifier
1616
1717
18+ NOT_ESTAB = "Not Established"
19+ ESTAB = "Established"
20+
21+
1822class Conn (IFlowalertsAnalyzer ):
1923 def init (self ):
2024 # get the default gateway
@@ -38,6 +42,7 @@ def init(self):
3842 self .classifier = FlowClassifier ()
3943 self .our_ips = utils .get_own_ips ()
4044 self .input_type : str = self .db .get_input_type ()
45+ self .multiple_reconnection_attempts_threshold = 5
4146
4247 def read_configuration (self ):
4348 conf = ConfigParser ()
@@ -171,7 +176,7 @@ def check_unknown_port(self, profileid, twid, flow):
171176 """
172177 if not flow .dport :
173178 return
174- if flow .interpreted_state != "Established" :
179+ if flow .interpreted_state != ESTAB :
175180 # detect unknown ports on established conns only
176181 return False
177182
@@ -195,6 +200,54 @@ def check_unknown_port(self, profileid, twid, flow):
195200 self .set_evidence .unknown_port (twid , flow )
196201 return True
197202
203+ def is_telnet (self , flow ) -> bool :
204+ try :
205+ dport = int (flow .dport )
206+ except ValueError :
207+ # binetflow icmp ports are hex strings
208+ return False
209+
210+ telnet_ports = (23 , 2323 )
211+ return dport in telnet_ports and flow .proto .lower () == "tcp"
212+
213+ def check_multiple_telnet_reconnection_attempts (
214+ self , profileid , twid , flow
215+ ):
216+ if flow .interpreted_state != NOT_ESTAB :
217+ return
218+
219+ if not self .is_telnet (flow ):
220+ return
221+
222+ key = f"{ flow .saddr } -{ flow .daddr } -telnet"
223+ # add this conn to the stored number of reconnections
224+ current_reconnections = self .db .get_reconnections_for_tw (
225+ profileid , twid
226+ )
227+ try :
228+ reconnections , uids = current_reconnections [key ]
229+ reconnections += 1
230+ uids .append (flow .uid )
231+ current_reconnections [key ] = (reconnections , uids )
232+ except KeyError :
233+ current_reconnections [key ] = (1 , [flow .uid ])
234+ reconnections = 1
235+
236+ if reconnections < 4 :
237+ # update the reconnections ctr in the db
238+ self .db .set_reconnections (profileid , twid , current_reconnections )
239+ return
240+
241+ self .set_evidence .multiple_telnet_reconnection_attempts (
242+ twid , flow , reconnections , current_reconnections [key ][1 ]
243+ )
244+
245+ # reset the reconnection attempts of this src->dst since an evidence
246+ # is set
247+ current_reconnections [key ] = (0 , [])
248+
249+ self .db .set_reconnections (profileid , twid , current_reconnections )
250+
198251 def check_multiple_reconnection_attempts (self , profileid , twid , flow ):
199252 """
200253 Alerts when 5+ reconnection attempts from the same source IP to
@@ -219,7 +272,8 @@ def check_multiple_reconnection_attempts(self, profileid, twid, flow):
219272 current_reconnections [key ] = (1 , [flow .uid ])
220273 reconnections = 1
221274
222- if reconnections < 5 :
275+ if reconnections < self .multiple_reconnection_attempts_threshold :
276+ self .db .set_reconnections (profileid , twid , current_reconnections )
223277 return
224278
225279 self .set_evidence .multiple_reconnection_attempts (
@@ -511,7 +565,7 @@ def check_conn_to_port_0(self, profileid, twid, flow):
511565 )
512566
513567 def detect_connection_to_multiple_ports (self , profileid , twid , flow ):
514- if flow .proto != "tcp" or flow .interpreted_state != "Established" :
568+ if flow .proto != "tcp" or flow .interpreted_state != ESTAB :
515569 return
516570
517571 dport_name = flow .appproto
@@ -525,7 +579,7 @@ def detect_connection_to_multiple_ports(self, profileid, twid, flow):
525579 # Connection to multiple ports to the destination IP
526580 if profileid .split ("_" )[1 ] == flow .saddr :
527581 direction = "Dst"
528- state = "Established"
582+ state = ESTAB
529583 protocol = "TCP"
530584 role = "Client"
531585 type_data = "IPs"
@@ -565,7 +619,7 @@ def detect_connection_to_multiple_ports(self, profileid, twid, flow):
565619 # Happens in the mode 'all'
566620 elif profileid .split ("_" )[- 1 ] == flow .daddr :
567621 direction = "Src"
568- state = "Established"
622+ state = ESTAB
569623 protocol = "TCP"
570624 role = "Server"
571625 type_data = "IPs"
@@ -608,7 +662,7 @@ def check_non_http_port_80_conns(self, twid, flow):
608662 str (flow .dport ) == "80"
609663 and flow .proto .lower () == "tcp"
610664 and str (flow .appproto ).lower () != "http"
611- and flow .interpreted_state == "Established"
665+ and flow .interpreted_state == ESTAB
612666 and (flow .sbytes + flow .dbytes ) != 0
613667 ):
614668 self .set_evidence .non_http_port_80_conn (twid , flow )
@@ -734,6 +788,9 @@ async def analyze(self, msg):
734788 self .check_long_connection (twid , flow )
735789 self .check_unknown_port (profileid , twid , flow )
736790 self .check_multiple_reconnection_attempts (profileid , twid , flow )
791+ self .check_multiple_telnet_reconnection_attempts (
792+ profileid , twid , flow
793+ )
737794 self .check_conn_to_port_0 (profileid , twid , flow )
738795 self .check_different_localnet_usage (
739796 twid , flow , what_to_check = "dstip"
0 commit comments