一. 何为共享库?
.so 文件在可执行程序运行之前就会预先加载,Linux 进程经常使用这些共享库。这种技术可以重写系统的库函数,只需要在预加载的链接库中重新定义相同名称的库函数,程序调用库函数时,重新定义的函数即会短路正常的库函数,这种技术可以用来重写系统中有漏洞的库函数,达到修复漏洞的目的。
ldd 命令可以对任何程序文件显示其共享库,如下面的:linux-vdso.so.1
1 | [root@test ~]# ldd /bin/date |
二. 共享库隐患
这种技术也可以被不怀好意的攻击者用来写rootkit,通过重写mkdir, mkdirat, chdir, fchdir, opendir, opendir64, fdopendir, readdir, readdir64等和系统文件,网络,进程相关的库函数来达到隐藏文件,进程的目的。相对于普通的用户空间rootkit而言,手段更加隐蔽,更加难以被发现,相对于内核模块rootkit来说,兼容性更好,编写难度更低,综合这两种优点,使得这类型rootkit逐年增多,难以查杀。
三. 动态库预加载型rootkit所用技术
- linux动态链接库预加载机制
在linux操作系统的动态链接库加载过程中,动态链接器会读取LD_PRELOAD环境变量的值和默认配置文件/etc/ld.so.preload的文件内容,并将读取到的动态链接库进行预加载,即使程序不依赖这些动态链接库,LD_PRELOAD环境变量和/etc/ld.so.preload配置文件中指定的动态链接库依然会被装载,它们的优先级比LD_LIBRARY_PATH环境变量所定义的链接库查找路径的文件优先级要高,所以能够提前于用户调用的动态库载入。
- 全局符号介入机制
全局符号介入指的是应用程序调用库函数时,调用的库函数如果在多个动态链接库中都存在,即存在同名函数,那么链接器只会保留第一个链接的函数,而忽略后面链接进来的函数,所以只要预加载的全局符号中有和后加载的普通共享库中全局符号重名,那么就会覆盖后装载的共享库以及目标文件里的全局符号。
- rootkit利用的技术点
因为动态链接库预加载机制和全局符号介入这两种系统机制,可以控制程序运行时的链接(Runtime linker),允许用户在程序运行前优先加载自定义的动态链接库,使得恶意动态链接库优先于正常动态链接库加载,根据全局符号介入的顺序原理来”短路”正常函数,执行攻击者定义的恶意函数。
从上图中我们可以看到3种利用方式:
- 将恶意动态链接库通过LD_PRELOAD环境变量进行加载
- 将恶意动态链接库通过/etc/ld.so.preload配置文件进行加载
- 修改动态链接器来实现恶意功能,例如修改动态链接器中默认的用于预加载的配置文件路径/etc/ld.so.preload为攻击者自定义路径,然后在里面写入要加载的恶意动态链接库,当然修改的姿势还有很多,如修改默认环境变量,直接将要hook的动态链接库写入到动态链接器当中。
四. 防御 - 动态链接库预加载型rootkit
1:利用LD_PRELOAD加载恶意动态链接库
检测—-如果LD_PRELOAD中有值,则将该文件上传到virustotal或微步在线等恶意软件检测平台检测该文件是否正常 或认为判断是否为恶意程序
1
2[root@test ~]# echo $LD_PRELOAD
/lib/evil.so清除
1
[root@test ~]# unset LD_PRELOAD
2. 利用/etc/ld.so.preload加载恶意动态链接库
将恶意动态链接库路径写入/etc/ld.so.preload(没有则创建)配置文件中,及时生效。且对应的恶意动态链接库文件被隐藏
1 | [root@test ~]# echo "/lib/evil.so" > /etc/ld.so.preload |
- 检测
因为恶意动态链接库一般都有隐藏/etc/ld.so.preload文件的功能,我们使用普通的ls,cat等命令无法读取对应配置文件的内容,此时我们可以使用静态编译的ls命令,cat命令(推荐使用busybox自带命令)来绕过预加载的恶意动态链接库。
如下图,通过使用普通的cat命令和busybox中的cat命令查看/etc/ld.so.preload文件内容对比,即可判断出是否有通过/etc/ld.so.preload配置文件加载的恶意动态链接库。
1 | [root@test ~]# cat /etc/ld.so.preload |
- 清除
首先清除上方/etc/ld.so.preload文件中查看到的/lib/evil.so文件,使其无法正常预加载。然后清除/etc/ld.so.preload中的恶意文件内容,有的恶意动态链接库会修改该文件的隐藏权限,以及普通的读写权限,所以需要看一下,然后再清除,到此为止即清除成功。
1 | [root@test ~]# mv /lib/evil.so /lib/test.so |
3. 修改动态链接器来实现恶意功能
检测
使用strace命令来查看预加载的配置文件是不是/etc/ld.so.preload文件,如下图,动态链接库预加载的配置文件是/sbin/.XsknPn3F而不是原有的配置文件,我们即可确认系统中存在修改动态链接器的rootkit
使用busybox自带的cat命令查看该文件,因为使用正常cat命令无法查看该文件,被预加载的库函数给隐藏了
清除
清除修改动态链接器的rootkit,需要使用相同系统的相同版本动态链接器替换被修改了的动态链接器,才能达到彻底清除的目的。暂时缓解的方式则是将上方检测过程中看到的恶意动态链接库删除,以及将对应的动态链接库配置文件中的内容清除。
参考:FreeBuf专栏
- 本文作者: GaryWu
- 本文链接: https://garywu520.github.io/2020/04/13/Linux共享库文件注入-防御与清理/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!