Inhaltsverzeichnis

Some DHCP magic

A friend asked how it is possible for a DHCP server to get the kernel version of a client and print messages on the desktop of the client connecting to the server.

I couldn't answer right away so I researched on it and the result is DHCP is an awesome and dangerous protocol.

First basics

To understand why DHCP can do awesome things there are some basics you need to know.

Like every protocol DHCP has a header which controls all.
In this header are things like:

If you want to now more about the header format have a look at the tcpipguide

Usage

So to anwser the question of my friend there are only 2 keys needed.

get kernel version

First for getting the kernel version the server just has to read the key 'vendorclassid' which defaults to 'dhcp-client-prog-version-kernel' e.g. 'dhcpcd-5.6.2-Linux-3.5.4' for every dhcp client program.
This is a big information leakage which is why I immidiately change the value to something else.
If you are using 'dhcpcd' you just have to add the following to '/etc/dhcpcd.conf':

vendorclassid any-text-you-want-to-send

Because most DHCP-Server don't interpret this key any value can be set.

The second part printing a message on the desktop of the client is a bit harder because the client has to support this feature.
Fortunately for all users of NetworkManager this support is build in.
The key used for that is number 56 'DHCP-Message'. All ASCII characters except of whitespace can be used.
So you just have to configure your DHCP server to send this key and every client supporting it will display a notification with the message after successfully retrieving an ip.

If you use dhcpcd you can easily add support for it using the hook system.
The following script requires notify-osd (for Arch Linux you can find a package in my repository) to be installed and running by the users. If you are using any other notification daemon it should work by replacing 'notify-osd' with the executable of your daemon.

/usr/lib/dhcpcd/dhcpcd-hooks/50-notify.conf
# notify message
 
if $if_up && [ "$reason" == BOUND ]
then
  if [ -n "$new_dhcp_message" ]
  then
    for i in $(ps -C notify-osd -o euser --no-header)
    do
      su "$i" -c "DISPLAY=:0 /usr/bin/notify-send DHCP-message \"${new_dhcp_message//-/ }\""
    done
  fi
fi

To support whitespaces in the message the script will replace all '-' with ' '. So now you just need to find out how you can set the key in your DHCP server.

On OpenWRT you have to add the following to the options of dhcp in '/etc/config/dhcp':

list dhcp_option 'br-lan,56,your-message-\n-are-interpreted-as-new-line'

Why is it dangerous?

Well first the option 'vendorclassid' leaks critical information about your system, the kernel version.
This piece of information is a big step to hacking the system.
Because most distributions add there name to the kernel while compiling you'll easily get the distribution, now a short search on the net and you get all flaws of the kernel itself and the version of the distribution.
Many distribution aren't rolling release distributions which means if you get the distribution version you get the version of all software running on the system.
After gathering these information you can start creating an exploit for this system.

DHCP in default configuration has no authentication which is why everyone can set up a DHCP server, trap all systems within the network on it and gather information.

If you have a look at the keys which are possible in the options field you'll see something like:

These options are very handy as long as you control the area network they are used in.
But if you are e.g. sitting in a Starbucks using the WLAN it is dangerous to use a client configuration which supports that stuff because even the WLAN can be snapped easily by anyone sitting next to you.
To guard you from such events you should have a look in the man page of your dhcp client. The client dhcpcd for example supports whitelists of dhcp servers with the parameter 'whitelist' and blacklisting of options with 'nooption'.

The following is my 'nooption' setting which disables all option which are not network related and might lead to huge information leakage like core dump and log server:

nooption 4 7 14 17 19 20 21 27 40 41 42 69 70 71 72 73 75 76