移动安全-第一天 安卓基本原理

安卓这个系统是基于linux的,安卓端应用使用java语言编程

本次冬令营的学习目标是:

  • 掌握基本逆向分析方法,应用的漏洞原理
  • 掌握apk中java层分析
  • 掌握apk中native层分析
  • 通过对apk分析发现问题,实现利用

JAVA中Action层, Service层 ,modle层 和 Dao层的功能区分

  1. modle层就是对应的数据库表的实体类。

  2. Dao层是使用了Hibernate连接数据库、操作数据库(增删改查)。

  3. Service层:引用对应的Dao数据库操作,在这里可以编写自己需要的代码(比如简单的判断)。

  4. Action层:引用对应的Service层,在这里结合Struts的配置文件,跳转到指定的页面,当然也能接受页面传递的请求数据,也可以做些计算处理。

安卓原理

系统架构

这个就是我们Android的整体系统架构图了,我们首先从整体上来看看Android的体系结构。

Linux Kernel:我们知道Android其实就是一个操作系统,其底层是基于Linux Kernel的,这一层主要完成的是操作系统所具有的功能,比如这一层有许多的驱动程序,正是通过这些驱动程序来驱动我们设备上的硬件设备的。

Android Runtime:Android的运行环境,我们学过java的都知道,java程序的运行需要java的核心包的支持,然后通过JVM虚拟机来运行我们的应用程序,这里Android Runtime里的Core Libraries就相当于java的JDK,是运行android应用程序所需要的核心库,Dalvik Virtual Machine就相当于JVM,这时Google专为Android开发的运行android应用程序所需的虚拟机。

Liberaries:这里面都是Android的库文件,例如我们访问SQLite数据库的库文件等等。

Application Framework:应用程序的框架,这个是非常的重要的,相信Framework这个词大家都应该非常的熟悉了,我们学习Android也主要学的就是这一层,我们通过这些各种各样的框架来实现我们的Application。

Application:这个就是我们开发的Application了。

最底层的各种驱动层 共享内存等 是修改版本的linux。

设备启动流程

android设备的启动分为三个阶段:Boot Loader, Linux Kernel,Android 系统服务。Android系统实际上是运行在Linux Kernel之上的一系列系统服务进程。init进程是Android中被启动的第一个进程,PID = 0 。它通过解析init.rc脚本来构建出android运行初始化形态(android系统服务程序大多是在这个脚本中被启动) 

系统启动流程图可以从这个图里面看出。

常用问题

常讲的是共享内存 和 Bander(跨进程通信框架)

      Binder是Android系统进程间通信(IPC)方式之一。Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder具有无可比拟的优势。

驱动问题改进

早期的驱动开发时,审核不严格,规范 测试不严格,drive以文件形式存在,可以通过IO 文件读写 接口等方式访问。以前apk是可以直接访问驱动的,使用的时候出发安全问题,进行提权等。

现在驱动处理的比较好,有严格的审查机制,难以直接访问某些关键的dirve,需要中间代理取缓解,无法再应用层触发漏洞。

内核自保护:安全监测 防御手段 阻断攻击  //arm结构 内核度量 

 

library--media

library库,一个是引用很多第三方的库 开源的第三方软件 。

前两年最关键的出现在media里 爆了近200个漏洞 (内存操作 整形溢出 )

1.base+offset 

0            0x05000000
int 20       0x05000020
   int 2000000    0x007000000
    可能跳出了申请的内存
    int -0x00490000
    偏移可以覆盖整个内存空间 根据int offset的偏移
 
struct {0x10}
N  {0x10}
x= malloc(0x10*0x10)
for(int i=0;i<N;i++)
    struct init
    
如果我们设置很大的N {0xf0000001}
分配的内存为0x10*0xf0000001 = 0x00000010 实际上下面的访问超出了

那么实际上寄存器会设置为一些数值 判断相乘时 是否会产生溢出 media中有一个Underfine Behavior Sanitizer 抑制一些无符号整数溢出错误等

后来的改进将media拆分了,造成所有的media、server的漏洞可以影响其他部分,通过沙箱减少权限等

关心的问题

  • library是如何暴露给外部数据源的,网页 数据库都是如何调用库的
  • 减少攻击面 让用户无法直接使用library 使用沙箱给用户 即使攻击了也无法获取关键信

