Fortiphyd / GRFICSv2

Version 2 of the Graphical Realism Framework for Industrial Control Simulation (GRFICS)
GNU General Public License v3.0
405 stars 74 forks source link

OpenPLC / libmodbus not supporting "Read Write Register" (0x17) function #18

Open HomeSen opened 1 year ago

HomeSen commented 1 year ago

According to the Usenix paper, a libmodbus version had been used for OpenPLC that is vulnerable to a buffer overflow. The buffer overflow can be verified by issuing an according "Read Registers" command that results in a service crash (or SIGSEGV under gdb). As the paper further mentions, the lesser-known "Read Write Register" function (code 0x17) has to be used to gain actual Remote Code Execution.

Unfortuantely, the Modbus service on the PLC returns an "Illegal Function" error, when using that function code, as can be seen from the pymodbus.console output: image

and also under Wireshark: image image

Looking at the libmodbus code inside this repo (and also on the pre-built PLC VM), one can see that this function code is defined: https://github.com/Fortiphyd/GRFICSv2/blob/master/plc_vm/OpenPLC_v2-master/libmodbus-3.0.4/src/modbus-private.h#L65

and that it should also be properly handled: https://github.com/Fortiphyd/GRFICSv2/blob/master/plc_vm/OpenPLC_v2-master/libmodbus-3.0.4/src/modbus.c#L870

So, the code path for responding with an "Illegal Function" error should not be taken.

EDIT: Taking another look at the PLC code base, I realized that the openplc gets linked against libmodbus, but actually uses its own Modbus implementation. The modbus.cpp does not contain a definition for function code 0x17 and also does not have the code implemented for handling it. Thus the message handling function defaults to the "Illegal Function" response.

The overflow still triggers for read requests, due to the modbus.cpp having been modified, accordingly: https://github.com/Fortiphyd/GRFICSv2/blob/master/plc_vm/OpenPLC_v2-master/core/modbus.cpp#L292

So, apparently, it would be required to also re-implement the "Read and Write Registers" function inside the modbus.cpp to gain code executioin.

hackingprofessional commented 7 months ago

Hi bro! I am also studying on the topic.... Did you manage to exploit the BOF? Could you give me some hint .... Thanks!