gotr00t@firewall:~$

Reading the Room: Detecting Firewalls Before They Detect You

Firewalls on Linux

Whats a firewall on Linux? A firewall installed on a Linux system acts as a traffic filtering system that controls which network activities ares allowed. It enforces security policy by inspecting packet headers and deciding to accept, drop or reject them.

Why detect firewalls?

Detecting firewalls during post exploitation its about mapping the control plane of the network, it allows you to understand what security boundaries exist and how traffic is filtered.

Defining the Attack Surface

A firewall can determine which ports are reachable, which protocols are allowed and what hosts and services are exposed. Without detecting this attack surface you may wast time attacking blocked ports and miss reachable services on alternate ports.

A lot of different firewall policies leak information through packet behavior. These behaviors allow you to identify if there's a firewall blocking your requests.

Main Linux Firewalls

1. Iptables

Low-level CLI to configure Netfilter using tables and chains.

iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -j DROP

Lets look at these 2 commands, at first glance they're short, but together they implement a strong default and deny firewall policy.

First rule — allow SSH:

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

What each part means:

  1. -A INPUT: append rule to the INPUT chain (traffic coming into this machine)
  2. -p tcp: match TCP packets only
  3. --dport 22: match destination port 22
  4. -j ACCEPT: allow the packet

Second rule — drop everything else:

iptables -A INPUT -j DROP

What it means:

  1. -A INPUT: still filtering inbound traffic
  2. -j DROP: silently discard packets

2. Nftables

Successor to iptables. Unified, faster, simpler rule engine.

nft add rule inet filter input tcp dport 22 accept

This command allows incoming SSH traffic.

3. Firewalld

Higher-level service that manages nftables/iptables underneath.

firewall-cmd --add-service=ssh
firewall-cmd --permanent --add-service=http

These 2 commands allows SSH now and also allows HTTP permanently.

4. UFW

Simple frontend to iptables/nftables, beginner-friendly.

ufw allow 22
ufw enable

These 2 commands will allow SSH access and turn the firewall on.

Automating the Process of Detecting Firewalls

I wrote a simple but effective Bash script that detects which firewalls are installed and running on a Linux system. This is the first time I'm sharing the code publicly.

fw_detect.sh:

#!/bin/bash
# fw_detect.sh — Quick Linux firewall detection
# by c0d3Ninja

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
RESET='\033[0m'

echo -e "${BOLD}${CYAN}[*] Firewall Detection${RESET}"
echo -e "─────────────────────────────────"
found=0

# iptables
if command -v iptables &>/dev/null; then
    rules=$(iptables -L -n 2>/dev/null | grep -cve '^Chain\|^target\|^$' 2>/dev/null)
    if [ "$rules" -gt 0 ] 2>/dev/null; then
        echo -e "${GREEN}[+] iptables${RESET} — ACTIVE ($rules rules)"
        found=1
    else
        echo -e "${YELLOW}[~] iptables${RESET} — installed, no rules"
    fi
fi

# nftables
if command -v nft &>/dev/null; then
    tables=$(nft list tables 2>/dev/null | wc -l)
    if [ "$tables" -gt 0 ] 2>/dev/null; then
        echo -e "${GREEN}[+] nftables${RESET} — ACTIVE ($tables tables)"
        found=1
    else
        echo -e "${YELLOW}[~] nftables${RESET} — installed, no tables"
    fi
fi

# ufw
if command -v ufw &>/dev/null; then
    status=$(ufw status 2>/dev/null | head -1)
    if echo "$status" | grep -qi "active"; then
        echo -e "${GREEN}[+] ufw${RESET} — ACTIVE"
        found=1
    else
        echo -e "${YELLOW}[~] ufw${RESET} — installed, inactive"
    fi
fi

# firewalld
if command -v firewall-cmd &>/dev/null; then
    if firewall-cmd --state 2>/dev/null | grep -qi "running"; then
        zone=$(firewall-cmd --get-default-zone 2>/dev/null)
        echo -e "${GREEN}[+] firewalld${RESET} — ACTIVE (zone: $zone)"
        found=1
    else
        echo -e "${YELLOW}[~] firewalld${RESET} — installed, not running"
    fi
