Android security知识点总结

Linux sepolicy uses ipk package, each binary has three sepolicy files, they are if (interface), fc (file context), te. opkg install selinux.ipk

1 Chain of Trust
1.1 qcom efuse
对bootloader签名,熔丝文件:sec.dat

1)烧写signed bootloader
2)将密匙文件sec.dat烧写入efuse
3)重启设备,设备的bootROM会读取efuse中的密匙pubk验证bootloader
4)bootloader验证通过,启动,开始基于信任链(chain of trust)的AVB验证流程

1.2 编译时关闭AVB
BoardConfig.mk
BOARD_AVB_ENABLE := false
BOARD_BUILD_DISABLED_VBMETAIMAGE := true

Android 8.0之后没有独立的recovery.img,boot.img根据cmdline参数来决定mount哪个ramdisk。
如果有skip_initramfs参数,那么mount打包在system.img(system-as-root)中的normal ramdisk;否则mount打包在boot.img中的recovery ramdisk。

参数BOARD_BUILD_SYSTEM_ROOT_IMAGE的配置决定是将normal ramdisk打包到boot.img中还是打包到system.img中。
打包到boot.img中:
BOARD_BUILD_SYSTEM_ROOT_IMAGE := false

打包到system.img中(system-as-root):
BOARD_BUILD_SYSTEM_ROOT_IMAGE := true

1.3 AVB验证流程
需要提前挂载分区的fstab来自于commandline的androidboot.android_dt_dir
1)bootloader使用内置的OEM pubk验证vbmeta.img,验证通过后用vbmeta.img中的boot pubk验证boot.img,如果验证通过就启动boot.img
2)init启动后,init/fs_mgr使用vbmeta.img中的vendor pubk、system pubk、odm pubk验证vendor.img、system.img、odm.img,验证通过就mount,否则不会mount

编译生成Metadata流程:
@ build/core/Makefile
->
@ build/tools/releasetools/build_image.py
->
BuildVerityTree() - 用来生成dm_verity需要的签名数据
BuildVerityMetadata() - 生成Metadata数据
->
@ system/extras/verity/build_verity_metadata.py
->
build_verity_metadata()

1.4 dm-verity
可以使用内核配置CONFIG_DM_VERITY_HASH_PREFETCH_MIN_SIZE(默认大小为128)来启用dm-verity哈希预提取大小,该修改可提升启动速度。

1.5 Android 8.0 userdebug版本刷机时禁止dm-verity
Android 8.0 dm-verity disable flag存在于vbmeta.img(keystore分区)中;而老版本是放置在system.img分区的dm-verity metadata中。
1)在设置中打开OEM unlocking选项
2)在设置中打开USB debugging选项
3)adb reboot bootloader
4)fastboot flashing unlock和fastboot oem unlock
5)fastboot --disable-verity --disable-verification flash vbmeta vbmeta.img
6)fastboot reboot
7)adb root
8)adb remount

1.6 vbmeta for AVB disabled
# commands from zcat out/verbose.log.gz
# PEM: Privacy Enhanced Mail
#!/bin/sh

MY_PATH=${PWD}
TARGET_DIR=${MY_PATH}/out/target/product/${TARGET_PRODUCT}
AVB_TOOL=${MY_PATH}/external/avb/avbtool
# or your own xxx_rsa4096.pem file
TESTKEY=${MY_PATH}/external/avb/test/data/testkey_rsa4096.pem

# in x86_64 platform, replace dtbo.img with tos.img
python ${AVB_TOOL} make_vbmeta_image --output ${TARGET_DIR}/vbmeta_disabled.img \
    --include_descriptors_from_image ${TARGET_DIR}/boot.img \
    --include_descriptors_from_image ${TARGET_DIR}/system.img \
    --include_descriptors_from_image ${TARGET_DIR}/vendor.img \
    --include_descriptors_from_image ${TARGET_DIR}/dtbo.img \
    --setup_rootfs_from_kernel ${TARGET_DIR}/system.img \
    --algorithm SHA256_RSA4096 \
    --key ${TESTKEY} \
    --padding_size 4096 \
    --set_hashtree_disabled_flag

