`
ydbc
  • 浏览: 718706 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

Android操作系统安全

 
阅读更多

Android在迅猛发展的同时,其安全问题一直没有引起足够的重视,但在2010年6月研究人员发布Android平台的KernelRootkit以来,Android平台的安全问题引来了越来越多的关注,而同时,Android平台的恶意软件也开始流行起来。[3]

根据以上的Android系统架构分析,可以发现在三个层面可能存在恶意软件。分别是处于最高位置的应用层(Applications),函数库层(Libraries)之上,还有Android的Linux内核中。根据编程语言的不同,也可以叫做Java层,NativeC层,Linux Kernel层[4]

Native C层安全

虽然Android平台的软件要用Java开发,但是也并非全部如此。Android底层必定是一个Linux[11],在Linux内核之上又有大量的标准C函数库,在理论上,是可以编译出可以直接依靠这些函数库运行的C语言程序的。事实上,在Android系统自身中已经存在很多这样的程序,在Android的超级终端中,我们可以像在Linux的超级终端中一样调用一些常用的命令,比如ls,ps,cd,free,等等,这样的命令在Android中有几十个。其实这些命令都存在于“/system/bin”或“/system/xbin”下,而且都是C语言编写的程序。

早在Android NDK发布以前,研究人员就已经可以利用Android的源码中的资源(.h文件等)和Linux下的编译工具(gcc,交叉编译器等)编译C语言程序,并且可以像执行这些命令一样执行这些程序,我们可以称之为Native C。

AndroidNDK的发布,使得Native C程序的开发更加方便。AndroidNDK于

2009年7月发布第一个版本(Release1),目前已经发布到第五个版本(Release5)。

Android NDK使得普通的应用程序(.apk)中可以使用库文件(.so),这些库文件用C语言编写,并且在Java语言的代码中,可以通过JNI调用C语言代码。在这些C语言代码中,可以调用一些运行时函数(printf,memcpy等等),以及一些Linux中存在的函数(ptrace,waite等等),甚至是一些Android的核心API。再加之C语言对内存有绝对的控制权限,使得一些安全技术可以在这里大展拳脚,尤其是HOOK技术,这对恶意软件还是安全软件来说,都是一件好事。Android NDK的发布不仅有利于安全编程,对于其他领域的软件,尤其是需要较高效率计算,不适宜在较高层的Java语言编写的软件,比如拥有自己核心的浏览器(火狐,Opera等)和大型游戏,NativeC都给他们带来的好消息。

在2011年三月,一个叫LBE的团队发布了一款基于主动防御的隐私安全软件,LBE隐私卫士。这是第一款正式发布的Android平台的主动防御安全软件。LBE小组曾经将Android的移植到魅族M8(原来运行Mymobile)上,其核心成员常年致力于ARM平台Linux的研究,有很扎实的Linux功底。这款LBE隐私卫士就是用Android NDK开发的,其中用到了APIHOOK技术。

关于HOOK技术:HOOK技术无论对于安全软件还是恶意软件都是十分关键的一项技术,其本质就是劫持函数调用(在Windows中,HOOK也可以理解为窗口消息劫持),不管是Windows 还是Linux平添,HOOK在安全软件中的应用都十分广泛。

NativeC层面的程序虽然是C语言,但是依然处于Android用户态,即Linux的用户态。因此NativeC层上只能对某一进程(当然也可以是所有进程)进行API HOOK。不管是Windows还是Linux,其用户态的每个进程都拥有独立的进程空间,要对其进行API HOOK必须进入其进程空间才能修改这个进程的代码,即必须有能力修改目标进程的内存。对于这一方面Windows和Linux采用了不同的方法。Windows没有API可以修改某一进程的内存,因此一般采用Dll注入(或称远程线程注入)的方法。而Linux则常用ptrace与plt实现API HOOK。

在Windows中,APIHOOK的一般流程为:

① OpenProcess,打开目标进程。

② 获取LoadLibrary的函数地址,该函数地址一般在每个进程空间内都是相同的。

③ VirtualAllocEx,在打开的进程中申请内存。

④ WriteProcessMemory,在申请的内存中写入要注入的Dll路径字符串(此处也可以直接写入需要的代码,然后CreateRemoteThread执行来进行HOOK,此方法更加隐蔽,但更加复杂困难)。

⑤ CreateRemoteThread,启动远程线程,入口地址为LoadLibrary的函数地址,参数为要注入的Dll路径字符串(也就是远程申请的内存地址)。

⑥ 注入的Dll中代码会在自身被加载时开始运行。

⑦ 找到要HOOK的API所在的函数库基址。

⑧ 找到要HOOK的API再其函数库中的导出表所在位置。

⑨ 修改导出表,指向自己的函数入口地址。

⑩ 在自己的函数中调用原API。

当然在注入成功后也可以直接修改API的开头几个字节,jmp到自己的函数,然后再jmp回去,这种方法称为InLineHOOK,InLine HOOK更不容易被检测到,但是稳定性,通用性都较差,而且操作更加复杂。

在Linux中,APIHOOK进入目标进程空间时使用了Linux中的ptrace函数[9]。ptrace函数原本是用于调试程序用的,功能十分强大,不仅可以绑定某一进程(PTRACE_ATTACH),而且可以任意修改目标进程的内存空间(PTRACE_PEEKDATA,读内存。PTRACE_POKEDATA,写内存),甚至是寄存器(PTRACE_SETREGS,PTRACE_GETREGS)。其一般过程为:

① PTRACE_ATTACH,绑定目标进程。

② PTRACE_GETREGS,获取目标进程寄存器状态,并保存。

③ PTRACE_PEEKDATA与PTRACE_POKEDATA配合,保存原代码,写入要注入的代码到当前运行位置。

④ PTRACE_SETREGS,恢复寄存器状态,并继续执行,这是注入的代码开始在目标进程内执行,注入代码完成HOOK,过程与Windows下相似。

⑤ 在HOOK完成后,注入的代码执行int3被ptrace捕获,目标进程再次暂停执行。

⑥ PTRACE_GETREGS,再次保存寄存器。

⑦ PTRACE_PEEKDATA与PTRACE_POKEDATA配合还原代码。

⑧ PTRACE_SETREGS,恢复寄存器,目标进程继续执行。

⑨ PTRACE_DETACH,撤销绑定目标进程。

Linux下还可以LD_PRELOAD来注入代码[7]从而进行HOOK。

在前面提到的Native C级安全软件LBE隐私卫士出现后我对其实现方法进行了研究,发现了类似的方法。LBE隐私卫士中有两个用NativeC编写的函数库,分别为libloader.so和libservice.so。其中libloader.so负责将libservice.so注入到系统进程,libservice.so在注入后负责HOOK相关的API,从而实现对这些API的监控功能。在libloader.so的导出函数中可以看到以下三个函数:

\" src= 由于在root权限等方面所遇到的问题,目前Android Linux Kernel级的安全软件尚属空白

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics