Talos Vulnerability Report

TALOS-2021-1302

CODESYS Development System PackageManagement.plugin ExtensionMethods.Clone() Unsafe Deserialization vulnerability

July 26, 2021
CVE Number

CVE-2021-21865

Summary

An unsafe deserialization vulnerability exists in the PackageManagement.plugin ExtensionMethods.Clone() functionality of CODESYS GmbH CODESYS Development System 3.5.16. A specially crafted file can lead to arbitrary command execution. An attacker can provide a malicious file to trigger this vulnerability.

Tested Versions

CODESYS GmbH CODESYS Development System 3.5.16

Product URLs

https://store.codesys.com/codesys.html

CVSSv3 Score

8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

CWE

CWE-502 - Deserialization of Untrusted Data

Details

The CODESYS Development System is the IEC 61131-3 programming tool for industrial control and automation technology, available in 32- and a 64-bit versions.

The vulnerable method is _3S.CoDeSys.PackageManagement.ExtensionMethods.Clone()

public static T Clone<T>(this T obj)
{
    BinaryFormatter binaryFormatter = new BinaryFormatter();
    ((IFormatter)binaryFormatter).SurrogateSelector = new SurrogateSelector();
    ((IFormatter)binaryFormatter).SurrogateSelector.ChainSelector(new ExtensionMethods.NonSerialiazableTypeSurrogateSelector());
    MemoryStream memoryStream = new MemoryStream();
    ((IFormatter)binaryFormatter).Serialize(memoryStream, obj);
    memoryStream.Position = 0L;
    return (T)((object)((IFormatter)binaryFormatter).Deserialize(memoryStream)); // [1]
}

The BinaryFormatter.Deserialize method is never safe when used with untrusted input [2]. The deserialization that occurs at [1] is vulnerable to exploitation via copy/paste functionality within the Package Designer tree view.

[2] https://docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide

Crash Information

Partial Call Stack

packagemanagement.plugin.dll!_3S.CoDeSys.PackageManagement.ExtensionMethods.Clone<System.Windows.Forms.TreeNode>(System.Windows.Forms.TreeNode obj = {System.Windows.Forms.TreeNode})
packagemanagement.plugin.dll!_3S.CoDeSys.PackageManagement.PackageDesignerViewPresenter.Copy()
packagemanagement.plugin.dll!_3S.CoDeSys.PackageManagement.PackageDesignerViewPresenter.OnTreeViewNodeCopy(object sender = {_3S.CoDeSys.PackageManagement.PackageDesignerView}, System.EventArgs e = {System.EventArgs})
packagemanagement.plugin.dll!_3S.CoDeSys.PackageManagement.PackageDesignerView.Copy()
packagemanagement.plugin.dll!_3S.CoDeSys.PackageManagement.PackageDesignerView.ExecuteStandardCommand(System.Guid commandGuid = {System.Guid})
editcommands.plugin.dll!_3S.CoDeSys.EditCommands.StandardCommandHelper.ExecuteBatch(System.Guid commandGuid = {System.Guid}, string[] batchCommand = {string[0x00000002]}, string[] arguments = {string[0x00000000]})
editcommands.plugin.dll!_3S.CoDeSys.EditCommands.EditCopyCommand.ExecuteBatch(string[] arguments = {string[0x00000000]})
engine.plugin.dll!ns3.Class11<_3S.CoDeSys.Core.Commands.IStandardCommand, _3S.CoDeSys.Core.Commands.ICustomizedStandardCommand, CODESYS.Commands.IStandardCommandsCustomizer>.ExecuteBatch(string[] arguments = {string[0x00000000]})
engine.plugin.dll!ns0.Class16<_3S.CoDeSys.Core.Commands.IStandardCommand, _3S.CoDeSys.Core.Commands.ICustomizedStandardCommand, ns0.Class12, CODESYS.Commands.IStandardCommandsCustomizer>.imethod_1(string[] string_0 = {string[0x00000000]})
engine.plugin.dll!_3S.CoDeSys.Engine.CommandManager.method_2(System.Guid guid_0 = {System.Guid}, string[] string_0 = {string[0x00000000]})
engine.plugin.dll!_3S.CoDeSys.Engine.CommandManager.ExecuteStandardCommand(System.Guid commandGuid = {System.Guid}, bool bInvokedByContextMenu = false)
...

Timeline

2021-05-18 - Vendor Disclosure
2021-07-26 - Public Release

Credit

Discovered by Patrick DeSantis of Cisco Talos.