1.7 EXT4 Encryption
FBE:加密的仅仅是文件内容和文件名,其他的信息比如文件大小,权限等都没有加密,这些内容就是filesystem metadata
Metadata分区:加密文件大小,权限等除了文件内容和文件名之外的文件信息,/metadata/vold/metadata_encryption/key
QSEE: Qualcomm Security Executing Environment

github ext4-crypt
add_key() - e4crypt add_key
keyctl_search()
keyctl_unlink()

setenforce 0
# erase RPMB
qseecom_sample_client -v sampleapp 15 1
# program RPMB
qseecom_sample_client -v sampleapp 14 1

adb push keybox.xml /data
adb shell
cd /data
LD_LIBRARY_PATH=/vendor/lib/hw KmInstallKeybox keybox.xml <dev_id> true

1.8 lpunpack
lp: Logical Partition images

make lpunpack

simg2img super.img super_ext4.img
mkdir super_ext4
out/host/linux-x86/bin/lpunpack super_ext4.img super_ext4/

2 Android selinux
2.1 LSM的五种实现
LSM(Linux Security Module)的名字并不是特别准确,因为它并不是真正意义上的Linux模块,而是一些函数的hook机制。
AppArmor:应用盔甲,AppArmor is installed by default in Ubuntu
SELinux:Security Enhanced Linux,基于inode,Android当前使用的就是这种
SMACK:Simple Mandatory Access Control Kernel,基于inode
Tomoyo:日本女人名“智代”,日本人实现的代码,基于path
Yama:来自梵文,中文名为“阎罗”,只处理ptrace和文件链接

2.2 selinux权限检查原理
Linux系统先做DAC(Discretionary Access Control,自主访问控制,Linux传统权限)检查。如果没有通过DAC权限检查,则操作直接失败。通过DAC检查之后,再做MAC(Mandatory Access Control,selinux)权限检查。

编译时强制打开selinux。
BOARD_KERNEL_CMDLINE += androidboot.selinux=enforcing

2.3 struct security_hook_heads
struct security_hook_list selinux_hooks[]
security_add_hooks()
security_delete_hooks()
找到selinux_hooks的地址,使用ARRAY_SIZE算出有多少个element,每个element都是一个链表,是同一个hook对象的结合,譬如当检查file_open时,那么这个链表的所有节点的回调函数都要运行一次。使用security_delete_hooks()可以反注册selinux_hooks。

2.4 查看设备节点的selinux权限
ls -alZ /dev/kmsg
getprop -Z persist.sys.usb.config
ps -AZ
restorecon -v /vendor/bin/xxx

2.5 打开关闭sepolicy
需要Android版本是usereng/eng

adb root
adb shell

关闭:
# setenforce 0
打开:
# setenforce 1

2.6 添加到启动脚本中禁止security
on nonencrypted
    # A/B update verifier that marks a successful boot.
    exec - root cache -- /system/bin/update_verifier nonencrypted
    class_start main
    class_start late_start

in late_start script, add [setenforce 0]

2.7 根据avc log生成sepolicy
1)提取所有的avc log
adb shell "cat /proc/kmsg | grep avc" > avc_log.txt

or

adb shell
dmesg | grep avc > /dev/avc_log.txt
adb pull /dev/avc_log.txt .

2)使用audit2allow直接生成policy
sudo apt-get install policycoreutils
audit2allow -i avc_log.txt -o output_pol.te
vi output_pol.te

3)
external/selinux/prebuilts/bin/audit2allow \
-i abc.txt > abc.te

2.8 Android 8.0 adb root sepolicy
CTS SELinuxNeverallowRulesTest.java
private - not visible to OEM
public - visible to OEM

CIL: SELinux Common Intermediate Language
/system/bin/secilc
-N: disable neverallow check before build

1) extract adbd.cil and su.cil from userdebug /system/etc/selinux/plat_sepolicy.cil
2) before pack system image, write adbd.cil and su.cil to user /system/etc/selinux/plat_sepolicy.cil
- function build-systemimage-target, pass 3 args to build/tools/releasetools/build_image.py
- add the following 5 commands to function build-systemimage-target
  # Use the following command to add su to typeattributeset coredomain and typeattributeset mlstrustedsubject.
  # @sed -i "s#abcdzcb(.∗abcdzcb(.∗ xxx#\1 su xxx#" 1.txt
  @sed -i -e '/neverallow \
  adbd/d' /path/to/plat_sepolicy.cil
  @cat /path/to/adbd.cil >> \
  /path/to/plat_sepolicy.cil
  @cat /path/to/su.cil >> \ 
  /path/to/plat_sepolicy.cil
