iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android逆向——过frida检测+so层算法逆向
  • 459
分享到

Android逆向——过frida检测+so层算法逆向

网络 2023-09-02 08:09:07 459人浏览 八月长安
摘要

0x01 过frida检测 frida可以说是逆向里面很受欢迎的工具了,你可以在运行的时候得到几乎你想要的所有东西,函数地址、内存数据、java实例,根据我们的需要去修改程序的运行逻辑等等,但是太流行也不好,迎来了各种检测。 pt

0x01 过frida检测

frida可以说是逆向里面很受欢迎的工具了,你可以在运行的时候得到几乎你想要的所有东西,函数地址、内存数据、java实例,根据我们的需要去修改程序的运行逻辑等等,但是太流行也不好,迎来了各种检测。

  • ptrace占坑、进程名检测、端口检测。(这绕过太简单了)
  • D-Bus通信协议的检测。
  • maps、fd检测。
  • App中线程名的检测。

直接拿出App,看看他到底怎么检测的。节省时间,直接用hluda-server,修改一下运行端口,以spawn方式注入frida。(hluda-server的好处在于,他所生成的各种so库名字,去掉了frida等特征字段,可以很好的绕过maps和fd的检测。)

直接给我干掉了??猜测有没有可能是D-Bus通信协议的检测,App向每一个端口都发送了D-Bus认证消息,那肯定会利用strcmp( )或者strstr( )函数进行检测回复的消息。那么就hook一下看看。

同样的方法hook一下strstr函数

 不仅没有任何输出,app还是直接给我干掉了。

思考一下,不是D-Bus协议检测、不是ptrace占坑、进程名检测、端口检测、fd和maps检测利用hluda绕过了,emm,等等不一定,跟师傅讨论一下,又搜了几个文章,发现有的app检测非常恶心,只要是maps和fd中存在/data/local/tmp/,甚至只有tmp的字段,app就给kill掉。因为这个目录对于安卓逆向工作来说,是一个比较敏感的目录。hluda-server和frida-server都会在/data/local/tmp/目录下生成一个包含frida所需要的so库等文件。所以当app一旦发现了加载了/data/local/tmp下的任何东西,直接就挂掉。

那怎么办呢?让该文件夹生成到别的目录下,有一个-d参数,试了好多次,有些问题,一直都是在tmp目录下递归生成。所以便想到,你既然去检测maps,肯定是要读取里面的内容,然后寻找是否有该目录的字段咯。

那就直接hook open函数,将原程序的maps文件中一切带有tmp的行都过滤掉,剩余的内容输出到另一个文件中,最后修改open的返回值,指向新生成的文件。完美!

function main() {    const openPtr = Module.getExportByName('libc.so', 'open');    const open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);    var readPtr = Module.findExportByName("libc.so", "read");    var read = new NativeFunction(readPtr, 'int', ['int', 'pointer', "int"]);    var fakePath = "/data/datamaps";    var file = new File(fakePath, "w");    var buffer = Memory.alloc(512);    Interceptor.replace(openPtr, new NativeCallback(function (pathnameptr, flag) {        var pathname = Memory.readUtf8String(pathnameptr);        var realFd = open(pathnameptr, flag);        if (pathname.indexOf("maps") != 0) {            while (parseInt(read(realFd, buffer, 512)) !== 0) {                var oneLine = Memory.readCString(buffer);                if (oneLine.indexOf("tmp") === -1) {                    file.write(oneLine);                }            }            var filename = Memory.allocUtf8String(fakePath);            return open(filename, flag);        }        var fd = open(pathnameptr, flag);        return fd;    }, 'int', ['pointer', 'int']));}setImmediate(main)

 完美过掉!

0x02 SO层算法逆向

1、抓个包看看,里面都有啥东西?

登录的时候,用户名:123456789,密码:123456

根据字段名字的分析,重点关注的是sign字段(看着像是个hash散列),其次这个passWord应该是经过加密处理的。

 2、so算法逆向(passwrod参数)

