ith wireless networks beginning to dominate both home and corporate networking, new challenges on the security front are inevitable. The first step in securing a wireless network is determining the state of the network (without any prior knowledge) and then providing a defense against intrusions. Enter Scapy, an excellent packet-crafting tool written in Python by Philippe Biondi. Unlike other sniffers such as Kismet and Airodump-ng, Scapy is scriptable and extremely easy to use.
This article outlines a methodology for wireless network assessment and intrusion detection using proven techniques with tools such as Scapy.
The Methodology: Passive Sniffing
A wireless network consists of several stations, which can be divided into two categories: access points and NICs (network interface cards). These stations communicate using IEEE 802.11 standards. The 802.11 packets that the stations transmit consist of three types of frames: management, control, and data. Each of these frames contains critical information that can help in establishing and managing communication channels between stations.
A wireless network assessment methodology can employ one of two techniques:
This article discusses a passive-sniffing methodology. The following are the steps for this approach:
Setting Up the Station for RF Monitor Mode
When you set up a station for RF monitor mode, its NIC should be able to sniff the 2.4 GHz spectrum to capture 802.11 packets. Most 802.11a/b/g NICs have this capacity. For example, this article uses Linux to set up the NIC and the Linux kernel contains a driver to handle this capability.
Here is the command to put the interface in monitor mode:
root@bluelinux:/home/shreeraj/wifi# iwconfig eth1 mode monitor
root@bluelinux:/home/shreeraj/wifi# iwconfig eth1
eth1 IEEE 802.11b ESSID:"" Nickname:"Prism I"
Mode:Monitor Frequency:2.462 GHz Access Point: Not-Associated
Bit Rate:11 Mb/s Sensitivity:1/3
Retry min limit:8 RTS thr:off Fragment thr:off
Encryption key:off
Power Management:off
Link Quality=76/92 Signal level=-26 dBm Noise level=-149 dBm
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:0 Invalid misc:0 Missed beacon:0
Note: For madwifi, you may need to use the wlanconfig command to set it up.
Next, you need to define a channel or frequency on which to perform the packet sniffing. Use the following command (example for channel 11):
root@bluelinux:/home/shreeraj/wifi# iwconfig eth1 channel 11
You also can channel-hop to sniff different channels by assigning a slice of time to each of them.
Sniffing Packets and Discovering Network Access Points
Access points are critical infrastructure; they are the bridge between the wireless and wired IP networks. Other NICs connect these access points and add them to the larger network over wireless networks. Unfortunately, access points also are points of attack for malicious hackers. The first requirement for performing wireless network assessment is a simple discovery phase in which you identify possible access points.
Access points are configured to emit beacon management frames at regular intervals. These frames contain information about SSID, MAC address, timestamp, etc. Once the interface eth1 is in monitor mode, one can start accessing the beacon frames. You can use Scapy to access these packets as follows:
root@bluelinux:/home/shreeraj/wifi# scapy
Welcome to Scapy (1.0.4.1beta)
>>> conf.iface="eth1"
>>> p=sniff(count=1)
>>> p
>>> p[0]
>>>>>>>>>
>>>
The preceding block shows that Scapy has started and one packet on eth1 is sniffed. Viewing the contents of the packet reveals that it is clearly a Dot11 packet containing a beacon frame with information. Scapy provides a method for getting a pictorial view. Entering the following commands at the interactive prompt activates this method:
>>> pkt=p[0]
>>> pkt.pdfdump()
Figure 1 offers a peek at the PDF document of this particular packet.
| Figure 1. 802.11 Beacon Frame |
This frame helps you determine critical information such as MAC address of access point, SSID, and WEP support. You can build an identical view for all the different Dot11 packets and frames. This view is a great help in learning 802.11 standards.
The following is a set of commands that you can run to extract critical fields from the packet. This block provides the SSID and base MAC address:
>>> pkt.addr2
'00:12:17:3c:b6:ed'
>>> pkt.payload.payload.info
'netsquare4'
>>>
You can extract the same information from the following command as well using sprintf(), a nice method for printing out various fields of the packet.
>>> pkt.sprintf("%Dot11.addr2%[%Dot11Elt.info%|%Dot11Beacon.cap%]")
"00:12:17:3c:b6:ed['netsquare4'|ESS]"
>>>
The following is a simple script that collects all beacon packets and extracts information. It uses the list "unique" to maintain your list of collected beacons based on their MAC addresses. This provides a filtered view of the considerable air traffic.
#!/usr/bin/env python
import sys
from scapy import *
interface = sys.argv[1]
unique = []
def sniffBeacon(p):
if p.haslayer(Dot11Beacon):
if unique.count(p.addr2) == 0:
unique.append(p.addr2)
print p.sprintf("%Dot11.addr2%[%Dot11Elt.info%|%Dot11Beacon.cap%]")
sniff(iface=interface,prn=sniffBeacon)
Running this script produces the following output:
root@bluelinux:/home/shreeraj/wifi# ./sniffssid.py eth1
00:12:17:3c:b6:ed['netsquare4'|short-slot+ESS]
00:30:bd:ca:1e:1e['netsquare7'|ESS+privacy]
00:06:25:51:6b:79['\x00\x00\x00\x00\x00\x00\x00'|ESS+privacy]
Netsquare7 has a privacy bit turned on that suggests it is WEP supported. Running this script allows the discovery of wireless access points residing in the neighborhood, along with their configuration.
Discovering Hidden Access Points and SSID
In many cases access points are deployed in such a way that they are restricted from broadcasting beacon packets. At the same time it is also possible to cloak SSIDs so they cannot be determined by simply looking at the beacon. The previous example detected one beacon packet with cloaked SSID as shown below:
00:06:25:51:6b:79['\x00\x00\x00\x00\x00\x00\x00'|ESS+privacy]
You can sniff non-beacon packets and try to determine hidden access points or cloaked SSIDs. Management frames probe and associate disclose these values. Scapy has support for several of these layers as well, as shown below:
| >>> Dot11 | ||
| Dot11 | Dot11AssoResp | Dot11ProbeReq |
| Dot11ATIM | Dot11Auth | Dot11ProbeResp |
| Dot11Addr2MACField | Dot11Beacon | Dot11ReassoReq |
| Dot11Addr3MACField | Dot11Deauth | Dot11ReassoResp |
| Dot11Addr4MACField | Dot11Disas | Dot11WEP |
| Dot11AddrMACField | Dot11Elt | Dot11AssoReq |
| Dot11PacketList | ||
| >>> |
Here is a simple script to extract non-beacon packets and SSIDs:
#!/usr/bin/env python
import sys
from scapy import *
interface = sys.argv[1]
unique = []
def sniffNonBeacon(p):
if not p.haslayer(Dot11Beacon):
if unique.count(p.addr2) == 0:
unique.append(p.addr2)
print p.sprintf("[%Dot11.addr1%][%Dot11.addr2%][%Dot11Elt.info%]")
print p.summary()
sniff(iface=interface,prn=sniffNonBeacon)
This is the output of the script:
root@bluelinux:/home/shreeraj/wifi# ./sniffnb.py eth1
[00:0b:6c:21:27:c5][00:06:25:51:6b:79]['linksys']
802.11 Management 5L 00:06:25:51:6b:79 > 00:0b:6c:21:27:c5 / Dot11ProbeResp / SSID='linksys' / Dot11Elt / Dot11Elt
[00:06:25:51:6b:79][00:00:00:00:00:00][??]
802.11 Control 13L 00:00:00:00:00:00 > 00:06:25:51:6b:79
[ff:ff:ff:ff:ff:ff][00:0b:6c:21:27:c5]['linksys']
802.11 Management 4L 00:0b:6c:21:27:c5 > ff:ff:ff:ff:ff:ff / Dot11ProbeReq / SSID='linksys' / Dot11Elt
As is evident, we have harvested the 'linksys' SSID for the access point 00:06:25:51:6b:79, extracted from both probe request and response packet. Whenever a new client tries to access the access point, this packet is sent out "in the air" and is served by the corresponding access point. This way you can discover hidden networks in the air.
MAC and IP Address Harvesting
The MAC address of a station is a critical identity point for wireless networks. The Dot11 packet has four addresses at the top (see Figure 1). Addr1 is the address for recipients and addr2 is the address for transmitters. These MAC addresses can be harvested very easily. Here is a simple script to capture them:
import sys
from scapy import *
interface = sys.argv[1]
unique = []
def sniffMAC(p):
if p.haslayer(Dot11):
mac = p.sprintf("[%Dot11.addr1%)|(%Dot11.addr2%)|(%Dot11.addr3%)]")
if unique.count(mac) == 0:
unique.append(mac)
print mac
sniff(iface=interface,prn=sniffMAC)
The following is a sample output for the same:
root@bluelinux:/home/shreeraj/wifi# ./sniffmac.py eth1
[ff:ff:ff:ff:ff:ff)|(00:30:bd:ca:1e:1e)|(00:30:bd:ca:1e:1e)]
[ff:ff:ff:ff:ff:ff)|(00:12:17:3c:b6:ed)|(00:12:17:3c:b6:ed)]
[09:00:07:ff:ff:ff)|(00:12:17:3c:b6:ed)|(00:14:bf:6d:d5:4d)]
[00:12:17:3c:b6:ed)|(00:30:65:06:8c:eb)|(00:0f:a3:1f:b4:ff)]
This information can be linked to an access point's MAC address to get a list of clients connecting to that particular access point.
Another way of accessing some internal MAC addresses along with IP addresses is by capturing ARP and IP layers residing in the Dot11 packet. If packets are not encrypted with a WEP key, packets can reveal this internal information. Here is a sample script to harvest these packets and information:
import sys
from scapy import *
interface = sys.argv[1]
unique = []
def sniffarpip(p):
if p.haslayer(IP):
ip = p.sprintf("IP - [%IP.src%)|(%IP.dst%)]")
if unique.count(ip) == 0:
unique.append(ip)
print ip
elif p.haslayer(ARP):
arp = p.sprintf("ARP - [%ARP.hwsrc%)|(%ARP.psrc%)]-[%ARP.hwdst%)|(%ARP.pdst%)]")
if unique.count(arp) == 0:
unique.append(arp)
print arp
sniff(iface=interface,prn=sniffarpip)
Run this script to fetch IPs and ARPs:
root@bluelinux:/home/shreeraj/wifi# ./sniffarpip.py eth1
IP - [192.168.7.9)|(192.168.7.255)]
IP - [192.168.7.41)|(192.168.7.3)]
ARP - [00:0f:a3:1f:b4:ff)|(192.168.7.3)]-[00:00:00:00:00:00)|(192.168.7.41)]
ARP - [00:30:65:06:8c:eb)|(192.168.7.41)]-[00:0f:a3:1f:b4:ff)|(192.168.7.3)]
Some of these addresses may be internal to the network.
A MAC address can help an attacker hack into MAC-filtered access points. An access point authenticates MAC addresses in their auth frames before associating the client address, and an attacker can replicate this behavior by spoofing a MAC address extracted from the sniffed traffic. MAC-based filtering at access points is trivial.
Internal IP disclosure poses another threat. An attacker can bind to an IP address along with a MAC address to become a part of your internal network and start typical scanning tools against the ranges.
Further Intrusion Detection with Sniffing
The methodology defined so far can be used to build intrusion detection systems and can be deployed to monitor wireless traffic. You can sniff this traffic using Scapy and build a script on top of it. This script can help in tracking intrusion detections.
The following sections present some examples of these concepts.
Discovering Rogue Access Points
If an unauthorized access point is deployed on your network, an administrator can find the traffic and exclude it from the network by capturing beacon packets or analyzing wireless IP traffic. For example, suppose your network is 192.168.7.0 and it consists of one access point with an address of 00:15:3d:3c:a6:eb. Your objective is to track down any surrounding access points, other than this access point, that are accessing the 192.168.7.0 network. Here is a little script to monitor traffic:
#!/usr/bin/env python
from scapy import *
import re
interface = sys.argv[1]
baseMAC = sys.argv[2]
IPregex = sys.argv[3]
reg=re.compile(IPregex)
def monitorIPMAC(p):
if p.haslayer(IP):
iplayer = p.getlayer(IP)
if reg.match(iplayer.src) or reg.match(iplayer.dst):
if not (p.addr1==baseMAC or p.addr2==baseMAC or p.addr3==baseMAC):
print "---"
print "MAC->"+p.addr1+"|"+p.addr2+"|"+p.addr3
print "IP->"+iplayer.src+"|"+iplayer.dst
print "---"
sniff(iface=interface,prn=monitorIPMAC)
The preceding script captures all packets from the air and dissects the IP layer. A decision-making point is the source and destination IP address for the packets. If these packets are not part of an authorized access point defined by the MAC address, then they are reported. This can be a potential access point running on 192.168.7.0. You can verify its existence and traffic from the wire side once you notice intrusion to reduce false positives. This example uses regular expressions to compare the networks. Here's the output of the script:
root@linbliss:/home/shreeraj/idswifi# ./sniffRap.py eth2 00:15:3d:3c:a6:eb 192\.168\.7\.*
---
MAC->00:12:17:3c:b6:ed|00:06:25:09:49:f3|00:0f:a3:1f:b4:ff
IP->192.168.7.111|209.85.139.19
---
---
MAC->00:12:17:3c:b6:ed|00:06:25:09:49:f3|00:0f:a3:1f:b4:ff
IP->192.168.7.111|209.85.139.19
The preceding example takes 192\.168\.7\.*, an authorized MAC address of the access point. Traffic for the network 192.168.7.0 that originated from an unauthorized MAC (access point) was sniffed. This could be an intrusion in the network.
Discovering Dummy Access Point
A dummy access point started with the same SSID as a corporate network poses a threat to the network. You can detect this by capturing packets and comparing their MAC addresses with authorized MAC addresses. Here is a simple script to capture a dummy access point:
#!/usr/bin/env python
import sys
from scapy import *
interface = sys.argv[1]
ssid = "'"+sys.argv[2]+"'"
mac = sys.argv[3]
def monitorSSID(p):
if p.haslayer(Dot11Beacon):
pssid = p.sprintf("%Dot11Elt.info%")
pmac = p.sprintf("%Dot11.addr2%")
if(ssid == pssid):
if not (pmac==mac):
print "Dummy AP found -> "+pmac
sniff(iface=interface,prn=monitorSSID)
The preceding script takes an authorized access point with its base address and SSID and continues sniffing for beacon packets, while looking for the same SSID with a different base MAC. The script reports any and all access points located, as shown below:
root@linbliss:/home/shreeraj/idswifi# ./sniffDap.py eth2 netsquare4 00:12:17:3c:b6:eb
Dummy AP found -> 00:12:17:3c:b6:ed
Dummy AP found -> 00:12:17:3c:b6:ed
Unauthorized MAC Detections
You can detect an attacker who's trying to gain access to access points with MAC addresses that are not part of an authorized list by sniffing all the packets and determining the source of the probe. A list of authorized MACs can be built on the basis of IPs assigned by the DHCP server. For example, to observe traffic originating from unauthorized MACs, prepare a list of authorized MACs and place these in a file. Then use this script:
#!/usr/bin/env python
import sys
from scapy import *
interface = sys.argv[1]
baseMAC = sys.argv[2]
unique = []
macfile = open("authmac","r")
temp = macfile.readlines()
for line in temp:
authmac = line.rstrip("\n")
unique.append(authmac)
def monitorUnauthMAC(p):
if not p.haslayer(Dot11Beacon):
if (p.addr1==baseMAC or p.addr2==baseMAC or p.addr3==baseMAC):
if (unique.count(p.addr1) == 0 and unique.count(p.addr2) == 0 and unique.count(p.addr3) == 0):
print "Unathorized MAC->"+p.addr1+"|"+p.addr2+"|"+p.addr3
sniff(iface=interface,prn=monitorUnauthMAC)
Begin by reading the file and then keep monitoring the target access point. A Dot11 packet containing an unauthorized MAC is reported as shown below:
root@linbliss:/home/shreeraj/idswifi# ./sniffUnauthMAC.py eth2 00:15:3d:3c:a6:eb
Unathorized MAC->00:12:17:3c:b6:ed|00:30:65:06:8c:eb|00:50:56:07:01:80
Unathorized MAC->00:30:65:06:8c:eb|00:12:17:3c:b6:ed|00:50:56:07:01:80
This way you can keep monitoring unauthorized traffic coming from war drivers and maintain a whitelist of the MAC addresses.
Detecting Deauth and Disassociation Notification
Raw deauth and disassociation packets arriving from an unauthorized MAC address clearly represent a malicious attempt to disrupt the network. They can lead to denial-of-service (DoS) or man-in-the-middle attacks. The following script can report these packets, complete with MAC address. If the access point is not rebooted and these packets are observable, then someone may be injecting these packets at the client end.
#!/usr/bin/env python
import sys
from scapy import *
interface = sys.argv[1]
def monitorDPackets(p):
if p.haslayer(Dot11Deauth) or p.haslayer(Dot11Disas):
print "MAC->"+p.addr1+"|"+p.addr2+"|"+p.addr3
sniff(iface=interface,prn=monitorDPackets)
This way you can track down any intrusion coming from malicious hardware.
The following are a few other intrusion detection points that you can monitor:
With good sniffing scripts in place alerts can be generated to reduce threats to wireless infrastructure. Once this information is in place you can perform active assessment by injecting packets into a wireless network by patching the driver with appropriate capabilities. Here, too, Scapy comes in handy since it enables you to inject packets at Layer 2 using sendp().
Detect the Vulnerabilities in Your Wireless Network
While wireless assessment is becoming an integral part of penetration testing and network assessments, analyzing wireless networks and related products is a challenging task. The methodology discussed in this article in conjunction with Scapy can help you detect the vulnerabilities in your wireless networks. Scapy works in Python in both interactive and scripting modes, enhancing its effectiveness and making it a must-have tool in a wireless network assessment toolkit. Scapy is also extendable, allowing you to build powerful scripts for performing network monitoring.
| DevX is a division of Internet.com. © Copyright 2010 Internet.com. All Rights Reserved. Legal Notices |