字体对话框java实验_Java Web安全 || Java基础 sun.misc.Unsafe
點擊上方“凌天實驗室”,“星標(biāo)或置頂公眾號”
漏洞、技術(shù)還是其他,我都想第一時間和你分享
“【歷史】已連載更新全部內(nèi)容:【菜單欄】-【JAVA SEC】
sun.misc.Unsafe是Java底層API(僅限Java內(nèi)部使用,反射可調(diào)用)提供的一個神奇的Java類,Unsafe提供了非常底層的內(nèi)存、CAS、線程調(diào)度、類、對象等操作、Unsafe正如它的名字一樣它提供的幾乎所有的方法都是不安全的,本節(jié)只講解如何使用Unsafe定義Java類、創(chuàng)建類實例。
如何獲取Unsafe對象
Unsafe是Java內(nèi)部API,外部是禁止調(diào)用的,在編譯Java類時如果檢測到引用了Unsafe類也會有禁止使用的警告:Unsafe是內(nèi)部專用 API, 可能會在未來發(fā)行版中刪除。
sun.misc.Unsafe代碼片段:
import sun.reflect.CallerSensitive;import sun.reflect.Reflection;
public final class Unsafe {
private static final Unsafe theUnsafe;
static {
theUnsafe = new Unsafe();
省去其他代碼......
}
private Unsafe() {
}
@CallerSensitive
public static Unsafe getUnsafe() {
Class var0 = Reflection.getCallerClass();
if (var0.getClassLoader() != null) {
throw new SecurityException("Unsafe");
} else {
return theUnsafe;
}
}
省去其他代碼......
}
由上代碼片段可以看到,Unsafe類是一個不能被繼承的類且不能直接通過new的方式創(chuàng)建Unsafe類實例,如果通過getUnsafe方法獲取Unsafe實例還會檢查類加載器,默認只允許Bootstrap Classloader調(diào)用。
既然無法直接通過Unsafe.getUnsafe()的方式調(diào)用,那么可以使用反射的方式去獲取Unsafe類實例。
反射獲取Unsafe類實例代碼片段:
// 反射獲取Unsafe的theUnsafe成員變量當(dāng)然我們也可以用反射創(chuàng)建Unsafe類實例的方式去獲取Unsafe對象:
// 獲取Unsafe無參構(gòu)造方法Constructor constructor = Unsafe.class.getDeclaredConstructor();
// 修改構(gòu)造方法訪問權(quán)限
constructor.setAccessible(true);
// 反射創(chuàng)建Unsafe類實例,等價于 Unsafe unsafe1 = new Unsafe();
Unsafe unsafe1 = (Unsafe) constructor.newInstance();
獲取到了Unsafe對象我們就可以調(diào)用內(nèi)部的方法了。
allocateInstance無視構(gòu)造方法創(chuàng)建類實例
假設(shè)我們有一個叫com.anbai.sec.unsafe.UnSafeTest的類,因為某種原因我們不能直接通過反射的方式去創(chuàng)建UnSafeTest類實例,那么這個時候使用Unsafe的allocateInstance方法就可以繞過這個限制了。
UnSafeTest代碼片段:
public class UnSafeTest {private UnSafeTest() {
// 假設(shè)RASP在這個構(gòu)造方法中插入了Hook代碼,我們可以利用Unsafe來創(chuàng)建類實例
System.out.println("init...");
}
}
使用Unsafe創(chuàng)建UnSafeTest對象:
// 使用Unsafe創(chuàng)建UnSafeTest類實例UnSafeTest test = (UnSafeTest) unsafe1.allocateInstance(UnSafeTest.class);
Google的GSON庫在JSON反序列化的時候就使用這個方式來創(chuàng)建類實例,在滲透測試中也會經(jīng)常遇到這樣的限制,比如RASP限制了java.io.FileInputStream類的構(gòu)造方法導(dǎo)致我們無法讀文件或者限制了UNIXProcess/ProcessImpl類的構(gòu)造方法導(dǎo)致我們無法執(zhí)行本地命令等。
defineClass直接調(diào)用JVM創(chuàng)建類對象
ClassLoader章節(jié)我們講了通過ClassLoader類的defineClass0/1/2方法我們可以直接向JVM中注冊一個類,如果ClassLoader被限制的情況下我們還可以使用Unsafe的defineClass方法來實現(xiàn)同樣的功能。
Unsafe提供了一個通過傳入類名、類字節(jié)碼的方式就可以定義類的defineClass方法:
public native Class defineClass(String var1, byte[] var2, int var3, int var4);
public native Class> defineClass(String var1, byte[] var2, int var3, int var4, ClassLoader var5, ProtectionDomain var6);
使用Unsafe創(chuàng)建TestHelloWorld對象:
// 使用Unsafe向JVM中注冊com.anbai.sec.classloader.TestHelloWorld類Class helloWorldClass = unsafe1.defineClass(TEST_CLASS_NAME, TEST_CLASS_BYTES, 0, TEST_CLASS_BYTES.length);
或調(diào)用需要傳入類加載器和保護域的方法:
// 獲取系統(tǒng)的類加載器ClassLoader classLoader = ClassLoader.getSystemClassLoader();
// 創(chuàng)建默認的保護域
ProtectionDomain domain = new ProtectionDomain(
new CodeSource(null, (Certificate[]) null), null, classLoader, null
);
// 使用Unsafe向JVM中注冊com.anbai.sec.classloader.TestHelloWorld類
Class helloWorldClass = unsafe1.defineClass(
TEST_CLASS_NAME, TEST_CLASS_BYTES, 0, TEST_CLASS_BYTES.length, classLoader, domain
);
Unsafe還可以通過defineAnonymousClass方法創(chuàng)建內(nèi)部類,這里不再多做測試。
注意:
這個實例僅適用于Java 8以前的版本如果在Java 8中應(yīng)該使用應(yīng)該調(diào)用需要傳類加載器和保護域的那個方法。Java 11開始Unsafe類已經(jīng)把defineClass方法移除了(defineAnonymousClass方法還在),雖然可以使用java.lang.invoke.MethodHandles.Lookup.defineClass來代替,但是MethodHandles只是間接的調(diào)用了ClassLoader的defineClass,所以一切也就回到了ClassLoader。
**如果您在閱讀文章的時候發(fā)現(xiàn)任何問題都可以通過Vchat與我們聯(lián)系,也歡迎大家加入javasec微信群一起交流。
Vchat獲取方式:對話框發(fā)送“javasec”
凌天實驗室凌天實驗室,是安百科技旗下針對應(yīng)用安全領(lǐng)域進行攻防研究的專業(yè)技術(shù)團隊,其核心成員來自原烏云創(chuàng)始團隊及社區(qū)知名白帽子,團隊專業(yè)性強、技術(shù)層次高且富有實戰(zhàn)經(jīng)驗。實驗室成立于2016年,發(fā)展至今團隊成員已達35人,在應(yīng)用安全領(lǐng)域深耕不輟,向網(wǎng)絡(luò)安全行業(yè)頂尖水平攻防技術(shù)團隊的方向夯實邁進。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的字体对话框java实验_Java Web安全 || Java基础 sun.misc.Unsafe的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows svn
- 下一篇: java 静态方法_新手学Java,哪些