DHCP_PROBE(8) | System Manager's Manual | DHCP_PROBE(8) |
dhcp_probe - locate DCHP and BootP servers on a directly-attached network
dhcp_probe [ -c config_file ] [ -d debuglevel ] [ -f ] [ -h ] [ -l log_file ] [ -o capture_file ] [ -p pid_file ] [ -Q vlan_id ] [ -s capture_bufsize ] [ -T ] [ -v ] [ -w cwd ] interface_name
dhcp_probe attempts to discover DHCP and BootP servers on a directly-attached Ethernet network. A network administrator can use this tool to locate unauthorized DHCP and BootP servers.
The program must be run with root privilege.
The program periodically broadcasts a number of DHCP and BootP request packets out a single physical interface. Several different kinds of request packets are sent, as a DHCP or BootP server may only respond to certain requests, depending on the server's configuration. Essentially, dhcp_probe mimics a BootP or DHCP client in a variety of possible states, attempting to provoke responses from servers.
After sending each request packet, dhcp_probe listens for responses. After filtering out responses that do not appear to be in response to the probe, and responses from known DHCP and BootP servers (identified by their IP source addresses and optionally by their Ethernet source addresses), it logs any responses from unknown servers.
Optionally, responses from unknown servers may also be written to a packet capture file.
Optionally, an external program may be called each time a response from an unknown server is received.
dhcp_probe may not be able to locate all DHCP and BootP servers; see LIMITATIONS below.
As DHCP broadcasts do not ordinarily cross IP routers, dhcp_probe will locate only servers that are attached to the same physical network as the interface specified on the command line. Although BootP Relay Agents running on this network may help the broadcasts cross IP routers, these agents typically are configured to convert the broadcasts to unicasts directed to only the well-known DHCP or BootP servers located on other physical networks. As a result, BootP Relay Agents will allow your the servers to receive the requests issued by dhcp_probe, but will not cause remote unknown servers to hear these requests. Therefore, if you have multiple physical networks, you may wish to run dhcp_probe on each of these networks to discover unknown DHCP and BootP servers on each of them.
dhcp_probe functions on a single Ethernet interface specified on the command line; it does not listen on multiple interfaces. However, if the host has multiple physical interfaces, you may run an instance of dhcp_probe on each interface. If your physical interface supports 802.1Q, you can use that to create a logical interface on each VLAN, then run an instance of dhcp_probe on each logical interface.
dhcp_probe is intended for use by a network administrator. Before running dhcp_probe on any network other than one for which you are responsible, contact that network's administrator to learn if it is acceptable for you to run this software on that network. Running this software may violate on a network where you don't have permission to do so may violate that network's acceptable use policy.
dhcp_probe is a product of the Network Systems Group at Princeton University's Office of Information Technology, and is available from http://www.net.princeton.edu/software/dhcp_probe/
Presently the product builds and runs on Solaris 9 on SPARC with gcc. The program relies on the pcap(3) and libnet(3) libraries.
After initialization, the program enters its main event loop, in which it remains until you signal the program to exit with a SIGINT, SIGTERM, or SIGQUIT.
The main event loop (a.k.a. the "probe cycle") consists of the following actions, repeated until the program receives a request to quit:
Any responses that contains a bootp_chaddr field not equal to the chaddr used in the probe is ignored, as are any that have incorrect bootp_htype or bootp_hlen fields. These are not responses to our probe.
Any responses from known DHCP and BootP servers are ignored. The IP source address for responses from each known server is declared using a legal_server statement in the dhcp_probe.cf(5) file. Any response with an IP source address that does not appear in a legal_server statement is treated as an unknown server.
The Ethernet source address for responses from each known server is also optionaly declared using a legal_server_ethersrc statement in the dhcp_probe.cf(5) file. If at least one legal_server_ethersrc is specified, then any response with an Ethernet source address that does not appear in a legal_server_ethersrc statement is treated as an unknown server. If no legal_server_ethersrc statements appear, then the response's Ethernet source address is not checked. (The legal_server_ethersrc statement is considered experimental in version 1.3.0, as it has received only limited testing.)
For each response from an unknown server:
If the response packet's yiaddr is non-zero and falls within a "Lease Networks of Concern", the following optional options are also passed:
-p the name of the calling program (e.g. dhcp_probe)
-I the name of the interface on which the unexpected response packet was received
-i the IP source address of the packet
-m and the Ethernet source address of the packet
(We do not wait for the alert_program_name2 to complete; it runs in a child process.)
-y the non-zero yiaddr value
The pcap(3) filter the program installs normally does not specify that the interface should be placed into promiscuous mode (although it is possible the interface is already in promiscuous mode for some other reason). However, if in the dhcp_probe.cf(5) file you specify a chaddr or ether_src value other than the interface's actual hardware address, then the pcap filter will specify that the interface should be placed into promiscuous mode.
Although the filter used with pcap(3) specifies only UDP packets destined to port bootpc should be collected, on systems where bpf isn't part of the kernel, pcap(3) must implement bpf as part of the application. This can increase the number of packets that must be passed from the kernel to user space to be filtered. The program attempts to minimize the side-effects of this by removing the pcap(3) filter when it isn't actually listening for responses. In particular, the filter is not installed during the time the program sleeps between each probe cycle (the cycle_time).
If you do specify an alert_program_name, take care that the program you specify is safe for a privileged user to run; it is executed with the same (i.e. root) privileges as the calling program.
No single request packet is likely to provoke a response from every possible BootP and DHCP server. Some servers may only response to either BootP, or DHCP, but not both. Some servers may be configured to only respond to a small set of known clients. Some DHCP servers will only provide leases to a small set of known clients, but may be willing to respond (negatively) to unknown clients that request a lease renewal on an inappropriate IP address. Therefore, dhcp_probe actually sends not one, but five different flavor request packets, in the hopes of provoking responses from a wider variety of unknown servers.
The packet flavors are:
It will typically provoke a BOOTPREPLY from a BootP server willing to respond to any BootP client. (BootP servers configured to only respond to a set of known clients may not respond.)
The options field contains a DHCP Message Type specifying DHCPDISCOVER.
The options field contains a DHCP Client Identifier, which is computed by prepending 0x'01' to the value of chaddr. (The value chaddr is specified in the dhcp_probe.cf(5) file, otherwise it defaults to the interface's Ethernet address.)
This packet will typically provoke a DHCPOFFER from a DHCP server willing to respond to any DHCP client. (DHCP servers configured to only offer leases to a set of known clients may not respond.)
The options field contains a DHCP Message Type specifying DHCPREQUEST.
The options field contains a DHCP Client Identifier, which is computed by prepending 0x'01' to the value of chaddr. (The value chaddr is specified in the dhcp_probe.cf(5) file, otherwise it defaults to the interface's Ethernet address.)
The options field contains a DHCP Server Identifier specifying server_id, which should be an IP address that does not correspond to any valid DHCP Server Identifier on your network. (The value server_id is specified in the dhcp_probe.cf(5) file, otherwise it defaults to 10.254.254.254.)
The options field contains a DHCP Requested IP Address specifying client_ip_address, which should be an IP address that does not correspond to any valid IP address on your network. (The value client_ip_address is specified in the dhcp_probe.cf(5) file, otherwise it defaults to 172.31.254.254.)
This packet occassionally provokes a response from a broken DHCP server that fails to respect the DHCP Server Identifier option.
The options field contains a DHCP Message Type specifying DHCPREQUEST.
The options field contains a DHCP Client Identifier, which is computed by prepending 0x'01' to the value of chaddr. (The value chaddr is specified in the dhcp_probe.cf(5) file, otherwise it defaults to the interface's Ethernet address.)
The options field contains a DHCP Requested IP Address specifying client_ip_address, which should be an IP address that does not correspond to any valid IP address on your network; ideally it should be one that is topologically inappropriate for your network. (The value client_ip_address is specified in the dhcp_probe.cf(5) file, otherwise it defaults to 172.31.254.254.)
If the Requested IP Address option is topologically inappropriate for your network, this packet may provoke a DHCPNAK from any DHCP server that believes it is authoritative for the network's IP topology.
The options field contains a DHCP Message Type specifying DHCPREQUEST.
The options field contains a DHCP Client Identifier, which is computed by prepending 0x'01' to the value of chaddr. (The value chaddr is specified in the dhcp_probe.cf(5) file, otherwise it defaults to the interface's Ethernet address.)
The ciaddr field contains client_ip_address, which should be an IP address that does not correspond to any valid IP address on your network; ideally it should be one that is topologically inappropriate for your network. (The value client_ip_address is specified in the dhcp_probe.cf(5) file, otherwise it defaults to 172.31.254.254.)
If the value of ciaddr is topologically inappropriate for your network, this packet will provoke a DHCPNAK from any DHCP server that believes it is authoritative for the network's IP topology.
All the request packets sent by the program share the following common characteristics:
Ethernet Header
IP Header
UDP Header
BootP/DHCP Payload
Although dhcp_probe only supports monitoring a single physical interface, you may run an instance of the program on each physical interface; each monitors a different physical network.
When running multiple copies of dhcp_probe, be sure to specify a different pid_file for each instance.
If you specify a log_file and/or a capture_file, be sure to specify a different one for each instance.
You may specify a different config_file for each instance. If you don't need to customize the settings in that file for each instance, you may use the same configuration file for all instances.
If you have multiple logical interfaces on the same physical interface, or multiple logical IP networks running on a single physical network, there is no need to run multiple instances of dhcp_probe to monitor each logical interfaces or logical network. A single instance of the program running on a physical interface is sufficient to provoke any servers on that physical network that might be willing to respond.
If your physical interface supports 802.1Q, you can use a single physical interface to monitor multiple VLANs. Use your operating system to create a logical interface on each VLAN, then run an instance of the program on each logical interface. Since the program is responsible for constructing Ethernet frame headers, you will probably need to specify the -Q option to instruct it to add to outgoing frames an 802.1Q VLAN header with the appropriate VLAN ID.
The program will respond to a number of signals:
Because re-opening the capture file causes the file to be truncated and a new pcap(3) header to be written to it, if you want to save the prior contents of the capture file, move the existing capture file aside before sending the signal.
Most rogue BootP/DHCP servers distribute private IP addresses to clients, or send DHCPNAK messages to legitimate clients. Some even more disruptive rogue BootP/DHCP servers may distribute IP addresses that fall within your own networks' IP ranges. The "Lease Networks of Concern" feature is intended to help you identify these particularly disruptive servers.
You may activate the feature by specifying the lease_network_of_concern statement in your configuration file. Use the statement multiple times to specify all your legitimate network ranges.
When a rogue BootP/DHCP server is detected, if the rogue's response packet contains a non-zero yiaddr value, the value is compared to the "Lease Networks of Concern" you specified. If the value falls within any of those network ranges, the message logged by dhcp_probe is extended to make note of this, and to report the yiaddr value. Furthermore, if you are using the alert_program_name2 feature, the alert program is called with an extra -y yiaddr option so that alert program can take any additional action desired.
The program produces increasingly detailed output as the debuglevel increases. Under normal circumstances, you can run at debuglevel 0. Here's roughly what messages are added at each debuglevel.
Startup and shutdown notice.
Non-fatal errors in the configuration file.
Fatal errors.
Show each time we close and re-open the logfile or capture file.
Report on response packets that could not be parsed (e.g. truncated).
The program was written by Irwin Tillman of Princeton University's OIT Network Systems Group. It was written to run on Solaris, relying on the generally-available pcap(3) and libnet(3) libraries.
dhcp_probe is not guaranteed to locate all unknown DHCP and BootP servers attached to a network. If a BootP server is configured so it only responds to certain clients (e.g. those with certain hardware addresses), it will not respond to the BOOTPREQUEST packet we sent. If a DHCP server is configured so it only responds to certain clients (e.g. those with certain hardware addresses or DHCP Client Identifiers), it will not respond to the packets we send that mimic DHCP clients in the INIT state. If a DHCP server is configured so it does not send DHCPNAK packets to clients requesting topologically-inappropriate IP addresses, it will not respond the packets we send that mimic DHCP clients in the INIT-REBOOT and REBINDING states.
The upshot is that it is possible that dhcp_probe will be unable to provoke some BootP and DHCP servers into responding at all.
Flushing out such servers can be extremely difficult. One approach is to capture all UDP/IP packet destined to the BootP client port which cross your network; since most of these packets are unicast at Layer 2, capturing is only effective if all such packets must pass by your capture device's Ethernet interface (e.g. the capture device is located at a network choke point, or the network does not involve any Layer 2 switching). Another approach is to do UDP port scanning for all devices listening on the BootP server port, and assume that those which are listening on that port are running a BootP or DHCP server.
Malicious BootP or DHCP servers that forge the IP source address (and possibly the Ethernet source address) of their responses to match the values specified by legal_server and legal_server_ethersrc statements will not be detected.
The packet capture buffer size is limited; if a single request packet provokes more responses than will fit into the buffer, those that do not fit are silently dropped, without any diagnostic indicating that the buffer was too small. You can adjust the size of the packet capture buffer size using the -s capture_bufsize option.
We do not support non-Ethernet interfaces.
Because (re-)opening a packet capture file causes the file to be opened for writing (not appending), the contents of any existing packet capture file of the same name is lost when the program starts or receives a SIGUSR2 signal. If the file's previous contents should be preserved, move the old file aside before starting the program or sending it a SIGUSR2 signal. (This "feature" exists because opening a pcap(3) savefile always involves writing a pcap header record to the start of the file, so pcap always opens the file using mode "w".)
Because pcap(3) opens the packet capture file with a simple fopen(3) without checking to see if the file already exists, dhcp_probe may be tricked into overwriting or corrupting an existing file. As dhcp_probe is run with root privileges, this is a serious concern. To avoid this problem, if you use the -o option, ensure that the directory that will contain the capture file is writable only by root.
The packet capture file that is written is unparseable after the first packet. E.g. if read with tcpdump(8), it reports: tcpdump: pcap_loop: truncated dump file.
On platforms where pcap(3) is unable to support the timeout argument to pcap_open_live, the program may not reliably detect responses from DHCP and BootP servers, or may not function at all.
Mar 9 2009 | Princeton Univ. |