天创培训:您身边的信息安全培训专家!
技术中心
Android APP安全评估工具Drozer PC端重要代码解析

Android APP安全评估工具Drozer PC端重要代码解析

探讨一下drozer PC端代码解析,主要是为了写自己的工具而去研究其代码,还是抛砖引玉。
它的反射框架做的确实不错。估计很多人在为它写插件,superFuzz ,intentFuzz、BinderFuzz、AIDLFUZZ等等。
0×01 正题
在drozer中有一个重要的东西就是pydiesel,一看这个东西就想起来diesel,上网搜索一下原来是一个如下图

 
顾名思义,作者想搞一个I/O框架,将agent的内容映射到本地。本地用Python操作就非常方便了。
说了这么多先上重点。看图说话。协议就是protobuf_pb2


一看pydiesel最重要了,其中的reflector.py是反射的纽带。先上代码
 

一个一个解释,init自然不必说,获取会话session
def construct(self, robj,*args): 构造一个类的新实例,可选参数,返回的对象实例。原来是一个new 对象。
def delete(self, robj): 删除存储在远程对象存储的对象。
def deleteAll(self):顾名思义删除所有的。
def getProperty(self,robj, property_name): 获取的对象的属性。
def invoke(self, robj,method, *args):一看就知道是调用了。
def resolve(self, class_name):说明这个类可用,可被初始化。
def setProperty(self,robj, property_name, value): 设置的对象的属性。
def sendAndReceive(self,message_or_factory):充当通讯桥梁。
反射的类型都在这儿定义了

 
reflected_array 列表
reflected_binary 指的二进制,一般用base64编码
reflected_null  null
reflected_object 对象
reflected_primitive基本数据类型(bool,char,int等)
reflected_string 字符串类型
0×02实例解析
第一实例:
先拿base.py开刀,

base.py是自定义模块的一个基类,也可说是一个接口,模块自己去实现就好了。
最不可缺的就是

session.reflector反射,后面会用到。一个典型的例子就是:

 
getContext是agent的一个上下文。可以干好多事呢。比喻说获取所有的安装程序包。
就是通过self.reflector.resolve(class_name)实现的。
看到self.klass(‘com.mwr.dz.Agent’).getContext(),可以断定,这个东西可以直接调用java的方法了。太牛逼了。
第二例子:datetime.py模块

 
在直接new一个对象,完了还可以用setToNow(),time.format2445()方法,这些方法只有JAVA内可以用呀。
第三个例子:最相对于反射框架第二牛的就是classload,多少个木马后门都是用了这个东西,大部分黑客心里清楚的很呀。
工具中有classload用来做工具也是不错的,动态的换刀头嘛。
先上代码。

下面圈红就是先准备编译java文件为apk文件所需的环境,
条件如下:Android_path=  android.jar的路径
dx_path=dx.bat的路径
javac_path= javac.exe的路径
先javac.exe 将java文件xxx.java 编译成class文件
在from pydiesel.reflectionimport utils 有两个文件

 

先获取代码文件在

先判断是java文件,还是编译好的apk文件,若是java文件就需要编译成apk来用。

 
进入编译环节了。跟进去。
就有2次命令执行

 
第一个是 javac -cp android.jarxxx.java 生成了class文件
第二波是 dx.bat –dex –outputxxx.apk 生成apk文件就完了。
 

上述代码中俨然是用反射生成file对象实例apk文件(其实只是一个dex文件的jar)
然后通过self.construct(“java.io.FileOutputStream”,file_path) 生成FileOutputStream对象流
最好用上了关键东西self.construct(‘dalvik.system.DexClassLoader’,file_path, self.cache_path, None, self.system_class_loader)
等价于DexClassLoader (apkPath,cache_path, classname)
就完了
调用可以看一个例子
shell.py中

 
看看java代码
有一个静态函数

 
直接调用多方便呀。
0×03总结
从上面反射的例子可以看出,这完全就是一个虚拟化的操作。将java的反射映射到Python。还可以用Java的方法。
例如:攻击已注册的系统服务
通过adb shell service list可以查看在context manager(或servicemanager)中注册的系统服务名称和IBinder接口。

获取了空间命名和服务名,
轻松获取Stub Proxy这些特征,便可以用反射进行fuzz操作。