Suricata & Iptables cheatsheet

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ

Iptables

Chains

iptables์—์„œ ๊ทœ์น™ ๋ชฉ๋ก์€ ์ฒด์ธ์œผ๋กœ ์•Œ๋ ค์ ธ ์žˆ์œผ๋ฉฐ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ์ด ์ค‘ ์„ธ ๊ฐ€์ง€ ์ฃผ์š” ์ฒด์ธ์€ ๋ณดํŽธ์ ์œผ๋กœ ์กด์žฌํ•˜๋ฉฐ, ์‹œ์Šคํ…œ์˜ ๊ธฐ๋Šฅ์— ๋”ฐ๋ผ NAT์™€ ๊ฐ™์€ ์ถ”๊ฐ€ ์ฒด์ธ์ด ์ง€์›๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Input Chain: ๋“ค์–ด์˜ค๋Š” ์—ฐ๊ฒฐ์˜ ๋™์ž‘์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • Forward Chain: ๋กœ์ปฌ ์‹œ์Šคํ…œ์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜์ง€ ์•Š๋Š” ๋“ค์–ด์˜ค๋Š” ์—ฐ๊ฒฐ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ผ์šฐํ„ฐ ์—ญํ• ์„ ํ•˜๋Š” ์žฅ์น˜์—์„œ ์ผ๋ฐ˜์ ์ด๋ฉฐ, ์ˆ˜์‹ ๋œ ๋ฐ์ดํ„ฐ๋Š” ๋‹ค๋ฅธ ๋ชฉ์ ์ง€๋กœ ์ „๋‹ฌ๋˜๋„๋ก ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ฒด์ธ์€ ์‹œ์Šคํ…œ์ด ๋ผ์šฐํŒ…, NAT ๋˜๋Š” ์œ ์‚ฌํ•œ ํ™œ๋™์— ๊ด€์—ฌํ•  ๋•Œ ์ฃผ๋กœ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • Output Chain: ๋‚˜๊ฐ€๋Š” ์—ฐ๊ฒฐ์˜ ๊ทœ์ œ๋ฅผ ์ „๋‹ดํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ฒด์ธ์€ ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์˜ ์งˆ์„œ ์žˆ๋Š” ์ฒ˜๋ฆฌ๋ฅผ ๋ณด์žฅํ•˜๋ฉฐ, ์‹œ์Šคํ…œ์œผ๋กœ ๋“ค์–ด์˜ค๊ณ , ํ†ต๊ณผํ•˜๊ณ , ๋‚˜๊ฐ€๋Š” ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ๊ทœ์ œํ•˜๋Š” ์„ธ๋ถ€ ๊ทœ์น™์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

# Delete all rules
iptables -F

# List all rules
iptables -L
iptables -S

# Block IP addresses & ports
iptables -I INPUT -s ip1,ip2,ip3 -j DROP
iptables -I INPUT -p tcp --dport 443 -j DROP
iptables -I INPUT -s ip1,ip2 -p tcp --dport 443 -j DROP

# String based drop
## Strings are case sensitive (pretty easy to bypass if you want to check an SQLi for example)
iptables -I INPUT -p tcp --dport <port_listening> -m string --algo bm --string '<payload>' -j DROP
iptables -I OUTPUT -p tcp --sport <port_listening> -m string --algo bm --string 'CTF{' -j DROP
## You can also check for the hex, base64 and double base64 of the expected CTF flag chars

# Drop every input port except some
iptables -P INPUT DROP # Default to drop
iptables -I INPUT -p tcp --dport 8000 -j ACCEPT
iptables -I INPUT -p tcp --dport 443 -j ACCEPT


# Persist Iptables
## Debian/Ubuntu:
apt-get install iptables-persistent
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
iptables-restore < /etc/iptables/rules.v4
##RHEL/CentOS:
iptables-save > /etc/sysconfig/iptables
ip6tables-save > /etc/sysconfig/ip6tables
iptables-restore < /etc/sysconfig/iptables

Suricata

์„ค์น˜ ๋ฐ ๊ตฌ์„ฑ

# Install details from: https://suricata.readthedocs.io/en/suricata-6.0.0/install.html#install-binary-packages
# Ubuntu
add-apt-repository ppa:oisf/suricata-stable
apt-get update
apt-get install suricata