fi

# CSF (ConfigServer Firewall)
if command -v csf &>/dev/null; then
    if csf -l &>/dev/null; then
        echo -e "${GREEN}[+] CSF${RESET} — ACTIVE"
        found=1
    else
        echo -e "${YELLOW}[~] CSF${RESET} — installed"
    fi
fi

# APF (Advanced Policy Firewall)
if command -v apf &>/dev/null; then
    echo -e "${GREEN}[+] APF${RESET} — installed"
    found=1
fi

# Shorewall
if command -v shorewall &>/dev/null; then
    if shorewall status 2>/dev/null | grep -qi "running"; then
        echo -e "${GREEN}[+] Shorewall${RESET} — ACTIVE"
        found=1
    else
        echo -e "${YELLOW}[~] Shorewall${RESET} — installed, not running"
    fi
fi

# fail2ban
if command -v fail2ban-client &>/dev/null; then
    jails=$(fail2ban-client status 2>/dev/null | grep "Number of jail" | awk '{print $NF}')
    if [ -n "$jails" ] && [ "$jails" -gt 0 ] 2>/dev/null; then
        echo -e "${GREEN}[+] fail2ban${RESET} — ACTIVE ($jails jails)"
        found=1
    else
        echo -e "${YELLOW}[~] fail2ban${RESET} — installed"
    fi
fi

# SELinux
if command -v getenforce &>/dev/null; then
    mode=$(getenforce 2>/dev/null)
    if [ "$mode" = "Enforcing" ]; then
        echo -e "${GREEN}[+] SELinux${RESET} — ENFORCING"
        found=1
    elif [ "$mode" = "Permissive" ]; then
        echo -e "${YELLOW}[~] SELinux${RESET} — Permissive (logging only)"
    else
        echo -e "${YELLOW}[~] SELinux${RESET} — Disabled"
    fi
fi

# AppArmor
if command -v aa-status &>/dev/null; then
    profiles=$(aa-status 2>/dev/null | grep "profiles are in enforce" | awk '{print $1}')
    if [ -n "$profiles" ] && [ "$profiles" -gt 0 ] 2>/dev/null; then
        echo -e "${GREEN}[+] AppArmor${RESET} — ACTIVE ($profiles enforced profiles)"
        found=1
    else
        echo -e "${YELLOW}[~] AppArmor${RESET} — installed"
    fi
fi

# AWS Security Groups (check if running on EC2)
if curl -s --connect-timeout 1 http://169.254.169.254/latest/meta-data/ &>/dev/null; then
    echo -e "${CYAN}[*] AWS EC2${RESET} — Security Groups likely in place"
fi

# Check for related systemd services
echo ""
echo -e "${BOLD}${CYAN}[*] Firewall Services${RESET}"
echo -e "─────────────────────────────────"
for svc in iptables nftables ufw firewalld csf fail2ban apparmor; do
    status=$(systemctl is-active $svc 2>/dev/null)
    if [ "$status" = "active" ]; then
        echo -e "${GREEN}[+] $svc.service${RESET} — running"
    elif systemctl list-unit-files 2>/dev/null | grep -q "^${svc}"; then
        echo -e "${YELLOW}[~] $svc.service${RESET} — installed, $status"
    fi
done

# Open ports as seen internally
echo ""
echo -e "${BOLD}${CYAN}[*] Listening Ports${RESET}"
echo -e "─────────────────────────────────"
if command -v ss &>/dev/null; then
    ss -tlnp 2>/dev/null | tail -n +2
elif command -v netstat &>/dev/null; then
    netstat -tlnp 2>/dev/null | tail -n +2
fi

echo ""
if [ "$found" -eq 0 ]; then
    echo -e "${RED}${BOLD}[!] No active firewall detected${RESET}"
else
    echo -e "${GREEN}${BOLD}[+] Firewall(s) detected${RESET}"
fi

Once you identify which firewall services are installed on the compromised system, you can adjust rules to allow specific ports and services or otherwise modify the firewall configuration to remove restrictions and continue further testing.

HACKING FROM THE SHADOWS!