Git Product home page Git Product logo

dhcpoptinj's Introduction

DHCP option injector

Build Status Total alerts

Have you ever wanted to intercept DHCP requests and squeeze in a few extra DHCP options, unbeknownst to the sender? Probably not. However, should the need ever come, dhcpoptinj will (hopefully) help you.

Why

There can be many a reason to mangle DHCP requests, although chances are you ought to look for a much better method for solving your problem. Perhaps you do not have access to the DHCP server/clients and need to modify their DHCP options, perhaps the DHCP software is difficult to configure (or does not support what you want to do), perhaps you have a very complex and/or odd setup, or perhaps you just want to experiment sending exotic or malformed options? There is a small chance that dhcoptinj might actually be of some use.

How

dhcpoptinj waits for packets to arrive in a netfilter queue. It will ensure that a packet is in fact a BOOTP/DHCP packet, and if so proceed to inject options. It will recalculate the IPv4 header checksum, disable the UDP checksum (for a simpler implementation) and then give the packet back to netfilter.

You need an iptables rule in order to intercept packets and send them to dhcpoptinj. Let us say you have two interfaces bridged together, eth0 and eth1. Let us say you want to intercept all BOOTP requests coming from eth0 and inject the relay agent information option (82/0x52). Let us make up a silly payload: An agent circuit ID sub-option with the value "Fjas".

Add a rule to the iptables mangle table:sudo iptables -t mangle -A PREROUTING -m physdev --physdev-in eth0 -p udp --dport 67 -j NFQUEUE --queue-num 42.

Then run dhcpoptinj (let us run it in the foreground with extra debug output): sudo dhcpoptinj -d -f -q 42 -o'52 01 04 46 6A 61 73'. Note that dhcpoptinj must be run by a user with the CAP_NET_ADMIN capability. You do not need to, and you really should not run dhcpoptinj as root. Instead, you can for instance grant the CAP_NET_ADMIN capability to the binary (using setcap) and limit execution rights to only a specific user or group. This is a method used for running wireshark as non-root, so you will find several guides helping you accomplish this.

Now send a DHCP packet to the eth0 interface and watch it (using a tool like wireshark) having been modified when it reaches the bridged interface. It should have the injected option at the end of the option list. If you capture the incoming DHCP packet with Wireshark, it will appear unmodified although it will in fact be mangled.

Note the format of the argument to the -o option: It should be a hexadecimal string starting with the DHCP option code followed by the option payload. The option length (the byte that normally follows the option code) is automatically calculated and must not be specified. The hex string can be delimited by non-hexadecimal characters for readability. All options must have a payload, except for the special pad option (code 0).

The layout of the nonsensical option used in this example (first the DHCP option layout, then the specific relay agent information option sub-option layout) is as follows:

Code Length Data
52 (auto) 01 04 46 6A 61 73 ("Fjas")
Sub-opt. Length Data
01 4 46 6A 61 73 ("Fjas")

Note that dhcpoptinj does not care about what you write in the option payloads, nor does it check whether your option code exists. It does however forbid you to use the option code 255 (the terminating end option). dhcpoptinj inserts this option as the last option automatically.

Screenshot

dhcpoptinj -f -d -q42 -r -o'0C 66 6A 61 73 65 68 6F 73 74' -o'52 01 04 46 6A 61 73' -o 320A141E28
3 DHCP option(s) to inject (with a total of 25 bytes): 12 (0x0C) (Hostname), 82 (0x52) (Relay Agent Information), 50 (0x32) (Address Request)
Existing options will be removed
Initialising netfilter queue
Initialising signal handler
Initialisation completed. Waiting for packets to mangle on queue 42
Received 416 bytes
Inspecting 328-byte DHCP packet from B6:40:FE:41:30:DC to 255.255.255.255:67
Mangling packet
Found option  53 (0x35) (DHCP message type)        DHCPREQUEST (copying)
Found option  54 (0x36) (DHCP Server Id)           with   4-byte payload 0A 14 1E 01 (copying)
Found option  50 (0x32) (Address Request)          with   4-byte payload 0A 14 1E 28 (removing)
Found option  12 (0x0C) (Hostname)                 with  12-byte payload 33 31 36 64 65 39 31 34 64 61 62 34 (removing)
Found option  55 (0x37) (Parameter List)           with  13-byte payload 01 1C 02 03 0F 06 77 0C 2C 2F 1A 79 2A (copying)
Found END option (removing)
Injecting option  12 (0x0C) (Hostname)                 with   9-byte payload 66 6A 61 73 65 68 6F 73 74
Injecting option  82 (0x52) (Relay Agent Information)  with   6-byte payload 01 04 46 6A 61 73
Injecting option  50 (0x32) (Address Request)          with   4-byte payload 0A 14 1E 28
Inserting END option
Padding with 10 byte(s) to meet minimal BOOTP payload size
Sending mangled packet