application framework

现在权限已经很小了,系统提供了100多个servers,可以实现很多的功能了,application层没有使用很多库,。

攻击路径:application-服务 内核   (apk静默安装权限 逻辑漏洞 )

application 

第三方库 和系统的提供的服务等

我们最先访问的就是application,这是一个内存安全的,绝大多数apk都有逻辑漏洞。

进程视角

https://blog.csdn.net/ffmxnjm/article/details/70918119

1.当电源按下,引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序到RAM,然后执行。

2. 引导程序是在Android操作系统开始运行前的一个小程序。引导程序是运行的第一个程序,因此它是针对特定的主板与芯片的。设备制造商要么使用很受欢迎的引导程序比如redboot、uboot、qi bootloader或者开发自己的引导程序,它不是Android操作系统的一部分( 对于Android整个启动过程来说,基本可以划分成三个阶段:Bootloader引导、Linux kernel启动、Android启动)。引导程序是OEM厂商或者运营商加锁和限制的地方。

引导程序分两个阶段执行。第一个阶段,检测外部的RAM以及加载对第二阶段有用的程序;第二阶段,引导程序设置网络、内存等等。这些对于运行内核是必要的,为了达到特殊的目标,引导程序可以根据配置参数或者输入数据设置内核。

3.Android内核与桌面linux内核启动的方式差不多。内核启动时,设置缓存、被保护存储器、计划列表,加载驱动。当内核完成系统设置,它首先在系统文件中寻找”init”文件,然后启动root进程或者系统的第一个进程。

4.init是第一个进程,我们可以说它是root进程或者说有进程的父进程。init进程有两个责任,一是挂载目录,比如/sys、/dev、/proc,二是运行init.rc脚本。

对于init.rc文件,Android中有特定的格式以及规则。在Android中,我们叫做Android初始化语言。
Android初始化语言由四大类型的声明组成,即Actions(动作)、Commands(命令)、Services(服务)、以及Options(选项)。

5.在Java中,我们知道不同的虚拟机实例会为不同的应用分配不同的内存。假如Android应用应该尽可能快地启动,但如果Android系统为每一个应用启动不同的Dalvik虚拟机实例,就会消耗大量的内存以及时间。因此,为了克服这个问题,Android系统创造了”Zygote”。Zygote让Dalvik虚拟机共享代码、低内存占用以及最小的启动时间成为可能。Zygote是一个虚拟器进程,正如我们在前一个步骤所说的在系统引导的时候启动。Zygote预加载以及初始化核心库类。通常,这些核心类一般是只读的,也是Android SDK或者核心框架的一部分。在Java虚拟机中,每一个实例都有它自己的核心库类文件和堆对象的拷贝。

6.完成了上面几步之后,运行环境请求Zygote运行系统服务。系统服务同时使用native以及java编写,系统服务可以认为是一个进程。同一个系统服务在Android SDK可以以System Services形式获得。系统服务包含了所有的System Services。

android安全沙箱机制

Android顺其自然地继承了Linux内核的安全机制,同时结合移动终端的具体应用特点,进行了许多有益的改进与提升。
  window与unix/linux等传统操作系统以用户为中心,假设用户之间是不可信的,更多考虑如何隔离不同用户对资源(存储区域与用户文件,内存区域与用户进程,底层设备等)的访问。在Android系统中,假设应用软件之间是不可信的,甚至用户自行安装的应用程序也是不可信的,因此,首先需要限制应用程序的功能,也就是将应用程序置于“沙箱”之内,实现应用程序之间的隔离,并且设定允许或拒绝API调用的权限,控制应用程序对资源的访问,如访问文件,目录,网络,传感器等。
  Android扩展了Linux内核安全模型的用户与权限机制,将多用户操作系统的用户隔离机制巧妙地移植为应用程序隔离。在linux中,一个用户标识(UID)识别一个给定用户;在Android上,一个UID则识别一个应用程序。在安装应用程序时向其分配UID。应用程序在设备上存续期间内,其UID保持不变。仅限用于允许或限制应用程序(而非用户)对设备资源的访问。如此,Android的安全机制与Linux内核的安全模型完美衔接!不同的应用程序分别属于不同的用户,因此,应用程序运行于自己独立的进程空间,与UID不同的应用程序自然形成资源隔离,如此便形成了一个操作系统级别的应用程序“沙箱”。
  应用程序进程之间,应用程序与操作系统之间的安全性由Linux操作系统的标准进程级安全机制实现。在默认状态下,应用程序之间无法交互,运行在进程沙箱内的应用程序没有被分配权限,无法访问系统或资源。因此,无论是直接运行于操作系统之上的应用程序,还是运行于Dalvik虚拟机的应用程序都得到同样的安全隔离与保护,被限制在各自“沙箱”内的应用程序互不干扰,对系统与其他应用程序的损害可降至最低。Android应用程序的“沙箱”机制如下图,互相不具备信任关系的应用程序相互隔离,独自运行:

  在很多情况下,源自同一开发者或同一开发机构的应用程序,相互间存在信任关系。Android系统提供一种所谓共享UID(SharedUserID)机制,使具备信任关系的应用程序可以运行于同一进程空间。通常 ,这种信任关系由应用程序的数字签名确定,并且需要应用程序在manifest文件中使用相同的UID。共享UID的应用程序进程空间

