动态库搜索路径可被改写
Linux 程序依赖动态链接库,运行时按固定顺序查找:先看程序自身指定的路径与 LD_LIBRARY_PATH 环境变量,再查 /etc/ld.so.cache 里缓存的位置,而缓存内容由 /etc/ld.so.conf 与 /etc/ld.so.conf.d/ 下的配置文件在运行 ldconfig 时生成。只要把自定义目录加进配置并放入同名库文件,就能实现全局替换——这是很隐蔽的持久化手法。
核查要同时看两处
只看配置目录还不够,配置了目录却没有放入同名库文件不会产生任何实际影响。判定时必须一起核对:配置文件的时间戳与内容、ldconfig 缓存里该库名对应的实际路径、以及这些路径下的文件时间与哈希。缓存文件 /etc/ld.so.cache 的修改时间可以反映最近一次 ldconfig 的执行时刻。
基本信息
| 适用平台 | Linux(glibc 动态链接器) |
|---|---|
| 配置文件 | /etc/ld.so.conf、/etc/ld.so.conf.d/*.conf |
| 缓存文件 | /etc/ld.so.cache,由 ldconfig 生成 |
| 查询命令 | ldconfig -p | grep <库名> |
| 其他入口 | LD_PRELOAD 环境变量与 /etc/ld.so.preload 文件 |
典型使用场景
- 发现异常网络行为但找不到进程:检查是否有库被替换用于劫持系统调用
- 排查持久化点:查看配置目录中新增的 .conf 文件与对应目录
- 核对库位置:确认某个系统库实际加载的是哪个路径下的文件
- 排查登录劫持:结合 pam 相关库的加载路径判断是否被替换
- 建立基线:记录正常配置文件与缓存哈希,异常时快速比对
核查配置与缓存
核查配置与缓存
# 配置文件时间戳:新增的 .conf 往往是重点
ls -lt --time-style=long-iso /etc/ld.so.conf.d/
cat /etc/ld.so.conf /etc/ld.so.conf.d/*.conf 2>/dev/null
# 查看缓存中该库实际解析到的路径
ldconfig -p | grep -E 'libc\.so|libpam' | head
# 核对对应文件的属性与时间
# ls -l /usr/local/lib/libxxx.so*
# 检查预加载入口:这里被写入会全局生效
cat /etc/ld.so.preload 2>/dev/null
env | grep -i LD_搜索顺序与劫持点
| 环节 | 来源 | 被利用的方式 |
|---|---|---|
| 程序内置路径 | 编译时写入的 rpath | 正常情况下不应指向临时目录 |
| 环境变量 | LD_LIBRARY_PATH、LD_PRELOAD | 登录脚本中被设置即可劫持 |
| 预加载文件 | /etc/ld.so.preload | 全系统生效,隐蔽性高 |
| 配置文件目录 | /etc/ld.so.conf.d/*.conf | 新增目录并放入同名库 |
| 系统默认目录 | /lib、/usr/lib 等 | 直接替换系统库文件 |
改动配置文件后需要执行 ldconfig 才会生成新的缓存,因此缓存文件的修改时间通常晚于配置文件的修改时间,两者的时间差可以辅助判断操作顺序。
库文件替换后系统通常仍能正常启动,因为部分二进制使用静态链接或绝对路径加载;「系统看起来没问题」不能作为未被替换的依据。