详解 SEAndroid 以及 Hack 其规则(sepolicy)

详解 SEAndroid 以及 Hack 其规则(sepolicy),第1张

之前在搞Xposed的时候遇到一个问题是Xposed的卸载原本需要root权限,但是Xposed的原理是hack了zygote这个进程(xposed原理以后有时间再写),而zygote本身是有root权限的,所以Xposed应该是可以利用zygote的root权限来卸载自身。但是实际 *** 作中发现并不可以。经过一番研究发现这是由于SEAndroid的缘故,zygote的一些 *** 作会被SEAndroid限制,它的root权限并不是为所欲为的。下面就要详细的谈一下SEAndroid这个东西,然后再谈一谈如何去更改这个规则。

本文章有三个目的:

1.理解SEAndorid的工作原理

2.能够看懂SEAndroid的规则

3.能够自己增添删改其规则(这一条估计大多数人都用不到,所以前两条是主要目的)

SEAndroid 是御好闷SELinux 在Android 上面的一个移植。SELinux 是Linux上系统保护机制,SELinux 全称 Security Enhanced Linux (安全强化 Linux),是MAC (Mandatory Access Control,强制访问控制系统)的一个实现。其目的在于明确的指明某个进程可以访问哪些资源(文件、网络端口等)。Android系统基于Linux实现。针对传统Linux系统,NSA开发了一套安全机制SELinux,用来加强安全性。然而,由于Android系 统有着独特的用户空间运行时,因此SELinux不能完全适用于Android系统。为此,NSA同Google一起针对Android系统,在SELinux基础上开发了 SEAndroid。

Android 4.4首次引入了这一机制,SEAndroid与SELinux最大的不同在于SEAndroid对Android系统中的Binder做来了适配。进入adb shell 之后可以通过getenforce命令来查看其是否应用。root之后可以通过setenforce 0关闭SEAndroid。但是目前好像镇弯关闭了这一功能。

理解SEAndorid的概念不得不提到DAC 和 MAC。

DAC是传统的Linux的访问控制方式,DAC可以对文件、文件夹、共享资源等进行访问控制。 在DAC这种模型中,文件客体的所有者(或者管理员)负责管理访问控制。DAC使用了ACL(Access Control List,访问控制列袜空表)来给非管理者用户提供不同的权限,而root用户对文件系统有完全自由的控制权。

通俗的说就是,小明如果建立的某个文件他就对这个文件拥有绝对的控制权,他能够自主的控制其他人对该文件的权限。一个文件权限有读(r)写(w)执行(x)三种。我们可以通过ls -l 这个命令看到各个文件的权限情况。然后通过 chmod 这个命令可以指定这个其他人对这个文件的权限。(chmod 777  1.txt 这个命令大家应该都明白就不细说了)

但是这个机制有个不好的地方就是root用户可以控制任意文件的权限,可以为所欲为。而且控制粒度较粗,如果我只想让另一个人读我的文件,而这个人跟我不是同一用户组,我只能通过chmod XX4 XX 才能达到这一目的,但是这样的话其他任何人都可以读我的文件。所以说它粒度比较粗。

所以Linux就引入了MAC机制,即强制控制访问。 MAC核心思想 : 即任何进程想在SELinux系统中干任何事情,都必须先在安全策略配置文件中赋予权限。凡是没有出现在安全策略配置文件中的权限,进程就没有该权限。这个机制相当于一个白名单,这个白名单上配置了所有进程的权限,进程只能做白名单上权限内的事情,一旦它想做一个不属于它权限的 *** 作就会被拒绝。

MAC不再像DAC一样简单的把进程分为root others等,而是每个进程(Subject,主体)和文件(Object,客体)都配置了一个类型(Type),当一个进程去 *** 控(读写等)一个文件时,系统会检测该进程类型是否有对该文件类型的 *** 作权限。

通过命令ps -Z 可以查看进程的安全label,ls -Z 可以看到文件的label(安全上下文)。

比如进程安全上下文中的init进程,他的type为init,下面的进程的type为kernel。( 其实进程的type也被称为Domain )

文件安全上下文中的 123.txt 的 type为 tootfs。

(进程和文件安全上下文label格式为 user:role: type :security_level 中的其它几列不用管。这个涉及到SELinux中其它几种访问控制模型,在SEAndroid中我们只用关心他的type就好,比如init进程的  u:r: init: s0,我们只用知道他的type为init。)

知道进程和文件的安全上下文,那具体是怎么通过他们的安全上下文来控制权限的呢?

