精华内容
下载资源
问答
  • Safety mechanisms for random ECU hardware failures in compliance with ISO 26262 Volvo 发动机辅助制动相关从概念阶段到ST以及错误注入的案例。
  • 安全机制

    千次阅读 2016-07-20 00:10:41
    安全机制包括两个不同的部分,第一是网页的安全,包括但是不限于网页数据安全传输、跨域访问、用户数据安全等,第二部分是游览器的安全,具体是指网页或者JavaScript代码有一些安全问题或者存在安全漏洞,游览器也...

    安全机制包括两个不同的部分,第一是网页的安全,包括但是不限于网页数据安全传输、跨域访问、用户数据安全等,第二部分是游览器的安全,具体是指网页或者JavaScript代码有一些安全问题或者存在安全漏洞,游览器也能够在运行它们的时候保证自身的安全,不受攻击从而泄漏数据或者使系统破坏

    网页安全模型

    安全模型基础

    当用户访问网页的时候,游览器需要确保该网页中数据的安全性,如Cookie、用户名和密码等信息不会被其他的恶意网页所获取。

    它表示的是网页所在的域名、传输协议和端口等信息,域是表明网页身份的重要标识,如网页“http://blog.csdn.net/steward2011”,它的域是”http://blog.csdn.net“,其中”http:”是协议,”blog.csdn.net”是域名,而端口默认为80,用户可以打开chrome游览器的开发者工具和控制台,输入”window.location”查看域的各种信息。根据安全模型的定义,不同域中网页间的资源访问是收到严格限制的,也就是网页的DOM对象、个人数据、XMLHttpRequest等需要收到控制,默认情况下,不同网页间的这些数据是被游览器隔离的,不能互相访问,这是HTML的“Same origin Policy”策略。

    XSS

    XSS全称Cross Site Scripting,其含义是执行跨域的JavaScript脚本代码,执行脚本本身没什么问题,但由于执行其他域的脚本代码可能存在严重的危害,还有可能会盗取当前域中的各种数据,因此HTML5规范之前,跨域的资源共享是不被允许的,这样做会造成功能上的缺陷,为此标准组织和WebKit使用了大量的技术来避免各种攻击的发生,例如在HTTP消息头中定义了一个名为“X-XSS_Protection”的字段,此时游览器会打开防止XSS攻击的过滤器,目前主要的游览器都支持该技术。

    CSP

    Content Security Policy是一种防止XSS攻击的技术,它使用HTTP消息头来指定网站能够标注哪些域中的哪些类型的资源被允许加载在该域的网页中,包括JavaScript、CSS、HTML Frames、字体、图片和嵌入对象(如插件、Java Applet等),在HTTP消息头中,可以使用相应的字段来控制这些域和资源的访问,其主要是服务器返回的HTTP消息头,目前不同游览器中使用不同的字段名来表示,主要包含三种名称:Content-Security-Policy(由标准组织定义)、X-WebKit-CSP(实验性的字段名)和X-Content-Security-Policy(Firefox使用),该字段的定义格式如下(字段名:指令名 指令值;指令名 指令值;….. )。下表是包含一个字段名及一系列的“指令名+指令值”对的列表,其包括11种类型的指令来控制网页中的各种资源和安全行为:

    指令名含义
    default-src控制所有的资源,如果已经包含该指定资源的指令,那么default-src优先级较低,如果没有包含该知道的指令,那么使用default-src指令定义的内容
    script-src用于控制JavaScript代码
    stype-src用于控制CSS样式表
    img-src用于控制图片资源
    connect-src用于控制XMLHttpRequest、WebSocket等同连接相关
    font-src用于控制字体资源
    object-src用于控制“embed”、“object”、“applet”等元素加载的资源
    media-src用于控制多媒体资源,包括音频和视频
    frame-src用于控制可以加载的框
    sandbox用于控制网页中是否允许弹出对话框,插件和脚本的执行等,值可能是”allow-forms”、”allow-same-origin”、”allow-script”、”allow-to-navigation”
    report-uri将错误消息发送到指定的URI
    CORS

    根据“Same Origin Policy”原则,游览器做了很多的限制以组织跨域的访问,所以跨域的资源共享又变成了一个问题,标准组织为了适应现实的需要,zhi’ding 额CORS(Cross Origin Resource Sharing)规范,也就是跨域资源共享,该规范借助域HTTP消息头并通过定义一些字段来实现,主要是定义不同域之间交互数据的方式,当某个网页希望访问其他域资源的时候,需要按照CORS定义的标准从一个域访问另外一个域的数据。CORS使用HTTP头来描述规范定义的内容,HTTP消息头是指包含有限个字段(如Accept、Accept-language等)并请求类型只是HEAD、GET和POST。通常简单的HTTP消息头只需要较小的代价,而包含了CORS的消息头却不是简单的HTTP消息头,该消息请求在CORS里面被称为“Preflight”消息请求,CORS使用到的字段如下表:

    字段名类型含义
    Origin请求端请求端申明该请求来源于哪个域
    Access-Control-Request-Method请求端请求端的HTTP请求类型,如PUT、GET、HEAD等
    Access-Control-Request-Headers请求端一个以“,”为分隔符的列表,表项是自定义请求的字段
    Access-Control-Allow-Origin响应端表明响应端允许的域,可以指定特定的域,也可以使用“*”表示允许所有的域请求
    Access-Control-Allow-Credentials响应端默认情况Cookie之类的信息是不能共享的,但如果设置该字段为真,那么Cookit是可以传输给请求端的
    Access-Control-Expose-Headers响应端是否暴露回复消息给XHR,以便XHR能够读取响应消息的内容
    Access-Control-Max-Age响应端Prelight请求的有效时间
    Access-Control-Allow-Methods响应端响应端 允许的HTTP请求类型,如前面的PUT、GET、HEAD等
    Access-Control-Allow-Headers响应端响应端支持的自定义字段

    其类型可以分成请求段和相应端,如果每个HTTP消息头都要包含这些字段那是一种浪费,因为没有必要每个HTTP消息头都重复包含这些类型,为了就会使用到“Preflight”请求来发送包含CORS字段的消息,而其他则是简单的HTTP消息头,表中Access-Control-Max-Age表示Prefight请求的有效期,在有效期内不需要重复发送CORS定义字段的消息,CORS和CSP的区别在于CSP定义的是网页自身能够访问的某些域和资源,而CORS定义的是一个网页如何才能访问被同源策略禁止的跨域资源,规定了两者交互的协议和方式。

    Cross Document Messaging

    Cross Document Messaging定义的是通过window.postMessage接口让JavaScript在不同域的文档中传递消息成为可能,以下代码演示了如何使用该技术来传递消息:

    http://csdn.com中JavaScript代码
    contentWin.postMessage('Hello','http://blog.csdn.net');
    
    http://blog.csdn.net/steward网页中的JavaScript代码
    window.addEventListener('message',function receiver(e)) {
      if (e.origin == 'http://myweb.com') {
        if (e.data == 'Hello') {
          e.source.postMessage('Hello2', e.origin);
        } else {
          alert(e.data);
        }
      }
    }, false);

    该机制使用“window”对象的postMessage方法来传递给其他域网页消息,该方法包含两个参数,第一个是消息内容,第二个是需要对方的域消息,而在接收方,开发者在JavaScript代码中注册一个消息响应函数,如果检测出消息来源于上述“http://csdn.com”,那么就回复一个“Hello2”的消息。

    安全传输协议

    对于用户而言,网页的安全还包含一个重要点,就是用户和服务器之间交互数据的安全性问题,对于一般的网页而言,这些数据的传输都是使用明文方式,也就是说它们对谁都是可见的,这能够满足大多数的使用情况,但是对于隐私的数据,如密码、银行帐号等,如果使用明文来传输就存在风险,为此Web引入了安全的数据传输协议HTTPS,HTTPS是在HTTP协议之上使用SSL(Secure Socket Layer)技术来对传输的数据进行加密,从而保证了数据的安全性,SSL协议是构建在TCP协议之上、应用层协议HTTP之下的,SSL工作的主要流程是先进行服务器认证,然后是用户认证,SSL协议主要是服务提供商对用户信息保密的承诺,这有利于提供商而不利于消费者,同时SSL还存在一些问题,例如只能提供交易中客户域服务器间的双方认证,在涉及多方的电子交易中,SSL协议并不能协调各方的安全传输和信任关系。TLS(Transport Layer Security)是在SSL3.0基础上发展起来的,它使用了新的加密算法,因此同HTTPS之间不兼容,TLS用于两个通信应用程序之间,提供保密性和数据完整性,该协议是由两层子协议组成的,包括TLS记录协议(TLS Record)和TLS握手协议(TLS Handshake),较低的层为TLS记录协议,位于TCP协议之上,TLS握手协议具有三个属性,其一是可以使用非对称的密码术来认证对等方的身份,其二是共享加密密钥的协商是安全的,对偷窃者来说协商加密是难以获得的,此外经过认证的连接不能获取加密,即使是进入连接中间的攻击者也不能,其三是协商是可靠的,如果没有经过通信方成员的检测,任何攻击者都不能修改通信协商。TLS独立于高层协议,如HTTP协议,高层协议如HTTP协议可以透明的分布在TLS协议上面,然而,TLS标准并没有规定应用程序如何在TLS上增加安全性,它把如何启动TLS握手协议及如何解释交换的认证证书的决定权留给协议的设计者和实施者来判断。

    WebKit的实现

    首先看WebKit为了防止XSS攻击所做的工作,下图是WebKit中启动XSS过滤功能所使用的相关基础设施,为了防止XSS攻击,需要在解释HTML的过程中进行XSS过滤,也就是对词法分析器分析之后的词语(Token)进行过滤,以发现潜在的问题:
    这里写图片描述
    基本工作是这样,在HTMLDocumentParser类揭示出一个词语之后,如果需要进行XSS过滤功能,则每一个词语使用HTMLDocumentParser类的XSSAuditor对象来进行过滤,也就是图中的XSSAudior::filterToken函数,对于每一个词语,该函数进行过滤并生成相应的结果XSSInfo对象,该对象包含是否需要阻止整个页面渲染等信息,XSSAuditor不做决定,而是由HTMLDocumentParser将这些信息交给XSSAuditorDelegate类来处理,在根据这些信息来生成报告,XSSAuditorDelegate将结果报告发送给“report-uri”,XSS有很多种攻击的类型,这里主要包括对于元素开始和结束及其属性的检查,同时对于一些特定类型的词语进行过滤,包括input、form、button、iframe、script等,当发现潜在危险的时候再生成相应的结果信息此处为XSSInfo对象。其次是CSP方面的支持,下图是WebKit支持CSP所定义的相关基础设施,同时包括Origin的定义,其中对于CSP支持的主要部分是ContentSecurityPolicy和SecurityContext这两个类:
    这里写图片描述

    • ContentSecurityPolicy:主要包括对于规范中定义的各个字段的解释和解释后内容的保存,如图中的didReceiveHeader函数就是处理服务器端的HTTP消息头,该类将指令和指令的内容保存在”m_policies”中,形成一个列表
    • SecurityContext:支持安全机制的上下文类,包含Origin对象和ContentSecurityPolicy对象,其他对CSP等的调用都是通过该类来获取的

    图中最下部分为两个类WebSecurityOrigin和WebSecurityPolicy,这是WebKit的Chromium移植定义的两个接口,可以被Chromium调用,它们都有内部的实现,具体分别是SecurityOrigin和SecurityPolicy,SecurityOrigin就是规范中对于Origin的定义,而SecurityPolicy就是对CSP策略的定义,通过WebSecurityPolicy接口,Chromium可以自定义一些策略并设置到WebKit中。Document类间接继承了SecurityContext,由此Document也继承了CSP的设置,因为Document会在各处都使用,这样方便调用CSP的功能,DOMSecurityPolicy为了将CSP的信息暴露到JavaScript中,这样JavaScript代码可以获取CSP定义的内容,如“script-src”指令所定义的允许访问的域,ResourceFetcher是获取资源的类,根据CSP的定义,对于各种类型的资源,在获取之间都需要检查该资源是否在CSP定义的允许范围内,如果不在,则拒绝请求,并报告错误,如果在,则发起请求,该请求需要依赖SecurityPolicy提供的一些信息。最后是CORS的支持,下图是WebKit支持CORS所涉及的一些类,其中最主要的是CrossOriginAccesControl部分,它不是一个类,里面只是包含了一组全局函数,用来帮助生成符合CORS规范的“Preflight”请求或者其他简单请求,同时包括处理来自回复端的消息,在WebKit使用WebURLLoader请求的时候,使用这些方法能够生成相应的请求:
    这里写图片描述

    沙箱模型

    原理

    一般而言,对于网络上的网页中的JavaScript代码和插件是不受信的,特别是一些故意设计侵入游览器运行的主机代码更是危险,通过一些手段或者游览器中的漏洞,这些代码可能获取了主机的管理权限,这对主机系统来说十分危险,所以除了保证网页本身之外,还需要保证游览器和游览器所在的系统不存在危险。对于网络上的网页,游览器认为它们是不安全的,因为网页总是存在各种可能性,也许是无意或有意的攻击,如果有一种机制,将网页的运行限制在一个特定的环境中,也就是一个沙箱中,使它只能访问有限的功能,那么即使网页工作的渲染引擎被攻击,它也不能够获取渲染引擎工作的主机系统中的任何权限,这就是沙箱模型的思想。Chromium是以多进程为基础的,网页的渲染在一个独立的Renderer进程中,这位实现沙箱模型提供了基础,因为可以相对容易的使用一些技术将整个网页的渲染过程放在一个受限的进程中来完成,如下图所示,受限的环境只能被某些或者很少的系统调用而且不能直接访问用户数据,沙箱模型工作的基本单位就是进程。
    这里写图片描述
    Chromium的沙箱模型是利用系统提供的安全技术,让网页在执行过程中不会修改操作系统或者是访问系统中的隐私数据,而需要访问系统资源或者说是系统调用的时候,通过一个代理机制来完成。

    实现机制

    由于沙箱模型依赖操作系统提供的技术,而不同操作系统提供的安全技术是不一样的,这意味着不同操作系统上的实现是不一致的,需要分别针对不同平台来讨论,但是不管是Linux还是Windows,或者是其他平台,Chromium都是在进程的力度下来实现沙箱模型,也就是说需要运行在沙箱下的操作都是一个单独的进程:
    这里写图片描述
    图中右侧是目标进程,也就是需要在沙箱中运行的代码,左侧是代理进程,它需要负责创建目标进程并为目标进程设置各种安全策略,同时建立IPC连接,接受目标进程的各种请求,因为目标进程是不能访问过多资源的。

    Linux

    在Linux上,沙箱模型分成两个层,第一层是阻止某个或者某些进程通常能够访问的资源,chromium中称为“语义层,这里使用的系统技术主要是“setuid“,第二层是防止进程访问能够攻击内核的接口或者供给面,这里使用的系统技术主要是”Seccomp”,在沙箱机制启动之后,如果运行Chromium程序,会产生下面的进程层次结构,它是一棵树,树的根节点是“browser“进程,该进程启动后,会孵化多个子进程,包括”GPU“、”chrome_sandbox“等进程,而对于沙箱模型来说,这里关注”chrome_sandbox“进程,它的目的主要是使用”setuid“技术来实现模型的第一层,生成了”zygote“子进程,其中”chrome_sandbox“进程使用的是上面介绍的目标”chrome_sanbox”生成的二进制可执行文件,而其它的是目标”chrome“生成的结果,二者是不一样的。
    这里写图片描述
    生成第一个”zygote“之后,该进程会生成两个子进程,第一个是”nacl-helper“进程,是为了支持NaCl插件进程服务的,第二个又是一个”zygote“,这个不同于它的父亲,主要是为了生成各种”Renderer“进程服务,这样每个”Renderer“进程经过上面的过程后都会使用沙箱机制进行处理,网页在”Renderer“中的运行就收到了限制,Renderer进程域代理进程通过进程间通信机制来交互,所有的请求都是发送给代理进程,代理进程将结果返回给Renderer进程,这里的代理进程就是Browser进程,Browser进程拥有访问这些资源和系统调用的权限。其中第一层主要使用两种技术:

    • 使用setuid来为新进程设置新用户ID和组ID,根据Linux的规定,两个不同用户ID之间的数据是隔离开的,这将Renderer进程同Browser进程分开,后者拥有访问很多关键数据的能力,如各个网页的Cookie,在现在的Chromium实现中,不再使用setuid来实现,而是使用CLONE_NEWPID标记,该标记是在Linux系统调用clone时设置,从而为新进程创建一个新的名空间,也就是上面描述的文件系统等
    • 显示网络访问,Chromium使用标记”CLONE_NEWNET“设置在调用”clone“系统调用的参数中,使用这这些技术之后克隆出来的进程就同父进程分离开来,包括新文件系统等和限制网络的访问等

    第二层使用的主要技术是Seccomp和Seccomp-BPF,seccomp是Linux内核提供的一种简单的沙箱机制,它能够允许进程进入一种不可逆的安全状态,进入该状态的进程只能够调用4个系统调用,包括exit、sigreturn、read和write,而且最后两个系统调用只能操作已经打开的文件描述符,如果该进程尝试调用其他的系统调用,那么内核会通过SIGKILL信号来杀死该进程,进入该按去哪状态的方法就是使用系统调用prctl社会自标记位PR_SET_SECCOMP就可以了,前提是系统的内核在编译的时候就加入了对Seccomp的支持,因为不是所有使用Linux内核的操作系统都能打开该机制,Seccomp-BPF是Seccomp及时的一个扩展,它允许使用BPF所定义的方法来将系统调用转变成BPF格式的小程序,BPF(Berkeley Packet Filter)原是Berkeley开发的一种用来过滤网络包的技术,现在被应用在Seccomp,Seccomp-BPF将系统调用转变成BPF格式的小程序,这些小程序能够被内核所解释,这样每个系统调用的次数和参数都能够被重新评估或者被限制。对于开发者来说,如果想要关闭第二层的沙箱技术只需在命令行韩总加入参数”–disable-seccomp-filter-sandbox“就可以了,对于Android系统来讲,虽然Android是基于Linux内核开发出来的,但还是有些区别,目前沙箱机制的第二层在Android上并没有得到支持,只是第一层得到了支持,但是在Android上,系统支持的安全机制都已经在Chrome的Android版本上得到了启动,主要体现在两个方面,第一是SUID,Android系统上稍微不同,它是UID isolation(UID隔离技术),Android可以为每一个进程设置一个新的UID,这些每个进程之间就不能随意修改和访问数据,这是由Linux内核机制来保证的。

    展开全文
  • Android的安全机制

    千次阅读 2018-04-29 08:45:12
       Android是一个基于Linux内核的移动操作系统。Linux是一个支持多用户的系统,系统中的...Android在Linux内核提供的基于UID和GID的安全机制的基础上,又实现了一套称为Permission的安全机制,如图1所示:   ...

     

     

            Android是一个基于Linux内核的移动操作系统。Linux是一个支持多用户的系统,系统中的文件的访问权限是通过用户ID(UID)和用户组ID(GID)来控制的。换句话说,就是Linux的安全机制是基于UID和GID来实现的。Android在Linux内核提供的基于UID和GID的安全机制的基础上,又实现了一套称为Permission的安全机制,如图1所示:

     

     

    图1 Linux的UID/GID安全机制与Android的Permission安全机制

            那么,这两个安全机制是如何对应起来的呢?

            我们首先看一下Linux基于UID和GID的安全机制,它包含三个基本角色:用户、进程和文件,如图2所示:

    图2 Linux基于UID/GID的安全机制的三个角色

            Linux中的每一个用户都分配有一个UID,然后所有的用户又按组来进划分,每一个用户组都分配有一个GID。注意,一个用户可以属于多个用户组,也就是说,一个UID可以对应多个GID。在一个用户所对应的用户组中,其中有一个称为主用户组,其它的称为补充用户组。

            Linux中的每一个文件都具有三种权限:Read、Write和Execute。这三种权限又按照用户属性划分为三组:Owner、Group和Other。如图3所示:

    图3 Linux的文件权限划分

            从图3就可以看出文件acct:1. 所有者为root,可读可写可执行;2. 所有者所属的主用户组为root,在这个组中的其它用户可读可执行;3. 其余的用户可读可执行。

            Linux中的每一个进程都关联有一个用户,也就是对应有一个UID,如图4所示:

    图4 Linux的进程

             由于每一个用户都对应有一个主用户组,以及若干个补充用户组,因此,每一个进程除了有一个对应的UID之外,还对应有一个主GID,以及若干个Supplementary GIDs。这些UID和GID就决定了一个进程所能访问的文件或者所能调用的系统API。例如,在图4中,PID为340的进程一般来说,就只能访问所有者为u0_a19的文件。

             一个进程的UID是怎么来的呢?在默认情况下,就等于创建它的进程的UID,也就是它的父进程的UID。Linux的第一个进程是init进程,它是由内核在启动完成后创建的,它的UID是root。然后系统中的所有其它进程都是直接由init进程或者间接由init进程的子进程来创建。所以默认情况下,系统的所有进程的UID都应该是root。但是实际情况并非如此,因为父进程在创建子进程之后,也就是在fork之后,可以调用setuid来改变它的UID。例如,在PC中,init进程启动之后,会先让用户登录。用户登录成功后,就对应有一个shell进程。该shell进程的UID就会被setuid修改为所登录的用户。之后系统中创建的其余进程的UID为所登录的用户。

            进程的UID除了来自于父进程之外,还有另外一种途径。上面我们说到,Linux的文件有三种权限,分别是Read、Wirte和Execute。其实还有另外一个种权限,叫做SUID。例如,我们对Android手机进行root的过程中,会在里面放置一个su文件。这个su文件就具有SUID权限,如图5所示:

    图5 su的SUID和SGID

            一个可执行文件一旦被设置了SUID位,那么当它被一个进程通过exec加载之后,该进程的UID就会变成该可执行文件的所有者的UID。也就是说,当上述的su被执行的时候,它所运行在的进程的UID是root,于是它就具有最高级别的权限,想干什么就干什么。

            与SUI类似,文件还有另外一个称为SGID的权限,不过它描述的是用户组。也就是说,一个可执行文件一旦被设置了GUID位,么当它被一个进程通过exec加载之后,该进程的主UID就会变成该可执行文件的所有者的主UID。

            现在,小伙伴们应该可以理解Android手机的root原理了吧:一个普通的进程通过执行su,从而获得一个具有root权限的进程。有了这个具有root权限的进程之后,就可以想干什么就干什么了。su所做的事情其实很简单,它再fork另外一个子进程来做真正的事情,也就是我们在执行su的时候,后面所跟的那些参数。由于su所运行在的进程的UID是root,因此由它fork出来的子进程的UID也是root。于是,子进程也可以想干什么就干什么了。

            不过呢,用来root手机的su还会配合另外一个称为superuser的app来使用。su在fork子进程来做真正的事情之前,会将superuser启动起来,询问用户是否允许fork一个UID是root的子进程。这样就可以对root权限进行控制,避免被恶意应用偷偷地使用。

            这里是su的源代码,小伙伴们可以根据上面所讲的知识读一读:https://code.google.com/p/superuser/source/browse/trunk/su/su.c?r=2

            在传统的UNIX以及类UNIX系统中,进程的权限只划分两种:特权和非特权。UID等于0的进程就是特权进程,它们可以通过一切的权限检查。UID不等于0的进程就非特权进程,它们在访问一些敏感资源或者调用一个敏感API时,需要进行权限检查。这种纯粹通过UID来做权限检查的安全机制来粗放了。于是,Linux从2.2开始,从进程的权限进行了细分,称为Capabilities。一个进程所具有Capabilities可以通过capset和prctl等系统API来设置。也就是说,当一个进程调用一个敏感的系统API时,Linux内核除了考虑它的UID之外,还会考虑它是否具有对应的Capability。

            这里就是Linux所设计的Capabilities列表,有兴趣的小伙伴可以再读一读:http://man7.org/linux/man-pages/man7/capabilities.7.html

            以上就是Linux基于UID/GID的安全机制的核心内容。接下来我们再看Android基于Permission的安全机制,它也有三个角色:apk、signature和permission,如图6所示:

    图6 Android的Permission安全机制

            

            Android的APK经过PackageManagerService安装之后,就相当于Linux里面的User,它们都会被分配到一个UID和一个主GID,而APK所申请的Permission就相当于是Linux里面的Supplementary GID。

            我们知道,Android的APK都是运行在独立的应用程序进程里面的,并且这些应用程序进程都是Zygote进程fork出来的。Zygote进程又是由init进程fork出来的,并且它被init进程fork出来后,没有被setuid降权,也就是它的uid仍然是root。按照我们前面所说的,应用程序进程被Zygote进程fork出来的时候,它的UID也应当是root。但是,它们的UID会被setuid修改为所加载的APK被分配的UID。

           参照Android应用程序进程启动过程的源代码分析一文的分析,ActivityManagerService在请求Zygote创建应用程序进程的时候,会将这个应用程序所加载的APK所分配得到的UID和GID(包括主GID和Supplementary GID)都收集起来,并且将它们作为参数传递给Zygote进程。Zygote进程通过执行函数来fork应用程序进程:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片

    1. /* 
    2.  * Utility routine to fork zygote and specialize the child process. 
    3.  */  
    4. static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)  
    5. {     
    6.     pid_t pid;  
    7.       
    8.     uid_t uid = (uid_t) args[0];  
    9.     gid_t gid = (gid_t) args[1];  
    10.     ArrayObject* gids = (ArrayObject *)args[2];  
    11.     ......  
    12.       
    13.     pid = fork();  
    14.       
    15.     if (pid == 0) {  
    16.         ......  
    17.           
    18.         err = setgroupsIntarray(gids);  
    19.         ......  
    20.           
    21.         err = setgid(gid);  
    22.         ......  
    23.           
    24.         err = setuid(uid);  
    25.         ......  
    26.     }     
    27.       
    28.     .....  
    29.       
    30.     return pid;  
    31. }     

            参数args[0]、args[1]和args[]保存的就是APK分配到的UID、主GID和Supplementary GID,它们分别通过setuid、setgid和setgroupsIntarray设置给当前fork出来的应用程序进程,于是应用程序进程就不再具有root权限了。

            那么,Signature又充当什么作用呢?两个作用:1. 控制哪些APK可以共享同一个UID;2. 控制哪些APK可以申请哪些Permission。

            我们知道,如果要让两个APK共享同一个UID,那么就需要在AndroidManifest中配置android:sharedUserId属性。PackageManagerService在安装APK的时候,如果发现两个APK具有相同的android:sharedUserId属性,那么它们就会被分配到相同的UID。当然这有一个前提,就是这两个APK必须具有相同的Signature。这很重要,否则的话,如果我知道别人的APK设置了android:sharedUserId属性,那么我也在自己的APK中设置相同的android:sharedUserId属性,就可以去访问别人APK的数据了。

            除了可以通过android:sharedUserId属性申请让两个APK共享同一个UID之外,我们还可以将android:sharedUserId属性的值设置为“android.uid.system”,从而让一个APK的UID设置为1000。UID是1000的用户是system,系统的关键服务都是运行在的进程的UID就是它。它的权限虽然不等同于root,不过也足够大了。我们可以通过Master Key漏洞来看一下有多大。

            Master Key漏洞发布时,曾轰动了整个Android界,它的具体情况老罗就不分析了,网上很多,这里是一篇官方的文章:http://bluebox.com/corporate-blog/bluebox-uncovers-android-master-key/。现在就简单说说它是怎么利用的:

            1. 找到一个具有系统签名的APP,并且这个APP通过android:sharedUserId属性申请了android.uid.system这个UID。

            2. 通过Master Key向这个APP注入恶意代码。

            3. 注入到这个APP的恶意代码在运行时就获得了system用户身份。

            4. 修改/data/local.prop文件,将属性ro.kernel.qemu的值设置为1。

            5. 重启手机,由于ro.kernel.qemu的值等于1,这时候手机里面的adb进程不会被setuid剥夺掉root权限。

            6. 通过具有root权限的adb进程就可以向系统注入我们熟悉的su和superuser.apk,于是整个root过程完成。

            注意,第1步之所以要找一个具有系统签名的APP,是因为通过android:sharedUserId属性申请android.uid.system这个UID需要有系统签名,也就是说不是谁可以申请system这个UID的。另外,/data/local.prop文件的Owner是system,因此,只有获得了system这个UID的进程,才可以对它进行修改。

            再说说Signature与Permission的关系。有些Permission,例如INSTALL_PACKAGE,不是谁都可以申请的,必须要具有系统签名才可以,这样就可以控制Suppementary GID的分配,从而控制应用程序进程的权限。具有哪些Permission是具有系统签名才可以申请的,可以参考官方文档:http://developer.android.com/reference/android/Manifest.html,就是哪些标记为“Not for use by third-party applications”的Permission。

            了解了Android的Permission机制之后,我们就可以知道:

             1. Android的APK就相当于是Linux的UID。

             2. Android的Permission就相当于是Linux的GID。

             3. Android的Signature就是用来控制APK的UID和GID分配的。

             这就是Android基于Permission的安全机制与Linux基于UID/GID的安全机制的关系,概括来说,我们常说的应用程序沙箱就是这样的:

    图7 Android的Application Sandbox

            Android是一个基于Linux内核的移动操作系统。Linux是一个支持多用户的系统,系统中的文件的访问权限是通过用户ID(UID)和用户组ID(GID)来控制的。换句话说,就是Linux的安全机制是基于UID和GID来实现的。Android在Linux内核提供的基于UID和GID的安全机制的基础上,又实现了一套称为Permission的安全机制,如图1所示:

    图1 Linux的UID/GID安全机制与Android的Permission安全机制

            那么,这两个安全机制是如何对应起来的呢?

            我们首先看一下Linux基于UID和GID的安全机制,它包含三个基本角色:用户、进程和文件,如图2所示:

    图2 Linux基于UID/GID的安全机制的三个角色

            Linux中的每一个用户都分配有一个UID,然后所有的用户又按组来进划分,每一个用户组都分配有一个GID。注意,一个用户可以属于多个用户组,也就是说,一个UID可以对应多个GID。在一个用户所对应的用户组中,其中有一个称为主用户组,其它的称为补充用户组。

            Linux中的每一个文件都具有三种权限:Read、Write和Execute。这三种权限又按照用户属性划分为三组:Owner、Group和Other。如图3所示:

    图3 Linux的文件权限划分

            从图3就可以看出文件acct:1. 所有者为root,可读可写可执行;2. 所有者所属的主用户组为root,在这个组中的其它用户可读可执行;3. 其余的用户可读可执行。

            Linux中的每一个进程都关联有一个用户,也就是对应有一个UID,如图4所示:

    图4 Linux的进程

             由于每一个用户都对应有一个主用户组,以及若干个补充用户组,因此,每一个进程除了有一个对应的UID之外,还对应有一个主GID,以及若干个Supplementary GIDs。这些UID和GID就决定了一个进程所能访问的文件或者所能调用的系统API。例如,在图4中,PID为340的进程一般来说,就只能访问所有者为u0_a19的文件。

             一个进程的UID是怎么来的呢?在默认情况下,就等于创建它的进程的UID,也就是它的父进程的UID。Linux的第一个进程是init进程,它是由内核在启动完成后创建的,它的UID是root。然后系统中的所有其它进程都是直接由init进程或者间接由init进程的子进程来创建。所以默认情况下,系统的所有进程的UID都应该是root。但是实际情况并非如此,因为父进程在创建子进程之后,也就是在fork之后,可以调用setuid来改变它的UID。例如,在PC中,init进程启动之后,会先让用户登录。用户登录成功后,就对应有一个shell进程。该shell进程的UID就会被setuid修改为所登录的用户。之后系统中创建的其余进程的UID为所登录的用户。

            进程的UID除了来自于父进程之外,还有另外一种途径。上面我们说到,Linux的文件有三种权限,分别是Read、Wirte和Execute。其实还有另外一个种权限,叫做SUID。例如,我们对Android手机进行root的过程中,会在里面放置一个su文件。这个su文件就具有SUID权限,如图5所示:

    图5 su的SUID和SGID

            一个可执行文件一旦被设置了SUID位,那么当它被一个进程通过exec加载之后,该进程的UID就会变成该可执行文件的所有者的UID。也就是说,当上述的su被执行的时候,它所运行在的进程的UID是root,于是它就具有最高级别的权限,想干什么就干什么。

            与SUI类似,文件还有另外一个称为SGID的权限,不过它描述的是用户组。也就是说,一个可执行文件一旦被设置了GUID位,么当它被一个进程通过exec加载之后,该进程的主UID就会变成该可执行文件的所有者的主UID。

            现在,小伙伴们应该可以理解Android手机的root原理了吧:一个普通的进程通过执行su,从而获得一个具有root权限的进程。有了这个具有root权限的进程之后,就可以想干什么就干什么了。su所做的事情其实很简单,它再fork另外一个子进程来做真正的事情,也就是我们在执行su的时候,后面所跟的那些参数。由于su所运行在的进程的UID是root,因此由它fork出来的子进程的UID也是root。于是,子进程也可以想干什么就干什么了。

            不过呢,用来root手机的su还会配合另外一个称为superuser的app来使用。su在fork子进程来做真正的事情之前,会将superuser启动起来,询问用户是否允许fork一个UID是root的子进程。这样就可以对root权限进行控制,避免被恶意应用偷偷地使用。

            这里是su的源代码,小伙伴们可以根据上面所讲的知识读一读:https://code.google.com/p/superuser/source/browse/trunk/su/su.c?r=2

            在传统的UNIX以及类UNIX系统中,进程的权限只划分两种:特权和非特权。UID等于0的进程就是特权进程,它们可以通过一切的权限检查。UID不等于0的进程就非特权进程,它们在访问一些敏感资源或者调用一个敏感API时,需要进行权限检查。这种纯粹通过UID来做权限检查的安全机制来粗放了。于是,Linux从2.2开始,从进程的权限进行了细分,称为Capabilities。一个进程所具有Capabilities可以通过capset和prctl等系统API来设置。也就是说,当一个进程调用一个敏感的系统API时,Linux内核除了考虑它的UID之外,还会考虑它是否具有对应的Capability。

            这里就是Linux所设计的Capabilities列表,有兴趣的小伙伴可以再读一读:http://man7.org/linux/man-pages/man7/capabilities.7.html

            以上就是Linux基于UID/GID的安全机制的核心内容。接下来我们再看Android基于Permission的安全机制,它也有三个角色:apk、signature和permission,如图6所示:

    图6 Android的Permission安全机制

            

            Android的APK经过PackageManagerService安装之后,就相当于Linux里面的User,它们都会被分配到一个UID和一个主GID,而APK所申请的Permission就相当于是Linux里面的Supplementary GID。

            我们知道,Android的APK都是运行在独立的应用程序进程里面的,并且这些应用程序进程都是Zygote进程fork出来的。Zygote进程又是由init进程fork出来的,并且它被init进程fork出来后,没有被setuid降权,也就是它的uid仍然是root。按照我们前面所说的,应用程序进程被Zygote进程fork出来的时候,它的UID也应当是root。但是,它们的UID会被setuid修改为所加载的APK被分配的UID。

           参照Android应用程序进程启动过程的源代码分析一文的分析,ActivityManagerService在请求Zygote创建应用程序进程的时候,会将这个应用程序所加载的APK所分配得到的UID和GID(包括主GID和Supplementary GID)都收集起来,并且将它们作为参数传递给Zygote进程。Zygote进程通过执行函数来fork应用程序进程:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片

    1. /* 
    2.  * Utility routine to fork zygote and specialize the child process. 
    3.  */  
    4. static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)  
    5. {     
    6.     pid_t pid;  
    7.       
    8.     uid_t uid = (uid_t) args[0];  
    9.     gid_t gid = (gid_t) args[1];  
    10.     ArrayObject* gids = (ArrayObject *)args[2];  
    11.     ......  
    12.       
    13.     pid = fork();  
    14.       
    15.     if (pid == 0) {  
    16.         ......  
    17.           
    18.         err = setgroupsIntarray(gids);  
    19.         ......  
    20.           
    21.         err = setgid(gid);  
    22.         ......  
    23.           
    24.         err = setuid(uid);  
    25.         ......  
    26.     }     
    27.       
    28.     .....  
    29.       
    30.     return pid;  
    31. }     

            参数args[0]、args[1]和args[]保存的就是APK分配到的UID、主GID和Supplementary GID,它们分别通过setuid、setgid和setgroupsIntarray设置给当前fork出来的应用程序进程,于是应用程序进程就不再具有root权限了。

            那么,Signature又充当什么作用呢?两个作用:1. 控制哪些APK可以共享同一个UID;2. 控制哪些APK可以申请哪些Permission。

            我们知道,如果要让两个APK共享同一个UID,那么就需要在AndroidManifest中配置android:sharedUserId属性。PackageManagerService在安装APK的时候,如果发现两个APK具有相同的android:sharedUserId属性,那么它们就会被分配到相同的UID。当然这有一个前提,就是这两个APK必须具有相同的Signature。这很重要,否则的话,如果我知道别人的APK设置了android:sharedUserId属性,那么我也在自己的APK中设置相同的android:sharedUserId属性,就可以去访问别人APK的数据了。

            除了可以通过android:sharedUserId属性申请让两个APK共享同一个UID之外,我们还可以将android:sharedUserId属性的值设置为“android.uid.system”,从而让一个APK的UID设置为1000。UID是1000的用户是system,系统的关键服务都是运行在的进程的UID就是它。它的权限虽然不等同于root,不过也足够大了。我们可以通过Master Key漏洞来看一下有多大。

            Master Key漏洞发布时,曾轰动了整个Android界,它的具体情况老罗就不分析了,网上很多,这里是一篇官方的文章:http://bluebox.com/corporate-blog/bluebox-uncovers-android-master-key/。现在就简单说说它是怎么利用的:

            1. 找到一个具有系统签名的APP,并且这个APP通过android:sharedUserId属性申请了android.uid.system这个UID。

            2. 通过Master Key向这个APP注入恶意代码。

            3. 注入到这个APP的恶意代码在运行时就获得了system用户身份。

            4. 修改/data/local.prop文件,将属性ro.kernel.qemu的值设置为1。

            5. 重启手机,由于ro.kernel.qemu的值等于1,这时候手机里面的adb进程不会被setuid剥夺掉root权限。

            6. 通过具有root权限的adb进程就可以向系统注入我们熟悉的su和superuser.apk,于是整个root过程完成。

            注意,第1步之所以要找一个具有系统签名的APP,是因为通过android:sharedUserId属性申请android.uid.system这个UID需要有系统签名,也就是说不是谁可以申请system这个UID的。另外,/data/local.prop文件的Owner是system,因此,只有获得了system这个UID的进程,才可以对它进行修改。

            再说说Signature与Permission的关系。有些Permission,例如INSTALL_PACKAGE,不是谁都可以申请的,必须要具有系统签名才可以,这样就可以控制Suppementary GID的分配,从而控制应用程序进程的权限。具有哪些Permission是具有系统签名才可以申请的,可以参考官方文档:http://developer.android.com/reference/android/Manifest.html,就是哪些标记为“Not for use by third-party applications”的Permission。

            了解了Android的Permission机制之后,我们就可以知道:

             1. Android的APK就相当于是Linux的UID。

             2. Android的Permission就相当于是Linux的GID。

             3. Android的Signature就是用来控制APK的UID和GID分配的。

             这就是Android基于Permission的安全机制与Linux基于UID/GID的安全机制的关系,概括来说,我们常说的应用程序沙箱就是这样的:

    图7 Android的Application Sandbox

    展开全文
  • 网络安全策略和网络安全机制

    千次阅读 2019-01-05 18:03:28
    考研初试专业课中的一个题目,考的是有关安全机制和安全策略有关的方面,在专业课教材里翻了好久没有找到相关的内容,拿到复试的教材后发现才里面有提到~于是今天拿出来总结一下好了 网络安全策略 安全策略是指在一...

    考研初试专业课中的一个题目,考的是有关安全机制和安全策略有关的方面,在专业课教材里翻了好久没有找到相关的内容,拿到复试的教材后发现才里面有提到~于是今天拿出来总结一下好了

    网络安全策略

    安全策略是指在一个特定的环境里,为保证提供一定安全级别的安全保护所必须遵守的规则

    主要包括以下内容:

    • 先进的网络安全技术是网络安全的根本保证
    • 严格的安全管理是确保安全策略落实的基础
    • 严格的法律、法规是网络安全保障的坚强后盾

    随着应用环境的不同、实施客体的不同、指定阶段的不同,所使用的安全策略都将有所不同。

    网络安全策略按适用对象可分为:

    • 网络规划安全策略
    • 管理员策略
    • 网络用户安全策略
    • 安全架构策略等

    1、网络规划时的安全策略

    • 明确网络安全的责任人和安全策略的实施者
    • 对网络上的所有的服务器和网络设备,设置物理上的安全措施(防火、防盗、防水)和环境上的安全措施(供电、温度)。对小型的局域网最好将网络上的公用服务器和主交换设备在一间中心机房内集中放置
    • 网络设备应考虑容错和备份
    • 如果规划的网络与Intetnet有固定连接(静态的IP地址),只要资金允许,最好在网络和Internet之间安装防火墙
    • 网络使用代理服务器访问Internet,不仅可以降低访问成本,而且隐藏了网络规模和特性,加强了网络的安全性

    2、网络管理员的安全策略

    3、网络用户的安全策略

    网络安全机制

    网络要提供安全服务,依赖于安全机制的支持。目前,OSI安全体系结构采用的安全机制 主要有以下八种:

    • 加密机制
      加密是确保数据安全性的基本方法
    • 数字签名机制
      数字签名是确保数据真实性的基本方法
    • 访问控制机制
      访问控制机制是从计算机系统的处理能力方面对信息提供保护
    • 数据完整性机制
      • 数据单元或域的完整性
      • 数据单元或域的序列的完整性

    完整性是指数据在传输过程中没有被篡改和伪造,没有被修改

    • 验证交换机制
      通过交换信息来确认真实身份的机制
    • 信息流填充机制
      信息流填充机制提供对流量分析的多级保护,适用于保密性服务保护流量填充
    • 路由控制机制
      路由控制机制课根据信息发送者的申请选择特殊的安全路径,以确保数据安全
    • 仲裁机制
      引入仲裁机制后,通信双方进行通信时必须经过这个公证机构来交换,以确保共征集后能得到所必需的消息,供日后仲裁使用

    安全服务和安全机制的关系

    安全服务可以由一种或多种安全机制来提供,而有的安全机制又可以用于实现多种安全服务

    安全策略和安全机制的区别

    • 安全策略是指在一个特定的环境里,为保证提供一定安全级别的安全保护所必须遵守的规则,而安全机制是一种为了提供安全服务而运行的机制
    • 安全策略为安全机制的建立提供了依据和准则
    • 安全策略是保证提供一定安全级别的规则,安全机制是具体实现安全服务保证数据安全的措施
    展开全文
  • linux 内核安全机制

    千次阅读 2019-04-10 21:57:09
    Android是一个基于Linux内核的移动操作系统。Linux是一个支持多用户的系统,...Android在Linux内核提供的基于UID和GID的安全机制的基础上,又实现了一套称为Permission的安全机制,如图1所示: 图1 Linux的UID/...

     Android是一个基于Linux内核的移动操作系统。Linux是一个支持多用户的系统,系统中的文件的访问权限是通过用户ID(UID)和用户组ID(GID)来控制的。换句话说,就是Linux的安全机制是基于UID和GID来实现的。Android在Linux内核提供的基于UID和GID的安全机制的基础上,又实现了一套称为Permission的安全机制,如图1所示:

    图1 Linux的UID/GID安全机制与Android的Permission安全机制

            那么,这两个安全机制是如何对应起来的呢?

            我们首先看一下Linux基于UID和GID的安全机制,它包含三个基本角色:用户、进程和文件,如图2所示:

    图2 Linux基于UID/GID的安全机制的三个角色

            Linux中的每一个用户都分配有一个UID,然后所有的用户又按组来进划分,每一个用户组都分配有一个GID。注意,一个用户可以属于多个用户组,也就是说,一个UID可以对应多个GID。在一个用户所对应的用户组中,其中有一个称为主用户组,其它的称为补充用户组。

            Linux中的每一个文件都具有三种权限:Read、Write和Execute。这三种权限又按照用户属性划分为三组:Owner、Group和Other。如图3所示:

    图3 Linux的文件权限划分

            从图3就可以看出文件acct:1. 所有者为root,可读可写可执行;2. 所有者所属的主用户组为root,在这个组中的其它用户可读可执行;3. 其余的用户可读可执行。

            Linux中的每一个进程都关联有一个用户,也就是对应有一个UID,如图4所示:

    图4 Linux的进程

             由于每一个用户都对应有一个主用户组,以及若干个补充用户组,因此,每一个进程除了有一个对应的UID之外,还对应有一个主GID,以及若干个Supplementary GIDs。这些UID和GID就决定了一个进程所能访问的文件或者所能调用的系统API。例如,在图4中,PID为340的进程一般来说,就只能访问所有者为u0_a19的文件。

             一个进程的UID是怎么来的呢?在默认情况下,就等于创建它的进程的UID,也就是它的父进程的UID。Linux的第一个进程是init进程,它是由内核在启动完成后创建的,它的UID是root。然后系统中的所有其它进程都是直接由init进程或者间接由init进程的子进程来创建。所以默认情况下,系统的所有进程的UID都应该是root。但是实际情况并非如此,因为父进程在创建子进程之后,也就是在fork之后,可以调用setuid来改变它的UID。例如,在PC中,init进程启动之后,会先让用户登录。用户登录成功后,就对应有一个shell进程。该shell进程的UID就会被setuid修改为所登录的用户。之后系统中创建的其余进程的UID为所登录的用户。

            进程的UID除了来自于父进程之外,还有另外一种途径。上面我们说到,Linux的文件有三种权限,分别是Read、Wirte和Execute。其实还有另外一个种权限,叫做SUID。例如,我们对Android手机进行root的过程中,会在里面放置一个su文件。这个su文件就具有SUID权限,如图5所示:

    图5 su的SUID和SGID

            一个可执行文件一旦被设置了SUID位,那么当它被一个进程通过exec加载之后,该进程的UID就会变成该可执行文件的所有者的UID。也就是说,当上述的su被执行的时候,它所运行在的进程的UID是root,于是它就具有最高级别的权限,想干什么就干什么。

            与SUI类似,文件还有另外一个称为SGID的权限,不过它描述的是用户组。也就是说,一个可执行文件一旦被设置了GUID位,么当它被一个进程通过exec加载之后,该进程的主UID就会变成该可执行文件的所有者的主UID。

            现在,小伙伴们应该可以理解Android手机的root原理了吧:一个普通的进程通过执行su,从而获得一个具有root权限的进程。有了这个具有root权限的进程之后,就可以想干什么就干什么了。su所做的事情其实很简单,它再fork另外一个子进程来做真正的事情,也就是我们在执行su的时候,后面所跟的那些参数。由于su所运行在的进程的UID是root,因此由它fork出来的子进程的UID也是root。于是,子进程也可以想干什么就干什么了。

            不过呢,用来root手机的su还会配合另外一个称为superuser的app来使用。su在fork子进程来做真正的事情之前,会将superuser启动起来,询问用户是否允许fork一个UID是root的子进程。这样就可以对root权限进行控制,避免被恶意应用偷偷地使用。

            这里是su的源代码,小伙伴们可以根据上面所讲的知识读一读:https://code.google.com/p/superuser/source/browse/trunk/su/su.c?r=2

            在传统的UNIX以及类UNIX系统中,进程的权限只划分两种:特权和非特权。UID等于0的进程就是特权进程,它们可以通过一切的权限检查。UID不等于0的进程就非特权进程,它们在访问一些敏感资源或者调用一个敏感API时,需要进行权限检查。这种纯粹通过UID来做权限检查的安全机制来粗放了。于是,Linux从2.2开始,从进程的权限进行了细分,称为Capabilities。一个进程所具有Capabilities可以通过capset和prctl等系统API来设置。也就是说,当一个进程调用一个敏感的系统API时,Linux内核除了考虑它的UID之外,还会考虑它是否具有对应的Capability。

            这里就是Linux所设计的Capabilities列表,有兴趣的小伙伴可以再读一读:http://man7.org/linux/man-pages/man7/capabilities.7.html

            以上就是Linux基于UID/GID的安全机制的核心内容。接下来我们再看Android基于Permission的安全机制,它也有三个角色:apk、signature和permission,如图6所示:

    图6 Android的Permission安全机制

            

            Android的APK经过PackageManagerService安装之后,就相当于Linux里面的User,它们都会被分配到一个UID和一个主GID,而APK所申请的Permission就相当于是Linux里面的Supplementary GID。

            我们知道,Android的APK都是运行在独立的应用程序进程里面的,并且这些应用程序进程都是Zygote进程fork出来的。Zygote进程又是由init进程fork出来的,并且它被init进程fork出来后,没有被setuid降权,也就是它的uid仍然是root。按照我们前面所说的,应用程序进程被Zygote进程fork出来的时候,它的UID也应当是root。但是,它们的UID会被setuid修改为所加载的APK被分配的UID。

           参照Android应用程序进程启动过程的源代码分析一文的分析,ActivityManagerService在请求Zygote创建应用程序进程的时候,会将这个应用程序所加载的APK所分配得到的UID和GID(包括主GID和Supplementary GID)都收集起来,并且将它们作为参数传递给Zygote进程。Zygote进程通过执行函数来fork应用程序进程:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片

    1. /* 
    2.  * Utility routine to fork zygote and specialize the child process. 
    3.  */  
    4. static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)  
    5. {     
    6.     pid_t pid;  
    7.       
    8.     uid_t uid = (uid_t) args[0];  
    9.     gid_t gid = (gid_t) args[1];  
    10.     ArrayObject* gids = (ArrayObject *)args[2];  
    11.     ......  
    12.       
    13.     pid = fork();  
    14.       
    15.     if (pid == 0) {  
    16.         ......  
    17.           
    18.         err = setgroupsIntarray(gids);  
    19.         ......  
    20.           
    21.         err = setgid(gid);  
    22.         ......  
    23.           
    24.         err = setuid(uid);  
    25.         ......  
    26.     }     
    27.       
    28.     .....  
    29.       
    30.     return pid;  
    31. }     

            参数args[0]、args[1]和args[]保存的就是APK分配到的UID、主GID和Supplementary GID,它们分别通过setuid、setgid和setgroupsIntarray设置给当前fork出来的应用程序进程,于是应用程序进程就不再具有root权限了。

            那么,Signature又充当什么作用呢?两个作用:1. 控制哪些APK可以共享同一个UID;2. 控制哪些APK可以申请哪些Permission。

            我们知道,如果要让两个APK共享同一个UID,那么就需要在AndroidManifest中配置android:sharedUserId属性。PackageManagerService在安装APK的时候,如果发现两个APK具有相同的android:sharedUserId属性,那么它们就会被分配到相同的UID。当然这有一个前提,就是这两个APK必须具有相同的Signature。这很重要,否则的话,如果我知道别人的APK设置了android:sharedUserId属性,那么我也在自己的APK中设置相同的android:sharedUserId属性,就可以去访问别人APK的数据了。

            除了可以通过android:sharedUserId属性申请让两个APK共享同一个UID之外,我们还可以将android:sharedUserId属性的值设置为“android.uid.system”,从而让一个APK的UID设置为1000。UID是1000的用户是system,系统的关键服务都是运行在的进程的UID就是它。它的权限虽然不等同于root,不过也足够大了。我们可以通过Master Key漏洞来看一下有多大。

            Master Key漏洞发布时,曾轰动了整个Android界,它的具体情况老罗就不分析了,网上很多,这里是一篇官方的文章:http://bluebox.com/corporate-blog/bluebox-uncovers-android-master-key/。现在就简单说说它是怎么利用的:

            1. 找到一个具有系统签名的APP,并且这个APP通过android:sharedUserId属性申请了android.uid.system这个UID。

            2. 通过Master Key向这个APP注入恶意代码。

            3. 注入到这个APP的恶意代码在运行时就获得了system用户身份。

            4. 修改/data/local.prop文件,将属性ro.kernel.qemu的值设置为1。

            5. 重启手机,由于ro.kernel.qemu的值等于1,这时候手机里面的adb进程不会被setuid剥夺掉root权限。

            6. 通过具有root权限的adb进程就可以向系统注入我们熟悉的su和superuser.apk,于是整个root过程完成。

            注意,第1步之所以要找一个具有系统签名的APP,是因为通过android:sharedUserId属性申请android.uid.system这个UID需要有系统签名,也就是说不是谁可以申请system这个UID的。另外,/data/local.prop文件的Owner是system,因此,只有获得了system这个UID的进程,才可以对它进行修改。

            再说说Signature与Permission的关系。有些Permission,例如INSTALL_PACKAGE,不是谁都可以申请的,必须要具有系统签名才可以,这样就可以控制Suppementary GID的分配,从而控制应用程序进程的权限。具有哪些Permission是具有系统签名才可以申请的,可以参考官方文档:http://developer.android.com/reference/android/Manifest.html,就是哪些标记为“Not for use by third-party applications”的Permission。

            了解了Android的Permission机制之后,我们就可以知道:

             1. Android的APK就相当于是Linux的UID。

             2. Android的Permission就相当于是Linux的GID。

             3. Android的Signature就是用来控制APK的UID和GID分配的。

             这就是Android基于Permission的安全机制与Linux基于UID/GID的安全机制的关系,概括来说,我们常说的应用程序沙箱就是这样的:

    图7 Android的Application Sandbox

    展开全文
  • 操作系统安全机制

    千次阅读 2018-09-16 23:38:37
    版权声明:本文为博主原创文章,未经博主允许不得转载。...操作系统的安全性表现 物理上分离:要求进程使用不同的物理实体 时间上分离:具有不同安全要求进程在不同时间运行 逻辑上分离:要求进程...
  • 安全机制设计原则

    千次阅读 2020-03-21 16:27:56
    安全机制设计八大原则: ①经济性原则(Economy of Mechanism) 安全机制设计尽可能简单短小,从而在排查缺陷、检测漏洞时代码更容易处理 ②默认拒绝原则(Fail-Safe Defaults) 只要没有授权的信息就不允许访问 ...
  • 理解Android安全机制

    千次阅读 2017-06-10 19:01:57
     SE Android安全机制所要保护的对象是系统中的资源,这些资源分布在各个子系统中。实际上,系统中需要保护的资源非常多,除了文件之外,还有进程、socket和IPC等。SE Android是一个复杂的安全模型,本文就不进一步...
  • 安全要解决什么问题 你都会的密码术 回顾与总结
  • Android安全机制介绍

    千次阅读 2018-02-09 21:14:51
    Android的安全机制包括以下几个方面: •进程沙箱隔离机制。 •应用程序签名机制。 •权限声明机制。 •访问控制机制。 •进程通信机制。 •内存管理机制。 •SELinux1.进程沙箱隔离机制Android应用程序在安装时被...
  • JVM-沙箱安全机制

    千次阅读 2020-03-12 21:28:20
     Java安全模型的核心就是Java沙箱(sandbox),什么是沙箱?沙箱是一个限制程序运行的环境。沙箱机制就是将 Java 代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来...
  • (7)操作系统安全机制

    万次阅读 2017-12-30 10:22:19
    操作系统安全机制:自主访问控制、强制访问控制机制、客体重用机制、标识与鉴别机制、可信路径机制、安全审计
  • 初识RFID的物理与逻辑安全机制

    千次阅读 2020-04-14 12:00:19
    RFID的安全与隐私保护: 三类威胁: 1.身份隐私威胁,即攻击者能够推导出参与通信的节点的身份 ...为了保护RFID系统的安全,需要建立相应的RFID安全机制,包括物理安全机制和逻辑安全机制以及两者的结合 ...
  • 常见的安全机制

    千次阅读 2020-02-24 16:49:05
    常见的安全机制
  • SELinux MAC安全机制简介

    千次阅读 2019-03-11 10:46:19
    SELinux MAC安全机制 SELinux MAC Security Enhanced Linux(SELinux),使用Mandatory Access Control(MAC)方式对权限进行管控。 MAC强制访问控制,针对特定的程序与特定的文件资源进行权限管理。 MAC采用政策...
  • SQL系统的两种安全机制

    千次阅读 2019-04-19 21:55:26
    在SQL系统中,有两种安全机制。 一种是视图机制,当用户通过视图访问数据库时,不能访问此视图外的数据,视图机制提供了一定的安全性。视图是一个虚拟表,其内容由定义查询。同基本表一样,视图包含一系列带有名称...
  • 数据库安全机制.pdf

    2020-01-26 19:55:08
    1.1数据库安全机制 数据库安全机制是用于实现数据库的各种安全策略的功能集合 正是由这些安全机制来 实现安全模型进而实现保护数据库系统安全的目标 数据库系统的安全机制如图所示 授权机制 约束机制 审计 身份验证 ...
  • 6种核心安全机制(1)

    千次阅读 2016-09-01 14:48:35
    6种核心安全机制-加密、密钥、签名与证书安全机制之对称加密 秘钥:氛围加密秘钥和解密秘钥 明文:没有加密的信息 密文:加密了的信息 加密:明文到密文的过程 解密:密文->明文 过程 对称加密概念:加密端和解密的使用的...
  • OSI安全体系结构的八种安全机制包括加密、数据签名、访问控制、数据完整性、鉴别交换、业务流填充、路由控制和公正等,其含义分别解释如下:  1)加密机制:提供对数据或信息流的保密,并可作为其它安全机制的补充...
  • HTTP协议安全机制

    千次阅读 2019-03-12 16:58:25
    缺点:不够安全——明文传输,不做加密,易被中间人攻击(中间人截获甚至篡改信息) 改进:HTTPS协议 改进流程: (一)对称加密(约定一个随机生成密钥,用密钥对信息加密解密) 缺点:直接用对称加密仍不安全...
  • ISO 26262-4: 6.4.7 1. The safety mechanisms shall be specified by technical safety ...安全机制通过分析技术安全需求来制定,包括: a) the measures related to the detection, indication and control of ...
  • API安全机制

    千次阅读 2018-02-02 18:11:14
    API 安全机制 接口的安全性主要围绕Token、Timestamp和Sign三个机制展开设计,保证接口的数据不会被篡改和重复调用,下面具体来看: Token授权机制:用户使用用户名密码登录后服务器给客户端返回一个Token(通常是...
  • API安全 API? 与因特网相连的端系统提供了一个应用程序接口(英语:Application Programming Interface,缩写:API;又称为应用程序编程接口)是软件系统不同组成部分衔接的约定。 API规定了运行在一个端系统上的...
  • 【Sql Server】数据库的安全机制

    千次阅读 2019-04-14 17:43:10
    如何实现安全机制:从以下几个方面,但主要的途径是角色和授权的方面。掌握这些便可以很好的对数据进行保护! 安全机制 客户机 网传(加密) 实例...
  • Hadoop安全机制

    千次阅读 2016-05-25 17:42:51
    Hadoop集群安全 Hadoop自带两种安全机制:Simple机制、Kerberos机制
  • OSI安全体系结构的五类安全服务以及八类安全机制

    万次阅读 多人点赞 2017-03-15 10:01:56
    五类安全服务包括认证(鉴别)服务、访问控制服务、数据保密性服务、数据完整性服务和抗否认性服务。 认证(鉴别)服务:在网络交互过程中,对收发双方的身份及数据来源进行验证。 访问控制服务:防止未授权用户...
  • 数据库之SQL(安全机制一)

    千次阅读 2018-08-18 17:38:37
    一、什么是安全机制? 数据库的安全机制:保护数据库以防止不合法的使用所造成的数据泄露、更改或破坏。 二、安全机制有几个等级? 客户机安全机制 网络传输安全机制 实例级别安全机制 数据库级别安全机制 ...
  • 1、JAVA数据运行区 java源文件通过javac编译成java字节码文件.class 通过类加载器ClassLoader加载.class文件,将class文件放入内存中各个区域 ...下面主要讲ClassLoader双亲委派和沙箱安全机制 2、C...
  • 文章目录Windows安全机制数据执行保护:DEP机制原理绕过攻击未启用的DEP程序利用Re2Libc挑战DEP利用可执行内存利用.NET攻击利用Java applet Windows安全机制 微软关于内存保护机制 GS编译技术 SEH的安全校验...
  • SEAndroid安全机制框架分析

    万次阅读 多人点赞 2014-07-14 01:00:02
    针对传统Linux系统,NSA开发了一套安全机制SELinux,用来加强安全性。然而,由于Android系统有着独特的用户空间运行时,因此SELinux不能完全适用于Android系统。为此,NSA针对Android系统,在SELinux基础上开发了...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 981,334
精华内容 392,533
关键字:

安全机制