安卓组件

对进程进行封装,如果进程的概念,可以使用组件进行快速开发

Intent组件虽然不是四大组件,但却是连接四大组件的桥梁,学习好这个知识,也非常的重要。

Android四大组件分别为activity、service、content provider、broadcast receiver。

1、activity(主线程 显示界面和动态形式等)

(1)一个Activity通常就是一个单独的屏幕(窗口)。

(2)Activity之间通过Intent进行通信。

(3)android应用中每一个Activity都必须要在AndroidManifest.xml配置文件中声明,否则系统将不识别也不执行该Activity。

(4)不要在主线程进行太多数据操作,界面会死掉。

2、service

(1)service用于在后台完成用户指定的操作。service分为两种:

(a)started(启动):当应用程序组件(如activity)调用startService()方法启动服务时,服务处于started状态。

(b)bound(绑定):当应用程序组件调用bindService()方法绑定到服务时,服务处于bound状态。

后台运行组件,没有界面,多个线程进行后台处理,客户端UI可以和service端建立连接

创建services和基本原理在这里可以看 https://blog.csdn.net/u010018325/article/details/8758769

3、content provider(给其他程序提供数据)

(1)android平台提供了Content Provider使一个应用程序的指定数据集提供给其他应用程序。其他应用可以通过ContentResolver类从该内容提供者中获取或存入数据。

(2)只有需要在多个应用程序间共享数据是才需要内容提供者。例如,通讯录数据被多个应用程序使用,且必须存储在一个内容提供者中。它的好处是统一数据访问方式。

(3)ContentProvider实现数据共享。ContentProvider用于保存和获取数据,并使其对所有应用程序可见。这是不同应用程序间共享数据的唯一方式,因为android没有提供所有应用共同访问的公共存储区。

4、broadcast receiver(就是响应外部事件的)

(1)你的应用可以使用它对外部事件进行过滤,只对感兴趣的外部事件(如当电话呼入时,或者数据网络可用时)进行接收并做出响应。广播接收器没有用户界面。然而,它们可以启动一个activity或serice来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力,例如闪动背灯、震动、播放声音等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。

(2)广播接收者的注册有两种方法,分别是程序动态注册和AndroidManifest文件中进行静态注册。

(3)动态注册广播接收器特点是当用来注册的Activity关掉后,广播也就失效了。静态注册无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器也是打开着的。也就是说哪怕app本身未启动,该app订阅的广播在触发时也会对它起作用。

Intent

Intent的概念:

Android中提供了Intent机制来协助应用间的交互与通讯,或者采用更准确的说法是,Intent不仅可用于应用程序之间,也可用于应用程序内部的activity, service和broadcast receiver之间的交互。Intent这个英语单词的本意是“目的、意向、意图”。

Intent是一种运行时绑定(runtime binding)机制,它能在程序运行的过程中连接两个不同的组件。通过Intent,你的程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来响应。

activity、service和broadcast receiver之间是通过Intent进行通信的,而另外一个组件Content Provider本身就是一种通信机制,不需要通过Intent。

Intent中的四个重要属性——Action、Data、Category、Extras