3) Android init process will call /system/bin/secilc compile CIL files to binary, then write binary to kernel.

mmm system/sepolicy
out/target/product/<ppp>
/system/etc/selinux - AOSP
/vendor/etc/selinux - OEM

3 audit2allow python
#
# audit2allow, translate avc log to .te file
# Author: George Tso
#
# usage
# dmesg | grep "avc" > /dev/avc.log
# adb pull /dev/avc.log .
# audit2allow avc.log avc.te

import re
import string
import sys

def write_outfile(outfile, hashmap):
    for (hm_key, hm_value) in hashmap.items():
    #{
        allow_value = ''
        hm_value.sort()

        if (len(hm_value) == 1):
            allow_line = hm_key +
                ' ' + hm_value[0] + ';' + '\n'
        else:
            for value in hm_value:
                allow_value += ' ' + value
            allow_line = hm_key +
                ' {' + allow_value + ' };' + '\n'

        outfile.writelines(allow_line)
    #}

def has_proc(line, proc):
    e_list = line.split()
    for e in e_list:
    #{
        if (e.find('scontext') > -1):
            sub = e.split(':')
            if (proc == sub[2]):
                return True
            else:
                return False
    #}
    return False

def _generate_te(proc_list):
    src = ''
    tgt = ''
    tclass = ''
    got_tclass = False
    hashmap = {}
    got_key = False
    repeat = False

    outfile = open(sys.argv[2], 'w')
    for proc in proc_list:
    #{
        outfile.writelines('\n\n===============' +
            proc + '================\n')
        file = open(sys.argv[1], 'r')
        for line in file.readlines():
        #{
            line = line.strip()
            if not len(line) or line.startswith('#'):
                 continue

            if (has_proc(line, proc) == False):
                # not this process, continue
                continue

            # regular expression to extract {}
            perm = re.findall(r'[{](.*?)[}]', line)
            #print(perm[0].strip())

            e_list = line.split()
            for e in e_list:
            #{
                if (e.find('scontext') > -1):
                    sub = e.split(':')
                    src = sub[2]
                elif (e.find('tcontext') > -1):
                    sub = e.split(':')
                    tgt = sub[2]
                elif (e.find('tclass') > -1):
                    sub = e.split('=')
                    tclass = sub[1]
                    got_tclass = True

                if (got_tclass == True):
                    got_tclass = False

                    allow_key = 'allow' + ' ' + src +
                        ' ' + tgt + ':' + tclass.strip()
                    allow_value = perm[0].lstrip().rstrip()
                    hm_key = ''
                    hm_value = []

                    for (hm_key, hm_value) in \
                        hashmap.items():
                    #{
                        if (hm_key == allow_key):
                            got_key = True
                            break;
                    #}

                    if (got_key == True):
                        got_key = False

                        for value in hm_value:
                        #{
                            if (value == allow_value):
                                repeat = True
                                break;
                        #}
                        if (repeat == False):
                            hm_value.append(allow_value)
                            hashmap[allow_key] = \
                                hm_value
                        repeat = False
                    else:
                        hm_value = []
                        hm_value.append(allow_value)
                        hashmap[allow_key] = hm_value
            #} end of for e in e_list
        #} end of for line in file.readlines()

        write_outfile(outfile, hashmap)
        hashmap.clear()
        file.close()
    #} for proc in proc_list
    outfile.close()

def generate_te():
    # STEP 1 - FIND ALL THE PROCESSES
    proc_list = []
    repeat = False

    file = open(sys.argv[1], 'r')
    for line in file.readlines():
    #{
        line = line.strip()
        if not len(line) or line.startswith('#'):
             continue

        e_list = line.split()
        for e in e_list:
        #{
            if (e.find('scontext') > -1):
                sub = e.split(':')
                for proc in proc_list:
                #{
                    if (proc == sub[2]):
                        repeat = True;
                        break;
                #}
                if (repeat == False):
                    proc_list.append(sub[2])
                repeat = False
                break
        #}
    #}
    file.close()
    proc_list.sort()
    print proc_list

    # STEP 2 - GENERATE OUTPUT FILE
    _generate_te(proc_list)

