Constantine M. Maximov, PhD CS
© 2001-2005

Sniffer: a shield and a sword.

The sniffing principles.

Sniffer is a computer program which allows to listen and intercept network traffic. Discussing sniffers one usually draws an analogy with listening telephone conversations. Having connected to a telephone line, it is possible to intercept conversation of people. Similar technique is used in computer networks to intercept the information which computers exchange. Listening is possible due to the feature of the Ethernet network (IEEE 802.3). The architecture of the majority of local area networks (LAN) is based on Ethernet technology in which all devices are connected to and share one media. Topology of the Ethernet network can be linear or star-shaped, and the speed of data transmission can be 10, 100 and 1000 Mbits per second. Ethernet is a broadcasting network in which all devices can receive all messages passed through the network. This feature simplifies the sniffing process. There is no necessity for the non-authorized connection to a network segment and it is not required to cut cables. The computer, from which it is supposed to listen, is already connected to some network segment.

Sniffer analyzes data packets that pass through computers' network card. Inside network segment all packets are dispatched to all computers and so it is possible to listen to and intercept network data. Use of switchboards (switches, hub-switches) sometimes provides protection against listening and sniffing. The data between network segments pass through these switches. Switching of packets is the form of data transfer at which the data is splitted into packets. The packets can be sent from a source to destination by different routes. When someone in a network segment sends data inside the segment then the switchboard will not send the data across the segments' boundary.

Listening applications and packets analyzers are utilities with double purpose. On the one hand sniffer is a powerful weapon which makes it possible to inflict a passive attack on a network. Such applications are threat to network users because they steal information, intercept and decipher logins, names and passwords of users. It is known that many network protocols (FTP, POP, HTTP, Telnet) transfer information between client and server without any encryption. Therefore it is easy to get access to someone's information. Just download, configure and launch sniffer and wait, until the victim is connected to a server. On the other hand sniffers can help system administrators to carry out diagnostics of a network and to trace attacks of hackers. Also such applications can be used for detailed analysis of network configuration and data flow over network. In other words sniffer is a shield and a sword.

Let's consider the sniffer from the programmers' point of view. We shall see that such a utility can be a powerful tool for debugging and tracing network applications. First of all it applies to the network software and distributed information systems and client-server applications. This article is addressed to programmers and to network researchers, but not to evil-hackers.

Every device connected to the Ethernet-network receives all the data that is passed on the segment. By default the network card processes only data that is addressed to it. However listening programs turn network card in a mode of reception of all packages - promiscuous mode. Almost every sniffer is based on network drivers and libraries (libpcap, libnet) which carry out the most part of work. Low-level programming is required to turn network card into promiscuous mode. Only kernel-mode device drivers can do such work in multitask operating systems. The first programs of such type were created for Unix-systems. It is simple to turn the network card into such a mode. In Unix-console we should type the command:

$ifconfig eth0 promisc;

Soon sniffers were developed for the popular Windows operating system, but to work in this system they needed access to the network driver and the ability to switch network card (NIC - network interface card) into the promiscuous mode. Now it is easy to create the program to listen to a network segment for Windows 2000.

However before we start coding listening utility it is necessary to understand basics of data transfer over a network. Machines are not humans. Machines communicate among themselves with certain rules and protocols.

Basics of data transmission over Ethernet-networks.

Each device in Ethernet-network has unique six-byte MAC-address (Media Access Control). Frame is the unit of data transmission in this network. The frame contains MAC-addresses of the source and destination devices.

struct ETHERNET_FRAME
{
	unsigned char dest [6]; // destination device MAC-address (receiver)
	unsigned char src [6];  // source device MAC-address
	unsigned short type;    // version: IPv4 0x0800, IPv6 0x86DD, ARP 0x0806
	unsigned char data [];  // frame data (usually IP packet)
};

