利用sun.misc.Unsafe实现一次类混淆(Type Confusion)

unsafe是jdk里面非常有意思的函数,不仅仅是名字。具体功能大家可以搜一下看看,简单来说就是,这个类提供了直接操作硬件的方法。
我这边简单利用unsafe的putObject方法,实现一次类混淆,有点儿意思。
代码如下:
Dingo.java : (作用是跑一个计算器)
package ding.yang.controller;

import java.io.IOException;
import java.io.Serializable;

public class Dingo implements Serializable {

/**
*
*/
private static final long serialVersionUID = 1L;

public void fuck() {
ProcessBuilder pb = new ProcessBuilder("calc");
try {
pb.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Yang.java: (作用是跑一个记事本)
package ding.yang.controller;

import java.io.IOException;
import java.io.Serializable;

public class Yang implements Serializable {

/**
*
*/
private static final long serialVersionUID = 1L;

public void fuck() {
ProcessBuilder pb = new ProcessBuilder("notepad");
try {
pb.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Hello.java:
package ding.yang.controller;

public class Hello {

public Dingo dingo;

public Hello(Dingo dingo){
this.dingo = dingo;
}

}

接着利用putObject,将hello.java类中的dingo这个field,替换为yang.java
 package ding.yang.controller;

import java.io.IOException;
import java.lang.reflect.Field;
import java.security.AllPermission;
import java.security.ProtectionDomain;

import sun.misc.Unsafe;

public class TestUnsafe {

public static void main(String[] avgs) throws NoSuchFieldException,
SecurityException, IllegalArgumentException,
IllegalAccessException, IOException {

// 获取unsafe 的实例
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);

Hello hello = new Hello(new Dingo());
Yang yang = new Yang();
Field f = hello.getClass().getDeclaredField("dingo");
unsafe.putObject(hello, unsafe.objectFieldOffset(f), yang);
hello.dingo.fuck(); // 这里是弹计算器呢还是记事本呢?

}
}


总结:
1、上述代码最后是弹出了记事本,因为我们采用直接操作内存对象的方式,将hello类中的dingo对象,替换成了yang对象。
2、还有一个需要注意的点是,unsafe实例并不能直接获取,因为在unsafe中,判断了当前的classloader如果不是null,也就是root的classloader,会抛出一个securityexception异常,所以我们利用反射的方式,将private置为public,然后获取
3、上述代码当然只能在trust code环境里面运行了。

你可能感兴趣的:(java,安全,unsafe,类混淆,安全)