Security Advisory

mendelson AS2 Admin Service Unauthenticated Remote Code Execution

By exploiting a deserialization issue in the Admin service, unauthenticated attackers can gain remote code execution.

Advisory ID: MLSA-2023-002
CVE: None
CVSS: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Severity: high
Affected versions: ≤ mendelson AS2 2023
Fixed versions: ≥ mendelson AS2 2023 B569
Discovered by: Hans-Martin Münch

Product description

The mendelson AS2 software is a JAVA-based easy to use but highly configurable implementation of the EDIINT AS2 standard. This is your solution for secure and reliable automated data transfer with your communication partners. We make sure that your platforms are also supported - no matter if you are running Windows, Linux, Mac OS, AIX or others.

Details

mendelson AS2 provides an administrative service, running on port 1234 that can be used with a Swing based graphical application to configure the system settings. This service is based on Apache Mina, a Java based network application framework that can be used to create asynchronous APIs.

By default, Apache Mina uses simple memory buffers to communicate, however this does not work for complex Java objects. For these cases, Mina allows to setup so called CODES, which are (simplified) filters that can be applied before the object is sent over the network.

mendelson AS provides such a filter within the “de.mendelson.util.clientserver.codec” package. The following code snippet is from the ClientServerDecoder class:

 1protected boolean doDecode(IoSession ioSession, IoBuffer in, ProtocolDecoderOutput decoderOutput) throws Exception {
 2  int position = in.position();
 3  byte[] headerData = new byte[4];
 4  if (in.remaining() >= 4) {
 5    in.get(headerData);
 6  } else {
 7    
 8    return false;
 9  } 
10  int contentLength = decodeLengthHeader32Bit(headerData);
11  
12  if (in.remaining() < contentLength) {
13    
14    in.position(position);
15    
16    return false;
17  } 
18  
19  byte[] objectBuffer = new byte[contentLength];
20  in.get(objectBuffer);
21  ByteArrayInputStream objectInStream = new ByteArrayInputStream(objectBuffer);
22  ObjectInput objectInput = new ObjectInputStream(objectInStream);
23  try {
24    Object object = objectInput.readObject();
25    objectInput.close();
26    decoderOutput.write(object);
27  } catch (InvalidClassException ex) {
28    ex.printStackTrace();
29    this.logger.severe(this.rb.getResourceString("client.incompatible"));
30    if (this.clientCallback != null) {
31      this.clientCallback.clientIsIncompatible(this.rb.getResourceString("client.incompatible"));
32    }
33  } 
34  
35  return true;
36}
37

The code creates a ByteArrayInputStream form the Mina memory buffer and uses native Java deserialization (line 24) to retrieve the actual Java object. As no look-ahead deserialization is performed, the service is vulnerable to a deserialization attack. As the deserialization is peformed before other checks, this can be exploited without authentication.

mendelson AS2 includes Apache HttpClient, which ships with a CommonBeanutils 1.9.4 instance. This libary contains a known deserialization gadget (CommonsBeanutils1) that can be exploited using the ysoserial gadget collection.

The mendelson AS2 community edition only allows connnections from localhost, which reduces the attack surface of this attack. The commercial edition allows access from different hosts, if a certain command line argument is set. This is reflected in the CVSS attack complexity rating.

Workarounds

It is possible to prevent the deserialization of the BeanComparator class, used by the CommonsBeanutils1 gadget. This can be achieved by creating a global filter and pass it to the JRE on the command line:

$JAVAEXEC  -Djdk.serialFilter='!org.apache.commons.beanutils.BeanComparator;' -Xmx$MAX_HEAP -Xms92M -classpath $CLASSPATH de.mendelson.comm.as2.AS2 $1 $2 $3 $3 $4 $5 $6 $7 $8 $9

Exploitation of the vulnerability will then be blocked, leaving the following error in the mendelson AS2 log:

Unable to establish the client-server connection. The server is not able to deserialize the client messages. The main reason for this is different versions of client and server.

Please note that this approach only prevents the exploitation of the CommonsBeanutils gadget, others gadgets might exist.

Indicators of Compromise

None

Coordinated Disclosure Timeline

  • 02/02/2023 Initial contact with the Mendelson Service, sending link to the vulnerability description and PoC.
  • 02/02/2023 Response from Mendelson, refusing to Download the content from the link, due to ‘security’.
  • 02/02/2023 Response to Mendelson, sending only the vulnerability description as markdown file, referencing to the download.
  • 02/02/2023 Mendelson acknowledged that it received the vulnerability details, starting to review it.
  • 02/02/2023 Response from Mendelson service, say it will implement a filter. Asking more questions.
  • 02/02/2023 Response from MOGWAI LABS, trying to answer the additional questions.
  • 02/02/2023 Response from Mendelson service, more questions.
  • 02/02/2023 Response from MOGWAI LABS, providing a more detailed explanation.
  • 02/02/2023 Response from Mendelson, with acknowledgement, implementing quick-fix in all wrappers.
  • 03/02/2022 Mail from Mendelson, asking additional questions.
  • 03/02/2022 Reply from MOGWAI LABS, providing additional references how to prevent deserialization issues.
  • 03/02/2022 Mail from Mendelson, more questions.
  • 03/02/2022 Reply from MOGWAI LABS, answering questions.
  • 03/02/2022 Mail from Mendelson, providing code examples.
  • 03/02/2022 Mail from Mendelson with additional remarks.
  • 04/02/2022 Response from MOGWAI LABS, answering questions.
  • 06/02/2022 Response from Mendelson, confirming suggested solution.
  • 07/02/2022 Mendelson releases new AS2 version (B569), mention security fix.
  • 08/02/2022 Mail from MOGWAI LABS, asking if a CVE was requested.
  • 08/02/2022 Response from Mendelson service, saying it will not request a CVE.