zoukankan      html  css  js  c++  java
  • drozer源码学习:app

    源码下载:https://github.com/mwrlabs/drozer;模块的源码位于src.drozer.modules,根据模块名来划分文件夹:

         app、auxiliary、exploit、information、scanner、shell、tools。今天我们先分析app;以下PackageManagerService简称PMS。在分析模块原理之前稍微讲解下一些基础知识:

           PackageInfo:包含app的一系列属性,对应于app的AndroidManifest.xml。可由PMS get,但get到的packageInfo中信息取决于get函数中的flags参数,见activity.info模块

           Intents:在与drozer交互中时常需要构造intent,构造intent与adb中的命令有所不同,请”help intents”命令查看参数

     

     

    Activity

         

     info:列出exported activity的信息,-a指定package;

          指定package:      PMS.getpackageinfo(package,GET_ACTIVITIES)返回packageInfo; packageInfo.activities(包含package中所有activity,但只有GET_ACTIVITIES属性才会给packageInfo返回activities)

          没有指定package:       PMS.getInstallPackages(GET_ACTIVITIES)  返回list<packageInfo>

             PackageInfo.activities就是List<ActivityInfo>,根据ActivityInfo(父类是ComponentInfo->父类PackageItemInfo)的属性name、exported值来得到我们需要的activity。

     

       start:启动activity                                            

    通过startActivity(intent)来启动,利用start的参数来构造intent

     

       forintent:找出能处理特定intent的activity                      

    利用forintent参数构造intent,然后PMS. queryIntentActivities(intent,flags)查找符合intent的activity,并显示package和activity的名称。

     

     

    Broadcast:

           Info:       列出exported broadcast的信息,-a指定package。

                  指定package:PMS.getPackageInfo(package,flags)    ,注意这次的flag包括broadcast和permission表示返回的packageInfo中包含broadcast和permission(但貌似中没用到package的permission哎,只用到broadcast的permission)

                  无指定package:PMS.getPackages(flag),返回list< packageInfo > 过滤Info参数后剩余的broadcast显示receiver和对应的permission

           Send:     用intent启动广播

          利用send参数来构造intent,然后sendBroadcast(intent)。     

     

    Sniff:  注册广播接收器接收特定的intent,源码位于:src.drozer.modules.common.RegisterReceiver.java

               加载一个类,类中包含broadcast的注册代码且broadcast的intentFilter参数是通过sniff参数构建出来的(service.send类同操作)。

     

     

    Service

         info:列出exported service的信息

                  类同操作,通过PMS返回packageInfo,过滤参数后输出对应的service信息

     

         start:用intent启动service-> startService(intent)

                               

         stop:用intent停止service

                  注意:使用的是Context().stopService这个api,上面startService()也是Context。

     

         send:      绑定一个service并发送信息,如果service有返回信息会接收。  这是在不同app之间传递msg;但在这个send需要attcked app的配合。因为绑定service需要app的service在onbind()返回binder。这个有源代码在src.drozer.modules.common.ServiceBinder.java。需要注意的是参数 –bundle-as-obj它决定是否将bundle赋值给msg.obj;否则msg.setData(bundle)。再说一点,参数—extra的值由bundle来构造。

     

     

    Package

           attacksurface:     列出package中可被attack的各组件的个数

                  实际上这条命令是列出package中exproted的组件;通过PMS get 到PacakgeInfo,再过滤出exproted的packageInfo。

     

           backup:                列出使用backup的package

                  PMS get packageInfo,找到属性applicationInfo的FLAG_ALLOW_BACKUP对应位为1

     

           debuggable:        列出可被调试的package

                  PMS get packageInfo,找到属性applicationInfo的FLAG_DEBUGGABLE对应位为1

     

           info:                     列出设备上安装好的所有package的详细信息,但可使用参数来选定特定的package,详情”help”;PMS get到packageInfo(注意configuration flag),输出UID、gid、path等

     

           launchintent:       列出package中launch intent的信息(可以获知main activity)

                  PMS的queryIntentActivities函数去get,但与activity.forintent不同的是,这里指定intent为ACTION_MAIN

     

           list:                      列出设备上的所有的package(只有name),可指定参数;PMS get     

                 

           manifest:                    列出package的manifest文件内容

                  创建package的context得到资源从中获取到manifest文件,然后利用XmlAssetReader读取信息并显示,代码位于(createPackageContext(package,0)??)src.drozer.modules.common. XmlAssetReader.java

     

           native:                 列出package包含的so文件

                  PMS get到packageInfo,然后得到application的apk地址(/data/app;为什么不直接去/data/app-lib/下找呢?),在文件地址下查找后缀名为”.so”的文件(源码位于src.drozer.modules.common.Native.java;在此我们也可以看到apk格式实际就是zip压缩)

     

           shareduid:           列出共享uid的package

                  PMS getPackagesForUid(UID)去找到uid=UID的package

     

     

    Provider:             主要的函数体执行在commonprovider.py

           columns:       列出provider的列名

             contentResolver去利用uri得到ContentProviderClient,client去负责query后直接getColumnNames

     

           delete:          删除provider中符合参数的行

             同上,ContentProviderClient去执行delete操作       

     

           download:    下载provider文件

            首先getContentResolver()得到contentResolver,再利用uri得到

    ContentProviderClient①,然后用client去读取provider并写到本地文件;若①失败,直接openInputStream(URI)来读取provider。

     

           finduri:         列出package中的content uri

            PMS get packageInfo,跟info命令没区别啊,但它只输出provider authority

     

           info:              列出package中的详细信息

             PMS get到packageInfo信息;注意不加-u参数输出的是exproted的provider;4.2之前provider默认是exproted。

     

           insert:           在provider插入数据;同delete操作

            

           query:           在provider查询;同delete操作


           read:             从provider中读数据

    与download命令相同,少了写数据到本地文件的操作,直接输出


           update:         更新provider的数据;同delete操作
           在provider中,主要是利用contentResolver去操作。

     

           我们看到上述模块用到功能都是PMS来完成的,实际代码:

    getContext().getPackageManager().getPackageInfo()èApplicationPackageManager.getPackageInfo():

         public PackageInfo getPackageInfo(String packageName, int flags)

    104            throws NameNotFoundException {

    105        try {

    106            PackageInfo pi = mPM.getPackageInfo(packageName, flags, mContext.getUserId());

    107            if (pi != null) {

    108                return pi;

    109            }

    110        } catch (RemoteException e) {

    111            throw new RuntimeException("Package manager has died", e);

    112        }

    114        throw new NameNotFoundException(packageName);

    115    }

           我们看到getPackageInfo是调用mPM.getPackageInfo来完成操作的,而mPM是PackageManagerService在applicationPackageManager的binder代理。故最终的操作还是由PMS来执行,PMS管理package的所有信息。那PMS是根据什么来获取信息呢,manifest(安装apk时,会解析此文件并将info保存在/data/system/package.xml)?如果不是动态的话attackSurface是否会有遗漏(动态注册的broadcast)

     

           当drozer进行复杂或者需要与app交互的操作时,会直接加载特定功能的类到VM来达到交互:下面这个问题待解答

    self.loadClass("common/XmlAssetReader.apk", "XmlAssetReader")

     

    分析上述drozer模块我们发现,其实drozer做的是找到attacSurface然后人工组合特定intent(这个很关键)。但要达到attack的目的,需要我们根据app源码来构造特定intent,这需要我们掌握apk的反汇编和反编译工具并熟悉smail及java;IDE工具:Apk改之理、androidKiller、JEB

     

    至于app的attackSurface,请参考下图,但包含intent-filter的组件默认是exproted(安全性:保护等级-签名相同;权限要求:特定自己申明的权限(权限也是有等级:normal、dangerous、system、signature))。


    官方文档翻译:http://yunpan.cn/ccvBxd5XpQZ4P  访问密码 429e;不足之处还请见谅

     

    参考资料:

    1 the_mobile_hackers_handbook.pdf

     

     

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    【转】Intel Atom手机处理器“上窜下跳”
    神奇HVXC的MOS 分
    Skype 将支持 WebRTC 标准
    一篇文章算市值
    算法经典趣题三色旗
    Java基础(2)Java三大版本/体系
    一天一个 Linux 命令(27):mkfs 命令
    Java基础(1)Java特性及优势
    一天一个 Linux 命令(26):fdisk 命令
    关于Java中的整数类型值比较的疑问
  • 原文地址:https://www.cnblogs.com/vendanner/p/4784380.html
Copyright © 2011-2022 走看看