# Debian
echo "deb http://http.debian.net/debian buster-backports main" > \
/etc/apt/sources.list.d/backports.list
apt-get update
apt-get install suricata -t buster-backports

# CentOS
yum install epel-release
yum install suricata

# Get rules
suricata-update
suricata-update list-sources #List sources of the rules
suricata-update enable-source et/open #Add et/open rulesets
suricata-update
## To use the dowloaded rules update the following line in /etc/suricata/suricata.yaml
default-rule-path: /var/lib/suricata/rules
rule-files:
- suricata.rules

# Run
## Add rules in /etc/suricata/rules/suricata.rules
systemctl suricata start
suricata -c /etc/suricata/suricata.yaml -i eth0


# Reload rules
suricatasc -c ruleset-reload-nonblocking
## or set the follogin in /etc/suricata/suricata.yaml
detect-engine:
- rule-reload: true

# Validate suricata config
suricata -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: yes
flows: all

## Forward all packages to the queue where suricata can act as IPS
iptables -I INPUT -j NFQUEUE
iptables -I OUTPUT -j NFQUEUE

## Start suricata in IPS mode
suricata -c /etc/suricata/suricata.yaml  -q 0
### or modify the service config file as:
systemctl edit suricata.service

[Service]
ExecStart=
ExecStart=/usr/bin/suricata -c /etc/suricata/suricata.yaml --pidfile /run/suricata.pid -q 0 -vvv
Type=simple

systemctl daemon-reload

๊ทœ์น™ ์ •์˜

[๋ฌธ์„œ์—์„œ:] (https://github.com/OISF/suricata/blob/master/doc/userguide/rules/intro.rst) ๊ทœ์น™/์„œ๋ช…์€ ๋‹ค์Œ์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค:

  • ์ž‘์—…: ์„œ๋ช…์ด ์ผ์น˜ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ผ์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ํ—ค๋”: ๊ทœ์น™์˜ ํ”„๋กœํ† ์ฝœ, IP ์ฃผ์†Œ, ํฌํŠธ ๋ฐ ๋ฐฉํ–ฅ์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ทœ์น™ ์˜ต์…˜: ๊ทœ์น™์˜ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
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;)

์œ ํšจํ•œ ์ž‘์—…์€

  • alert - ๊ฒฝ๊ณ  ์ƒ์„ฑ
  • pass - ํŒจํ‚ท์˜ ์ถ”๊ฐ€ ๊ฒ€์‚ฌ๋ฅผ ์ค‘์ง€
  • drop - ํŒจํ‚ท์„ ๋“œ๋กญํ•˜๊ณ  ๊ฒฝ๊ณ  ์ƒ์„ฑ
  • reject - ์ผ์น˜ํ•˜๋Š” ํŒจํ‚ท์˜ ๋ฐœ์‹ ์ž์—๊ฒŒ RST/ICMP ๋„๋‹ฌ ๋ถˆ๊ฐ€ ์˜ค๋ฅ˜ ์ „์†ก
  • rejectsrc - ๋‹จ์ˆœํžˆ _reject_์™€ ๋™์ผ
  • rejectdst - ์ผ์น˜ํ•˜๋Š” ํŒจํ‚ท์˜ ์ˆ˜์‹ ์ž์—๊ฒŒ RST/ICMP ์˜ค๋ฅ˜ ํŒจํ‚ท ์ „์†ก
  • rejectboth - ๋Œ€ํ™”์˜ ์–‘์ชฝ์— RST/ICMP ์˜ค๋ฅ˜ ํŒจํ‚ท ์ „์†ก

ํ”„๋กœํ† ์ฝœ

  • tcp (tcp ํŠธ๋ž˜ํ”ฝ์šฉ)
  • udp
  • icmp
  • ip (ip๋Š” โ€˜๋ชจ๋“ โ€™ ๋˜๋Š” โ€™์•„๋ฌดโ€™๋ฅผ ์˜๋ฏธ)
  • layer7 ํ”„๋กœํ† ์ฝœ: http, ftp, tls, smb, dns, sshโ€ฆ (์ž์„ธํ•œ ๋‚ด์šฉ์€ docs์—์„œ ํ™•์ธ)

