网上教程中的demo代码多半比较复杂,干扰要素较多,而且基本都来自于最初几个教程,很多写文章的人只是照着前人教程复现- -遍,其实不一定对此有深刻的理解。另外我也不建议直接读ysoserial的源码,因为ysoserial的源 码中对代码进行了很多优化,导致理解起来可能比较难一点.

0x01 前言

在p牛安全漫谈的第九篇中,p牛贴出了简化版的CC1链。为什么要有简化版呢?

0x02 简化版CC1链分析

        是不是看起来非常的简单,短短六行代码即可。

        Transformer[] transformers = new Transformer[]{
        new ConstantTransformer(Runtime.getRuntime()),
        new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})};
        Transformer transformer = new ChainedTransformer(transformers);
        Map innerMap = new HashMap();
        Map outerMap = TransformedMap.decorate(innerMap,null,transformer);
        outerMap.put("test","xxxxx");

       首先来分析ConstantTransformer,在进行初始化之后,就无其它操作了

new ConstantTransformer(Runtime.getRuntime())
深入浅出”P牛”版CC1链插图

InvokerTransformer初始化如下,1传递方法名,2传递参数类型,3传递参数的值

深入浅出”P牛”版CC1链插图1

ChainedTransformer的实现如下:

深入浅出”P牛”版CC1链插图2

也就说首先new之后transformer变量存储的内容如下

深入浅出”P牛”版CC1链插图3

TransformedMap.decorate如下,这里可以看出直接能调用到有参构造。换种意思来说就是将transformer变量内容存入到了valueTransformer中.

深入浅出”P牛”版CC1链插图4

那么最后一个outerMap.put(“test”,”xxxxx”);就是最重要的一点了。 跟进put发现了transformValue方法

深入浅出”P牛”版CC1链插图5

transformValue会调用:valueTransformer.transform(object)

深入浅出”P牛”版CC1链插图6

而valueTransformer此时为ChainedTransformer,所以会调用到ChainedTransformer.transform()方法

深入浅出”P牛”版CC1链插图7
深入浅出”P牛”版CC1链插图7

在第一次循环执行之后,返回的Object是Runtime

深入浅出”P牛”版CC1链插图8

然后将object当做参数带入,再次执行transform(),一个经典的命令执行

深入浅出”P牛”版CC1链插图9

0x04 结尾

本文只是简单剖析,更详细的话,可以跟着断点进行一步步调试