CVE-2024-24976
A denial of service vulnerability exists in the OAS Engine File Data Source Configuration functionality of Open Automation Software OAS Platform V19.00.0057. A specially crafted series of network requests can cause the running program to stop. An attacker can send a sequence of requests to trigger this vulnerability.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
Open Automation Software OAS Platform V19.00.0057
OAS Platform - https://openautomationsoftware.com/knowledge-base/getting-started-with-oas/
4.9 - CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H
CWE-130 - Improper Handling of Length Parameter Inconsistency
The OAS Platform, capable of running on a variety of systems including Windows, Linux, and Docker, was built to facilitate simplified communication between various proprietary devices and applications that might otherwise be incompatible. This is done through use of the “Universal Data Connector”. In the “Connectivity Layer” OAS acts as an “IoT Gateway and protocol bus,” allowing for native communication with devices, databases, and cloud services. Connectors implemented in the “Connectivity Layer” can then communicate with each other via the OAS Live Data Cloud, representing the “Aggregation Layer”. This information can then be stored, analyzed, and visualized through the data historian, alarm logging/notification, and visualization tools that make up the “Application Layer”. OAS additionally exposes a few sets of developer tools, allowing for programmatic access to the platform.
The OAS Engine provides authenticated users access to a variety of user-modifiable configuration fields. Included within these options is the File Data Source
configuration, allowing users to specify a system path and filename to use with specially configured Tag
entities.
The File Data Source
configuration can be set through use of a CSV_Import
protobuf as part of a greater authenticated request. The format of this structure resembles the following, where the Strings
field contains the configuration options in CSV format with the File Data Source Path
containing the target filepath and File Data Source File Name
containing the target name.
message CSV_Import {
int32 Version = 1;
U_EP UEP = 2;
repeated string Strings = 3;
}
When a File Data Source Path
is set, it is first checked to ensure that the provided value is not a blank string in the case of Linux, or the root C directory in Windows. This can be seen in the code snippet below where the global::i.aej
variable contains a slightly modified value provided to the File Data Source Path
field.
if (!(Operators.CompareString(global::i.aej, "", false) == 0 | Operators.CompareString(global::i.aej, "C:\\", false) == 0))
If that passes, the value is next checked to ensure that it begins with one (and only one) backslash, as seen in the code snippet below.
if (Operators.CompareString(global::i.aej.Substring(0, 1), "\\", false) == 0 & Operators.CompareString(global::i.aej.Substring(0, 2), "\\\\", false) != 0)
If a blank string is provided as the value of File Data Source Path
it is modified by the Engine to contain a single backslash. This modification causes the first check to succeed and allows execution to continue to the second check. At this time, the second call to Substring
will raise an ArgumentOutOfRangeException
exception due to the Length
field of the Substring
call being greater (0x02) than the length of the string itself (0x01). Since this exception is not caught it causes the OAS Engine process to die.
System.ArgumentOutOfRangeException: Index and length must refer to a location within the string. (Parameter 'length')
at System.String.Substring(Int32 startIndex, Int32 length)
at i.t(Object A_0)
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.TimerQueueTimer.Fire(Boolean isThreadPool)
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
2024-02-29 - Vendor Disclosure
2024-03-04 - Vendor Patch Release
2024-04-03 - Public Release
Discovered by Jared Rittle of Cisco Talos.