在手机上有个文件叫做sepolicy,这个文件就是SEAndroid的安全策略配置文件,里面有所有进程的权限配置,进程只能进行它的权限规定内的 *** 作。这个文件就有root权限也删不掉。把这个文件的内容dump出来后会发现里面有好多条规则(我逆过魅族的4000条,三星的20000条)。看两条例子。

      allow untrusted_app system_app_data_file : file { read }

      allow zygote sdcard_type : file { read write creat rename }

它的具体格式为: allow Domain Type : Class { Permission }   (Domain 是指进程的type)

通过这个格式解读上面的三条规则就是,

1. 允许 untrusted_app类型的进程对 system_app_data_file类型的文件进行read。

2.允许zygote类型的进程对sdcard_type的file进行 read write creat rename。

所以MAC控制方式是这个样子的:当一个进程去 *** 作一个文件的时候,系统会去检测这个进程和文件的上下文,看看这个进程的所属的type有没有对这个的文件的type *** 作的权限。比如:zygote如果要去读sdcard上的一个文件,这个文件的type为sdcard,zygote的type(Domain)为zygote, 系统去检测看看发现这条规则 allow zygote sdcard_type : file { read write creat rename }。那么这个 *** 作就会被允许执行。zygote要是想删除一个sdcard上的文件,系统发现对应的规则里没有delete,那么就会被deny。(上面的两条规则和这个例子是我自己编的,只是为了说明情况,真实情况下zygote是有权限删除sdcard上的文件的。)

DAC和MAC是同时作用的,一个 *** 作会先后根据DAC和MAC检测完再去执行,不满足任何一个机制的条件都会被拒绝。

上面一节解释了SEAndroid的工作原理,这下知道为什么zygote的root权限并不能为所欲为了,但是如何去更改SEAndroid的规则,扩大zygote的权限。直接更改sepolicy是不行的,因为sepolicy在boot.img里面,每次开机都会重写读取sepolicy这个文件,无法更改成功。

所以要直接解压boot.img替换里面的sepolicy然后重打包。Linux上有一套解压打包工具,windows解压工具为Android-Image-Tools-windows.zip  先找到手机厂商的官方ROM刷机包,找到boot.img解压。里面有个文件是sepolicy。修改sepolicy然后替换它重新打包刷入手机。(好吧其实蛮复杂的,但是我觉得大多数人可能用不到就先这样写吧,以后有需要的话会详细写。本来打算上传自己工具,不知道怎么上传文件。。。 我找不到我工具的链接了,可以去这里找找))

https://github.com/xmikos/setools-android

  1.sepolicy-inject:插入规则

2.sesearch:反编译sepolicy

3.seinfo: 查看sepolicy版本

修改sepolicy的命令:push到手机上 直接输入./(相应文件)即可查看其使用方式 (下面是我插入的其中一条命令)

./sepolicy-inject -s zygote -t labeledfs -c filesystem -p remount,getattr,relabelto,transition,quotamod,unmount -P /sepolicy -o /sdcard/sepolicy1

https://forum.xda-developers.com/showthread.php?t=2073775

博客是学习的起点而不是终点。。。 这篇文章只是入门SEAndroid,目的性较强,只讲了主要部分,很多内容没有涉及。深入了解SEAndroid的话可以去看看老罗的文章。

**最后, 同学点个赞吧!!! 加个关注好么**

参考链接:

SEAndroid安全机制简要介绍和学习计划 强烈推荐老罗

SEAndroid策略分析 推荐

Android的安全机制

深入理解SELinux

你好朋友

1. 禁止selinux

1.1 在内核中关闭selinux编译选项CONFIG_SECURITY_SELINUX

1.2 还可以在system.prop中定义ro.boot.selinux=disable

这两种方法都可以禁用selinux,也可以设置成ro.boot.selinux=permissive

宽容模式

1.3 可以通过setenforce 1 开启enforce模式,setenforce 0 为permissive模式

getenforce获取当前模芦老式

2. 所有安全策略最终编译成sepolicy文件放在root目录下,init进程启动后会读取/sepolicy策略文件,并通过/sys/fs/selinux/load节点

把策略文件内容写入内核

3 安全上下文存放root目录

/etc/security/mac_permissions.xml

/file_contexts //系统中所有file_contexts安全上下文

/seapp_contexts //app安全上下文

/property_contexts //属性的安全上下文

/service_contexts//service文件安全上下文

genfs_contexts //虚拟文件系统安全上下文

4. app在/data/data/文件的安全上下文设置过程

1. 根据uid,pkgname,seinfo在seapp_contexts中匹配.

2. 根据匹配到的contexts,重新设置给相对应文件

5. 系统中所有的object class 定义在external/sepolicy/security_classes中.

