CVE-2020-27265 (Pre-auth on KEPWARE products)

CVE-2020-27265 (Pre-auth on KEPWARE products)

Introduction

As a newbie in the field of OT Security, learning the protocols used in industrial environments is a necessity for me. That's why OPC UA is a protocol I can't ignore.
As we know PLC is a key point in OT network operation, and it is operated by proprietary protocols and products from different vendors, which makes interoperability with ICS/SCADA protocol becomes difficult. So the protocol is now used as a standardized protocol to allow a host to be able to communicate with all endpoints in the OT network easily.

I will focus on researching this protocol-enabled product from Kepware PTC, a leading industry product supplier.
Surfing the internet, I downloaded a public version of KEPServerEX version 6.6.350 and read an article summarizing the error on team82's Kepware PTC product.

There is some important information here, there is a Stack Overflow occurring during OPC string decoding which can overflow the 1024-byte buffer and can especially trigger pre-validation. Quite interested in this information so I will try to analyze this vulnerability, I think this is the right thing to do when starting to learn more about the protocol.

Analysis

Communication flow

Use Prosys OPC UA Browser as Client and make a connection to KEPServerEx.

The first message sent from the client is a Hello message, containing the parameters to initiate the connection. This is followed by an OpenSecureChannel request, If all goes well, the server will return a channel ID. When the secure channel is open, all messages exchanged will be sent over this channel. When the connection is closed, a CLose message will be sent to disconnect.

Vulnerability

Recommend: KEPaboo
Since this hip hole is pre-auth enabled, I will focus on the first two packets, Hello (HEL) and OenSecureChannel (OPN).

The HEL packet will have some information such as Message Type, Buffer size, and the address of the connected server. Before the EndpointUrl will be 4 bytes the size of the EndpointUrl string.
Using KEPaboo to debug, after checking the loaded modules, I will focus on 2 modules, libua.dll to handle opc ua tcp and libsocket.dll to create a stream to receive packets from the clients. Proceed to debug and reverse.

When an event is read, the ProcessReadEvent function is called and the FD_READ flag is set to 1 and the handleEventdRead function is called to process the packet.


The Message Size of the packet will be checked, then the 3rd-level pointer reference to the OPC request will be saved to this via updateRefAddrReq  and passed to the handleMsg.

The program will use the Peek function to save 8 bytes including MessageType, Chunk Type, and Message Size into bufMsgType, then pass it to callCheckMsgTypeHEL to check if it is the correct Message Type or not based on a hard-fixed string of packet types.

There are Message types as follows:

  • HEL: Hello message
  • ACK: Response message
  • OPN: OpenSecurityChannel message
  • MSG: Data exchange message
  • CLO: CloseSecurityChannel message
  • ERR: Error message

When the test is successful, now handStringReqHEL will be responsible for cutting the information in the packet and processing it. When reverse to the getStrReq, something special happens.

Here, the Read function inside libsocket is called, which has the function to copy size bytes to buf from the OPC request stored in this.

On to the main problem, the Read function will be called, cutting 4 bytes of the EndpointUrl length from the OPC Request stored into the variable lenStr, which is a signed int. This value is completely controllable. If we set the lenStr value to 0x7fffffff then lenStr > 0 (pass first check), then 0x7fffffff + 1 will overflow, and the result < 1024 (pass 2nd check). At this time, bufStack of size 1024 bytes will be selected as the buffer to store 0x7fffffff bytes EndpointUrl, the result will stack overflow. Just like the information and reports Team82 wrote.

But life is not like a dream, actually the program is like this.

Results have been converted to unsigned int and can't overflow here lollllll. A question mark arises, whether the version I installed has been fixed, I immediately re-read the information, and the vulnerability was found by team82 on ThingWorx Kepware Server 6.8 - 6.9.

I immediately went to the homepage to download the V6.8.0 demo to check, and now only V6.8.875 is the lowest.

The code has added exception handling with the value 0x7fffffff. With this type of code, I guess the vulnerability CVE-2020-27265 actually happened here. Or maybe I'm the wrong lollllll. Sorry, I couldn't find 6.8.0 to verify. Thank you to everyone who has read this far. I will share more new information I find in the next posts.