Intent是联系Activity,Service,Broadcast之间的纽带,其作用并不仅是简单的数据传递。通过自带的属性,可以方便的完成很多较为复杂的操作。列如直接调用拨号功能,直接调用合适的程序打开不同类型的文件等,都可以通过设置Intent属性来完成。

Intent主要有4个属性,分别是:

Action:系统中已经有的一些操作;Action属性的值是一个字符串,它代表了系统中定义的一系列常用动作。通过setAction()方法或在清单文件AndroidMainfest.xml中设置。默认为:DEFAULT。

Data:接收数据的格式;Dta通常是URL格式定义的操作数据。列如:tel//。通过setData()方法设置。

Category:接受的intent类别;Category属性用于指定当前动作(Action)被执行的环境。通过addCategory()方法或在清单文件 AndroidMainfest.xml中设置.默认为:CATEGORY_DEFAULT。

Extras:给目标组件传递额外的数据。通过putExtras()方法设置.

消息处理机制

一、handler的引入:

我们都知道,Android UI是线程不安全的,如果在子线程中尝试进行UI操作,程序就有可能会崩溃。相信大家在日常的工作当中都会经常遇到这个问题,解决的方案应该也是早已烂熟于心,即创建一个Message对象,然后借助Handler发送出去,之后在Handler的handleMessage()方法中获得刚才发送的Message对象,然后在这里进行UI操作就不会再出现崩溃了。

Android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长时间的任务后做出相应的通知。

  • UI线程:就是我们的主线程,系统在创建UI线程的时候会初始化一个Looper对象,同时也会创建一个与其关联的MessageQueue;
  • Handler:作用就是发送与处理信息,如果希望Handler正常工作,在当前线程中要有一个Looper对象
  • Message:Handler接收与处理的消息对象
  • MessageQueue:消息队列,先进先出管理Message,在初始化Looper对象时会创建一个与之关联的MessageQueue;
  • Looper:每个线程只能够有一个Looper,管理MessageQueue,不断地从中取出Message分发给对应的Handler处理!

  通俗一点讲:当我们的子线程想修改Activity中的UI组件时,我们可以新建一个Handler对象,通过这个对象向主线程发送信息;而我们发送的信息会先到主线程的MessageQueue进行等待,由Looper按先入先出顺序取出,再根据message对象的what属性分发给对应的Handler进行处理!

package com.example.androidthreadtest;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {

    public static final int UPDATE_TEXT = 1;
    private TextView text;
    private Button changeText;
    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case UPDATE_TEXT:
                text.setText("Nice to meet you");
                break;
            default:
                break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (TextView) findViewById(R.id.text);
        changeText = (Button) findViewById(R.id.change_text);
        changeText.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.change_text:
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Message message = new Message();
                    message.what = UPDATE_TEXT;
                    handler.sendMessage(message);
                }
            }).start();
            break;
        default:
            break;
        }
    }
}

我们并没有在子线程中直接进行UI操作,而是创建了一个Message对象,并将它的what字段的值指定为了一个整形常量UPDATE_TEXT,用于表示更新TextView这个动作。然后调用Handler的sendMessage()方法将这条Message发送出去。很快,Handler就会收到这条Message,并在handleMessage()方法,在这里对具体的Message进行处理(需要注意的是,此时handleMessage()方法中的代码是在主线程中运行的)。如果发现Message的what字段的值等于UPDATE_TEXT,就将TextView显示的内容更新。运行程序后,点击按钮,TextView就会显示出更新的内容。

https://www.cnblogs.com/fuck1/p/5513412.html

http://www.cnblogs.com/smyhvae/p/4003922.html

https://www.cnblogs.com/to-creat/p/5891089.html

https://www.cnblogs.com/to-creat/p/5891089.html

https://www.cnblogs.com/blueskyli/p/8630934.html

https://www.cnblogs.com/shaweng/p/4000611.html

https://zhidao.baidu.com/question/365181594.html

https://blog.csdn.net/ffmxnjm/article/details/70918119

https://blog.csdn.net/google_huchun/article/details/77142132   Intent中的四个重要属性

https://blog.csdn.net/u014529755/article/details/51674249

http://gityuan.com/android/

https://www.cnblogs.com/xiaoluo501395377/p/3389411.html

猜你喜欢

转载自blog.csdn.net/iamsongyu/article/details/86891425