object class使用在allow语句中,object class所具有的 *** 作定义在external/sepolicy/access_vectors

文件中

6 allow语句缺宽

allow语句用来权限设置

rule_name source_type target_type : class perm_set

rule_name : 有allow,neverallow

source_type : 权限主体,表示source_type对target_type有perm_set描述的权限

如:

allow zygote init:process sigchld

允许zygote域里面的进程可对init域的进程发送sigchld信号

typeattribute表示把属性和type关联起来

7 role定义

Android系统中的role定义在external/sepolicy/roles中,

目前只定义了r

8 socket 使用

以/data/misc/wifi/sockets/wlan0 socket来说明使用方法

1. 定义socket type

type wpa_socket ,file_type

2. 指定安全上下文

/data/misc/wifi/sockets(/.*)? u:object_r:wpa_socket:s0

给/data/misc/wifi/sockets目录下所有的文件统一指定安全上下陪扮升文为wpa_socket

3.声明socket使用权限

在进程te中使用unix_socket_send(clientdomain, wpa, serverdomain)即可建立socket连接

9 binder使用

在使用binder 进程的te中根据情况使用如下宏:

binder_use(domain)//允许domain域中的进程使用binder通信

binder_call(clientdomain, serverdomain) //允许clientdomain和serverdomain域中的进程通信

binder_service(domain) //标志domain为service端

10 文件的使用

以/dev/wmtWifi来说明:

1.定义type

type wmtWifi_device dev_type //dev_type用来标志/dev/下的文件

2.给/dev/wmtWifi指定完全上下文

/dev/wmtWifi(/.*)? u:object_r:wmtWifi_device:s0

3.进程权限设置

在进程te文件中allow权限

allow netd wmtWifi_device:chr_file { write open }

11 property 属性设置

以蓝牙的各种属性来说明

1.定义type

type bluetooth_prop, property_type

2 设置安全上下文

bluetooth. u:object_r:bluetooth_prop:s0

3 进程权限设置

allow bluetooth bluetooth_prop:property_service set

5 专业词汇

MLS :Multi-Level Security

RBAC :Role Based Access Control

DAC :Discretionary Access Control

MAC :Mandatory Access Control

TEAC :Type Enforcement Accesc Control

望采纳祝你好运

[SELinux Policy]如何设置SELinux策略规则?

[Description]

android KK 4.4 版本后,Google 默认启用了SELinux, 并会把SELinux 审查异常打印在kernel log

或者 android log(L 版本)中,对应的核森关键字是: "avc: denied" 或者"avc: denied"

如一行LOG:

<5>[ 17.285600].(0)[503:idmap]type=1400 audit(1356999072.320:202): avc: denied { create

} for pid=503 comm="idmap" name="overlays.list" scontext=u:r:zygote:s0

tcontext=ubject_r:resource_cache_data_file:s0 tclass=file

即表明idmap 这个process, 使用zygote 的source context, 访问/data/resource_cache 目录,并

创建文件时,被段春SELinux 拒绝访问。

[Keyword]

android, SELinux, avc: denied, audit

[Solution]

KK 版本, Google 只有限制的启用SELinux, 即只有针对netd, installd, zygote, vold 以及它们

直接fork 出的child process 使用enforcing mode, 但不包括zygote fork的普通app.

L 版本, Google 全面开启SELinux, 几乎所有的process 都使enforcing mode, 影响面非常广.

目前所有的SELinux check 失败,在kernel log 或者android log(L版本后)中都有对应的"avc:

denied" 或者 "avc: denied"的LOG 与之对应。反过来,有此LOG,并非就会直接失败,还需要确认

当时SELinux 的模式, 是enforcing mode 还是 permissve mode.

首先, 务必确认对应进程访问系统资源是否正常, 是否有必要 ?如果本身是异常非法访问,那么

就要自行消除访问。

其次, 如果确认访问是必要,并且正常的,那么就要对对应的process/domain 增加新的policy.

1). 简化方法

1.1 提取所有的avc LOG. 如 adb shell "cat /proc/kmsg | grep avc" >avc_log.txt

1.2 使用 audit2allow tool 直接生成policy. audit2allow -i avc_log.txt 即可自动输出生成的

policy

1.3 将对应的policy 添加到selinux policy 规则中,对应MTK Solution, 您可以将它们添加在KK:

mediatek/custom/common/sepolicy, L: device/mediatek/common/sepolicy 下面,如

allow zygote resource_cache_data_file:dir rw_dir_perms

allow zygote resource_cache_data_file:file create_file_perms

===>mediatek/custom/common/sepolicy/zygote.te (KK)

