fortify Unsafe JNI


Unsafe JNI 

主要解決問題:

1.system.currentTimeMillis();

使用SystemClock.now()替換。

2.isAssignableFrom();

使用新定義的isAssignableFromForCC()方法替換

   /**
     * Checks if one {@code Class} can be assigned to a variable of
     * another {@code Class}.</p>
     * @param cls: the Class to check, may be null
     * @param tocls: the Class to try to assign into, returns false if null
     * @return
     */
   public static boolean isAssignableFromForCC( Class<?> cls,  Class<?> tocls) {
        return ClassUtils.isAssignable(cls, tocls);// use org.apache.commons.lang3.ClassUtils;
   }

3.obj.hashCode()

使用新定義的hashCodeForCC()方法替換

public static int hashCodeForCC(Object obj) {
   return ObjectUtils.hashCode(obj);//org.apache.commons.lang3.ObjectUtils;
}

4.getModifiers()

使用新定義的getModifiersForCC()方法替換

public static int getModifiersForCC(Class clazz) {
   return ReflectUtils.getClassInfo(clazz).getModifiers();//org.springframework.cglib.core.ReflectUtils;
}

5.Thread.sleep(1000L);

TimeUnit.SECONDS.sleep(1);

6.Thread.currentThread().getContextClassLoader();

ClassUtils.class.getClassLoader();

 

Abstract

Java Native Interface(JNI)應用不當會導致 Java 應用程序容易受到其他語言的安全漏洞攻擊。

Explanation

當 Java 應用程序使用 JNI 調用以其他編程語言編寫的代碼時,會發生 Unsafe JNI 漏洞。 例如:以下 Java
代碼定義了一個名為 Echo 的類。 這個類聲明了一個本地方法(下文定義),使用 C 語言將控制台上輸入的
命令回顯給用戶。
class Echo {
  public native void runEcho();
 
  static {
    System.loadLibrary("echo");
  }
 
  public static void main(String[] args) {
    new Echo().runEcho();
  }
}

 

以下 C 語言代碼定義了在 Echo 類中實現的本地方法:
#include <jni.h>
#include "Echo.h" //the java class above compiled with javah
#include <stdio.h>
JNIEXPORT void JNICALL
Java_Echo_runEcho(JNIEnv *env, jobject obj)
{
  char buf[64];
  gets(buf);
  printf(buf);
}

 

因為這個例子是在 Java 中實現的,所以看上去似乎可以避免諸如 buffer overflow 之類的內存問題。 雖然
Java 在內存安全方面做的很好,但是該保護機制並不適用於其他語言編寫的且通過 Java 本地接口 (Java
Native Interface,JNI) 訪問的源代碼中出現的漏洞。 盡管有 Java 提供的內存保護機制,但是這個例子中的 C
語言代碼仍然很容易受到 buffer overflow 的攻擊,因為它在沒有執行任何輸入檢查的情況下就使用了
gets()。 Sun Java(TM) 教程對 JNI 描述如下 [1]: 一旦有了 JNI 框架,您的本地方法就可以像 Java 代碼那
樣利用 Java 對象。 本地方法可以創建 Java 對象(包括數組和字符串),並且檢查和應用這些對象,以便執
行各種相關的任務。 本地方法也可以檢查和應用由 Java 應用程序代碼創建的對象。 本地方法甚至可以更新
由自己創建的或傳遞給它的 Java 對象,且更新后的對象可以應用到 Java 應用程序中。 因此,在應用程序
中,無論是本地語言還是 Java 語言都能創建、更新和訪問 Java 對象,並在兩種語言間共享這些對象。 通過
檢查本地方法實現的源代碼,可以輕松地發現上述例子中存在的漏洞。 根據不同的 C 語言源代碼和項目構建
方式,這種方式可能在某些情況下不可行,但是多數情況下還是可行的。 然而,這種能夠在 Java 方法和本
地方法間共享對象的能力會進一步加大潛在的風險。在 Java 中數據處理不當時,可能會導致本地代碼出現意
想不到的漏洞,同樣本地代碼中的不安全操作會破壞 Java 的數據結構。 通過 Java 應用程序訪問的本地代碼
中出現的漏洞,通常與由本地語言編寫的應用程序中存在的漏洞是一樣的。 這種攻擊面臨的唯一挑戰是:攻
擊者需要確定 Java 應用程序是否使用了本地代碼執行某些特定的操作。 可以用多種方法實現上述目的,包
括識別那些通常用本地代碼實現的某些特定行為,或者利用 Java 應用程序中 system information leak 的漏洞
(表明系統使用了 JNI) [2]。

Recommendation

審計所有構成某個特定應用程序的源代碼,包括在其他語言中執行的本地方法。 審計期間,要確保能夠正確
地解釋和處理 Java 和本地代碼在邊界檢查和其他行為之間的差別。 特別是確保在以下所有階段都正確處理
了共享對象: 對象被傳遞到本地代碼前、對象被本地代碼應用期間以及對象被返回給 Java 應用程序后。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM