小问题
setenforce 0
这个命令有个效果就是强制突破seandroid机制,等于关闭了seandroid。
理论上讲,即使是root 设备,这个命令应该一般情况下也不能随意执行。不然被病毒攻击后,执行了这个指令后seandroid完全没啥乱用了就。不过我在miui9的一个修改的刷机版本了(拥有root)里实验了下这个命令,是可以在root下执行的。
也就是说,在这个版本里,seandroid形同虚设。
难道是我理解错了,先记录下来吧。
后来我想了下,seandroid这个访问机制的核心是策略和安全上下文,
我这里设置enforce属性用的是adbd进程,但是病毒的话,即使是得到了root权限,它的context属性肯定就是普通的应用。
(当然如果病毒修改了seandroid就另当别论了,我们不考虑这种情况,当然这也需要更高的技术了)。那么他的上下文就会受到SEandroid策略的限制,使得病毒的能力大大削减。这样seandroid就能发挥作用了。困扰了我多时的问题解决了,感觉神清气爽。
其实这里还有一种方式,如果攻击上下文属性高的进程,那病毒功能就会直接继承强大的能力了吧。
安全上下文 security_context
SEAndroid安全机制框架分析
在开启了SEAndroid安全机制的设备上执行带-Z选项的ps命令,就可以看到一个进程的安全上下文:
$ ps -Z
LABEL USER PID PPID NAME
u:r:init:s0 root 1 0 /init
......
上面的命令列出进程init的安全上下文为“u:r:init:s0”,这表明进程init的SELinux用户、SELinux角色、类型和安全级别分别为u、r、init和s0。
类型是比较重要的,其他一般忽略,影响较小。也就是第三个属性。
上下文的相关属性一般会跟文件所在的目录有关,定义在文件external/sepolicy/file_contexts中。
安全策略
int main(int argc, char **argv)
{
......
union selinux_callback cb;
cb.func_log = klog_write;
selinux_set_callback(SELINUX_CB_LOG, cb);
cb.func_audit = audit_callback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
INFO("loading selinux policy\n");
if (selinux_enabled) {
if (selinux_android_load_policy() < 0) {
selinux_enabled = 0;
INFO("SELinux: Disabled due to failed policy load\n");
} else {
selinux_init_all_handles();
}
} else {
INFO("SELinux: Disabled by command line option\n");
}
......
}
上述代码定义在文件system/core/init/init.c中。
这里调用到了三个与SEAndroid相关的函数:selinux_set_callback、selinux_android_load_policy和selinux_init_all_handles,其中,selinux_set_callback和selinux_android_load_policy来自于libselinux,而selinux_init_all_handles也是定义在文件system/core/init/init.c中,并且它最终也是通过调用libselinux的函数来打开前面分析file_contexts和property_contexts文件,以便可以用来查询系统文件和系统属性的安全上下文。
这里就比较清晰了。如果我们需要绕过seandroid的相关限制,就可以直接hook这些函数。把加载的file_contexts和property_context文件修改,那么,我们就实现了真正的最高权限。或者直接修改rom中对应的文件。
源码中实现方式
SEAndroid安全机制中的文件安全上下文关联分析
SEAndroid安全机制中的进程安全上下文关联分析
这两篇分别写了seandroid在源码中的文件上下文属性和进程上下文属性的设置过程。
static int setSELinuxContext(uid_t uid, bool isSystemServer,
const char *seInfo, const char *niceName)
{
#ifdef HAVE_ANDROID_OS
return selinux_android_setcontext(uid, isSystemServer, seInfo, niceName);
#else
return 0;
#endif
}
这个函数定义在文件dalvik/vm/native/dalvik_system_Zygote.cpp中。
函数setSELinuxContext的实现很简单,它通过调用libselinux提供的函数selinux_android_setcontext来设置刚刚创建出来的应用程序进程的安全上下文。
从设备上可以读取一个sepolicy文件,如下所示:
./adb pull /sepolicy ./sepolicy
2372 KB/s (558936 bytes in 0.230s)
读取出来的sepolicy文件实际上描述的就是设备使用的SEAndroid安全策略,我们可以通过apol工具对它进行分析。
接着我们打开apol工具,并且从File菜单中点击Open项打开上述sepolicy文件。切换到Policy Components选项卡,在左则的Types列表中找到adbd项,双击查看它的属性,通过这种方式可以查看各种domain包含的权限。
这个工具还可以查看各种type在相应的进程上下文中的可操作权限。详细介绍查看本小节给出的链接2。