Android Logcat Security

來源:互聯網
上載者:User

標籤:

講解了在Android開發中logcat使用不當導致的安全問題
原帖地址:http://drops.wooyun.org/tips/3812 0x00 科普

development version :開發版,正在開發內測的版本,會有許多調試日誌。

release version : 發行版,簽名後開發給使用者的正式版本,日誌量較少。

android.util.Log:提供了五種輸出日誌的方法

Log.e(), Log.w(), Log.i(), Log.d(), Log.v()

ERROR, WARN, INFO, DEBUG, VERBOSE

android.permission.READ_LOGS:app讀取日誌許可權,android 4.1之前版本通過申請READ_LOGS許可權就可以讀取其他應用的log了。但是Google發現這樣存在安全風險,於是android 4.1以及之後版本,即使申請了READ_LOGS許可權也無法讀取其他應用的日誌資訊了。4.1版本中 Logcat的簽名變為“signature|system|development”了,這意味著只有系統簽名的app或者root許可權的app才能使用該許可權。普通使用者可以通過ADB查看所有日誌。

0x01 測試

測試方法是非常簡單的,可以使用sdk中的小工具monitor或者ADT中整合的logcat來查看日誌,將工具目錄加入環境變數用起來比較方便。當然如果你想更有bigger也可以使用adb logcat。android整體日誌資訊量是非常大的,想要高效一些就必須使用filter來過濾一些無關資訊,filter是支援正則的,可以做一些關鍵字匹配比如password、token、email等。本來準備想做個小工具自動化收集,但是覺得這東西略雞肋沒太大必要,故本文的重點也是在如何安全的使用logcat方面。

當然也可以自己寫個app在直接在手機上抓取logcat,不過前面提到因為android系統原因如果手機是android4.1或者之後版本即使在manifest.xml中加入了如下申請也是無法讀取到其他應用的log的。

<uses-permission android:name="android.permission.READ_LOGS"/>

root許可權可以隨便看logcat,所以“logcat資訊泄露”漏洞因Google在4.1上的動作變得很雞肋了。

0x02 smali注入logcat

http://drops.wooyun.org/tips/2986 一文中提到將敏感性資料在加密前列印出來就是利用靜態smali注入插入了logcat方法。 使用APK改之理smali注入非常方便,但要注意隨意添加寄存器可能破壞本身邏輯,新手建議不添加寄存器直接使用已有的寄存器。

invoke-static {v0, v0}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I

0x03 建議

有些人認為任何log都不應該在發行版本列印。但是為了app的錯誤採集,異常反饋,必要的日誌還是要被輸出的,只要遵循安全編碼規範就可以將風險控制在最小範圍。

Log.e()/w()/i():建議列印動作記錄

Log.d()/v():建議列印開發日誌

1、敏感資訊不應用Log.e()/w()/i(), System.out/err 列印。

2、如果需要列印一些敏感資訊建議使用 Log.d()/v()。(前提:release版本將被自動去除)

@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_proguard);// *** POINT 1 *** Sensitive information must not be output by Log.e()/w()/i(), System.out/err.Log.e(LOG_TAG, "Not sensitive information (ERROR)");Log.w(LOG_TAG, "Not sensitive information (WARN)");Log.i(LOG_TAG, "Not sensitive information (INFO)");// *** POINT 2 *** Sensitive information should be output by Log.d()/v() in case of need.// *** POINT 3 *** The return value of Log.d()/v()should not be used (with the purpose of substitution or comparison).Log.d(LOG_TAG, "sensitive information (DEBUG)");Log.v(LOG_TAG, "sensitive information (VERBOSE)");}

3、Log.d()/v()的傳回值不應被使用。(僅做開發調試觀測)

Examination code which Log.v() that is specifeied to be deleted is not deketed

int i = android.util.Log.v("tag", "message");System.out.println(String.format("Log.v() returned %d. ", i)); //Use the returned value of Log.v() for examination

4、release版apk實現自動刪除Log.d()/v()等代碼。

eclipse中配置ProGuard

開發版所有log都列印出來了。

發行版ProGuard移除了d/v的log

反編譯後查看確實被remove了

5、公開的APK檔案應該是release版而不是development版。

0x04 native code

android.util.Log的建構函式是私人的,並不會被執行個體化,只是提供了靜態屬性和方法。 而android.util.Log的各種Log記錄方法的實現都依賴於native的實現println_native(),Log.v()/Log.d()/Log.i()/Log.w()/Log.e()最終都是調用了println_native()。

Log.e(String tag, String msg)

public static int v(String tag, String msg) {     return println_native(LOG_ID_MAIN, VERBOSE, tag, msg);}