===>device/mediatek/common/sepolicy/zygote.te (L)

注意audit2allow 它自动机械的帮您将LOG 转换成policy, 而无法知道你 *** 作的真实意图,有可能

出现权限放大问题,经常出现policy 无改燃亩法编译通过的情况。

2). 按需确认方法

此方法需要工程人员对SELinux 基本原理,以及SELinux Policy Language 有了解.

2.1 确认是哪个进程访问哪个资源,具体需要哪些访问权限,read ? write ? exec ? create ?

search ?

2.2 当前进程是否已经创建了policy 文件? 通常是process 的执行档.te,如果没有,并且它的父

进程即source context 无须访问对应的资源,则创建新的te 文件.

在L 版本上, Google 要求维护关键 security context 的唯一性, 比如严禁zygote, netd,

installd, vold, ueventd 等关键process 与其它process 共享同一个security context.

2.3 创建文件后,关联它的执行档,在file_contexts 中, 关联相关的执行档.

比如 /system/bin/idmap 则是 /system/bin/idmap ubject_r:idmap_exec:s0

2.4 填写policy 到相关的te 文件中

如果沿用原来父进程的te 文件,则直接添加.

如果是新的文件,那么首先:

#==============================================

# Type Declaration

#==============================================

type idmap, domain

type idmap_exec, exec_type,file_type

#==============================================

# Android Policy Rule

#==============================================

#permissive idmap

domain_auto_trans(zygote, idmap_exec, idmap)

然后添加新的policy

# new policy

allow idmap resource_cache_data_file:dir rw_dir_perms

allow idmap resource_cache_data_file:file create_file_perms

3). 权限放大情况处理

如果直接按照avc: denied 的LOG 转换出SELinux Policy, 往往会产生权限放大问题. 比如因为要

访问某个device, 在这个device 没有细化SELinux Label 的情况下, 可能出现:

<7>[11281.586780] avc: denied { read write } for pid=1217 comm="mediaserver"

name="tfa9897" dev="tmpfs" ino=4385 scontext=u:r:mediaserver:s0

tcontext=ubject_r:device:s0 tclass=chr_file permissive=0

如果直接按照此LOG 转换出SELinux Policy: allow mediaserver device:chr_file {read write}

那么就会放开mediaserver 读写所有device 的权限. 而Google 为了防止这样的情况, 使用了

neverallow 语句来约束, 这样你编译sepolicy 时就无法编译通过.

为了规避这种权限放大情况, 我们需要细化访问目标(Object) 的SELinux Label, 做到按需申请.

通常会由三步构成

3.1 定义相关的SELinux type.

比如上述案例, 在 device/mediatek/common/sepolicy/device.te 添加

type tfa9897_device, dev_type

3.2 绑定文件与SELinux type.

比如上述案例, 在 device/mediatek/common/sepolicy/file_contexts 添加

/dev/tfa9897(/.*)? ubject_r:tfa9897_device:s0

3.3 添加对应process/domain 的访问权限.

比如上述案例, 在 device/mediatek/common/sepolicy/mediaserver.te 添加

allow mediaserver tfa9897_device:chr_file { open read write }

那么哪些访问对象通常会遇到此类呢?(以L 版本为例)

* device

-- 类型定义: external/sepolicy/device.tedevice/mediatek/common/sepolicy/device.te

-- 类型绑定:

external/sepolicy/file_contextsdevice/mediatek/common/sepolicy/file_contexts

* File 类型:

-- 类型定义: external/sepolicy/file.tedevice/mediatek/common/sepolicy/file.te

-- 绑定类型:

external/sepolicy/file_contextsdevice/mediatek/common/sepolicy/file_contexts

* 虚拟File 类型:

-- 类型定义: external/sepolicy/file.tedevice/mediatek/common/sepolicy/file.te

-- 绑定类型:

external/sepolicy/genfs_contextsdevice/mediatek/common/sepolicy/genfs_contexts

* Service 类型:

-- 类型定义: external/sepolicy/service.tedevice/mediatek/common/sepolicy/service.te

-- 绑定类型

:external/sepolicyservice_contextsdevice/mediatek/common/sepolicy/service_contexts

* Property 类型:

-- 类型定义: external/sepolicy/property.tedevice/mediatek/common/sepolicy/property.te

-- 绑定类型:

external/sepolicy/property_contextsdevice/mediatek/common/sepolicy/property_contexts

通常我们强烈反对更新google default 的policy, 大家可以更新mediatek 下面的相关的policy.


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/12236911.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-22
下一篇 2023-05-22

发表评论

登录后才能评论

评论列表(0条)

保存