Installing

Packaging status

dhcpoptinj is in Debian/Ubuntu. The deb package is under source control at salsa. Installing dhcpoptinj from the deb package is recommended over the following manual installation procedure, because it also includes a man page, bash completion rules, example files etc.

Prerequisites

You need cmake and libnetfilter_queue (and a C compiler that supports C99). Hopefully, you are using a Debian-like system, in which case you can run the following to install them: sudo apt-get install cmake libnetfilter-queue-dev.

Build

  1. Download or clone the source: git clone git://github.com/misje/dhcpoptinj
  2. Enter the directory: cd dhcpoptinj
  3. Create a build directory and enter it (optional, but recommended): mkdir build && cd build
  4. Run cmake: cmake .. (or cmake -DCMAKE_BUILD_TYPE=Debug .. if you want a debug build)
  5. Run make: make -j4
  6. Install (optional, but you will benefit from having dhcpoptinj in your PATH): sudo make install

Demolish

  1. Run sudo make uninstall from your build directory

The build directory with all its contents can be safely removed. If you did not use a build directory, you can get rid of all the cmake rubbish by running git clean -dfx. Note, however, that this removes everything in the project directory that is not under source control.

Configuration file

dhcptopinj will attempt to parse /etc/dhcpoptinj.conf or the file passed with -c/--conf-file. The syntax of the configuration file is

  • key=value, where key is the long option name, or
  • key if the option does not take an argument

Whitespace is optional. Anything after and including the character # is considered a comment. DHCP options are listed one-by-one as option=01:02:03. Quotes around the option hex string is optional, and the bytes may be separated by any number of non-hexadecimal characters.

The options version, help and conf-file are not accepted in a configuration file.

Example:

# Run in foreground:
foreground
# Enable debug output:
debug
# Override hostname to "fjasehost":
option = '0C 66 6A 61 73 65 68 6F 73 74'
# Send agent ID "Fjas":
option = "52:01:04:46:6A:61:73"
# Override address request to ask for 10.20.30.40:
option=320A141E28
# Use queue 12:
queue = 12

remove-existing-opt # Remove options before inserting

Help

This readme should have got you started. Also check out the man page (in the deb package) and the help output (dhcpoptinj -h), which should cover everything the utility has to offer.

For bugs and suggestions please create an issue.

Limitations

dhcpoptinj is simple and will hopefully stay that way. Nonetheless, the following are missing features that hopefully will be added some day:

  1. Remove options instead of having to replace them
  2. Filter incoming packets by their DHCP message type (code 53) before mangling them

Troubleshooting

  1. Failed to bind queue handler to AF_INET: Operation not permitted

    Most likely you do not have CAP_NET_ADMIN capability or there is another process (perhaps another dhcpoptinj instance?) bound to the same netfilter queue number.

Known issues

  1. Memory leak on non-normal exit.

    This is not considered a leak. However, there should be no memory leak on a normal exit (catching SIGTERM, SIGINT or SIGHUP).

Useful information

When creating iptables rules to use with dhcpoptinj, the following options can be useful:

  • --queue-bypass

    Do not drop packets, but let them pass through if dhcpoptinj is not running (or not listening on the correct queue number).

Contributing

If you have any suggestions please leave an issue, and I will come back to you. You are welcome to contribute and pull requests are much appreciated.

If you find dhcpoptinj useful I would love to hear what you are using it for. Update the wiki page and describe your use.

License

I have chosen to use GPL for this project. If that does not suit you, contact me, and we can agree on a different license.

dhcpoptinj's People

