首先声明,我是主做android安全的,对别的行业也有涉略,我想将一些问题简单化,然后找出解决他的方法,这是一篇我目前做安全中遇到的大多数问题,各个平台都通用,我整理了一下,我并没有直接给出某个问题的答案,但是我觉得我写了问题解决的思路。
应用安全甚至是软件含义行业已经很多年了,各个平台,各种工具,各种技术都不断的迭代,其实主要目的在防逆向。但是逆向从理论上来说其实是一个100%的问题,任何一个软件只要有足够的时间和精力都会被破解,在这种前提之下,安全的核心宗旨其实就是提高逆向成本,但是同时安全又是为产品服务的,要兼顾产品的需求。所以软件安全的核心宗旨就是在满足产品需求的情况下,尽可能的提高逆向成本。
一个平台应用安全的发展,完全是逆向工程催生的,安全产品的出现,也说明逆向工程已成规模,在这个平台已经有了一套逆向的工具和方法论,可以完成平台系统逆向基础工作,专注于对应用本身进行逆向。
android逆向
apktool 反编译apk文件,smail可以单独反编译dex,so文件通过ida分析, java调试可以使用android studio 的smail插件借助as调试模块进行调试,so调试使用ida,gdb,lldb都可以
linux 和win 逆向
ida、od、ghidra的工具对文件进行分析,同时可以动态调试
unity 逆向
这个我很久不搞了,不知道是否有新方案了,当时有c#反编译工具的,后来c#语言变成了il2cpp,调试的时候我都是用的本地调试工具,不清楚c#是否有专有调试工具
前端js
执行文件为明文,不需要反编译,调试需要借助浏览器调试工具
通过以上这些不同的平台的逆向方法,我们发现已经为我们提供了平台逆向相应的工具,我们只需要对应用进行逆向就可以了。
应用是什么
应用对我们来说可能就是一个文件安装到系统中运行,但是对于这个系统来说它是“插件”,我们可以把它叫做系统功能扩展插件。这个文件就是插入到操作系统中的,依赖于操作系统提供的接口,实现这个应用的内容所编写的功能。
为什么应用可以运行
因为应用经过了这个系统平台的特定的编译器,或者说编译集成平台的编译,编译器是一种跟系统约定俗成的转化器,可以将我们人类写的代码转变成应用,系统平台和编译器是一一对应的关系。
应用逆向方法和工具的本质
应用逆向就是一个和开发完全反向的过程,在开发中,我们是需要依赖于编译器来对我们写的代码进行转化的,所以逆向也是这样需要反编译工具将代码反向转化回去。而这种反编译工具,就是逆向的基础工具。开发程序一般都比较简单,这是因为很多平台都有集成式ide,直接能编译出来就可以,但是逆向往往工序复杂,这是因为逆向工具完成度不够,基本没有集成ide那样,逆向工具很多都是靠开源项目,而开发ide,是有大公司来做的,即使是后续工具完善了,也往往存在缺陷需要我们通过方法手工避雷。
在做逆向的时候,我们很少去考虑逆向工具的原理,就像开发的时候,我们不用考虑编译器,IDE的原理一样,这属于完全抽离出来的透明技术层。但是逆向跟开发不同的是,开发的IDE工具是由官方、社区、公司这些比较大的组织提供的,比较完善,有bug修复速度往往也很快,而且他们对于这些问题的解决方式和方法更加趋于正确,能够多方协调。逆向工具,往往都是由开源项目发起的,很多时候是某个技术大佬来做的,工具本身可能有bug,对于逆向问题的解决方式可能是片面的,更新不及时,做不到多技术融合的IDE平台等等很多问题。所以对于逆向,这些问题可能都需要靠我们自身的能力来解决。
应用文件格式解析
应用文件,是应用的载体,开发时,编译相关工具会将代码编译组合成某种格式,来存储应用相关信息,包括代码,变量、配置文件等等。andorid的apk文件,linux elf文件,windows pe文件,davilk dex文件,这些都有一定的格式,是需要进行格式解析的,前端js,php,这些脚本语言,文本格式,这些其实也是有格式的,但是不用解析的原因是系统自带了文本格式解析工具。文件格式解析是逆向工程静态分析的基础。apktool,其中包括了解析axml,dex等文件格式解析,readelf,解析elf文件格式,ida 支持解析多种文件格式。
代码还原(反编译、反汇编,还原成源码)
对于文件格式解析出来数据内容,进行解析还原成开发源码,比如反汇编,静态编译型语言,存储的都是字节码,这是需要先进行反编译,然后进行反汇编,比如c,c++ java 编译的程序,都是编译成字节码,通过字节码来运行,逆向的时候,需要先对字节码进行解析成汇编,然后通过汇编语言进行反汇编,还原成源码。反编译,这部分比较简单,对照手册和架构相关的文档说明,是可以完美还原的。反汇编,是专门针对一些有bytecode的中间代码,这类的应用,将这些bytecode或者中间代码,转变成开发代码,这种代码还原技术现在其实不算很成熟,高级语言,或者是经过编译器编译的代码进行还原效果还是不错的,但是经过人工编写,或者主动对抗的代码还原程度还是不高的。原因是编译器编译出来的代码符合一定的规则,不同工具编译出来的有可能规则不一样,像ida这种反编译工具,反编译的时候是可以选中编译器的,他应该是针对这些不同的编译器有不同的规则,或者说研究过不同编译编译出来的代码的特种,指定策略进行还原。
应用平台安全架构突破
为了保证应用的安全性,应用平台一般会有一些系统安全措施来保护应用不被攻击,而想要侵入应用进程,进行动态观测,读取修改内容,是需要绕过的,比如android ios签名问题,ios调试是需要修改配置的否则无法ptrace,android上java要么改系统rmo,要么改配置才能进行调试。还有比如selinux,mac这些安全机制,而且这种安全机制随着系统的更新,也会不断的更新的,需要不断兼容学习。
应用系统底层运行环境对接
一个应用的逆向,不只有文件分析部分,还需要应用动态执行的时候可以对他进行观察,而且,颗粒的越细越好。这方面,最好的就是调试系统,其次就是进程注入,调试系统很多平台会提供api,或者工具,也可以使用系统提供的api自己写,效果好,容易被检测和对抗。进程注入方法多种多样,因平台而已,不容易被检测,但是颗粒度不够细,比如不能单步,只能读写。
应用运行以后,会通过加载系统将文件加载到内存中,有可能不改变内存分布,也有可能改变内存分布,在前面我们写道要对应用进程进行观测,所以我们需要了解应用加载到内存中的分布,解析和使用,ida,附加的进程以后,会解析加载的所有so,可以查看他们的符号,和函数,查看内存分开,这就是进行了解析。
模块、库管理系统,不算是基础分析所需要的,但是提供给这个功能,是可以加速分析的,你可以快速的知道你的应用所使用的有那些库,然后你可以去对照着寻找开源项目,或者系统库说明,加快分析速度。android native 的solist,java层的类加载器等等,我们可以通过某些特有api或者特有函数,去对接库管理系统。
运行系统架构体系
cpu代码执行,android davlik指令执行,在我们分析代码的时候都会遇到,这就要求对指令熟悉,同时还有架构体系,比如arm 三级流水线,在某些特殊指令的时候,如果不了解,代码往哪里跑都不知道,还有一些特殊指令,不是常规的指令,ida前几个版本的时候,arm 有it,没法单步,就是因为不支持这个指令。
模块、库管理系统
模块、库管理系统,不算是基础分析所需要的,但是提供给这个功能,是可以加速分析的,你可以快速的知道你的应用所使用的有那些库,然后你可以去对照着寻找开源项目,或者系统库说明,加快分析速度。android native 的solist,java层的类加载器等等,我们可以通过某些特有api或者特有函数,去对接库管理系统。
应用文件加载系统
应用运行以后,会通过加载系统将文件加载到内存中,有可能不改变内存分布,也有可能改变内存分布,在前面我们写道要对应用进程进行观测,所以我们需要了解应用加载到内存中的分布,解析和使用,ida,附加的进程以后,会解析加载的所有so,可以查看他们的符号,和函数,查看内存分开,这就是进行了解析。
应用动态运行观测
一个应用的逆向,不只有文件分析部分,还需要应用动态执行的时候可以对他进行观察,而且,颗粒的越细越好。这方面,最好的就是调试系统,其次就是进程注入,调试系统很多平台会提供api,或者工具,也可以使用系统提供的api自己写,效果好,容易被检测和对抗。进程注入方法多种多样,因平台而已,不容易被检测,但是颗粒度不够细,比如不能单步,只能读写。
应用语言底层运行环境对接
对接开发语言所运行的环境,而不是前面提到的运行系统的底层系统语言对应的环境。比如逆向so,目标语言系统对应的是汇编,而我们可以用c语言环境对接,使用c中的变量,函数,这个可能看不出有多大改变,那就更进一步,用c++对接,有什么区别那,比如,c++使用的对象,我们hook或者某种方式,获取到这个c++的对象的地址,然后导出它对应函数成员的函数符号,用这个函数符号,和c++对象,就可以完成c++中的调用某个对象的成员函数。再举个例子unity游戏,经过保护以后,unity游戏全部变成了il2cpp,他的代码全部变成了native,但是我想在想用il2cpp编一个文件注入进去,然后调用它,这是可能的吗,说实话我目前没试过,但是这在理论上是可能的,只不过需要极为严格的环境对接,有个项目叫frida-il2cpp-bridge,他通过frida将unity的对象,类,这些从内存中解析从来,然后就可以直接通过frida调用它,这个也是个经典的例子。
应用安全保护
加固出现的主要原因,是因为有了静态应用文件分析工具,逆向分析已成规模,所以加固公司就可以宣扬应用文件的已经不安全。应用加固目前来看,主要有两个方面:文件格式加固,文件内容加固。
文件格式加固
针对于静态存储的文件,即使在运行以后这类文件也不会改变,只是加载到内存中解析,包括zip加密(zip打不开,需要密码),axml加密,但是这类技术往往不能够长时间奏效,主打时间差,利用逆向解析工具中的bug和对于文件解析中的漏洞来进行加固,阻止逆向程序工作。这类文件没必要保护文件内容,会被内存dump,因为文件内容是静态,dump一次即可,成本太高。
文件内容加固
当应用文件被逆向无法阻止的时候,于是就有了对文件的内容进行加固,就像http协议,通讯一定会被拦截,所有才有了https对于通讯内容加密。目前这种文件内容加固需要同时针对静态分析和动态dump,在静态分析的时候,让他无法找到正确的文件内容,但是动态运行以后这部分内容始终还是要解密出来的,要加载要运行,很多dump工具都是这个原理,所以对于动态运行的对抗方式就是在运行起来以后,自定义加载方式,不依赖与系统api,让dump无处下手,vmp,添加代码转化器,提供逆向难度,想要找到真正的代码,必须要先逆向vmp框架,代码混淆,即使找到了真正的文件内容,也难以理解代码的逻辑,无法使用。
对于经过加固的应用,脱壳的主要方法就是运行时内存dump(静态还原也是可能的,不过难度太高,基本不用)。还有例如风控,设备指纹,用户画像等等,也是在运行时动态计算,而逆向工程是可以对于应用或者系统的安全进行突破的,所以安全公司针对这方面进行了防护。
特征检测
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2024-1-12 14:10
被Thehepta编辑
,原因: 看雪的编辑和github 的md不一样导致内存缺失