既然是分析so层算法,具体的Java层的分析和定位就不浪费时间分析了。那么如何定位so文件和具体的函数呢。在Java层在和so层函数交互的时候,就是通过的JNI的机制,所以在so层函数加密数据之后,一定会把加密后的数据返回,通过JNIEnv下的NewStringUTF函数返回给Java层,所以hook一下这个函数,并且输出堆栈。

function hook_NewStringUTF(){    var artModule = Process.findModuleByName("libart.so");    var symbols = artModule.enumerateSymbols();    var newStringUTF = null;    for (let i = 0; i < symbols.length; i++) {        let symbol = symbols[i];        if(symbol.name.indexOf("NewStringUTF") != -1 && symbol.name.indexOf("Check") == -1){            console.log(symbol.name);            newStringUTF = symbol.address;        }            }    Interceptor.attach(newStringUTF, {        onEnter : function(args){            console.log(args[1].readCString());            console.log(Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n')        },onLeave : function(retval){        }    })}

 观看输出,尤其是堆栈信息,发现是libNativeHelper.so中的后面的是函数在文件中的偏移地址。

IDA反编译找到相应函数,反编译之后进行分析,怎么分析最快呢,当然是从你已经拥有的数据去反推未知的数据。(从后往前分析)

找到了NewStringUTF的调用,v19就是我们的FfQn1pwmgRY=,那么v19是怎么来的(猜测可能是base64,验证一下),找到上面的sub_1FEC,去里面看看。

看到这里面有一串字符,和base64很像。hook一下看看

输入

输出

难道上面的16进制数据,就是编码前的数据?经过验证之后,这个函数就是base64的编码函数,编码的数据以16进制形式传入。

那这个 15f427d69c268116 数据又是什么?继续向上找

进入这个函数一看,看不懂,不知道是干啥的太复杂了,hook看看。

这第一个参数不就是我们传入的密码么

第二个参数不就是刚才的16进制数据吗,其他参数看不懂了,猜测该函数应该是某种加密

而还有一个v22 = 0xEFCDAB9078563412LL;难道是某种密钥或者IV?

v23里面的数据很多,这是什么东西,跟踪v23的有关函数去看看

 进入函数里面查看,发现感觉有点眼熟,是DES加密?dest又是什么,dest是通过a3传过来的,经过hook之后,a3的数据是***************(程序的密钥,不方便展出)。

这个时候就有很多想法了,一个简单的数据,经过函数处理之后,出现了大量的内容,同时v23还是加密函数中的参数。难道是子密钥的生成??感觉很强烈,进入查看果然很像!

那这么一看v23就是子密钥咯,那v22很有可能就是IV向量了,去验证一下

验证是正确的(一定要注意字节序的问题)。

最终得出结论,将我们输入的密码,经过DES/CBC模式加密后,再经过base64编码就是password的值。

0x03 so算法逆向(sign参数)

根据最开始的hook  NewStringUTF,找到对应的函数位置。

不再一步步的分析了,直接找到特征

好像是MD5的初始化常量啊。

hook 

可以得到明文,然后对比一下数据包中

可以看到是 captcha + captchaId + dateline + deviceIdentifier + info + password + username + “ef2vx#sf*^FlklSD*9sdf(m$&qw%d7po”  拼接起来的数据。

这里的数据就是经过md5加密后的内容,验证一下。

 

 可以得到结论,sign的值就是将数据包中的

 captcha + captchaId + dateline + deviceIdentifier + info + password + username + “ef2vx#sf*^FlklSD*9sdf(m$&qw%d7po” 

拼接之后,在进行md5散列的结果。

至此,整个逆向结束。

来源地址:https://blog.csdn.net/weixin_43889136/article/details/127713563

--结束END--

本文标题: Android逆向——过frida检测+so层算法逆向

本文链接: https://www.lsjlt.com/news/390445.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作