About Modbus TCP

Vanilla Modbus TCP is a simple protocol that utilizes a basic request-response design. The specification is available from Modbus.org. at no charge.

The protocol transports application layer messages uses a simple envelope called the MBAP. The application layer itself supports function codes that completely determine the shape of the contents.

Modbus servers are easy to fuzz test. You can simply iterate through the various function code models. Modbus clients are more challenging, because any decent implementation will only parse response data that appears to be from the request. In other words, you will usually only be testing the parser for that particular request. This is very different to a DNP3 that has function + object semantics that allow for a nearly infinite number of permutations. To thoroughly test a Modbus client, the tester must iteratively reconfigure and test every possible function code that can be sent from the master.

Functions supported

The Modbus fuzzer provides good coverage via modeling of the following commonly-used function codes:

Future enhancements:

Health checks

The Modbus slave tests optionally use a simple READ_COILS request as a health check. This check can be disabled.

Modbus clients do not send a health check message, as there is no request you can send to a client to stimulate a response. Instead, the fuzzer waits for the next request as a health check, and then sends the next test frame with the same transaction id as the request.


Parameters differ for the slave and master tests.




Test Plans

Your Aegis installation of contains recommended test plans for Modbus slaves and masters.

In most cases, the only parameters you need to adjust will be the unitid of the target when testing slaves, and possibly the host (IP) parameter if you're testing an external target. Refer to the parameters section if you need to adjust timeouts or health checking.

The recommended test plan repeats some of the procedures with different fill or random seeds.

You should repeat the full master test plan with a high-frequency request for each function code that you can configure to do so. For instance, you might have four master configurations that respectively scan:

If you can configure your software to send control requests, run the suite against those function codes as well.