访客数— ◆阅读量— 文章数11

Android

阅读 —

Binder.getCallingPid()和Binder.getCallingUid()漏洞分析

结合 Ghera 示例分析 Binder 调用身份与组件权限校验问题。

最近在学习安卓漏挖,在分析ghera数据集时发现一个很有意思的binder特性,但还没搞懂底层原理,先挖个坑

漏洞分析

EnforceCallingOrSelfPermission-PrivilegeEscalation-Lean

以下代码使用Binder.getCallingPid()和Binder.getCallingUid()对调用方进行了权限检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// MyService.java
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyService", "Calling PID = " + Binder.getCallingPid() + " Calling UID = " + Binder.getCallingUid());
if (checkPermission("santos.benign.permission", Binder.getCallingPid(), Binder.getCallingUid()) == PackageManager.PERMISSION_GRAN
Log.d("MyService", "Service Started");
Intent activityIntent = new Intent(this, SensitiveActivity.class);
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activityIntent.putExtra("status_msg", "SUCCESS");
this.startActivity(activityIntent);
} else {
Log.d("MyService", "Failed to start the service");
}
return super.onStartCommand(intent, flags, startId);
}

其中调用方如下

1
2
3
4
5
6
7
8
9
10
11
// MainActivity.java
protected void onResume() {
super.onResume();
if (checkPermission("santos.benign.permission", android.os.Process.myPid(), android.os.Process.myUid()) == PackageM
Log.d("MyService", "permission to service already granted");
startService(new Intent(getApplicationContext(), MyService.class));
} else {
Log.d("MyService", "component does not have permission to call service");
ActivityCompat.requestPermissions(this, new String[]{"santos.benign.permission"}, 100);
}
}

可以看到,MyService是由MainActivity启动的,也就是他们都属于主线程。而在主线程调用Binder.getCallingPid()和Binder.getCallingUid()不会返回调用方的信息,只会返回自身进程的信息,这样上面代码的权限校验相当于只对自身权限做了检查,正确的做法应该是在manifest中静态声明权限或使用EnforceCallingPermission方法进行校验