The frame size can be 60 to 1514 bytes and the first 14 bytes are the frame header. To transfer more data the driver splits the data into several fragments and sends them in different frames. The frame is injected to the network and every device receives it. Variable named "type" defines a frame type and its version. The finishing section of the frame is used to check the integrity of the transmitted data, CRC error detection code (CRC32 - cyclic redundancy check). This code is calculated with the hash-function and is used to reveal distortion of the transmitted data.

Now take a look at the "data[]" section of the frame. Usually this is an IP-packet (Internet Protocol) or ARP-packet. ARP (Address Resolution Protocol) is an auxiliary broadcasting service that is used to translate IP-addresses to MAC-addresses of devices.

struct ETHERNET_ARP
{
	unsigned short hrd;     // Type of the media (Ethernet), 0x0001.
	unsigned short pro;     // Protocol (IP), 0x0800.
	unsigned char  hln;     // Length of hardware (MAC) address, 6 bytes.
	unsigned char  pln;     // Length of the protocol address (IP), 4 bytes.
	unsigned short  op;     // Operation {request, reply} = {1, 2}.
	unsigned char  sha [6]; // Hardware (MAC) address of the sender.
	unsigned char  spa [4]; // IP-address of the sender.
	unsigned char  tha [6]; // Target hardware (MAC) address.
	unsigned char  tpa [4]; // Target IP-address.
};

To deliver a packet in a network it is necessary to find the physical address of the destination device (network card or router). ARP is used for this purpose and it maps logical addresses to physical addresses (IP < = > MAC). RARP (Reverse ARP) is used to translate physical address to logical address (MAC < = > IP). When one computer needs to begin data exchange with another, it searches ARP-table for MAC-address of the destination host by the given IP-address. If it can't find MAC-address in ARP-table then it uses ARP protocol. It sends broadcasting ARP-packet (request) which contains target IP-address and the empty MAC-address (FF:FF:FF:FF:FF:FF). Target host sends the answer (reply) and tells its IP-address. After that the system is ready to transfer the data.

We are interested in IP-packets that are used to transfer user's information. Internet Protocol (IP) belongs to the next level of the OSI-model. The most popular is version four of the IP-protocol. However the sixth version of this protocol makes the first steps. This new version of the IP-protocol will expand a range of available addresses and will simplify automatic configuration of IP-networks. It is important to mention, that incoming sixth version of the IP has exclusive means of safety and ciphering the traffic.

struct IP6Header
{
	unsigned long ver:4;    // version of the IP-protocol
	unsigned long tclass:8; // class of the traffic
	unsigned long label:20; // label of a stream
	unsigned short length;  // length of packet
	unsigned char next;     // next header (options)
	unsigned char hop;      // hop-limit
	unsigned char src [16]; // source 128-bit address
	unsigned char dst [16]; // destination 128-bit address
};

Further in this article we will discuss only IP-packets of the most popular fourth version (IPv4). The packet consists of the header, the service information (options) and the data. In C programming language the IP-header is described by this structure:

typedef struct _IPHeader
{
	unsigned char  verlen;   // packet version and length of the header
	unsigned char  tos;      // type of service
	unsigned short length;   // length of packet
	unsigned short id;       // Id
	unsigned short offset;   // flags and displacement
	unsigned char  ttl;      // time to live
	unsigned char  protocol; // higher protocol (TCP,UDP, ICMP and so on)
	unsigned short xsum;     // the control sum
	unsigned long  src;      // source IP-address
	unsigned long  dest;     // destination IP-address
} IPHeader;

Detailed description of the Internet Protocol (IP) can be found in the RFC #791. We shall deal mainly with the IP-packet header and its three fields - "protocol", "src" and "dest". These fields are well-known IP-addresses of the source and destination hosts. For example, hexadecimal value of 0x0000140A address corresponds to 10.20.0.0 IP-address.

