IDS Snort regola per catturare Slow-Loris

1

Sto provando a scrivere una regola per catturare un attacco di Slow-Loris, questo è quello che ho -

alert tcp any any -> any any (msg:"Possible Slow Loris attack"; classtype: denial-of-service; flow: to_server, established; pcre: !"/\x0D\x0A\x0D\x0A$/H"; threshold: type threshold, track by_dst, count 10, seconds 5; sid 3000009; rev:1;)

(Potrei aver incasinato la sintassi un po 'ma questo è dovuto al fatto che provo a formattarlo qui, sono sicuro che la sintassi è okay alla mia fine)

Ho anche provato a fare confusione con l'RE, ho provato "/\x0D\x0A$/H" e non ha funzionato neanche

Gli Slow-Loris che ho provato a scrivere me stesso e lo Slow Loris che ho scaricato da qualche parte inviano pacchetti con intestazioni HTTP "incomplete", quindi non terminano con \r\n\r\n come un'intestazione finita. Ma non riesco a catturarne uno.

Guardati i pacchetti su Wireshark e terminano con 0D 0A

Guardato su download.rules e la regola non è presente. Tail per snort.conf e non ci sono errori lì. Forse service nsm status per vedere se il servizio non è stato pubblicato correttamente, ma è tutto OK . EDIT - C'era un : mancante, l'ho risolto e ora appare su download.rules. comunque non viene catturato però

Non sono proprio sicuro di cosa sto facendo male, apprezzerei un po 'di aiuto.

    
posta GoodKingRene 27.11.2017 - 20:06
fonte

1 risposta

2

Sembra che ci siano un paio di cose nella firma che non funzioneranno:

  1. L'utilizzo dell'opzione /H in PCRE utilizza il preprocessore HTTP e dice che il contenuto deve essere confrontato con http_header . Quando una richiesta GET viene analizzata dal preprocessore, |0d 0a 0d 0a| indica la fine dell'intestazione; il che significa che non puoi cercarlo all'interno dell'intestazione.

  2. Quando si utilizza flow o qualsiasi preprocessore HTTP, il flusso TCP viene riassemblato (per impostazione predefinita, se non diversamente specificato). Ciò significa che per far corrispondere il contenuto nell'intestazione, tutti i pacchetti che costituiscono la richiesta HTTP devono essere osservati e la richiesta deve terminare prima che il preprocessore sia in grado di analizzare tutte le parti che compongono la richiesta ( es. http_method , http_uri , http_header ).

Onestamente, non sono sicuro che l'approccio migliore sarebbe scrivere una firma per rilevare questa attività [genericamente], semplicemente perché va oltre i limiti normali di ciò che Snort è progettato per rilevare.

Tuttavia, ciò che consiglierei in questa situazione sarebbe trovare tutti gli strumenti disponibili pubblicamente per SlowLoris (a partire da link - disponibile per l'installazione tramite pip3), eseguirli in un ambiente di test e analizzare ciò che effettivamente avviene sul filo.

L'ho fatto e questo è il traffico che genera:

GET /?1153 HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0
Accept-language: en-US,en,q=0.5
X-a: 1350
X-a: 210
X-a: 518
X-a: 4622
X-a: 2951
X-a: 2666
X-a: 149
X-a: 1756
X-a: 4994
X-a: 2688

Questo accade su più connessioni fino al numero massimo di socket specificati (150 di default). Ogni connessione verrebbe mantenuta attiva con una richiesta GET HTTP incompleta inviando un ulteriore campo di intestazione X-a ogni tanto.

Il modo in cui scriverei una firma per rilevare questa attività sarebbe:

alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (msg:"SlowLoris.py DoS attempt"; \
    flow:established,to_server,no_stream; content:"X-a:"; dsize:<15; \
    detection_filter:track by_dst, count 3, seconds 30; \
    classtype:denial-of-service; sid:1; rev:1; )

event_filter gen_id 1, sig_id 1, type limit, track by_src, count 1, seconds 5

Cose importanti su questa regola:

  1. Aggiunta l'opzione no_stream a flow . Questo dice al preprocessore Stream5 di non preoccuparsi di controllare come il contenuto si riferisce nel contesto del flusso riassemblato. Fondamentalmente guarda solo il pacchetto stesso. Importante quando si utilizza l'opzione dsize .
  2. Aggiunto dsize:<15 . Le righe che contengono le intestazioni X-a vengono inviate in singoli pacchetti. Ho osservato un tipico pacchetto come:

    0000 58 2d 61 3a 20 32 36 38 38 0d 0a X-a: 2688..

    Con quattro cifre casuali per il valore, la lunghezza del contenuto è di 11 byte. Ho appena deciso di dire <15 per ogni evenienza.

  3. Aggiunto detection_filter . Trovo che una combinazione di detection_filter nella regola combinata con una event_filter offre un controllo migliore per la limitazione e la soglia delle allerte. Le opzioni detection_filter specificate assicurano di attivare gli avvisi solo se 3 o più si verificano dalla stessa origine in una finestra di 30 secondo.
  4. Aggiunto un event_filter per limitare il numero di avvisi attivati quando viene raggiunto detection_filter . Limitando gli avvisi a 1 ogni 5 secondi, l'avviso sarà ancora abbastanza loquace da permetterti di sapere che qualcosa sta succedendo senza allagarti con allarmi estranei.

Di seguito è riportato un esempio di output dal test in tempo reale utilizzando Snort v2.9.9.0 per la durata di 3 minuti

SlowLoris.py

(Python3) λ slowloris -p 80 192.168.126.128
[05-12-2017 13:45:01] Attacking 192.168.126.128 with 150 sockets.
[05-12-2017 13:45:01] Creating sockets...
[05-12-2017 13:45:05] Sending keep-alive headers... Socket count: 7
[05-12-2017 13:45:24] Sending keep-alive headers... Socket count: 7
[05-12-2017 13:45:43] Sending keep-alive headers... Socket count: 7
[05-12-2017 13:46:02] Sending keep-alive headers... Socket count: 7
[05-12-2017 13:46:21] Sending keep-alive headers... Socket count: 7
[05-12-2017 13:46:40] Sending keep-alive headers... Socket count: 7
[05-12-2017 13:46:59] Sending keep-alive headers... Socket count: 7
[05-12-2017 13:47:18] Sending keep-alive headers... Socket count: 7
[05-12-2017 13:47:37] Sending keep-alive headers... Socket count: 7
[05-12-2017 13:47:56] Sending keep-alive headers... Socket count: 7
^C

Registro server HTTP

user@host:~$ sudo python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
192.168.126.1 - - [05/Dec/2017 13:48:01] "GET /?1061 HTTP/1.1" 200 -
192.168.126.1 - - [05/Dec/2017 13:48:01] "GET /?524 HTTP/1.1" 200 -
192.168.126.1 - - [05/Dec/2017 13:48:01] "GET /?1171 HTTP/1.1" 200 -
192.168.126.1 - - [05/Dec/2017 13:48:01] "GET /?984 HTTP/1.1" 200 -
----------------------------------------
Exception happened during processing of request from ('192.168.126.1', 61831)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 290, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 318, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 331, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 654, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 713, in finish
    self.wfile.close()
  File "/usr/lib/python2.7/socket.py", line 283, in close
    self.flush()
  File "/usr/lib/python2.7/socket.py", line 307, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe
----------------------------------------
192.168.126.1 - - [05/Dec/2017 13:48:01] "GET /?634 HTTP/1.1" 200 -
----------------------------------------
Exception happened during processing of request from ('192.168.126.1', 61832)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 290, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 318, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 331, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 654, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 713, in finish
    self.wfile.close()
  File "/usr/lib/python2.7/socket.py", line 283, in close
    self.flush()
  File "/usr/lib/python2.7/socket.py", line 307, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe
----------------------------------------
192.168.126.1 - - [05/Dec/2017 13:48:01] "GET /?296 HTTP/1.1" 200 -
192.168.126.1 - - [05/Dec/2017 13:48:01] "GET /?640 HTTP/1.1" 200 -
----------------------------------------
Exception happened during processing of request from ('192.168.126.1', 61834)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 290, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 318, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 331, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 654, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 713, in finish
    self.wfile.close()
  File "/usr/lib/python2.7/socket.py", line 283, in close
    self.flush()
  File "/usr/lib/python2.7/socket.py", line 307, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe
----------------------------------------

Avvisi Snort

12/05-13:45:05.348446  [**] [1:1:1] SlowLoris.py DoS attempt [**] [Priority: 0] {TCP} 192.168.126.1:61831 -> 192.168.126.128:80
12/05-13:45:24.351347  [**] [1:1:1] SlowLoris.py DoS attempt [**] [Priority: 0] {TCP} 192.168.126.1:61828 -> 192.168.126.128:80
12/05-13:45:43.355735  [**] [1:1:1] SlowLoris.py DoS attempt [**] [Priority: 0] {TCP} 192.168.126.1:61828 -> 192.168.126.128:80
12/05-13:46:02.358688  [**] [1:1:1] SlowLoris.py DoS attempt [**] [Priority: 0] {TCP} 192.168.126.1:61828 -> 192.168.126.128:80
12/05-13:46:21.363346  [**] [1:1:1] SlowLoris.py DoS attempt [**] [Priority: 0] {TCP} 192.168.126.1:61828 -> 192.168.126.128:80
12/05-13:46:40.365834  [**] [1:1:1] SlowLoris.py DoS attempt [**] [Priority: 0] {TCP} 192.168.126.1:61828 -> 192.168.126.128:80
12/05-13:46:59.369221  [**] [1:1:1] SlowLoris.py DoS attempt [**] [Priority: 0] {TCP} 192.168.126.1:61828 -> 192.168.126.128:80
12/05-13:47:18.372293  [**] [1:1:1] SlowLoris.py DoS attempt [**] [Priority: 0] {TCP} 192.168.126.1:61828 -> 192.168.126.128:80
12/05-13:47:37.374814  [**] [1:1:1] SlowLoris.py DoS attempt [**] [Priority: 0] {TCP} 192.168.126.1:61828 -> 192.168.126.128:80
12/05-13:47:56.378355  [**] [1:1:1] SlowLoris.py DoS attempt [**] [Priority: 0] {TCP} 192.168.126.1:61828 -> 192.168.126.128:80

Spero che questo aiuti!

    
risposta data 05.12.2017 - 20:03
fonte

Leggi altre domande sui tag