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

     

     

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

  • 相关阅读:
    Android自定义之仿360Root大师水纹效果
    Android之TextView的Span样式源码剖析
    Android之TextView的样式类Span的使用详解
    随着ScrollView的滑动,渐渐的执行动画View
    仿微信主界面导航栏图标字体颜色的变化
    android自定义之 5.0 风格progressBar
    Android性能优化之内存篇
    Android性能优化之运算篇
    How to install Zabbix5.0 LTS version with Yum on the CentOS 7.8 system?
    How to install Zabbix4.0 LTS version with Yum on the Oracle Linux 7.3 system?
  • 原文地址:https://www.cnblogs.com/vendanner/p/4784380.html
Copyright © 2011-2022 走看看