Used files


Protocols and Ciphers

Magic Collaboration Studio consists of Java-based services - Teamwork Cloud (twcloud) and WebApp (webapp). 

Teamwork Cloud requires a supported Java version (see System requirements) (Java location varies depending on how it was deployed and configured), whereas Web Application Platform uses a bundled Java, located in <install_root>/WebAppPlatform/jre/

Therefore, in order to harden these services, we must begin by hardening the JVM. The default settings for the JVM are located in java.security

We can check the ciphers/protocols being used by the applications using nmap (version 7.x) or TestSSLServer.jar, available from https://community.rsa.com/s/article/How-to-check-for-available-SSL-TLS-protocols-and-ciphers-for-a-specific-port-in-RSA-Authentication-Manager-8-x.

As an example, below is a scan using both tools against a default installation. In this example, we will be testing port 8111, the Magic Collaboration Studio / Teamwork Cloud port.

# nmap --script ssl-enum-ciphers -p 8111 127.0.0.1
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-21 17:32 MDT
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00014s latency).

PORT     STATE SERVICE
8111/tcp open  unknown
| ssl-enum-ciphers:
|   TLSv1.0:
|     ciphers:
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: client
|     warnings:
|       Key exchange (dh 1024) of lower strength than certificate key
|   TLSv1.1:
|     ciphers:
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: client
|     warnings:
|       Key exchange (dh 1024) of lower strength than certificate key
|   TLSv1.2:
|     ciphers:
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 1024) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: client
|     warnings:
|       Key exchange (dh 1024) of lower strength than certificate key
|_  least strength: A

Nmap done: 1 IP address (1 host up) scanned in 0.76 seconds

# java -jar TestSSLServer.jar 127.0.0.1 8111
Supported versions: TLSv1.0 TLSv1.1 TLSv1.2
Deflate compression: no
Supported cipher suites (ORDER IS NOT SIGNIFICANT):
  TLSv1.0
     RSA_WITH_AES_128_CBC_SHA
     DHE_RSA_WITH_AES_128_CBC_SHA
     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
  (TLSv1.1: idem)
  TLSv1.2
     RSA_WITH_AES_128_CBC_SHA
     DHE_RSA_WITH_AES_128_CBC_SHA
     RSA_WITH_AES_128_CBC_SHA256
     DHE_RSA_WITH_AES_128_CBC_SHA256
     TLS_RSA_WITH_AES_128_GCM_SHA256
     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
     TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
----------------------
Server certificate(s):
  a241e1c3b957bd14e6e0242fd012f75853eef243: CN=X.X.X.X
----------------------
Minimal encryption strength:     strong encryption (96-bit or more)
Achievable encryption strength:  strong encryption (96-bit or more)
BEAST status: vulnerable
CRIME status: protected
CODE

As can be observed above, the default configuration using OpenJDK 1.8.0_242 allows TLS v1.0 and v1.1, which are deprecated. Additionally, we can see that several key exchanges are taking place using dh1024.

We then proceed to harden the configuration.

Since we are dealing with ciphers, you need to make sure that you do not disable a cipher required by your certificates.

After hardening the VM, we end up with a different set of allowed ciphers and protocols, as shown below.

# nmap --script ssl-enum-ciphers -p 8111 127.0.0.1
Starting Nmap 7.70 ( https://nmap.org ) at 2020-04-21 17:44 MDT
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00015s latency).

PORT     STATE SERVICE
8111/tcp open  unknown
| ssl-enum-ciphers:
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: client
|_  least strength: A

Nmap done: 1 IP address (1 host up) scanned in 0.95 seconds

# java -jar TestSSLServer.jar 127.0.0.1 8111
Supported versions: TLSv1.2
Deflate compression: no
Supported cipher suites (ORDER IS NOT SIGNIFICANT):
  TLSv1.2
     RSA_WITH_AES_128_CBC_SHA256
     TLS_RSA_WITH_AES_128_GCM_SHA256
----------------------
Server certificate(s):
  71ed3969e41a94877c51aacb87d995af4a12b6d9: CN=x.x.x.x
----------------------
Minimal encryption strength:     strong encryption (96-bit or more)
Achievable encryption strength:  strong encryption (96-bit or more)
BEAST status: protected
CRIME status: protected

