Suricata IPS
Zur Navigation springen
Zur Suche springen
Grundlagen und Installation
Wir installieren Suricata auf der Firewall
Installation
- sudo apt update
- sudo apt -y install suricata
- systemctl stop suricata
- suricata -V
This is Suricata version 6.0.1 RELEASE
IPS
- Wir können mit nf/iptables Pakete abfangen und einer QUEUE übergeben
- Diese QUEUE wird von suricata gelesen und ihrem REGELWERK übergeben.
- Wenn das Paket mit einer Regel übereinstimmt, wird eine Aktion ausgelöst.
- Alert führt zu einer Meldung
- Bei Drop wird das Paket verworfen.
Konfiguration Suricata
- vim /etc/suricata/suricata.yaml
%YAML 1.1
---
# Variablen für die Adressgruppen festlegen
vars:
address-groups:
LAN: "[172.26.2XX.0/24]"
DMZ: "[10.88.2XX.0/24]"
SERVER: "[10.2XX.1.0/24]"
INT: "[$LAN,$DMZ,$SERVER]"
HOME_NET: "$INT"
EXTERNAL_NET: "!$INT"
#Suricate nimmt die Pakete von NF/IPtables wieder auf
nfq:
mode: repeat
repeat-mark: 1
repeat-mask: 1
# Standard-Log-Verzeichnis
default-log-dir: /var/log/suricata/
# Statistiken aktivieren
stats:
enabled: yes
interval: 8
# Ausgaben konfigurieren
outputs:
- fast:
enabled: yes
filename: fast.log
append: yes
- alert-debug:
enabled: yes
filename: alert-debug.log
append: yes
- stats:
enabled: yes
filename: stats.log
append: yes
totals: yes
threads: no
- eve-log:
enabled: yes
filetype: regular
filename: eve.json
types:
- alert
- drop
- http
- dns
- tls
- flow
- ssh
- stats
# Logging-Einstellungen
logging:
default-log-level: notice
outputs:
- console:
enabled: yes
- file:
enabled: yes
level: info
filename: suricata.log
# PID-Datei
pid-file: /var/run/suricata.pid
# Coredump-Einstellungen
coredump:
max-dump: unlimited
# Host-Modus
host-mode: auto
# Unix-Befehlseingabe konfigurieren
unix-command:
enabled: yes
filename: /var/run/suricata-command.socket
# Engine-Analyse-Einstellungen
engine-analysis:
rules-fast-pattern: yes
rules: yes
# Defragmentierungseinstellungen
defrag:
memcap: 32mb
hash-size: 65536
trackers: 65535
max-frags: 65535
prealloc: yes
timeout: 60
# Standardregelverzeichnis
default-rule-path: /etc/suricata/rules
# Regel-Dateien
rule-files:
- local.rules
# Klassifikationsdatei
classification-file: /etc/suricata/classification.config
# Referenzkonfigurationsdatei
reference-config-file: /etc/suricata/reference.config
app-layer:
protocols:
http:
enabled: yes
tls:
enabled: yes
dcerpc:
enabled: yes
smb:
enabled: yes
ftp:
enabled: yes
ssh:
enabled: yes
smtp:
enabled: yes
dns:
enabled: yes
modbus:
enabled: yes
enip:
enabled: yes
dnp3:
enabled: yes
nfs:
enabled: yes
ntp:
enabled: yes
tftp:
enabled: yes
ikev2:
enabled: yes
krb5:
enabled: yes
dhcp:
enabled: yes
snmp:
enabled: yes
sip:
enabled: yes
rfb:
enabled: yes
mqtt:
enabled: yes
rdp:
enabled: yes
http2:
enabled: yes
imap:
enabled: yes
Local Rules
- cat /etc/suricata/rules/local.rules
# ICMP: einfacher Ping/Traceroute (schneller Funktionstest) # Test: ping -c 1 1.1.1.1 alert icmp any any -> any any (msg:"ICMP Test"; classtype:misc-activity; sid:9000041;) # HTTP: mögliches Command-Injection-Merkmal (Semikolon) in POST-Body # Test: curl -X POST http://www.it2XX.int/host.php --data-urlencode "fqdn=example.com;ls" -d "submit=Auflösen" alert http any any -> any any (msg:"Command Injection - Semicolon in POST DATA"; classtype:web-application-attack; flow:established; content:"%3B"; nocase; http_client_body; sid:9000002;) # HTTP: mögliches SQLi-Merkmal (einfaches Hochkomma) in POST-Body # Test: curl -X POST http://www.it2XX.int/sql-classic.php --data-urlencode "username=' OR '1'='1' --" alert http any any -> any any (msg:"Possible SQL Injection (singlequote in POST)"; classtype:web-application-attack; flow:established,to_server; content:"%27"; nocase; http_client_body; sid:9000003;) # DNS: Policy - verbietet "google" in DNS-Queries # Test: host google.de drop dns any any -> any any (msg:"Kein Googlen"; dns.query; content:"google"; nocase; classtype:policy-violation; sid:9000043;) # DoS: viele identische kurze HTTP-GETs (LOIC-ähnlich) # Test: ab -n 1000 -c 500 http://www.it2XX.int/ drop tcp any any -> any any (msg:"ET DOS Terse HTTP GET Likely LOIC"; flow:to_server,established; dsize:18; content:"GET / HTTP/1.1|0d 0a 0d 0a|"; depth:18; threshold:type both,track by_dst,count 500,seconds 60; classtype:own-dos; sid:9000054; rev:2;) # Scan: TCP SYN-Sweep (viele SYN in kurzer Zeit) # Test: nmap -sS -p1-100 10.88.2XX.21 drop tcp any any -> any any (msg:"OWN SCAN TCP SYN sweep"; flow:stateless,to_server; flags:S; detection_filter:track by_src,count 20,seconds 5; classtype:attempted-recon; sid:9000060; rev:1;) # Scan: TCP NULL-Scan (keine Flags gesetzt) # Test: nmap -sN -p1-100 10.88.2XX.21 drop tcp any any -> any any (msg:"OWN SCAN TCP NULL scan"; flow:stateless,to_server; flags:0; detection_filter:track by_src,count 5,seconds 10; classtype:attempted-recon; sid:9000061; rev:1;) # Scan: UDP-Sweep mit leerer Payload # Test: nmap -sU --min-rate=1000 10.88.2XX.21 drop udp any any -> any any (msg:"OWN SCAN UDP sweep (empty probes)"; flow:to_server; dsize:0; detection_filter:track by_src,count 15,seconds 10; classtype:attempted-recon; sid:9000064; rev:1;) # Scan: ICMP Ping-Sweep (viele Echo-Requests) # Test: nmap -sn 10.88.2XX.0/24 drop icmp any any -> any any (msg:"OWN SCAN ICMP ping sweep"; itype:8; detection_filter:track by_src,count 10,seconds 5; classtype:attempted-recon; sid:9000065; rev:1;) # Brute Force SSH # Test: hydra -l kit -P bad-passwords ssh://10.88.2XX.21 drop tcp any any -> any 22 (msg:"OWN SSH Brute Force"; flow:to_server,stateless; flags:S; detection_filter:track by_src,count 10,seconds 60; classtype:attempted-recon; sid:9000066; rev:1;) # HTTP: sqlmap User-Agent erkennen # Test: sqlmap -u "http://www.it2XX.int/sql-classic.php" --data "username=test" alert http any any -> any any (msg:"SQLmap Scanner detected"; http.user_agent; content:"sqlmap"; nocase; classtype:web-application-attack; sid:9000070; rev:1;) # HTTP: curl User-Agent erkennen # Test: curl http://www.it2XX.int/host.php alert http any any -> any any (msg:"curl User-Agent detected"; http.user_agent; content:"curl"; nocase; classtype:policy-violation; sid:9000071; rev:1;) # ICMP Tunnel - großes Payload # Test: ping -c 5 -s 500 10.88.2XX.21 alert icmp any any -> any any (msg:"OWN ICMP Large Payload - possible tunnel"; itype:8; dsize:>200; classtype:misc-attack; sid:9000072; rev:1;) # TCP SYN Flood # Test: hping3 -S --flood -V -p 80 10.88.2XX.21 alert tcp any any -> any any (msg:"TCP SYN Flood Potential Detected"; flags:S; threshold: type both, track by_dst, count 150, seconds 10; classtype:misc-attack; sid:9000073; rev:1;) # SSH Connection Attempt # Test: ssh root@10.88.2XX.21 alert tcp any any -> any 22 (msg:"SSH Connection Attempt"; content:"SSH"; nocase; classtype:misc-activity; sid:9000074; rev:1;)
Beschreibung
| Schlüsselwort | Beschreibung |
|---|---|
| alert / drop | Aktion bei Regelübereinstimmung. alert erzeugt einen Logeintrag, drop verwirft das Paket zusätzlich. |
| icmp / tcp / udp / http / dns | Protokoll das überwacht wird. |
| any | Platzhalter für beliebige IP-Adresse oder Port. |
| -> | Richtung des Datenverkehrs (Quelle → Ziel). |
| msg:"..." | Beschreibung die im Alert-Log erscheint. |
| classtype:... | Kategorie des Angriffs (z.B. web-application-attack, attempted-recon, policy-violation). |
| sid:... | Eindeutige Signatur-ID der Regel. Eigene Regeln beginnen ab 9000000. |
| flow:... | Verbindungsstatus (z.B. established, to_server, stateless). |
| content:"..." | Zeichenkette nach der im Paketinhalt gesucht wird. |
| nocase | Groß-/Kleinschreibung wird beim content-Vergleich ignoriert. |
| http_client_body | Sucht den content nur im HTTP-Request-Body. |
| http.user_agent | Sucht den content im HTTP User-Agent Header. |
| dns.query | Sucht den content im DNS-Query-Namen. |
| flags:... | TCP-Flags (z.B. S=SYN, F=FIN, FPU=XMAS). |
| itype:... | ICMP-Typ (z.B. 8 = Echo Request). |
| dsize:... | Größe der Nutzdaten in Bytes. |
| detection_filter:... | Schwellenwert für Häufigkeit bevor die Regel auslöst. |
| threshold:... | Begrenzung wie oft ein Alert pro Zeitraum ausgelöst wird. |
| rev:... | Revisionsnummer der Regel. |
Firewallanpassung
NFQUEUE Repeat
- Damit Suricata die nicht gedroppten Pakete automatisch akzeptiert, sondern dies der Firewall überlässt, kann es diese Pakete markieren und zurück zu iptables schicken
- Markierungen folgen der Syntax $MARK/$MASK
nftables Version
- vim /etc/nftables.conf
table inet filter {
chain forward {
type filter hook forward priority 0; policy drop;
# An Suricata übergeben, wenn Mark-Bit 0 nicht gesetzt
meta mark and 1 != 1 queue
# Logging und Akzeptanz nach Rückgabe durch Suricata (mit gesetztem Mark)
log prefix "nftables return from Suricata: "
ct state established,related accept
# Hier geht es mit den normalen Regeln weiter
}
}Start suricata
- suricata -D -q 0
- Den Unterschied zwischen repeat und accept kann man mit Ping und SSH testen (falls SSH in der FORWARD Kette blockiert ist)
- Die Verstöße können folgendermaßen gesehen werden
- tail -fn0 /var/log/suricata/fast.log
Suricata Fernbedienung
- Reload Rules
- suricatasc -c "reload-rules"
- Shutdown
- suricatasc -c "shutdown"
Suricata als IPS mit systemd starten
EveBox
Tests
ping
- ping -c 1 1.1.1.1
DNS Policy
- host google.de
Command Injection
- curl -X POST http://www.it2XX.int/host.php --data-urlencode "fqdn=example.com;ls" -d "submit=Auflösen"
SQL Injection
- curl -X POST http://www.it2XX.int/sql-classic.php --data-urlencode "username=' OR '1'='1' --"
Brute Force SSH
- wget https://xinux.de/downloads/bad-passwords
- hydra -l kit -P bad-passwords ssh://10.88.2XX.21
SSH Connection Attempt
- ssh root@10.88.2XX.21
HTTP User-Agent Erkennung
- sqlmap -u "http://www.it2XX.int/sql-classic.php" --data "username=test"
- curl http://www.it2XX.int/host.php
ICMP Tunnel Erkennung
- ping -c 5 -s 500 10.88.2XX.21
DoS
- ab -n 1000 -c 500 http://www.it2XX.int/
- hping3 -S --flood -V -p 80 10.88.2XX.21
Nmap Scans
- SYN-Sweep
- nmap -sS -p1-100 10.88.2XX.21
- UDP-Sweep
- nmap -sU --min-rate=1000 10.88.2XX.21
- Ping-Sweep
- nmap -sn 10.88.2XX.0/24
- NULL-Scan
- nmap -sN -p1-100 10.88.2XX.21