A network media usually is filled with packets that must be delivered from one host to another. It is recommended to filter packets and save CPU resources for further packets processing. Source and destination IP-addresses, type of the higher protocol (TCP, UDP, ICMP, PUP), and contents of a packet can be used as criteria of filtration. Filtration functions are rather useful, because they limit the information collected by the utility and they let it run fast and smooth. It is quite possible, that at times when network load is intensive the computer and the sniffer will be not able to process all incoming information. Without any filtration the application - interceptor will not have enough time and other resources to process all packets. It will fail to store all packets on a hard disk and even a large disk will be filled in a few minutes. An anti-sniffing application can be based on this fact. It sends into a network set of packets with the counterfeit information with passwords, logins, etc. As a result sniffers can't parse such a huge stream of disinformation.

The Network Driver Interface Specification (NDIS) library abstracts the network hardware from network drivers. NDIS also specifies a standard interface between layered network drivers, thereby abstracting lower-level drivers that manage hardware from upper-level drivers such as network transports.

The driver of the NIC (network interface card) receives and transfers frames to the Ethernet-medium. The maximal size of the data in the Ethernet-frame is 1500 bytes. The maximum size of an IP-packet is 64 kilobytes including the header and service data. If necessary the driver does fragmentation and assembly of IP-packets. The network subsystem in Microsoft Windows is based on multilevel architecture which was approved by the International Standards Organization (ISO) in 1978.

Our application that listens to a network segment works with IP-packets. It uses Windows Sockets library (version 2.2) and operates with Windows 2000/XP/2003. Programming "raw sockets" in older versions of Windows was impossible. In table #1 are listed different versions of the WinSock library and their features.

 

WinSock 1.1

Windows 98

WinSock 2.x

WinNT 4.0

WinSock 2.0

Windows 2000

WinSock 2.2

Raw ICMP

no

yes

yes

yes

Raw IP

no

no

no

yes

Raw TCP|UDP

no

no

no

no

Table 1

<ABSTRACT>

Recently many applications (especially for MS-DOS) had monolithic architecture. Inside the program there was a code for low level access to some hardware (modem, network card, display, printer), and other routines such as user interface, business logic and file reading and writing. Hardware changes leads to changes in such programs.

The architecture of modern network software is based on the 7-layer networking model developed by the International Standards Organization (ISO). Introduced in 1978, the ISO Open Systems Interconnection (OSI) reference model describes networking as a series of protocol layers with a specific set of functions allocated to each layer. Each layer offers specific services to higher layers while shielding these layers from the details of how the services are implemented.

Layer

Description

Application

This layer is for applications, such as WWW-browsers, mail programs, FTP-servers and clients. They do not depend on environment or media of data transmission and a way of data transmission.

Presentation

This layer is responsible for how the information transmitted over a network will be submitted to the user. For example, a html-page can be viewed as the html-code with tags or it can be viewed as a well formatted document. Another example - a picture in GIF-format (image) can be encoded in Base64 and transferred inside e-mail letter.

Session

Sessions are procedures of data exchange between applications (servers and clients). Sessions are intended for communication of workstations with servers. Examples are FTP-session and POP-session.

Transport

This layer ensures that messages are delivered error-free, in sequence, and with no loss or duplication. For examples TCP (Transmission Control Protocol) ensures that packets are delivered without errors and UDP (User Datagram Protocol) does not. Other examples are IPX protocol and SPX protocol.

Network

Well-known third level, usually it is IP (Internet Protocol). This layer controls the operation of the network. It determines the physical path the data should take. Here packets are transferred, routed, assembled and filtered. Packets contain information about source and destination hosts.

Data Link

At this level frames are transferred between computers, switchboards and other media access devices (Ethernet, ATM, Token Ring, PPP). The Media Access Control layer is implemented in the network interface card (NIC).

Physical

This is the lowest layer of the OSI model. This layer involves the reception and transmission of the raw bit stream over a physical medium. It describes the electrical, optical, mechanical, and functional interfaces to the physical medium.

</ABSTRACT>

Internals of the sniffing application.

