explains the security issues caused by improper use of Logcat in Android development
Original address: http://drops.wooyun.org/tips/3812 0x00 Popular Science
Development version: Development version, under development of beta version, there will be many debug logs.
Release version: Release, signed and developed to the user's official version, less log volume.
Android.util.Log: Provides five ways to output logs
LOG.E (), LOG.W (), LOG.I (), LOG.D (), LOG.V ()
ERROR, WARN, INFO, DEBUG, VERBOSE
Android.permission.READ_LOGS:app read log permissions, prior to Android 4.1, you can read the log of other applications by requesting Read_logs permissions. But Google found that there is a security risk, so Android 4.1 and later versions, even if the application of Read_logs permissions can not read the other application log information. The signature of Logcat in version 4.1 has changed to "signature|system|development", which means that only the system-signed app or the root-privileged app can use that permission. Regular users can view all logs through ADB.
0x01 test
The test method is very simple, and you can use the gadget monitor in the SDK or the integrated Logcat in ADT to view the log, which is handy for adding tool catalogs to environment variables. Of course you can use ADB logcat if you want to have more bigger. Android Overall log information is very large, want to be efficient some must use filter to filter some irrelevant information, filter is to support regular, can do some keyword matching such as password, token, email and so on. Originally prepared to want to do a small tool automated collection, but feel this thing slightly chicken not too much necessary, so the focus of this article is how to safely use the logcat aspect.
Of course, you can also write your own app to crawl Logcat directly on the phone, but mentioned earlier because of the Android system reason if the phone is android4.1 or later version even if the following applications in Manifest.xml can not be read to other applications log.
<uses-permission android:name="android.permission.READ_LOGS"/>
Root privileges can be casually see logcat, so "logcat information leaked" vulnerability due to Google's action on the 4.1 became very chicken.
0x02 Smali Injection Logcat
The http://drops.wooyun.org/tips/2986 article mentions that printing sensitive data before encryption is the use of static Smali injection to insert the Logcat method. Using the APK to change the Smali injection is very convenient, but to note that arbitrary addition of registers may break the logic itself, Novice recommends not to add registers directly using the existing registers.
invoke-static {v0, v0}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I
0X03 recommendations
Some people think that any log should not be printed in the release version. However, for the error collection of the app, abnormal feedback, the necessary logs are still to be output, as long as the security code to follow the code to control the risk in the smallest range.
LOG.E ()/w ()/I (): Recommended print Operation log
LOG.D ()/V (): Recommended Print Development log
1, sensitive information does not apply LOG.E ()/w ()/I (), System.out/err printing.
2. It is recommended to use LOG.D ()/V () If you need to print some sensitive information. (Prerequisite: Release version will be automatically removed)
@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, the return value of LOG.D ()/V () should not be used. (only for development and commissioning observations)
Examination code which LOG.V () that's specifeied to be deleted are 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 version APK implementation automatically delete log.d ()/V () and other code.
Configuring Proguard in Eclipse
All the logs in the development version are printed out.
Release Proguard removed d/v's log
Post-compilation view is actually removed.
5. The open apk file should be the release version instead of the development version.
0X04 native code
The Android.util.Log constructor is private and is not instantiated, but provides static properties and methods. The implementation of Android.util.Log's various log recording methods relies on the implementation of native Println_native (), LOG.V ()/log.d ()/log.i ()/LOG.W ()/LOG.E () Finally, the println_native () is called.
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) {& nbsp; jnithrownullpointerexception (env, "println needs a Message"); return -1;} if (Bufid < 0 | | Bufid >= log_id_max) { jnithrownullpointerexception (env, "bad BufID"); &nbs p; 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); Tag = NULL) env->releasestringutfchars (tagobj, tag); Env->releasestringutfchars ( Msgobj, msg); return res;}
The
__android_log_buf_write () also calls the Write_to_log function pointer.
static int __write_to_log_init (log_id_t log_id, struct Iovec *vec, size_t nr) {#ifdef have_pthreads & nbsp 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);}
In general, the println_native () operation is to open the device file and write the data.
0x05 Other Notes
1. Print the Exception object using LOG.D ()/V (). (such as sqliteexception may cause problems with SQL injection)
2, using the method of Android.util.Log class output log, do not recommend the use of System.out/err
3. The version with Buildconfig.debug ADT is not less than 21
public final static boolean DEBUG = true;
will be automatically set to false in release version
if (BuildConfig.DEBUG) android.util.Log.d(TAG, "Log output information");
4. When the activity is started, Activitymanager will output intent information as follows:
- Target Package Name
- Target class name
- URL for intent.setdata (URL)
5, even without System.out/err program may also output relevant information, such as the use of Exception.printstacktrace ()
6, Proguard can not remove the following log: ("Result:" + value).
Log.d(TAG, "result:" + value);
Bulidconfig should be used when encountering such situations (note ADT version)
if (BuildConfig.DEBUG) Log.d(TAG, "result:" + value);
7, the log should not be output to Sdscard, which will make the log become global readable
# #0x06 Cloud Case
Wooyun: TripAdvisor app logcat information leaks users ' chat content with group chat
Wooyun: Surf browser locat out user SMS
Wooyun: Hangzhou Bank Android Client login account password information local disclosure
0x07 Reference
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 (EXT)