Network.Security.Tools [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Network.Security.Tools [Electronic resources] - نسخه متنی

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید









10.3. libpcap and 802.11 Wireless Networks



As shown in Table 10-2, libpcap supports packet
capture from a wide variety of link types, including several link
types related to 802.11 wireless networks.


The Arpsniff tool we just demonstrated was designed to work only on
Ethernet networks (or more specifically, Ethernet II networks). We check the
link type of the network interface because we receive different types
of packet frames from the interface depending on the link type
reported. For example, Arpsniff is expecting to receive an Ethernet
II frame, containing an ARP packet. In this case, we know the
Ethernet II frame has a header consisting of 14 bytes, as shown in
Figure 10-2.




Figure 10-2. Ethernet II header format



Had Arpsniff been capturing packets from an 802.11

wireless network, however, something
such as the 802.11 packet header shown in Figure 10-3 would have been present.




Figure 10-3. Header format



In addition to expecting the correct packet framing for the data link
type we are using, there is one other major obstacle to successful
packet capture from wireless networks, and that is monitor
mode.



10.3.1. 802.11 Monitor Mode



In 802.11
wireless networks you are generally
interested in capturing all information on a particular frequency or
channel, regardless of the network the traffic belongs to.
Unfortunately, putting an 802.11 wireless card into promiscuous mode
does not allow you to capture all packets on a channel; rather, it
allows you to capture only the packets on the network you are
attached to on that channel. To capture all packets on a channel, you
need to put the card into a special mode known as
monitor or rfmon mode.



Monitor mode is the mode for monitoring traffic, usually on a
particular channel. A lot of wireless hardware is capable of entering
monitor mode, but the ability to set the wireless hardware into
monitor mode depends on support within the wireless driver. As such,
you can force many cards into monitor mode in Linux, but in Windows
you will probably need to write your own wireless network card
driver.



Table 10-5 shows some ways to make common 802.11 wireless cards enter
monitor mode. A good reference for cards capable of entering monitor
mode is available from the web site for the Kismet tool, located at
http://www.kismetwireless.net.



Table 10-5. Example commands to enter monitor mode



Driver/card




Operating system




Command




Cisco Aironet




Linux




Echo "mode: y" >
'/proc/driver/aironet/<device>/Config'




HostAP




Linux




iwconfig <device> mode monitor




Orinoco (patched)




Linux




iwpriv <device> monitor 1 <channel>




Madwifi




Linux




iwconfig <device> mode monitor




Wlan-ng




Linux




wlanctl-ng <device> lnxreq_wlansniff
channel=<channel> enable=true




Radiotap




FreeBSD




ifconfig <device> monitor up



Another complication when capturing packets from a wireless card in
monitor mode is that there is less consistency in packet-framing
format. In addition to the 802.11 packet header shown in Figure 10-3, many wireless drivers return custom headers
detailing a number of pieces of information about the captured
packet, such as signal strength and noise values. The two most common
of these are the Prism header and the AVS header.


The Prism monitor mode header was originally developed as part of the
linux-wlan-ng project (http://www.linux-wlan.com/), and was designed
for use when developing drivers for the Prism II 802.11b card for
Linux. Now this format is supported on a wide variety of drivers, and
it is supported by libpcap as the
DLT_PRISM_HEADER link type. The Prism monitor mode
header is of the following format:


struct prism_value
{
uint32 did;
uint16 status;
uint16 len;
uint32 data;
};
struct prism_header
{
uint32 msgcode;
uint32 msglen;
u8char devname[16];
struct prism_value hosttime;
struct prism_value mactime;
struct prism_value channel;
struct prism_value rssi;
struct prism_value sq;
struct prism_value signal;
struct prism_value noise;
struct prism_value rate;
struct prism_value istx;
struct prism_value frmlen;
};


The AVS
capture header is a newer development designed to replace the Prism
monitor mode header. In addition to providing additional information,
the AVS capture header can capture information about 802.11a and
802.11g packet-capture sources. The
doc/capturefrm.txt file in the linux
wlan-ng driver package is available from struct AVS_header
{
uint32 version;
uint32 length;
uint64 mactime;
uint64 hosttime;
uint32 phytype;
uint32 channel;
uint32 datarate;
uint32 antenna;
uint32 priority;
uint32 ssi_type;
int32 ssi_signal;
int32 ssi_noise;
uint32 preamble;
uint32 encoding;
};


Most recent wireless drivers that are capable of entering monitor
mode support either a Prism monitor mode header or the AVS capture
header, or both. Where possible you should use the AVS capture
format, as this is better documented (i.e., it
is documented, period) and is designed to be
extensible to support newer technologies.



10.3.2. Adapting Arpsniff to 802.11



To adapt Arpsniff to capture information
from a wireless packet-capture source, we need to make a few changes
to the application logic. We assume the wireless device used in this
example supports the AVS wireless capture format.


First of all, we need to specify the sizes of some of the additional
frames captured:


/* ugly shortcuts - Defining our header types */
#define ETH_HEADER_SIZE 14
#define AVS_HEADER_SIZE 64 /* AVS capture header size */
#define DATA_80211_FRAME_SIZE 24 /* header for 802.11 data packet */
#define LLC_HEADER_SIZE 8 /* LLC frame for encapsulation */


We are specifying additional header sizes because of the additional
headers our ARP packet has when
capturing from a wireless source due to RFC 1042 IP encapsulation, as
shown in Figure 10-4.




Figure 10-4. ARP packet format on 802.11 from an AVS capture source



To determine the type of packet embedded in the 802.11 packet, we
need to have a definition for the LLC header so that we can extract
the ether_type value:


/* SNAP LLC header format */
struct snap_header
{
u_int8_t dsap;
u_int8_t ssap;
u_int8_t ctl;
u_int16_t org;
u_int8_t org2;
u_int16_t ether_type; /* ethernet type */
} _ _attribute_ _ ((_ _packed_ _));


Now we can alter the
process_packet function to work with a captured
802.11 packet from an AVS wireless source:


/* callback function to process a packet when captured */
void
process_packet (u_char * args, const struct pcap_pkthdr *header,
const u_char * packet)
{
struct ether_header *eth_header; /* in ethernet.h included by if_eth.h */
struct snap_header *llc_header; /* RFC 1042 encapsulation header */
struct ether_arp *arp_packet; /* from if_eth.h */
if (wired) /* global flag - wired or wireless? */
{
eth_header = (struct ether_header *) packet;
arp_packet = (struct ether_arp *) (packet + ETH_HEADER_SIZE);
if (ntohs (eth_header->ether_type) != ETHERTYPE_ARP) return;
} else { /* wireless */
llc_header = (struct snap_header *)
(packet + AVS_HEADER_SIZE + DATA_80211_FRAME_SIZE);
arp_packet = (struct ether_arp *)
(packet + AVS_HEADER_SIZE + DATA_80211_FRAME_SIZE + LLC_HEADER_SIZE);
if (ntohs (llc_header->ether_type) != ETHERTYPE_ARP) return;
}
printf ("Source: %d.%d.%d.%d\t\tDestination: %d.%d.%d.%d\n",
arp_packet->arp_spa[0],
arp_packet->arp_spa[1],
arp_packet->arp_spa[2],
arp_packet->arp_spa[3],
arp_packet->arp_tpa[0],
arp_packet->arp_tpa[1],
arp_packet->arp_tpa[2],
arp_packet->arp_tpa[3]);
}


You might have noticed that we have introduced a global flag called
wired which we are going to use to determine a
packet's framing type. We will set this further down
in Arpsniff when we check the link type using
pcap_datalink:


  /* find out the datalink type of the connection */
if (pcap_datalink (handle) == DLT_EN10MB)
{
wired = 1; /* ethernet link */
} else {
if (pcap_datalink (handle) == DLT_IEEE802_11_RADIO_AVS)
{
wired = 0; /* wireless */
} else {
fprintf (stderr, "I don't support this interface type!\n");
exit (1);
}
}


Once we have made the preceding changes, Arpsniff is ready to capture
ARP packets from a wireless network interface in monitor mode. The
full source code for the updated version of Arpsniff is included in
Example 10-4.



Example 10-4. Arpsniff2 source code


#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <net/if.h>
#include <pcap.h>
#include <netinet/if_ether.h>
/* ugly shortcut -- Ethernet packet headers are 14 bytes */
#define ETH_HEADER_SIZE 14
#define AVS_HEADER_SIZE 64 /* AVS capture header size */
#define DATA_80211_FRAME_SIZE 24 /* header for 802.11 data packet */
#define LLC_HEADER_SIZE 8 /* LLC frame for encapsulation */
/* SNAP LLC header format */
struct snap_header
{
u_int8_t dsap;
u_int8_t ssap;
u_int8_t ctl;
u_int16_t org;
u_int8_t org2;
u_int16_t ether_type; /* ethernet type */
} __attribute__ ((__packed_ _));
/* for the sake of clarity we'll use globals for a few things */
char *device; /* device to sniff on */
int verbose = 0; /* verbose output about device */
pcap_t *handle; /* handle for the opened pcap session */
int wired=0; /* flag for wired/wireless */
/* gracefully handle a Control C */
void
ctrl_c ( )
{
printf ("Exiting\n");
pcap_breakloop (handle); /* tell pcap_loop or pcap_dispatch to stop capturing */
pcap_close(handle);
exit (0);
}
/* usage */
void
usage (char *name)
{
printf ("%s - simple ARP sniffer\n", name);
printf ("Usage: %s [-i interface] [-l] [-v]\n", name);
printf (" -i interface to sniff on\n");
printf (" -l list available interfaces\n");
printf (" -v print verbose info\n\n");
exit (1);
}
/* callback function to process a packet when captured */
void
process_packet (u_char * args, const struct pcap_pkthdr *header,
const u_char * packet)
{
struct ether_header *eth_header; /* in ethernet.h included by if_eth.h */
struct snap_header *llc_header; /* RFC 1042 encapsulation header */
struct ether_arp *arp_packet; /* from if_eth.h */
if (wired) /* global flag - wired or wireless? */
{
eth_header = (struct ether_header *) packet;
arp_packet = (struct ether_arp *) (packet + ETH_HEADER_SIZE);
if (ntohs (eth_header->ether_type) != ETHERTYPE_ARP) return;
} else { /* wireless */
llc_header = (struct snap_header *)
(packet + AVS_HEADER_SIZE + DATA_80211_FRAME_SIZE);
arp_packet = (struct ether_arp *)
(packet + AVS_HEADER_SIZE + DATA_80211_FRAME_SIZE + LLC_HEADER_SIZE);
if (ntohs (llc_header->ether_type) != ETHERTYPE_ARP) return;
}
printf ("Source: %d.%d.%d.%d\t\tDestination: %d.%d.%d.%d\n",
arp_packet->arp_spa[0],
arp_packet->arp_spa[1],
arp_packet->arp_spa[2],
arp_packet->arp_spa[3],
arp_packet->arp_tpa[0],
arp_packet->arp_tpa[1],
arp_packet->arp_tpa[2],
arp_packet->arp_tpa[3]);
}
int
main (int argc, char *argv[])
{
char o; /* for option processing */
char errbuf[PCAP_ERRBUF_SIZE]; /* pcap error messages buffer */
struct pcap_pkthdr header; /* packet header from pcap */
const u_char *packet; /* packet */
bpf_u_int32 netp; /* ip address of interface */
bpf_u_int32 maskp; /* subnet mask of interface */
char *filter = "arp"; /* filter for BPF (human readable) */
struct bpf_program fp; /* compiled BPF filter */
int r; /* generic return value */
pcap_if_t *alldevsp; /* list of interfaces */
while ((o = getopt (argc, argv, "i:vl")) > 0)
{
switch (o)
{
case 'i':
device = optarg;
break;
case 'l':
if (pcap_findalldevs (&alldevsp, errbuf) < 0)
{
fprintf (stderr, "%s", errbuf);
exit (1);
}
while (alldevsp != NULL)
{
printf ("%s\n", alldevsp->name);
alldevsp = alldevsp->next;
}
exit (0);
case 'v':
verbose = 1;
break;
default:
usage (argv[0]);
break;
}
}
/* setup signal handler so Control-C will gracefully exit */
signal (SIGINT, ctrl_c);
/* find device for sniffing if needed */
if (device == NULL) /* if user hasn't specified a device */
{
device = pcap_lookupdev (errbuf); /* let pcap find a compatible device */
if (device == NULL) /* there was an error */
{
fprintf (stderr, "%s", errbuf);
exit (1);
}
}
/* set errbuf to 0 length string to check for warnings */
errbuf[0] = 0;
/* open device for sniffing */
handle = pcap_open_live (device, /* device to sniff on */
BUFSIZ, /* maximum number of bytes to capture per packet */
/* BUFSIZE is defined in pcap.h */
1, /* promisc - 1 to set card in promiscuous mode, 0 to not */
0, /* to_ms - amount of time to perform packet capture in milliseconds */
/* 0 = sniff until error */
errbuf); /* error message buffer if something goes wrong */
if (handle == NULL) /* there was an error */
{
fprintf (stderr, "%s", errbuf);
exit (1);
}
if (strlen (errbuf) > 0)
{
fprintf (stderr, "Warning: %s", errbuf); /* a warning was generated */
errbuf[0] = 0; /* re-set error buffer */
}
if (verbose)
{
printf ("Using device: %s\n", device);
/* printf ("Using libpcap version %s", pcap_lib_version); */
}
/* find out the datalink type of the connection */
if (pcap_datalink (handle) == DLT_EN10MB)
{
wired = 1; /* ethernet link */
} else {
if (pcap_datalink (handle) == DLT_IEEE802_11_RADIO_AVS)
{
wired = 0; /* wireless */
} else {
fprintf (stderr, "I don't support this interface type!\n");
exit (1);
}
}
/* get the IP subnet mask of the device, so we set a filter on it */
if (pcap_lookupnet (device, &netp, &maskp, errbuf) == -1)
{
fprintf (stderr, "%s", errbuf);
exit (1);
}
/* compile the filter, so we can capture only stuff we are interested in */
if (pcap_compile (handle, &fp, filter, 0, maskp) == -1)
{
fprintf (stderr, "%s", pcap_geterr (handle));
exit (1);
}
/* set the filter for the device we have opened */
if (pcap_setfilter (handle, &fp) == -1)
{
fprintf (stderr, "%s", pcap_geterr (handle));
exit (1);
}
/* we'll be nice and free the memory used for the compiled filter */
pcap_freecode (&fp);
if ((r = pcap_loop (handle, -1, process_packet, NULL)) < 0)
{
if (r == -1) /* pcap error */
{
fprintf (stderr, "%s", pcap_geterr (handle));
exit (1);
}
/* otherwise return should be -2, meaning pcap_breakloop has been called */
}
/* close our devices */
pcap_close (handle);
}



If the wireless network is using encryption, we are not going to be
able to intercept all traffic in a readable format. Unfortunately, we
cannot be in monitor mode and have the wireless card decrypting data
for us, so any data requiring decryption should be captured while not
in monitor mode, or else the tool will have to implement decryption
for the

captured
data.



/ 85