Contributors

misje avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

dhcpoptinj's Issues

Add integration test

Create a test set up that can test packet mangling. It can be implemented using a docker container (remember --cap-add=NET_ADMIN and --cap-add=SYS_PTRACE --security-opt seccomp=unconfined would be handy to use container also for debugging) running dnsmasq + isc-dhcp-client.

Initial draft:

  1. inject a relay agent information option, use that as a tag in dnsmasq and send conditional options back. Parse the detailed DHCP log to identify that the DHCP request from the client was indeed mangled. No need to capture network traffic.
  2. Use dumpcap or similar and analyse network data directly. No need for dnsmasq.

With the first option a real-world-ish setup (the only one I have personally used) can be demonstrated and referred to in the help as an example to the user.

Use a CI/CD service to do build + test.

Improve debug output

  • Remove non-ASCII for prettier output in ascii-only terminals
  • Print queue number when starting
  • Print option hex string when starting
  • Print option hex string when injected
  • Space-align output in "found option"

Add DHCP message type filter

Make it possible to only mangle DHCP packets of a certain type. Add a command line option to filter incoming packets on their option 53 ("DHCP Message Type"). Or maybe add a generic DHCP option filter?

Does this work on a DHCP server?

Hi,

Not really an issue, but don't see where I could email you.

Wanted to ask if this would work on a DHCP server? I think that DHCPD receives DHCP requests on a raw socket and bypasses netfilter completely.

Thanks.

compatibility with openwrt

I'm new sorry if this is inappropriate. I am requesting that this tool be incorporated as a package in openwrt, or perhaps a suggestion about how to install the source into the toolkit and make automatically.

thanks

Nftables support

Hi! Can you please add support for nftables based firewalls? I can't longer use (now deprecated) iptables in my setup...

ps shows wrong

Hello
on openwrt device i run the code as dhcpoptinj -r -o"03c0a81e2" -o"3300000e10" -q 11
but when i do ps to show the list it shows dhcpoptinj -r -o-r -o"03c0a81e2" -o"3300000e10" -q 11
i tried on ubuntu machine as well here is the output there
dhcpoptinj -r-r -o03c0a81e2 -o3300000e10 -q 11

Fix "Syscall param […] points to uninitialised byte(s)" valgrind errors

Initialising netfilter queue …
==22190== Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
==22190== at 0x41338C1: sendto (socket.S:63)
==22190== by 0x4204739: nfnl_send (in /usr/lib/i386-linux-gnu/libnfnetlink.so.0.2.0)
==22190== by 0x420697B: nfnl_query (in /usr/lib/i386-linux-gnu/libnfnetlink.so.0.2.0)
==22190== by 0x40418AE: ??? (in /usr/lib/i386-linux-gnu/libnetfilter_queue.so.1.3.0)
==22190== by 0x4041C56: nfq_unbind_pf (in /usr/lib/i386-linux-gnu/libnetfilter_queue.so.1.3.0)
==22190== by 0x80492A1: main (in /home/andreas/dhcpoptinj/build/dhcpoptinj)
==22190== Address 0xbe9e04c9 is on thread 1's stack
==22190==
==22190== Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
==22190== at 0x41338C1: sendto (socket.S:63)
==22190== by 0x4204739: nfnl_send (in /usr/lib/i386-linux-gnu/libnfnetlink.so.0.2.0)
==22190== by 0x420697B: nfnl_query (in /usr/lib/i386-linux-gnu/libnfnetlink.so.0.2.0)
==22190== by 0x4041EAC: nfq_set_mode (in /usr/lib/i386-linux-gnu/libnetfilter_queue.so.1.3.0)
==22190== by 0x80492F3: main (in /home/andreas/dhcpoptinj/build/dhcpoptinj)
==22190== Address 0xbe9e04e9 is on thread 1's stack
==22190== in frame #3, created by nfq_set_mode (???)

As far as I can tell, this looks like an issue in libnetfilter_queue.

lib didn't work

Hi!
Program works, but Wireshark didn't see edited package - only old version of the package.
I use virtualbox and NAT inteface eth0.
When i try use dhclient - dhcpoptinj see that packet - but tcpdump dont have additional option.
What i can do ?
tnx

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.