์ถœ๋ฐœ์ง€ ๋ฐ ๋ชฉ์ ์ง€ ์ฃผ์†Œ

IP ๋ฒ”์œ„, ๋ถ€์ • ๋ฐ ์ฃผ์†Œ ๋ชฉ๋ก์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค:

์˜ˆ์‹œ์˜๋ฏธ
! 1.1.1.11.1.1.1์„ ์ œ์™ธํ•œ ๋ชจ๋“  IP ์ฃผ์†Œ
![1.1.1.1, 1.1.1.2]1.1.1.1๊ณผ 1.1.1.2๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  IP ์ฃผ์†Œ
$HOME_NETyaml์—์„œ ์„ค์ •ํ•œ HOME_NET
[$EXTERNAL_NET, !$HOME_NET]EXTERNAL_NET ๋ฐ HOME_NET ์ œ์™ธ
[10.0.0.0/24, !10.0.0.5]10.0.0.0/24์—์„œ 10.0.0.5 ์ œ์™ธ

์ถœ๋ฐœ์ง€ ๋ฐ ๋ชฉ์ ์ง€ ํฌํŠธ

ํฌํŠธ ๋ฒ”์œ„, ๋ถ€์ • ๋ฐ ํฌํŠธ ๋ชฉ๋ก์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค:

์˜ˆ์‹œ์˜๋ฏธ
any๋ชจ๋“  ์ฃผ์†Œ
[80, 81, 82]ํฌํŠธ 80, 81 ๋ฐ 82
[80: 82]80๋ถ€ํ„ฐ 82๊นŒ์ง€์˜ ๋ฒ”์œ„
[1024: ]1024๋ถ€ํ„ฐ ๊ฐ€์žฅ ๋†’์€ ํฌํŠธ ๋ฒˆํ˜ธ๊นŒ์ง€
!8080์„ ์ œ์™ธํ•œ ๋ชจ๋“  ํฌํŠธ
[80:100,!99]80๋ถ€ํ„ฐ 100๊นŒ์ง€์˜ ๋ฒ”์œ„์—์„œ 99 ์ œ์™ธ
[1:80,![2,4]]1-80 ๋ฒ”์œ„์—์„œ ํฌํŠธ 2์™€ 4 ์ œ์™ธ

๋ฐฉํ–ฅ

์ ์šฉ๋˜๋Š” ํ†ต์‹  ๊ทœ์น™์˜ ๋ฐฉํ–ฅ์„ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

source -> destination
source <> destination  (both directions)

ํ‚ค์›Œ๋“œ

Suricata์—๋Š” ์ฐพ๊ณ  ์žˆ๋Š” ํŠน์ • ํŒจํ‚ท์„ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋ฐฑ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํฅ๋ฏธ๋กœ์šด ๊ฒƒ์ด ๋ฐœ๊ฒฌ๋˜๋ฉด ์—ฌ๊ธฐ์—์„œ ์–ธ๊ธ‰๋ฉ๋‹ˆ๋‹ค. ๋” ๋งŽ์€ ์ •๋ณด๋Š” ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”!

# Meta Keywords
msg: "description"; #Set a description to the rule
sid:123 #Set a unique ID to the rule
rev:1 #Rule revision number
config classification: not-suspicious,Not Suspicious Traffic,3 #Classify
reference: url, www.info.com #Reference
priority:1; #Set a priority
metadata: key value, key value; #Extra metadata

# Filter by geolocation
geoip: src,RU;

# ICMP type & Code
itype:<10;
icode:0

# Filter by string
content: "something"
content: |61 61 61| #Hex: AAA
content: "http|3A|//" #Mix string and hex
content: "abc"; nocase; #Case insensitive
reject tcp any any -> any any (msg: "php-rce"; content: "eval"; nocase; metadata: tag php-rce; sid:101; rev: 1;)

# Replaces string
## Content and replace string must have the same length
content:"abc"; replace: "def"
alert tcp any any -> any any (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 regex
pcre:"/<regex>/opts"
pcre:"/NICK .*USA.*[0-9]{3,}/i"
drop tcp any any -> any any (msg:"regex"; pcre:"/CTF\{[\w]{3}/i"; sid:10001;)

# Other examples
## Drop by port
drop tcp any any -> any 8000 (msg:"8000 port"; sid:1000;)

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