一例简单的frida反调试绕过
2022-8-19 17:1:49 Author: 雷石安全实验室(查看原文) 阅读量:34 收藏

最近在分析一款app时遇见了frida反调试,花了时间简单学习了一下,有不少收获,记录下学习的过程。 

frida是一个很强大的hook框架,用的人多了,自然而然就出现了很多检测方案,这次碰到的app就检测了frida,可以正常打开,但是当你用frida -f启动或者attach进程,不久后就会闪退。   

1.检测frida-server文件名  

2.检测27042默认端口  

3.检测D-Bus  

4.检测/proc/pid/maps映射文件  

5.检测/proc/pid/tast/tid/stat或/proc/pid/tast/tid/status    

6.双进程保护  

前两种可以通过修改frida-server文件名,改默认端口绕过。双进程可以通过-f spawn模式启动绕过。其他的需要去hook修改。  

先针对简单的几个可能检测的方式,我修改了文件名,改了端口,也尝试了spawn启动,均会在启动后不久闪退。  

这时考虑到其他几种检测。  

首先用frida去看看载入了哪些so,看看是哪里检测了,看了个寂寞。  

    function fridaProcess(){      Java.perform(function () {        var enumMoudle = Process.enumerateModules();        for (var i = 0; i < enumMoudle.length; i++){          console.log("", enumMoudle[i].name)        }      });    }
setImmediate(fridaProcess,0)

因为so载入的时候,底层最后open去打开的。  

所以再用frida去hook应用中的open函数,看看读取了哪些so或者文件,可以看到最后断在了/proc/self/maps。   

var pth = Module.findExportByName(null,"open");    Interceptor.attach(ptr(pth),{        onEnter:function(args){            this.filename = args[0];            console.log("",this.filename.readCString())            if (this.filename.readCString().indexOf(".so") != -1){                args[0] = ptr(0)
}
},onLeave:function(retval){ return retval; } })

这里当挂上frida后对应的maps文件中会出现re.frida.server之类的特征,这是在使用frida server的时候自动创建的,其中存放着frida的功能模块,可以在载入so的hook脚本输出中能看到最后也是断在frida-agent.so。  

这里要绕过这个检测,我是通过备份一个正常启动时的maps文件(这里前面也讲到app不使用frida是能正常启动不闪退的)。 

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/data/com.app/maps";  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)

然后就可以继续调试了。 

这只是一个简单的例子,但是确实在这个bypass的过程中学到了东西,只要花时间是去分析,总能找到对应的突破口。   

往期回顾

01
渗透测试之只有一个登录框 
02

 记一次APP登录爆破
03
从代码层理解android的重定向漏洞

雷石安全实验室

商务咨询:

0571-87031601

商务邮箱:

[email protected]

联系地址:

浙江省杭州市市民街98号尊宝大厦金尊3301


文章来源: http://mp.weixin.qq.com/s?__biz=MzI5MDE0MjQ1NQ==&mid=2247515959&idx=1&sn=34e6afbaeffba8a91b095f7fdb9fd5f6&chksm=ec269eafdb5117b90420f4ac45431a2b81af13908f0f2f8dc3cca89bd6f078d90d9e4382f1c0#rd
如有侵权请联系:admin#unsafe.sh