if __name__ == '__main__':
    if (len(sys.argv) < 3):
        print(sys.argv[0] +
            ' ' + '<input_file.log>' +
            ' ' + '<output_file.te>')
        exit(0)
    generate_te()

4 Abbreviations
avb:Android Verified Boot,用dm-verify验证system分区的完整性,用在Android 8.0之后的fstab中
AVC:Access Vector Cache
cmnlib.mbn: qcom trustzone commonlib, qseecom_sample_client
DAC:Discretionary Access Control,自主访问控制
devcfg.mbn: qcom QUP访问权限控制,SPI片选和时钟线分别对应I2C的SDA和SCL
FRP:Factory Reset Protection
km41.mbn: qcom keymaster v4.1
LSM:Linux Security Module
seccomp: Android 8.1 secure computing
TE:Type Enforcement

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/838011.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

需要学习的东西

需要学习的东西 【&#xff08;关键词&#xff1a;spring - event&#xff09;&#xff08;副关键词&#xff1a;springCloud、代码解耦、主线程沟通子线程&#xff09;】 https://blog.csdn.net/SunBigBoy/article/details/130231585 【&#xff08;关键词&#xff1a;spring …

头歌实践教学平台——Java程序设计之数据结构

目录 Java 数据结构之栈、队列 实现基于数组的栈 实现基于链表的栈 基于数组的队列 基于链表的队列 Java数据结构-线性表的设计与实现 顺序表的实现之增删功能 顺序表的实现之查询功能 单链表的实现之增删功能 单链表的实现之查询功能 Java数据结构-循环链表的设计与…

深度学习设计模式之简单工厂模式

文章目录 前言一、简单工厂设计模式的作用&#xff1f;二、详细分析1.核心组成2.实现步骤3.示例代码4.优缺点优点缺点 5.使用场景 总结 前言 本文主要学习简单工厂设计模式&#xff0c;这个设计模式主要是将创建复杂对象的操作单独放到一个类中&#xff0c;这个类就是工厂类&a…

物联网D3——按键控制LED、光敏传感蜂鸣器

按键控制LED 按键抖动&#xff0c;电平发生变化&#xff0c;可用延时函数抵消按键抖动对系统的影响 传感器电路图 按键电路图 c语言对应类型 “_t”后缀表示使用typedef重命名的数据类型 枚举类型 #include<iostream> using namespace std; //定义枚举类型 typedef enu…

linux多网卡多网段配置ipv6路由

vi /etc/sysconfig/network-scripts/route6-enp4s0 2409:xxxx:xxxx:fd::/64 via 2409:xxxx:xxxx:fb::1 dev enp4s0 2409:xxxx:xxxx:80::/57 via 2409:xxxx:xxxx:fb::1 dev enp4s0 另一个网卡配置默认路由&#xff0c;该网卡IPV6_DEFAULTGW不配置&#xff0c;采用上面配置文件配…

基于springboot实现的在线动漫信息平台

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven…

vue2 结合iview和百度地图API实现电子围栏

vue2 结合iview和百度地图API实现电子围栏 实现在地图上绘制电子围栏并自定义电子围栏样式&#xff0c;还可以标记中心点 1.百度地图API相关JS引用 <script src"//api.map.baidu.com/api?typewebgl&v1.0&ak百度地图官网申请的ak"></script>//…

【JVM】调优工具

这里简单介绍一下各种调优用到的工具 一&#xff0c;环境准备 首先我们需要准备好Java环境&#xff0c;和win上的jdk环境&#xff08;图形化界面如jconsole只有jdk中有&#xff09;。 有这样一个类Prolem&#xff0c;每个线程都会带来100个垃圾对象&#xff0c;线程new完100…

翻译《The Old New Thing》- What does the CS_OWNDC class style do?

What does the CS_OWNDC class style do? - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20060601-06/?p31003 Raymond Chen 2006年06月01日 简要 本文讨论了CS_OWNDC窗口类样式的影响&#xff0c;它让窗口管理器为窗口创建一个永久的设…

品牌银饰售卖|基于SSM+vue的品牌银饰售卖平台的设计与实现(源码+数据库+文档)

