測試了一下,這裡記錄一下結果:
1、使用網上的poc,在java6u23,java6b13, java7u6下分別測試。(為什麼要測試java6u13,原因是SunToolkit.getField方法在低版本java6中也是public 的,所以測試看看在低版本是否也能重現java7的漏洞)
2、測試尋找是否有其他可以替代SunToolkit.getField方法的其他方法。
結果:
1、原始poc在java6里不行,java7里可以直接成功利用,彈出calc。
2、兩個版本的java6都沒法突破,原版poc,直接報錯:在applet下根本不允許訪問awt.SunToolkit包。
3、java7如果直接import這個包,也是同樣的報錯,jvm不允許加載此包。
4、嘗試了其他函數,沒有測試成功可以替換SunToolkit.getField方法的方法。
根據結果反饋的原理:
首先這個問題出在的重點有兩個,一個是classFinder,一個是java 7的sun.awt.SunToolkit上。
1、限制了只能在java7上成功。
2、限制了後續是否能disableSecurityManager,也就是去掉java代碼執行的沙盒限制。雖然說這個SunToolkit不是不可替 代的(field.setAccessible(true);找到這個類似代碼就行),但是我找了一下午沒有找到替代品。
因為需要加載2,所以必須要有1去用反射加載,就是因為java7的1這裡存在問題,原本不能加載的SunToolkit可以被加載了,所以才引發一系列 後續內容。至於getField是不是public有沒有影響,這裡沒有測試出來,因為1已經直接限制了即時是public的java6,也沒法調用 SunToolkit。
作者:GaRY
以上是今天的階段性測試結果,不保證原理完全正確,但是根據今天的測試結果看來是這樣的。這裡感謝@kxlzx和@tcpper
作者:esafe
@GaRY
上面有這樣一個問題:至於getField是不是public有沒有影響?
我剛找到一個這樣的例子,問題是:java反射的安全性控制機制好像沒有起作用?
01 |
public class GG { |
02 |
public String name = "test"; |
03 |
} |
04 |
public class Test1 { |
05 |
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchFieldException { |
06 |
07 |
Class cls = Class.forName(GG.class.getName()); |
08 |
09 |
GG gg = (GG) cls.newInstance(); |
10 |
Field field = cls.getDeclaredField("name"); |
11 |
12 |
//field.setAccessible(true); |
13 |
System.out.println((String)field.get(gg)); |
14 |
} |
15 |
} |
無論field.setAccessible(true);與否,都能調用GG類型name屬性值,因為name是public;如果是private就會報java.lang.IllegalAccessException(安全權限異常) 。
其實在java裡這是個很簡單的安全機制,例如:子類無法訪問父類的私有屬性或方法 (只能通過父類的,如:public方法訪問)。
所以反射機制的setAccessible(true);方法在這裡確實有很大問題!
@f4tb0y 配置好java環境,保存上面的為.java文件,並編譯為.class文件;創建一個.html
.html內容
<applet code="類名.class" width="0" height="0" ></applet>
把兩個文件放在同一路徑,運行一下.html文件就好了!