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.xdnf.cn/news/1423715.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Linux交叉编译

一. 交叉编译 1.使用环境要求 新版本的orangepi-build是在Ubuntu22.04的x64电脑或虚拟机上运行的 lsb_release -a //查看自己的虚拟机版本 因为编译出的SDK大概有16G大小&#xff0c;因此&#xff0c;至少给虚拟机分配50G的大小。 2.获取Linux SDK 方法一&#xff1a;从…

展出面积超40万平方米“2024第26届深圳高交会”正式开启预定

随着全球科技的飞速发展&#xff0c;信息技术和数字经济已成为引领新一轮产业革命的关键力量。在这股浪潮中&#xff0c;中国正以其庞大的市场规模和强大的创新能力&#xff0c;逐步崛起为全球数字经济的领导者。2024年&#xff0c;第26届深圳高交会的召开&#xff0c;不仅是对…

数据结构--AVL树

一、什么是AVL树 1、AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查 找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&#xff0c;两位俄罗斯的数学家G.M.Adelson-Velskii 和E.M.Landis在…

Python以docker形式部署,flask简易服务器。

公司大部分都是springboot 服务器&#xff0c;有时候用到python写的一些模型&#xff0c;部署在linux上进行处理 首先项目这样&#xff1a; flask就不说了&#xff0c;快捷服务器&#xff0c; # -*- coding: utf-8 -*-from flask import Flask, request# 实例化Flask对象 app…

山西省特岗教师报名流程及报名照片处理方法

山西省2024年特岗教师招聘公告已发布&#xff0c;计划招聘特岗教师1800名&#xff0c;这对于有志于教育事业的高校毕业生来说&#xff0c;无疑是一个极好的机会。本文将详细介绍报名流程&#xff0c;并提供报名照片处理的方法&#xff0c;帮助应聘者顺利通过报名环节。 一、报名…

SpringBoot:缓存

点击查看SpringBoot缓存demo&#xff1a;LearnSpringBoot09Cache-Redis 技术摘要 注解版的 mybatisCacheConfigCacheableCachePut&#xff1a;既调用方法&#xff0c;又更新缓存数据&#xff1b;同步更新缓存CacheEvict&#xff1a;缓存清除Caching&#xff1a;定义复杂的缓存…

【C语言每日题解】三题:回文检查、刘备 关羽 张飞三人过年放鞭炮、约瑟夫环问题(犹太人死亡游戏)(难度up,推荐)

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f308;感谢大家的阅读、点赞、收藏和关注 &#x1f970;希望大家喜欢我本次的讲解 &#x1f31f;非常推荐最后一道题 &#x1f339; 犹太人死亡游戏&#xff0c;建议观看 &…

第十六篇:数据库性能优化:从基础到高级的全面指南

数据库性能优化&#xff1a;从基础到高级的全面指南 1. 引言 在数字化的浪潮中&#xff0c;数据库作为信息系统的核心组件&#xff0c;其性能的优劣直接关系到企业的运营效率和市场竞争力。数据库性能优化不仅是一项技术挑战&#xff0c;更是一项战略任务。它要求我们深入理解…

BI报表大用处 揭秘BI报表在行业中的变革力量

BI报表&#xff0c;即商业智能报表&#xff0c;是一种利用商业智能技术将企业中的数据转换为有意义的信息和可视化展示的报告。它通过将企业内部的大量数据转化为直观、易于理解的图表和指标&#xff0c;帮助决策者快速捕捉关键业务信息&#xff0c;识别趋势和模式&#xff0c;…

物联网应用开发--STM32与新大陆云平台通信(云平台控制蜂鸣器、LED)

实现目标 1、掌握云平台执行器的创建 2、熟悉STM32 与ESP8266模块之间的通信 3、具体实现目标&#xff1a;&#xff08;1&#xff09;创建5个执行器&#xff1a;蜂鸣器&#xff0c;LED1&#xff0c;LED2&#xff0c;ED3&#xff0c;LED4;&#xff08;2&#xff09;执行器能对…

python继承和call魔术方法

文章目录 前言一、类的继承1 继承示例1:继承父类的所有属性和方法示例2:继承的传递性示例3:单继承与多继承2 继承中属性和方法的重写2.1 直接覆盖父类原来方法2.2 在父类的方法后增加新的内容(继承中重写__init__方法经常用到)示例1:简单的例子示例2:复杂点的例子二、ca…

数据密码机独特的安全性能

数据密码机&#xff0c;作为一种专用的信息安全设备&#xff0c;在现代社会的各个领域中都发挥着至关重要的作用。它以其独特的加密技术和安全性能&#xff0c;为数据的传输和存储提供了坚实的保护屏障。 首先&#xff0c;数据密码机的工作原理是基于复杂的加密算法。这些算法能…

FullCalendar日历组件集成实战(4)

背景 有一些应用系统或应用功能&#xff0c;如日程管理、任务管理需要使用到日历组件。虽然Element Plus也提供了日历组件&#xff0c;但功能比较简单&#xff0c;用来做数据展现勉强可用。但如果需要进行复杂的数据展示&#xff0c;以及互动操作如通过点击添加事件&#xff0…

在Android设备丢失数据后恢复数据的4个方法

了解 Android 媒体存储 媒体存储是下载、查看、播放和流式传输视频文件、音频文件、图像和其他媒体文件时所需的过程。此服务无法从手机桌面访问&#xff0c;因此您需要按照以下步骤通过安卓手机访问此系统服务。 步骤1&#xff1a;导航到手机设置&#xff0c;然后转到应用程…

128.Mit6.S081-实验1-Xv6 and Unix utilities(下)

今天我们继续实验一接下来的内容。 一、pingpong(难度easy) 1.需求 编写一个程序&#xff0c;使用 UNIX 系统调用通过一对管道(每个方向一个管道)在两个进程之间 "ping-pong" 传递一个字节。父进程应该向子进程发送一个字节; 子进程应该打印<pid>: received p…

LeetCode1004最大连续1的个数3

问题描述 给定一个二进制数组 nums 和一个整数 k&#xff0c;如果可以翻转最多 k 个 0 &#xff0c;则返回 数组中连续 1 的最大个数 。 解析 很明显的滑动窗口问题&#xff0c;移动右指针的同时确保窗口内只有k个0即可&#xff0c;当0的个数超过之后就移动左指针。 public in…

CKA-Ubuntu18.04安装Kubernetes集群

文档整理参考:虫之教育唐老师 文章目录 K8S是什么修改静态ip环境准备修改更新源安装Docker安装K8S-master1.安装kubeadm, kubelet, kubectl2.初始化3.创建kubeadm-config.yaml4.查看是否安装成功运行集群环境报错排查问题安装网络安装K8S-node1,2步参考master3.查看是否安装成…

Spring WebFlux 初探-响应式编程-021

&#x1f917; ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱&#xff0c;有温度&#xff0c;有质量&#xff0c;有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace The Nex…

酷开科技依托酷开系统“硬件+内容”产业布局,抢占全球机遇!

2024年3月26日&#xff0c;创维集团发布了2023年年度业绩报告&#xff0c;去年全年实现了总营业额690.31亿元较上一年的534.91亿元整体营业额增长了29.1%。然而&#xff0c;值得注意的是&#xff0c;2023年度&#xff0c;创维集团智能家电业务的营收306.37亿元&#xff0c;较上…

Python-VBA函数之旅-vars函数

目录 一、vars函数的常见应用场景 二、vars函数使用注意事项 三、如何用好vars函数&#xff1f; 1、vars函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a;https://myelsa1024.blog.csdn.net/ 一、vars函数…