println_native(LOG_ID_MAIN, VERBOSE, tag, msg)

/* * In class android.util.Log: *  public static native int println_native(int buffer, int priority, String tag, String msg) */static jint android_util_Log_println_native(JNIEnv* env, jobject clazz,     jint bufID, jint priority, jstring tagObj, jstring msgObj){const char* tag = NULL;const char* msg = NULL;if (msgObj == NULL) {     jniThrowNullPointerException(env, "println needs a message");     return -1;}if (bufID < 0 || bufID >= LOG_ID_MAX) {     jniThrowNullPointerException(env, "bad bufID");     return -1;}if (tagObj != NULL)     tag = env->GetStringUTFChars(tagObj, NULL);msg = env->GetStringUTFChars(msgObj, NULL);int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);if (tag != NULL)     env->ReleaseStringUTFChars(tagObj, tag);env->ReleaseStringUTFChars(msgObj, msg);return res;}

其中__android_log_buf_write()又調用了write_to_log函數指標。

static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr){#ifdef HAVE_PTHREADS     pthread_mutex_lock(&log_init_lock);#endif     if (write_to_log == __write_to_log_init) {         log_fds[LOG_ID_MAIN] = log_open("/dev/"LOGGER_LOG_MAIN, O_WRONLY);         log_fds[LOG_ID_RADIO] = log_open("/dev/"LOGGER_LOG_RADIO, O_WRONLY);         log_fds[LOG_ID_EVENTS] = log_open("/dev/"LOGGER_LOG_EVENTS, O_WRONLY);         log_fds[LOG_ID_SYSTEM] = log_open("/dev/"LOGGER_LOG_SYSTEM, O_WRONLY);         write_to_log = __write_to_log_kernel;         if (log_fds[LOG_ID_MAIN] < 0 || log_fds[LOG_ID_RADIO] < 0 ||             log_fds[LOG_ID_EVENTS] < 0) {             log_close(log_fds[LOG_ID_MAIN]);             log_close(log_fds[LOG_ID_RADIO]);             log_close(log_fds[LOG_ID_EVENTS]);             log_fds[LOG_ID_MAIN] = -1;             log_fds[LOG_ID_RADIO] = -1;             log_fds[LOG_ID_EVENTS] = -1;             write_to_log = __write_to_log_null;         }         if (log_fds[LOG_ID_SYSTEM] < 0) {             log_fds[LOG_ID_SYSTEM] = log_fds[LOG_ID_MAIN];         }     }#ifdef HAVE_PTHREADS     pthread_mutex_unlock(&log_init_lock);#endif     return write_to_log(log_id, vec, nr);}

總的來說println_native()的操作就是開啟裝置檔案然後寫入資料。

0x05 其他注意

1、使用Log.d()/v()列印異常對象。(如SQLiteException可能導致sql注入的問題)

2、使用android.util.Log類的方法輸出日誌,不推薦使用System.out/err

3、使用BuildConfig.DEBUG ADT的版本不低於21

public final static boolean DEBUG = true;

在release版本中會被自動化佈建為false

if (BuildConfig.DEBUG) android.util.Log.d(TAG, "Log output information");

4、啟動Activity的時候,ActivityManager會輸出intent的資訊如下:

  • 目標包名
  • 目標類名
  • intent.setData(URL)的URL

5、即使不用System.out/err程式也有可能輸出相關資訊,如使用 Exception.printStackTrace()

6、ProGuard不能移除如下log:("result:" + value).

Log.d(TAG, "result:" + value);

當遇到此類情況應該使用BulidConfig(注意ADT版本)

if (BuildConfig.DEBUG) Log.d(TAG, "result:" + value);

7、不應將日誌輸出到sdscard中,這樣會讓日誌變得全域可讀

##0x06 烏雲案例

WooYun: 途牛網app logcat資訊泄露使用者的同團聊的聊天內容

WooYun: 衝浪瀏覽器locat出使用者簡訊

WooYun: 杭州銀行Android用戶端登入帳號密碼資訊本地泄露

0x07 參考

http://www.jssec.org/dl/android_securecoding_en.pdf

http://source.android.com/source/code-style.html#log-sparingly

http://developer.android.com/intl/zh-cn/reference/android/util/Log.html

http://developer.android.com/intl/zh-cn/tools/debugging/debugging-log.html

http://developer.android.com/intl/zh-cn/tools/help/proguard.html

https://www.securecoding.cert.org/confluence/display/java/DRD04-J.+Do+not+log+sensitive+information

https://android.googlesource.com/platform/frameworks/base.git/+/android-4.2.2_r1/core/jni/android_util_Log.cpp

Android Logcat Security(轉)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.