In iptables, lists of rules known as chains are processed sequentially. Among these, three primary chains are universally present, with additional ones like NAT being potentially supported depending on the system's capabilities.
Input Chain: Utilized for managing the behavior of incoming connections.
Forward Chain: Employed for handling incoming connections that are not destined for the local system. This is typical for devices acting as routers, where the data received is meant to be forwarded to another destination. This chain is relevant primarily when the system is involved in routing, NATing, or similar activities.
Output Chain: Dedicated to the regulation of outgoing connections.
These chains ensure the orderly processing of network traffic, allowing for the specification of detailed rules governing the flow of data into, through, and out of a system.
# Delete all rulesiptables-F# List all rulesiptables-Liptables-S# Block IP addresses & portsiptables-IINPUT-sip1,ip2,ip3-jDROPiptables-IINPUT-ptcp--dport443-jDROPiptables-IINPUT-sip1,ip2-ptcp--dport443-jDROP# String based drop## Strings are case sensitive (pretty easy to bypass if you want to check an SQLi for example)iptables-IINPUT-ptcp--dport<port_listening>-mstring--algobm--string'<payload>'-jDROPiptables-IOUTPUT-ptcp--sport<port_listening>-mstring--algobm--string'CTF{'-jDROP## You can also check for the hex, base64 and double base64 of the expected CTF flag chars# Drop every input port except someiptables-PINPUTDROP# Default to dropiptables-IINPUT-ptcp--dport8000-jACCEPTiptables-IINPUT-ptcp--dport443-jACCEPT# Persist Iptables## Debian/Ubuntu:apt-getinstalliptables-persistentiptables-save>/etc/iptables/rules.v4ip6tables-save>/etc/iptables/rules.v6iptables-restore</etc/iptables/rules.v4##RHEL/CentOS:iptables-save>/etc/sysconfig/iptablesip6tables-save>/etc/sysconfig/ip6tablesiptables-restore</etc/sysconfig/iptables
Suricata
Install & Config
# Install details from: https://suricata.readthedocs.io/en/suricata-6.0.0/install.html#install-binary-packages# Ubuntuadd-apt-repositoryppa:oisf/suricata-stableapt-getupdateapt-getinstallsuricata# Debianecho"deb http://http.debian.net/debian buster-backports main"> \/etc/apt/sources.list.d/backports.listapt-getupdateapt-getinstallsuricata-tbuster-backports# CentOSyuminstallepel-releaseyuminstallsuricata# Get rulessuricata-updatesuricata-updatelist-sources#List sources of the rulessuricata-updateenable-sourceet/open#Add et/open rulesetssuricata-update## To use the dowloaded rules update the following line in /etc/suricata/suricata.yamldefault-rule-path:/var/lib/suricata/rulesrule-files:-suricata.rules# Run## Add rules in /etc/suricata/rules/suricata.rulessystemctlsuricatastartsuricata-c/etc/suricata/suricata.yaml-ieth0# Reload rulessuricatasc-cruleset-reload-nonblocking## or set the follogin in /etc/suricata/suricata.yamldetect-engine:-rule-reload:true# Validate suricata configsuricata-T-c/etc/suricata/suricata.yaml-v# Configure suricata as IPs## Config drop to generate alerts## Search for the following lines in /etc/suricata/suricata.yaml and remove comments:-drop:alerts:yesflows:all## Forward all packages to the queue where suricata can act as IPSiptables-IINPUT-jNFQUEUEiptables-IOUTPUT-jNFQUEUE## Start suricata in IPS modesuricata-c/etc/suricata/suricata.yaml-q0### or modify the service config file as:systemctleditsuricata.service[Service]ExecStart=ExecStart=/usr/bin/suricata-c/etc/suricata/suricata.yaml--pidfile/run/suricata.pid-q0-vvvType=simplesystemctldaemon-reload
Rules Definitions
From the docs: A rule/signature consists of the following:
The action, determines what happens when the signature matches.
The header, defines the protocol, IP addresses, ports and direction of the rule.
The rule options, define the specifics of the rule.
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP GET Request Containing Rule in URI"; flow:established,to_server; http.method; content:"GET"; http.uri; content:"rule"; fast_pattern; classtype:bad-unknown; sid:123; rev:1;)
Valid actions are
alert - generate an alert
pass - stop further inspection of the packet
drop - drop packet and generate alert
reject - send RST/ICMP unreachable error to the sender of the matching packet.
rejectsrc - same as just reject
rejectdst - send RST/ICMP error packet to the receiver of the matching packet.
rejectboth - send RST/ICMP error packets to both sides of the conversation.
Protocols
tcp (for tcp-traffic)
udp
icmp
ip (ip stands for ‘all’ or ‘any’)
layer7 protocols: http, ftp, tls, smb, dns, ssh... (more in the docs)
Source and Destination Addresses
It supports IP ranges, negations and a list of addresses:
Example
Meaning
! 1.1.1.1
Every IP address but 1.1.1.1
![1.1.1.1, 1.1.1.2]
Every IP address but 1.1.1.1 and 1.1.1.2
$HOME_NET
Your setting of HOME_NET in yaml
[$EXTERNAL_NET, !$HOME_NET]
EXTERNAL_NET and not HOME_NET
[10.0.0.0/24, !10.0.0.5]
10.0.0.0/24 except for 10.0.0.5
Source and Destination Ports
It supports port ranges, negations and lists of ports
Example
Meaning
any
any address
[80, 81, 82]
port 80, 81 and 82
[80: 82]
Range from 80 till 82
[1024: ]
From 1024 till the highest port-number
!80
Every port but 80
[80:100,!99]
Range from 80 till 100 but 99 excluded
[1:80,![2,4]]
Range from 1-80, except ports 2 and 4
Direction
It's possible to indicate the direction of the communication rule being applied:
There are hundreds of options available in Suricata to search for the specific packet you are looking for, here it will be mentioned if something interesting is found. Check the documentationfor more!
# Meta Keywordsmsg:"description"; #Set a description to the rulesid:123#Set a unique ID to the rulerev:1#Rule revision numberconfigclassification:not-suspicious,NotSuspiciousTraffic,3#Classifyreference:url,www.info.com#Referencepriority:1; #Set a prioritymetadata:keyvalue,keyvalue; #Extra metadata# Filter by geolocationgeoip:src,RU;# ICMP type & Codeitype:<10;icode:0# Filter by stringcontent:"something"content:|616161|#Hex: AAAcontent:"http|3A|//"#Mix string and hexcontent:"abc"; nocase; #Case insensitiverejecttcpanyany ->anyany (msg: "php-rce"; content:"eval"; nocase; metadata:tagphp-rce; sid:101; rev:1;)# Replaces string## Content and replace string must have the same lengthcontent:"abc"; replace:"def"alerttcpanyany ->anyany (msg: "flag replace"; content:"CTF{a6st"; replace:"CTF{u798"; nocase; sid:100; rev:1;)## The replace works in both input and output packets## But it only modifies the first match# Filter by regexpcre:"/<regex>/opts"pcre:"/NICK .*USA.*[0-9]{3,}/i"droptcpanyany ->anyany (msg:"regex"; pcre:"/CTF\{[\w]{3}/i"; sid:10001;)# Other examples## Drop by portdroptcpanyany ->any8000 (msg:"8000 port"; sid:1000;)