CODE

The process of hardening the JVM requires making some changes to the java.security file. While these can be made directly, the downside is that if you upgrade your JVM, you will have to reapply your changes.

However, we can place our modifications in our own file, and simply pass a parameter to the JVM upon invocation so that it will apply our changes.

For example, we can create a file <install_root>/TeamworkCloud/configuration/jmx.password, and pass a parameter to the JVM in the form of -Djava.security.properties=<install_root>/TeamworkCloud/configuration/twc.java.security.

Our hardened security settings are as shown below:

twc.java.security

jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, DH keySize < 2048, \
    EC keySize < 224, 3DES_EDE_CBC, anon, RSA keySize < 2048, SHA1, DHE, NULL
jdk.tls.ephemeralDHKeySize=2048
jdk.tls.rejectClientInitiatedRenegotiation=true
CODE

To apply these settings, we need to make changes to both the Teamwork Cloud and Web App Platform services.

  1. Teamwork Cloud service
    For Linux, edit <install_root>/TeamworkCloud/jvm.options and add a line as shown below:

    jvm.options

    -Djava.security.properties=<install_root>/TeamworkCloud/configuration/twc.java.security
    CODE

    For Windows, edit the registry key Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Apache Software Foundation\Procrun 2.0\TeamworkCloud\Parameters\Java\Options and append the setting pointing to your security overrides to the bottom of the settings.

  2. Web App Platform service
    For Linux, <install_root>/WebAppPlatform/bin/setenv.sh and add the directive to the JVM_OPTS variable as shown below:

    setenv.sh

    JVM_OPTS="-server -XX:+UseParallelGC  -Xms4096M -Xmx8192M -Djava.security.properties=<install_root>/TeamworkCloud/configuration/twc.java.security"
    CODE

    On Windows, you need to edit the registry key Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Apache Software Foundation\Procrun 2.0\WebApp\Parameters\Java\Options and append the setting pointing to your security overrides to the bottom of the settings.

JMX

By default, the Teamwork Cloud service activates a JMX remote port to facilitate application monitoring. The default configuration does not contain any form of authentication.

On Linux, the configuration is located in <install_root>/TeamworkCloud/jvm.options.

On Windows, it is located in the registry key Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Apache Software Foundation\Procrun 2.0\TeamworkCloud\Parameters\Java\Options.

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=2468
-Dcom.sun.management.jmxremote.rmi.port=2468
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
CODE

These settings can be removed, thereby removing JMX remote access.

If you would like to allow remote JMX access but require authentication, you can do so by adding settings. For complete documentation, please refer to the Java documentation.

As an example, the below configuration adds password authentication:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=2468
-Dcom.sun.management.jmxremote.rmi.port=2468
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.password.file=<install_root>/TeamworkCloud/configuration/jmx.password
-Dcom.sun.management.jmxremote.access.file=<install_root>/TeamworkCloud/configuration/jmx.access
-Dcom.sun.management.jmxremote.ssl=false
CODE

As can be seen, we are pointing to a set of files (<install_root>/TeamworkCloud/configuration/jmx.password and <install_root>/TeamworkCloud/configuration/twc.java.security) that control who can access these files.

The vulnerability vector is one whereby JMX could be exploited to execute code. To prevent this, we allow only an authenticated user (jmx.password) who has read-only rights (jmx.access).

jmx.password

monitoring  DqzbksT4ET
CODE

jmx.access

monitoring readonly
CODE

In this example, we created a user (monitoring) with a password (DqzbksT4ET), who can only read values via Remote JMX, but cannot write or execute anything via JMX.

The password and access files have a very stringent ownership requirement. They need to be owned by the user running the process and be accessible exclusively to that user.

In the default installation, the Teamwork Cloud service must run under the Teamwork Cloud (twcloud) user account. All related files must be owned by the twcloud user and must have full permissions (rwx) granted exclusively to this user. No other users are permitted to have any access to these files.

# ll jmx.*
-rwx------. 1 twcloud twcloud 20 Mar 16 15:11 jmx.access
-rwx------. 1 twcloud twcloud 26 Apr 21 10:41 jmx.password