品牌银饰售卖平台 目录 基于SSM&#xff0b;vue的品牌银饰售卖平台的设计与实现 一、前言 二、系统设计 三、系统功能设计 1前台功能模块 2后台功能模块 5.2.1管理员功能模块 5.2.2用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题…

Redission分布式锁 - 抢课系统

使用Redission分布式锁与Kafka消息队列&#xff0c;实现学生抢课系统&#xff08;高并发秒杀场景&#xff09;。 目录 一、思路1.为频繁访问的信息设置缓存&#xff08;1&#xff09;登陆&#xff08;2&#xff09;课程任务信息&#xff08;3&#xff09;用户抢课记录 2.消息队…

知识图谱开发日志

应用于应用环境的配置.测试.发布 假如你写了一个web,并且测试调试都没有问题 并且,你想发给你的朋友,导师,或者部署到远程云服务器上 那么,你需要配置相同的软件,比如数据库,web服务器,必要的插件,库,etc…但这并不一定能保证软件的正常运行,因为别人可能使用完全不同的操作系统…

在VMware安装Androidx86_64系统要点

上篇使用VirtualBox安装过Androidx86_64系统&#xff0c;尝试了没有蓝牙共享的好方法。本篇记录下使用Vmware虚机安装改系统&#xff0c;并使用蓝牙共享功能。 1.准备材料 本篇安装环境是安装Window10_64位系统。需要下载好Vmware安装包&#xff0c;VMWare版本&#xff1a;VMw…

winform中实现Oxyplot.WindowsForms.Plot的鼠标悬停坐标值展示

界面增加Oxyplot.WindowsForms.Plot&#xff0c;鼠标悬停显示坐标值。 PlotType PlotType.XY private void InitPlotModel() {this.plot.Model _PlotModel;this.plot.Enabled true;this.plot.MouseHover PlotView_MouseHover;this.plot.MouseHover PlotView_M…

HVV面试题2024护网蓝队面试题

一. 目前有防火墙&#xff0c;全流量检测&#xff0c;态势感知&#xff0c;IDS&#xff0c;waf&#xff0c;web服务器等设备&#xff0c;如何搭建一个安全的内网环境&#xff0c;请给出大概拓扑结构 &#xff08;适用于中高级&#xff09; 搭建安全内网环境拓扑结构&#xff1…

python:rename函数用法

在Pandas库中&#xff0c;rename函数是一个非常实用的方法&#xff0c;用于重命名DataFrame或Series的轴标签&#xff08;如列名或索引&#xff09;。以下是rename函数的基本用法、参数以及一些示例。 1.rename基本语法 DataFrame.rename(mapperNone, indexNone, columnsNone…

【以规划为导向的自动驾驶】Planning-oriented Autonomous Driving

ABSTRACT 研究背景&#xff1a; 现代自动驾驶系统是顺序化地排列多个任务模块, 近期的主流方法&#xff1a; ①为单个任务部署独立模型 ②设计具有分离式头部的多任务(multi-task)范式。 但是&#xff0c;这些方法会累积误差或任务间协同不足而不利于自动驾驶。 作者认为重…

【devops】Linux 日常磁盘清理 ubuntu 清理大文件 docker 镜像清理

日常磁盘清理 1、查找大文件 find / -type f -size 1G2、清理docker无用镜像&#xff08;drone产生的残余镜像文件&#xff09; docker system prune -a一、清理服务器磁盘 1、查找大文件 在Ubuntu系统中&#xff0c;你可以使用find命令来查找大文件。find命令是一个强大的…

从离线到实时:无锡锡商银行基于 Apache Doris 的数据仓库演进实践

作者&#xff1a;武基鹏&#xff0c;无锡锡商银行 大数据技术经理 编辑整理&#xff1a;SelectDB 技术团队 导读&#xff1a;为实现数据资产的价值转化以及全面数字化、智能化的风险管理&#xff0c;无锡锡商银行大数据平台经历从 Hive 离线数据仓库到 Apache Doris 实时数据仓…

软考 系统架构设计师系列知识点之杂项集萃(7)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;6&#xff09; 上一回在讲习题的时候引出来软件能力成熟度&#xff0c;由于内容较多&#xff0c;因此并未讲完&#xff0c;本回把剩余知识讲完。 软件能力成熟度模型 软件能力成熟度模型&#x…