With basic knowledge of IP-networking it is possible to start coding our simple sniffer for Windows 2000. The application can consist of several parts:

- network driver or library to receive all packets (it is already installed);

- memory buffer to accumulate and process packets; it can be an array of bytes or it can be a set of cyclic buffers;

- packets analyzer - a set of functions and procedures for filtering;

- decoder and encoder (for example to decode data from BASE64 format);

- packet editor or processor to make changes in incoming packets and to send them back to a network.

Every application that uses Windows Sockets library starts with initialization of the network library (WSAStartup). Next step is to create a socket, get host name of the computer and its IP-address (gethostbyname). In concluding this stage we set socket parameters (bind). Now it is necessary to switch the socket into promiscuous mode and let it receive all packets. The control function (ioctlsocket) with SIO_RCVALL argument switches on the promiscuous mode.

Then we see main application loop which will stop only when a user presses any key. Inside the loop IP-packets are received (recv) and processed. Every incoming packet is copied into memory buffer and is not analyzed in any way. The size of the buffer (64 KB) is large enough to store the biggest IP-packet. Our sniffer is very simple and there is no packet analyzer. Hopefully, any smart person knows how to improve this simple application.

Source code for the sample

#include 
#include 

#define MAX_PACKET_SIZE    0x10000
// Buffer to receive data
static BYTE Buffer[MAX_PACKET_SIZE]; // 64 Kbytes

void main()
{
  WSADATA     wsadata;   // Initialization of the WinSock.
  SOCKET      s;         // Listening socket.
  char        name[128]; // Host name (computer).
  HOSTENT*    phe;       // Host information.
  SOCKADDR_IN sa;        // Host address
  long        flag = 1;  // Promiscuous flag
 
  // Initialization
  WSAStartup(MAKEWORD(2,2), &wsadata);
  s = socket( AF_INET, SOCK_RAW, IPPROTO_IP );
  gethostname(name, sizeof(name));
  phe = gethostbyname( name );
  ZeroMemory( &sa, sizeof(sa) );
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = ((struct in_addr *)phe->h_addr_list[0])->s_addr;
  bind(s, (SOCKADDR *)&sa, sizeof(SOCKADDR));
  
  // Switches promiscuous mode.
  ioctlsocket(s, SIO_RCVALL, &flag);
 
  // Receiving IP-packets.
  while( !_kbhit() )
  {
    int count;
    count = recv( s, Buffer, sizeof(Buffer), 0 );
    // Processing IP-packets
    if( count >= sizeof(IPHeader) )
    {
      IPHeader* hdr = (IPHeader *)Buffer;
      // add here packet processing...
    }
  }
  // This is the end.
  closesocket( s );
  WSACleanup();
}

For successful compilation of the application it is necessary to link with "ws2_32.lib" library file. Now you have a sketch to start coding the useful/useless utility. To make the code clear all error-checks were removed. It is recommended to check return values of functions for correct work of the application in any conditions. It is necessary to mention that this article is intended only for educational purposes, and the author cannot be held responsible for any damage, use or misuse which can be put after studying this article.

How to protect yourself from sniffers.

Many people and network administrators worry of safety of their data connections. The problem can be solved by various ways. The first and the most expensive - a hardware method when network is built with switchboards (switch) and hardware ciphers, but not concentrators (hub). The second and most simple method is software ciphering of the network traffic. The information can be intercepted by sniffer, but it cannot be decoded by the newbie. It is possible to cipher data with SSL- technology (secure sockets layer) and SSL is built-in many Internet-browsers. It is used in e-commerce applications and is quite reliable. E-mail messages can be ciphered and signed with your unique digital signature (Secure MIME). In local area networks (LAN) it is recommended to turn on ciphering of all IP-traffic. It is very effective and simple, because it is transparent to the end-user, it just uses CPU-resources. In Windows 2000/XP/2003 this work is carried out by the IP Secure protocol (IPSEC). Following these rules you will guarantee confidentiality and safety of your data.