Created
February 19, 2025 03:12
-
-
Save nullenc0de/a076a1a2ba01d7bedebf9ea57acf243f to your computer and use it in GitHub Desktop.
Egress_segment.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Colors for output | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
YELLOW='\033[1;33m' | |
BLUE='\033[0;34m' | |
NC='\033[0m' | |
# Function to discover networks | |
discover_networks() { | |
echo "Discovering network segments..." | |
declare -gA SEGMENTS | |
# Read local routes | |
while read -r line; do | |
if [[ $line =~ ^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+) ]]; then | |
network="${BASH_REMATCH[1]}" | |
# Skip loopback and default routes | |
if [[ $network != "127.0.0.0/8" && $network != "0.0.0.0/0" ]]; then | |
# Try to determine segment type based on IP range | |
if [[ $network == "10.152.10.0/24" ]]; then | |
SEGMENTS["CDE"]=$network | |
elif [[ $network == "192.168."* ]]; then | |
SEGMENTS["DMZ"]=$network | |
elif [[ $network == "10.191."* ]]; then | |
if [[ $network == "10.191.10.0/24" ]]; then | |
SEGMENTS["Corporate"]=$network | |
elif [[ $network == "10.191.20.0/24" ]]; then | |
SEGMENTS["Development"]=$network | |
fi | |
fi | |
fi | |
fi | |
done < <(ip route show) | |
echo "Discovered segments:" | |
for segment in "${!SEGMENTS[@]}"; do | |
echo " $segment: ${SEGMENTS[$segment]}" | |
done | |
} | |
# Function to determine allowed paths based on common rules | |
determine_allowed_paths() { | |
echo "Determining allowed communication paths..." | |
declare -ga ALLOWED_PATHS=() | |
# Add standard paths based on best practices | |
if [[ -n "${SEGMENTS[Corporate]}" && -n "${SEGMENTS[CDE]}" ]]; then | |
ALLOWED_PATHS+=("Corporate:CDE:443") # HTTPS access to CDE | |
fi | |
if [[ -n "${SEGMENTS[DMZ]}" && -n "${SEGMENTS[CDE]}" ]]; then | |
ALLOWED_PATHS+=("DMZ:CDE:443") # HTTPS access from DMZ to CDE | |
fi | |
if [[ -n "${SEGMENTS[Corporate]}" && -n "${SEGMENTS[DMZ]}" ]]; then | |
ALLOWED_PATHS+=("Corporate:DMZ:80") # HTTP access to DMZ | |
ALLOWED_PATHS+=("Corporate:DMZ:443") # HTTPS access to DMZ | |
fi | |
echo "Determined allowed paths:" | |
for path in "${ALLOWED_PATHS[@]}"; do | |
echo " $path" | |
done | |
} | |
# Initialize network configuration | |
discover_networks | |
determine_allowed_paths | |
# Allow manual override of detected configuration | |
if [[ -f "network_config.txt" ]]; then | |
echo "Found network_config.txt - loading manual configuration..." | |
source network_config.txt | |
fi | |
# Define egress test ports | |
declare -a TEST_PORTS=( | |
"21" # FTP | |
"22" # SSH | |
"23" # Telnet | |
"25" # SMTP | |
"53" # DNS | |
"80" # HTTP | |
"443" # HTTPS | |
"3389" # RDP | |
"8080" # Alt HTTP | |
"8443" # Alt HTTPS | |
) | |
# Test domains for egress | |
EGRESS_TEST_DOMAIN="letmeoutofyour.net" | |
RESPONSE_CHECK="w00tw00t" | |
echo -e "${BLUE}Starting PCI DSS v4.0 Network Testing...${NC}" | |
echo "Testing from IP: $(ip route get 1 | awk '{print $(NF-2);exit}')" | |
echo "----------------------------------------" | |
# Function to test TCP connectivity | |
test_tcp() { | |
local host=$1 | |
local port=$2 | |
timeout 2 nc -zv -w 2 $host $port &>/dev/null | |
return $? | |
} | |
# Function to get a random IP from a subnet | |
get_random_ip() { | |
local subnet=$1 | |
local network=$(echo $subnet | cut -d/ -f1) | |
local netmask=$(echo $subnet | cut -d/ -f2) | |
local prefix=$(echo $network | cut -d. -f1-3) | |
local random_last=$((RANDOM % 254 + 1)) | |
echo "${prefix}.${random_last}" | |
} | |
# Function to test egress connectivity | |
test_egress() { | |
local port=$1 | |
local protocol=$2 | |
echo -e "\n${YELLOW}Testing egress on port $port ($protocol)${NC}" | |
case $protocol in | |
"TCP") | |
# Try HTTP/HTTPS connection | |
if [[ $port == "80" || $port == "443" ]]; then | |
response=$(curl -s -m 5 ${protocol,,}://$EGRESS_TEST_DOMAIN:$port 2>/dev/null) | |
if [[ $response == *"$RESPONSE_CHECK"* ]]; then | |
echo -e "${RED}WARNING: Egress allowed on port $port${NC}" | |
return 0 | |
fi | |
fi | |
# Try direct TCP connection | |
if nc -zv -w 5 $EGRESS_TEST_DOMAIN $port 2>/dev/null; then | |
echo -e "${RED}WARNING: Egress allowed on port $port${NC}" | |
return 0 | |
fi | |
;; | |
"UDP") | |
# Try UDP connection | |
echo "Testing UDP..." | nc -u -w 5 $EGRESS_TEST_DOMAIN $port &>/dev/null | |
if [[ $? -eq 0 ]]; then | |
echo -e "${RED}WARNING: UDP egress allowed on port $port${NC}" | |
return 0 | |
fi | |
;; | |
esac | |
echo -e "${GREEN}Egress blocked on port $port${NC}" | |
return 1 | |
} | |
echo -e "\n${BLUE}Phase 1: Testing Network Segmentation${NC}" | |
# Test allowed paths | |
for path in "${ALLOWED_PATHS[@]}"; do | |
IFS=':' read -r source_seg dest_seg port <<< "$path" | |
echo -e "\nTesting $source_seg to $dest_seg on port $port" | |
source_ip=$(get_random_ip "${SEGMENTS[$source_seg]}") | |
dest_ip=$(get_random_ip "${SEGMENTS[$dest_seg]}") | |
if test_tcp $dest_ip $port; then | |
echo -e "${GREEN}SUCCESS - Connection allowed as expected${NC}" | |
else | |
echo -e "${RED}FAIL - Expected connection blocked${NC}" | |
fi | |
done | |
# Test segment isolation | |
for source_seg in "${!SEGMENTS[@]}"; do | |
for dest_seg in "${!SEGMENTS[@]}"; do | |
if [ "$source_seg" != "$dest_seg" ]; then | |
# Skip allowed paths | |
skip=false | |
for allowed in "${ALLOWED_PATHS[@]}"; do | |
IFS=':' read -r as ds port <<< "$allowed" | |
if [ "$source_seg" == "$as" ] && [ "$dest_seg" == "$ds" ]; then | |
skip=true | |
break | |
fi | |
done | |
if [ "$skip" == "false" ]; then | |
source_ip=$(get_random_ip "${SEGMENTS[$source_seg]}") | |
dest_ip=$(get_random_ip "${SEGMENTS[$dest_seg]}") | |
echo -e "\nTesting isolation between $source_seg and $dest_seg" | |
for port in "${TEST_PORTS[@]}"; do | |
if test_tcp $dest_ip $port; then | |
echo -e "${RED}FAIL - Unexpected access allowed on port $port${NC}" | |
else | |
echo -e "${GREEN}SUCCESS - Connection blocked as expected on port $port${NC}" | |
fi | |
done | |
fi | |
fi | |
done | |
done | |
echo -e "\n${BLUE}Phase 2: Testing Egress Controls${NC}" | |
# Test egress using letmeoutofyour.net | |
echo "Testing egress using $EGRESS_TEST_DOMAIN" | |
# Test TCP ports | |
for port in "${TEST_PORTS[@]}"; do | |
test_egress $port "TCP" | |
done | |
# Test UDP ports | |
for port in "${TEST_PORTS[@]}"; do | |
test_egress $port "UDP" | |
done | |
# Test DNS exfiltration | |
echo -e "\n${YELLOW}Testing DNS Exfiltration${NC}" | |
if host "test.$EGRESS_TEST_DOMAIN" &>/dev/null; then | |
echo -e "${RED}WARNING: DNS queries to external domains allowed${NC}" | |
else | |
echo -e "${GREEN}SUCCESS - DNS queries restricted${NC}" | |
fi | |
echo -e "\n${BLUE}Testing Complete${NC}" | |
echo "Review results against network diagrams and PCI requirements" | |
echo "Remember to test from multiple network segments for comprehensive coverage" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment