freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

一例简单的frida反调试绕过
雷石安全实验室 2022-08-25 15:02:44 650437
所属地 浙江省

一例简单的frida反调试绕过

前言

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

抛出问题

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

常见frida检测

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)

1因为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;
    }
})

2

稍稍深入

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

这里要绕过这个检测,我是通过备份一个正常启动时的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)

4然后就可以继续调试了。

总结

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

# 移动安全
本文为 雷石安全实验室 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
雷石安全实验室 LV.6
这家伙太懒了,还未填写个人描述!
  • 88 文章数
  • 132 关注者
对用友NC“任意文件读取”漏洞的分析
2024-01-29
雷石|二进制漏洞之数组越界and缓冲区进行数据同步
2023-09-01
用友NC-ActionHandlerServlet反序列化漏洞分析
2023-08-18
文章目录