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.