阅读:2812回复:0
Frida-跨平台注入工具基础篇
◆0 功能介绍
官方主页 github Inject JavaScript to explore native apps on Windows, Mac, Linux, iOS and Android. [*]Hooking Functions [*]Modifying Function Arguments [*]Calling Functions [*]Sending messages from a target process [*]Handling runtime errors from JavaScript [*]Receiving messages in a target process [*]Blocking receives in the target process [*].... 优势:结合python和JavaScript开发更快捷. ◆1 Setting up your PC python环境+setuptools #!bashsudo easy_install frida可选:源码编译 #!bash$ git clone git://github.com/frida/frida.git$ cd frida$ make◆2 Testing your installation 创建一个进程用于注入: #!bash$ cat新建注入脚本example.py: #!pythonimport fridasession = frida.attach("cat")print([x.name for x in session.enumerate_modules()])linux环境下需要运行如下命令: #!bash$ sudo sysctl kernel.yama.ptrace_scope=0用于开启非子进程的ptracing. 运行frida脚本,观察: #!bash$ python example.py输出结果类似如下,代码环境正常安装成功: [u'cat', …, u'ld-2.15.so']◆3 Setting up your Android device 首先下载android版frida-server: #!bash$ curl -O http://build.frida.re/frida/android/arm/bin/frida-server$ chmod +x frida-server下一步部署到android设备上: #!bash$ adb push frida-server /data/local/tmp/◆4 Spin up Frida 设备上运行frida-server: #!bash$ adb shellroot@android:/ # chmod 700 frida-server$ adb shellroot@android:/ # /data/local/tmp/frida-server -t 0 (注意在root下运行)电脑上运行adb forward tcp转发: #!bashadb forward tcp:27042 tcp:27042adb forward tcp:27043 tcp:2704327042端口用于与frida-server通信,之后的每个端口对应每个注入的进程. 运行如下命令验证是否成功安装: #!bash$ frida-ps -R正常情况应该输出进程列表如下: PID NAME 1590 com.facebook.katana13194 com.facebook.katana:providers12326 com.facebook.orca13282 com.twitter.android…◆5 Tracing open() calls in Chrome 设备上打开chrome浏览器然后在pc运行如下命令: #!bash$ frida-trace -R -i open com.android.chromeUploading data...open: Auto-generated handler …/linker/open.jsopen: Auto-generated handler …/libc.so/open.jsStarted tracing 2 functions.Press ENTER to stop.开始使用chrome app然后会发现open()调用输出如下: 1392 ms open()1403 ms open()1420 ms open()现在可以实时编辑的上述JS代码来调用你的Android应用 ◆6 Building your own tools frida提供的几个工具frida-trace, frida-repl...绝逼非常有用,建议阅读Functions 和 Messages章节来了解Frida APIs, 首先,使用frida的API attach上需要注入的app #!pythonsession = frida.get_remote_device().attach("com.mahh.secretsafe")session对象允许你获取信息,同时也可以操作目标进程.比如,可以调用enumerate_modules()方法来获取进程中加载模块的host信息. #!python>>> print session.enumerate_modules()[Module(name="app_process", base_address=0x40096000, size=8192, path="/system/bin/app_process"), Module(name="linker", base_address=0x4009a000, size=61440, path="/system/bin/linker"), Module(name="libcutils.so", base_address=0x400b0000, size=36864, path="/system/lib/libcutils.so"), Module(name="liblog.so", base_address=0x400bb000, size=12288, path="/system/lib/liblog.so"), Module(name="libc.so", base_address=0x400c0000, size=53248, path="/system/lib/libc.so"), Module(name="libstdc++.so", base_address=0x4011b000, size=4096, path="/system/lib/libstdc++.so"), Module(name="libm.so", base_address=0x4011e000, size=98304, path="/system/lib/libm.so")然后使用Javascript API,通过session的create_script()方法放入JavaScript代码块.JavaScript API可以用来插桩目标app的类.在这个API中有些针对android的例子,下面是一些简单的案例: 取得一个类的js封装: #!pythonDalvik.perform(function () { var MyClass = Dalvik.use("com.mdsec.MyClass");});如果类的构造方法有一个String对象的参数,应该用如下方式创建类的实例: #!javascriptvar MyClass = Dalvik.use("com.mdsec.MyClass");var MyClassInstance = MyClass.$new(“MySecretString”);只需要加上对应的参数就可以调用刚才新建实例的方法.例如,调用MyClass类的MyMethod方法: #!javascriptvar result = MyClassInstance.MyMethod();如果想替换MyMethod方法的实现来return false,使用如下代码: #!javascriptMyClass.MyMethod.implementation = function(){ return false;};Android Context(上下文)用于获取对应app相关信息以及其运行环境.所以其被广泛用于app中,需要找一种方法来访问他.获取Android Context如下代码非常有效: #!javascriptvar currentApplication = Dalvik.use("android.app.ActivityThread").currentApplication();var context = currentApplication.getApplicationContext();接下来需要用到上文中提到的create_script()方法用于注册这段js代码到app session中. #!pythonscript = session.create_script(jscode)为了接收从Python session中JavaScript代码返回的数据,还需要注册一个message handler.注册一个message handler先要创建方法: #!pythondef on_message(message, data):print message然后通过调用on()方法注册event handler: #!pythonscript.on('message', on_message)可以通过JS方法send()给message handler发送消息.例如,使用如下代码讲Context对象发送给Python客户端: #!pythonDalvik.perform(function () { var currentApplication = Dalvik.use("android.app.ActivityThread").currentApplication(); var context = currentApplication.getApplicationContext(); send(context);});结果会返回app的context对象的地址: {u'type': u'send', u'payload': {u'$handle': u'0x1d50079a', u'$classHandle': u'0x1d5007e6', u'$weakRef': 20}}现在已经掌握frida的基础知识,现在可以实战演练如何破解LolliPin锁屏库.我们创建一个使用LolliPin的app截图如下: 图片:2015041211275631118.png PIN码生效后,可以使用插桩暴力破击.要达到这个目的首先要了解pin码验证是如何实现的.AppLockImpl类中验证方法如下: 图片:2015041211275631118.png 现在咱们忽略LolliPin的其他漏洞,就搞PIN码的暴露破解,这是客户端认证通过都会受到的分析. 可以创建一个AppLockImpl的实例,但是为了节约内存我们直接调用已有的.分析发现AppLockImpl被调用在LockManager的getAppLock()中,这个就仅仅返回了AppLock对象.而AppLock是抽象类AppLockImpl的具现. 图片:2015041211275631118.png LockManager有一个帮助方法用于返回自己的实例. 图片:2015041211275631118.png 结合上面的分析,咱们可以通过LockManager.getInstance()得到LockManager的实例,再调用getAppLock()得到AppLock.最后就可以调用AppLock的 checkPasscode()方法了. #!javascriptvar LockManager = Dalvik.use("com.github.orangegangsters.lollipin.lib.managers.LockManager");var LockManagerInstance = LockManager.getInstance();var AppLock = LockManagerInstance.getAppLock();通过for循环调用checkPasscode()来达到暴力破解的目的: #!javascriptfor(var i=1230; i |
|