Search code examples
bashdhcp

How can I forge a DHCP Discovery packet using Bash?


I would like to send via network (LAN) a classic DHCP Discover package using command line, in order to trigger a response from any DHCP server listening, so I could capture it with something like (say my IP address is 192.168.0.30 ):

tcpdump -i eth0 host 192.168.0.30 -n -s 0 -vvv -w listening.pcap

I think about this as a simple method to detect rogue DHCP servers on a network.

How can I do this using Bash ?

Further data:


Solution

  • Full Solution

    The solution is similar to 'hacker' with the difference that the UDP Discover package will be generated manually in the shell.

    The code is only intended to replace the given MAC of the network card with the form of spaces instead of colons and assigning to a variable (type in Bash):

    # manualy:
    MAC=ab:ab:ab:ab:ab:ab; MAC=`printf "$(echo $MAC | sed 's/:/ /g')%.0s"`
    # or automaticaly: 
    MAC=`printf "$(echo $(ifconfig -a |awk -v RS= '/eth0/' |awk '/ether/ {print($2)}') | sed 's/:/ /g')%.0s"`
    # or simply type (spaces instead of colons!):
    MAC="a6 a6 a6 a6 a6 a6"
    

    Using xxd generate a file containing the DHCPDISCOVER package ready to be sent. I use the fact that the checksum is not checked in practice by all DHCP servers. This avoids significant complications with the checksum calculation and its recording. The only element that needs to be changed is the MAC of the network card.
    The site was very helpful: DHCP (in Russian)

    echo -e $(echo -n -e "01 01 06 00 62 48 94 CA 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 $MAC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 63 82 53 63 35 01 01 FF") |xxd -r -p >blobfile
    

    For the DHCPDISCOVER packet to reach the DHCP server without distortion, it must be sent as binary data. Unfortunately, Bash receives some binary sequences as control commands.

    HEX codes from 00 to 1F are the range for control characters, different depending on the system. Many of them will be interpreted by BASH, e.g. 1F, 0d etc. Added to this are control sequences, e.g. 082008 or 610860.

    MAC addresses are theoretically 16777216, they usually contain parts identifying the manufacturer and hardware. There are more and more producers, also computers, there is also the practice of assigning imaginary or generating random MAC addresses. The chance of using control characters is therefore considerable.

    This excludes the use of echo Bash*. We will use cat.

    cat blobfile | nc -w1 -u -b 255.255.255.255 67
    

    A fragment of the result from Wireshark:

    Client MAC address: ab:ab:ab:ab:ab:ab (ab:ab:ab:ab:ab:ab)
    Option: (53) DHCP Message Type (Discover)
    

    The solution boils down to 2 lines of code using only cat and xxd and netcat assuming manually entering the MAC address in the shell.

    I didn't find a way to make Bash immune to binary data without breaking it. That is why I suggest excluding it from the package sending phase It may make sense to write the generator in C which will get rid of redirection to the file and the cat program and pack everything into 1 line. However, this is not the subject of the question.

    EDIT:

    The solution to the Bash problem is to install the rc shell from Plan 9. It is very small (96kB), fast, and most importantly, does not interpret binary characters as controlling. I checked on the standard version rc 1.7.4-1 Debian Linux available via apt. Now just follow the instructions below to send the correct DHCP Discover packet without using cat and the stub file, only shell and xxd and nc.

    MAC='08 20 08 1f 0d ff'
    echo -n -e "01 01 06 00 62 48 94 CA 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 $MAC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 63 82 53 63 35 01 01 FF" |xxd -r -p | nc -w1 -u -b 255.255.255.255 67